From 92940a4d46ed8950da4e80993c212c2a403b2df6 Mon Sep 17 00:00:00 2001 From: Michal Tuszowski Date: Tue, 16 Jun 2026 10:47:01 +0200 Subject: [PATCH] Changes, preparing for dockerization 2.0 --- backup_non_stable_docker | 0 rpg/armour.csv | 3 -- rpg/attack_test.js | 60 ---------------------------- rpg/critical_hits.csv | 6 --- rpg/focus_power.js | 50 ----------------------- rpg/hit_location.js | 22 ---------- rpg/hose_rules.js | 6 --- rpg/inititative.js | 11 ----- rpg/perils.csv | 21 ---------- rpg/powers.csv | 3 -- rpg/pp.csv | 21 ---------- rpg/quick_conditions.js | 28 ------------- rpg/quick_damage.js | 38 ------------------ rpg/table_gen.js | 26 ------------ rpg/talents.csv | 3 -- rpg/weapons.csv | 3 -- rpg/zealous_hatred.js | 33 --------------- working_copy/conanjurer_functions.py | 37 ++++++++--------- 18 files changed, 19 insertions(+), 352 deletions(-) create mode 100644 backup_non_stable_docker delete mode 100644 rpg/armour.csv delete mode 100644 rpg/attack_test.js delete mode 100644 rpg/critical_hits.csv delete mode 100644 rpg/focus_power.js delete mode 100644 rpg/hit_location.js delete mode 100644 rpg/hose_rules.js delete mode 100644 rpg/inititative.js delete mode 100644 rpg/perils.csv delete mode 100644 rpg/powers.csv delete mode 100644 rpg/pp.csv delete mode 100644 rpg/quick_conditions.js delete mode 100644 rpg/quick_damage.js delete mode 100644 rpg/table_gen.js delete mode 100644 rpg/talents.csv delete mode 100644 rpg/weapons.csv delete mode 100644 rpg/zealous_hatred.js diff --git a/backup_non_stable_docker b/backup_non_stable_docker new file mode 100644 index 0000000..e69de29 diff --git a/rpg/armour.csv b/rpg/armour.csv deleted file mode 100644 index 1afa6f2..0000000 --- a/rpg/armour.csv +++ /dev/null @@ -1,3 +0,0 @@ -name,type,locations,ap_head,ap_body,ap_larm,ap_rarm,ap_lleg,ap_rleg,max_ag,traits,weight,availability,source,notes -Flak Vest,armor,"Body",0,4,0,0,0,0,,Flak,7,Common,"DH2 CRB","PRZYKŁAD – ZASTĄP" -Power Armour (Astartes),armor,"All",8,10,8,8,9,9,,Environmental; Auto-senses,100,"Very Rare","DW CRB","PRZYKŁAD – ZASTĄP" diff --git a/rpg/attack_test.js b/rpg/attack_test.js deleted file mode 100644 index 2f8e32d..0000000 --- a/rpg/attack_test.js +++ /dev/null @@ -1,60 +0,0 @@ -// DH2 Attack Test v2 — presets: Aim/Range/Fire + Size/Light/Cover -const actor = canvas.tokens.controlled[0]?.actor ?? game.user.character; -if (!actor) return ui.notifications.warn("Zaznacz token albo przypisz postać."); -new Dialog({ - title: "🎯 Attack Test (WS/BS)", - content: ` -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
`, - buttons: { - roll: { - label: "Roll", - callback: async (html) => { - const get = n => Number(html.find(`[name="${n}"]`).val()); - const base = get("base"); - const total = base + get("aim") + get("range") + get("stance") + get("size") + get("light") + get("cover") + get("mod"); - const r = await(new Roll("1d100")).roll({async:true}); - const ok = r.total <= total; - const margin = Math.abs(total - r.total); - const dox = ok ? 1 + Math.floor(margin/10) : Math.floor(margin/10); - const table = ` - - - -
Target${total}Roll${r.total}
Result${ok?'SUCCESS':'FAIL'} — ${ok?dox+' DoS':dox+' DoF'}
`; - r.toMessage({speaker: ChatMessage.getSpeaker({actor}), flavor: `🎯 Attack Test
${table}`}); - } - } - } -}).render(true); diff --git a/rpg/critical_hits.csv b/rpg/critical_hits.csv deleted file mode 100644 index d30ef62..0000000 --- a/rpg/critical_hits.csv +++ /dev/null @@ -1,6 +0,0 @@ -Roll,Result -1,Energy/Head — wpis 1 -2,Energy/Head — wpis 2 -3,Energy/Head — wpis 3 -4,Energy/Head — wpis 4 -5,Energy/Head — wpis 5 diff --git a/rpg/focus_power.js b/rpg/focus_power.js deleted file mode 100644 index 8b8cddd..0000000 --- a/rpg/focus_power.js +++ /dev/null @@ -1,50 +0,0 @@ -// 🧠 Focus Power (DH2) — WP test + Phenomena/Perils with mode presets -const actor = canvas.tokens.controlled[0]?.actor ?? game.user.character; -if (!actor) return ui.notifications.warn("Zaznacz token."); -new Dialog({ - title: "🧠 Focus Power", - content: ` -
-
-
-
-
-
-
-
`, - buttons: { - roll: { label: "Roll", callback: async html => { - const wp = Number(html.find('[name="wp"]').val()); - const pr = Number(html.find('[name="pr"]').val()); - const mode = html.find('[name="mode"]').val(); - const flat = Number(html.find('[name="flat"]').val()); - const thr = Number(html.find('[name="thr"]').val()); - let effPR = pr, ppmod = 0, ppAlways = false, note = ""; - if (mode==="fettered"){ effPR = Math.max(1, Math.floor(pr/2)); note="(Fettered: PR/2, brak Phenomena)"; } - if (mode==="push"){ effPR = pr+3; ppmod=10; ppAlways = true; note="(Push: +3 PR, Phenomena zawsze, +10)"; } - const target = wp + flat; - const roll = await (new Roll("1d100")).roll({async:true}); - const ok = roll.total <= target; - const dos = ok ? 1 + Math.floor((target - roll.total)/10) : Math.floor((roll.total - target)/10); - const doubles = (roll.total%11===0) || (roll.total===100); - const info = ` - - - -
Target${target}Roll${roll.total}
Result${ok?'SUCCESS':'FAIL'} — ${ok?dos+' DoS':dos+' DoF'} ${doubles?' — DOUBLES':''}
Eff. PR${effPR}Range hint${effPR*10} m (jeśli moc tak działa)
`; - roll.toMessage({speaker: ChatMessage.getSpeaker({actor}), flavor:`🧠 Focus Power ${note}
${info}`}); - const needPP = (mode==="unfettered" && doubles) || (mode==="push") ; - if (needPP){ - const tbl = game.tables.getName("Psychic Phenomena"); - if (tbl){ - const r = await (new Roll(`1d100 + ${ppmod}`)).roll({async:true}); - await tbl.draw({displayResults:true, roll:r}); - if (r.total >= thr){ - const per = game.tables.getName("Perils of the Warp"); - if (per) await per.draw({displayResults:true}); - } - } else ChatMessage.create({content:"Utwórz RollTable: Psychic Phenomena (+ Perils of the Warp)"}); - } - }} - } -}).render(true); diff --git a/rpg/hit_location.js b/rpg/hit_location.js deleted file mode 100644 index 7c2b2a6..0000000 --- a/rpg/hit_location.js +++ /dev/null @@ -1,22 +0,0 @@ -// 🎯 Hit Location (DH mapping by reversed roll) -new Dialog({ - title:"🎯 Hit Location", - content:`
-
-
`, - buttons:{ - go:{label:"Resolve", callback: html=>{ - const n = Math.max(1, Math.min(100, Number(html.find('[name="roll"]').val()))); - const rev = Number(String(n).padStart(2,"0").split("").reverse().join("")); - let loc = ""; - if (rev<=10) loc="Head"; - else if (rev<=20) loc="Right Arm"; - else if (rev<=30) loc="Left Arm"; - else if (rev<=70) loc="Body"; - else if (rev<=85) loc="Right Leg"; - else loc="Left Leg"; - ChatMessage.create({content:`🎯 Hit Location: roll ${n} → reversed ${rev} → ${loc}`}); - }} - } - }).render(true); - \ No newline at end of file diff --git a/rpg/hose_rules.js b/rpg/hose_rules.js deleted file mode 100644 index eec1dcd..0000000 --- a/rpg/hose_rules.js +++ /dev/null @@ -1,6 +0,0 @@ -const text=`House Rules — DH2 chassis
-• Unnatural mapowanie: dawne ×2 bonus → Unnatural (+X) tak, by SB/TB odzwierciedlały linię źródłową.
-• Pancerz Astartes: zachowaj AP; zużycie zasilania jako +1 Fatigue co X scen zamiast liczenia minut.
-• Aptitudes: archetypy z RT/DW/BC mają przypisane 2–3 Aptitudes DH2 dla kosztów XP.
-• Psy: testy i PR z DH2 dla wszystkich; GK posiada Aegis Discipline (1×/scena reroll Perils) + 1–2 signature powers z DW.
-• RT Acquisition → DH2 Influence z modyfikatorami kontekstowymi (teatr działań, mandat Inkwizycji, czas).`;ChatMessage.create({content:text}); diff --git a/rpg/inititative.js b/rpg/inititative.js deleted file mode 100644 index f37d0c8..0000000 --- a/rpg/inititative.js +++ /dev/null @@ -1,11 +0,0 @@ -// 🚦 Initiative for selected tokens (1d10 + AG Bonus prompt) -if (!canvas.tokens.controlled.length) return ui.notifications.warn("Zaznacz co najmniej jeden token."); -const combat = game.combat ?? await Combat.implementation.create({}); -for (const t of canvas.tokens.controlled){ - if (!combat.combatants.some(c=>c.tokenId===t.id)) await combat.createEmbeddedDocuments("Combatant",[ {tokenId:t.id, sceneId: canvas.scene.id, hidden:false} ]); - const ag = Number(await Dialog.prompt({title:`AG Bonus for ${t.name}`, content:``, label:"OK"})); - const r = await (new Roll(`1d10 + ${ag}`)).roll({async:true}); - await combat.setInitiative(combat.combatants.find(c=>c.tokenId===t.id).id, r.total); - r.toMessage({flavor:`🚦 Initiative — ${t.name}: ${r.total}`}); -} -ui.notifications.info("Inicjatywy ustawione."); diff --git a/rpg/perils.csv b/rpg/perils.csv deleted file mode 100644 index aa97592..0000000 --- a/rpg/perils.csv +++ /dev/null @@ -1,21 +0,0 @@ -Roll,Result -1-5,Perils 1–5 — WPISZ -6-10,Perils 6–10 — WPISZ -11-15,Perils 11–15 — WPISZ -16-20,Perils 16–20 — WPISZ -21-25,Perils 21–25 — WPISZ -26-30,Perils 26–30 — WPISZ -31-35,Perils 31–35 — WPISZ -36-40,Perils 36–40 — WPISZ -41-45,Perils 41–45 — WPISZ -46-50,Perils 46–50 — WPISZ -51-55,Perils 51–55 — WPISZ -56-60,Perils 56–60 — WPISZ -61-65,Perils 61–65 — WPISZ -66-70,Perils 66–70 — WPISZ -71-75,Perils 71–75 — WPISZ -76-80,Perils 76–80 — WPISZ -81-85,Perils 81–85 — WPISZ -86-90,Perils 86–90 — WPISZ -91-95,Perils 91–95 — WPISZ -96-100,Perils 96–100 — WPISZ diff --git a/rpg/powers.csv b/rpg/powers.csv deleted file mode 100644 index c274d44..0000000 --- a/rpg/powers.csv +++ /dev/null @@ -1,3 +0,0 @@ -name,type,discipline,action,test,range,sustained,effect,source,notes -Smite,power,Biomancy,Half,"WP Challenging (+0)","PR*10m",No,"1d10+PR E; Tearing","DH2 CRB","PRZYKŁAD – ZASTĄP" -Foreboding,power,Divination,Reaction,"Per Difficult (-10)","Self",No,"Use as Evasion; DoS rules","DH2 CRB","PRZYKŁAD – ZASTĄP" diff --git a/rpg/pp.csv b/rpg/pp.csv deleted file mode 100644 index a5bd82f..0000000 --- a/rpg/pp.csv +++ /dev/null @@ -1,21 +0,0 @@ -Roll,Result -1-5,PP 1–5 — WPISZ -6-10,PP 6–10 — WPISZ -11-15,PP 11–15 — WPISZ -16-20,PP 16–20 — WPISZ -21-25,PP 21–25 — WPISZ -26-30,PP 26–30 — WPISZ -31-35,PP 31–35 — WPISZ -36-40,PP 36–40 — WPISZ -41-45,PP 41–45 — WPISZ -46-50,PP 46–50 — WPISZ -51-55,PP 51–55 — WPISZ -56-60,PP 56–60 — WPISZ -61-65,PP 61–65 — WPISZ -66-70,PP 66–70 — WPISZ -71-75,PP 71–75 — WPISZ -76-80,PP 76–80 — WPISZ -81-85,PP 81–85 — WPISZ -86-90,PP 86–90 — WPISZ -91-95,PP 91–95 — WPISZ -96-100,PP 96–100 — WPISZ diff --git a/rpg/quick_conditions.js b/rpg/quick_conditions.js deleted file mode 100644 index 90689f6..0000000 --- a/rpg/quick_conditions.js +++ /dev/null @@ -1,28 +0,0 @@ -// 🩹 Toggle conditions on selected tokens (Foundry v13) -const choices = [ - {id:"fatigued", label:"Fatigued"}, - {id:"stunned", label:"Stunned"}, - {id:"prone", label:"Prone"}, - {id:"frightened", label:"Frightened (Fear)"} - ]; - const opts = choices.map(c=>``).join("
"); - new Dialog({ - title:"🩹 Conditions", - content:`
${opts}
-
`, - buttons:{ - go:{label:"Apply",callback: html=>{ - const ids = Array.from(html.find('input[name="c"]:checked')).map(e=>e.value); - const mode = html.find('[name="mode"]').val(); - const getEf = id => CONFIG.statusEffects.find(e=>e.id===id) ?? {id}; - canvas.tokens.controlled.forEach(t=>{ - ids.forEach(id=>{ - if (mode==="toggle") t.toggleEffect(getEf(id)); - else if (mode==="on") t.actor?.effects?.some(e=>e.getFlag("core","statusId")===id) ? null : t.toggleEffect(getEf(id)); - else if (mode==="off") t.actor?.effects?.some(e=>e.getFlag("core","statusId")===id) ? t.toggleEffect(getEf(id)) : null; - }); - }); - }} - } - }).render(true); - \ No newline at end of file diff --git a/rpg/quick_damage.js b/rpg/quick_damage.js deleted file mode 100644 index 2020436..0000000 --- a/rpg/quick_damage.js +++ /dev/null @@ -1,38 +0,0 @@ -// 💥 Quick Damage — supports Tearing, Proven(X), Primitive(X), flat mod -new Dialog({ - title:"💥 Damage Roller", - content: ` -
-
-
- - - - - -
-
`, - buttons:{ - go:{label:"Roll", callback: async html=>{ - const mod = Number(html.find('[name="mod"]').val()); - const tearing = html.find('[name="tear"]')[0].checked; - const proven = html.find('[name="prov"]')[0].checked ? Number(html.find('[name="provV"]').val()) : 0; - const primitive = html.find('[name="prim"]')[0].checked ? Number(html.find('[name="primV"]').val()) : 0; - // base die (d10) with tearing (best of 2) - const r1 = await (new Roll("1d10")).roll({async:true}); - const r2 = tearing ? await (new Roll("1d10")).roll({async:true}) : null; - let die = tearing ? Math.max(r1.total, r2.total) : r1.total; - // apply Proven/Primitive - if (proven>0) die = Math.max(die, proven); - if (primitive>0) die = Math.min(die, primitive); - const rf = (die===10); // potential Zealous Hatred trigger - const total = die + mod; - let flavor = `💥 Damage
Die: ${die}${tearing?` (Tearing ${r1.total}/${r2.total.total})`:''} + Mod ${mod} = ${total}`; - if (proven>0) flavor += `
Proven(${proven}) zastosowano`; - if (primitive>0) flavor += `
Primitive(${primitive}) zastosowano`; - if (rf) flavor += `
⚡ Natural 10 — rozważ Zealous Hatred.`; - ChatMessage.create({speaker: ChatMessage.getSpeaker(), content: flavor}); - }} - } - }).render(true); - \ No newline at end of file diff --git a/rpg/table_gen.js b/rpg/table_gen.js deleted file mode 100644 index ec0f29c..0000000 --- a/rpg/table_gen.js +++ /dev/null @@ -1,26 +0,0 @@ -// 📚 Create placeholder RollTables for Crits + Psychic Phenomena/Perils (with icons) -const icon = {Energy:"⚡", Impact:"🔨", Rending:"🗡️", Explosive:"💥"}; -const dmgTypes = ["Energy","Impact","Rending","Explosive"]; -const locs = ["Head","Body","Left Arm","Right Arm","Left Leg","Right Leg"]; -async function makeCrit(dtype, loc){ - const name = `Crit: ${dtype} - ${loc}`; - if (game.tables.getName(name)) return; - const results = []; - for (let i=1;i<=5;i++){ - results.push({type:0, text:`${icon[dtype]||""} ${dtype}/${loc} — wpis ${i} (uzupełnij z PDF)`, weight:1, range:[i,i]}); - } - await RollTable.implementation.create({name, formula:"1d5", replacement:true, displayRoll:false, results}); -} -async function makeWide(name, emoji){ - if (game.tables.getName(name)) return; - const results = []; - for (let i=0;i<20;i++){ - const lo=i*5+1, hi=i*5+5; - results.push({type:0, text:`${emoji} ${name} ${lo}-${hi} — wpis (uzupełnij z PDF)`, weight:1, range:[lo,hi]}); - } - await RollTable.implementation.create({name, formula:"1d100", replacement:true, displayRoll:false, results}); -} -for (const d of dmgTypes) for (const l of locs) await makeCrit(d,l); -await makeWide("Psychic Phenomena","🌀"); -await makeWide("Perils of the Warp","☠️"); -ui.notifications.info("Utworzono puste tabele: Crits (4×6) + Phenomena + Perils."); diff --git a/rpg/talents.csv b/rpg/talents.csv deleted file mode 100644 index 529b9bb..0000000 --- a/rpg/talents.csv +++ /dev/null @@ -1,3 +0,0 @@ -name,type,tier,aptitudes,prereq,effect,source,notes -Ambidextrous,talent,1,"Agility; Offence","Ag 30","-10 to off-hand penalty","DH2 CRB","PRZYKŁAD – ZASTĄP" -Aegis Discipline (GK),talent,2,"Willpower; Defence","Psyker","Reroll Perils 1×scene","HOUSE","DODAJ WŁASNY OPIS" diff --git a/rpg/weapons.csv b/rpg/weapons.csv deleted file mode 100644 index 8c9eee5..0000000 --- a/rpg/weapons.csv +++ /dev/null @@ -1,3 +0,0 @@ -name,type,subtype,damage,pen,range,rof,qualities,weight,availability,source,notes -Lasgun M36,weapon,Basic,"1d10+3",0,100m,"S/3/–","Reliable",4,Common,"DH2 CRB p.142","PRZYKŁAD – ZASTĄP" -Astartes Bolter,weapon,Basic,"1d10+9",4,90m,"S/2/–","Tearing; Unreliable",9,Rare,"DW CRB","PRZYKŁAD – ZASTĄP" diff --git a/rpg/zealous_hatred.js b/rpg/zealous_hatred.js deleted file mode 100644 index a945ca9..0000000 --- a/rpg/zealous_hatred.js +++ /dev/null @@ -1,33 +0,0 @@ -// ⚡ Zealous Hatred helper (DH2) — roll 1d5 crit OR add +1d5 dmg -new Dialog({ - title: "⚡ Zealous Hatred", - content: ` -
-
-
-
-
-
-
-
-
`, - buttons: { - go: { label: "Resolve", callback: async html => { - const pen = html.find('[name="penetrated"]').val(); - if (pen === "yes") { - const dtype = html.find('[name="dtype"]').val(); - const loc = html.find('[name="loc"]').val(); - const override = html.find('[name="tname"]').val()?.trim(); - const name = override || `Crit: ${dtype} - ${loc}`; - const r = await (new Roll("1d5")).roll({async:true}); - const table = game.tables.getName(name); - if (table) await table.draw({displayResults:true, roll:r}); - else r.toMessage({flavor:`⚡ Zealous Hatred: Critical ${r.total} — brak tabeli ${name} (utwórz lub zmień nazwę).`}); - } else { - const r = await (new Roll("1d5")).roll({async:true}); - r.toMessage({flavor:"⚡ Zealous Hatred: Dodaj do obrażeń +1d5 (atak nie przebił Soak)."}); - } - }} - } - }).render(true); - \ No newline at end of file diff --git a/working_copy/conanjurer_functions.py b/working_copy/conanjurer_functions.py index c0b2011..b94d18f 100644 --- a/working_copy/conanjurer_functions.py +++ b/working_copy/conanjurer_functions.py @@ -9,7 +9,26 @@ from typing import AsyncIterator, Callable, Awaitable from aiomcrcon import Client as _Rcon # Source RCON over TCP import asyncssh +load_dotenv() + log = logging.getLogger("discord") +@dataclass +class Event: + kind: str # "chat" | "login" | "logout" | "death" | "raw" + text: str # gotowy do wyświetlenia tekst + raw: str # oryginalna linia (do debugowania) + + +# --- REGEXY DO DOSTROJENIA NA WŁASNYM LOGU --- +# Poniżej PRZYKŁADOWE wzorce. Conan/Pippi/Tot logują różnie — sprawdź swój log +# i dopasuj. Jeśli wzorzec nie pasuje, linia trafia jako "raw" tylko do debug. +_PATTERNS: list[tuple[str, re.Pattern]] = [ + ("chat", re.compile(r"Chat:\s*(?P.+?):\s*(?P.+)$", re.I)), + ("login", re.compile(r"(?P.+?)\s+(joined|connected|logged in)", re.I)), + ("logout", re.compile(r"(?P.+?)\s+(left|disconnected|logged out)", re.I)), + ("death", re.compile(r"(?P.+?)\s+was killed by\s+(?P.+)$", re.I)), +] + @dataclass(frozen=True) class Config: # Discord @@ -91,22 +110,6 @@ class RconClient: pass self._client = None -@dataclass -class Event: - kind: str # "chat" | "login" | "logout" | "death" | "raw" - text: str # gotowy do wyświetlenia tekst - raw: str # oryginalna linia (do debugowania) - - -# --- REGEXY DO DOSTROJENIA NA WŁASNYM LOGU --- -# Poniżej PRZYKŁADOWE wzorce. Conan/Pippi/Tot logują różnie — sprawdź swój log -# i dopasuj. Jeśli wzorzec nie pasuje, linia trafia jako "raw" tylko do debug. -_PATTERNS: list[tuple[str, re.Pattern]] = [ - ("chat", re.compile(r"Chat:\s*(?P.+?):\s*(?P.+)$", re.I)), - ("login", re.compile(r"(?P.+?)\s+(joined|connected|logged in)", re.I)), - ("logout", re.compile(r"(?P.+?)\s+(left|disconnected|logged out)", re.I)), - ("death", re.compile(r"(?P.+?)\s+was killed by\s+(?P.+)$", re.I)), -] def parse_line(line: str) -> Event | None: @@ -195,8 +198,6 @@ async def watch(cfg, on_event: Callable[[Event], Awaitable[None]]) -> None: except Exception: log.exception("Błąd obsługi zdarzenia") -load_dotenv() - def _req(key: str) -> str: val = os.getenv(key) if not val or val.startswith("wklej") or val.startswith("000000"):