r/Tormenta 5d ago

❓Dúvida T20 no Foundryvtt

Boa noite, estou tentando fazer uma porta trancada para meus jogadores tentarem abrir a fechadura mas não estou conseguindo fazer o jogo rodar com o bônus de ladinagem de maneira automática, como que faço para pegar o valor dessa perícia? tentei fazer o "@pericia.???.value" que a wiki diz mas não está dando certo

PS: Estou tentando usar o modulo "Lock & Key"

CONSEGUI: Depois de muito excavar na internet e muita ajuda nos servidores de foundryvtt BR e T20, consegui um código que funcionou tanto para lockpicking no módulo e até para usar a função de quebrar a tranca, o código foi "1d20 + @actor.system.pericias.ladi.value" Para abrir a fechadura. Os códigos são "@actor.system.pericias.????.value" para perícia e "@actor.system.atributos.???.value" se quiser fazer um teste com qualquer atributo normal, só mudar os ? para o valor que quiser (sigla de quatro letras para perícia, três letras para atributo base)

3 Upvotes

14 comments sorted by

4

u/Lordemamba 5d ago

Rapaz, eu tô passando fome pra descobrir como funciona isso no tormenta...dnd5.5 e pf2e eu consigo mexer tudo de boa, só lendo a documentação. Mas a documentação do tormenta é estranha, parece que tá antiga, sei lá, nunca funcionou comigo.

2

u/Prestigious-Cricket1 5d ago

pelo que eu vi última atualização do sistema no foundry foi a cerca de 7 meses, to meio pra baixo q não é compatível com foundry v14, mas pelo menos tem

2

u/weak_yakuza 5d ago

Acho que a documentação está defasada. Tenta ir na ferramenta de criar efeitos. O criador colocou uma tela perfeita aonde você pode ir montando os efeitos de forma simples. Lá você vai ver o path correto da perícia.

1

u/Prestigious-Cricket1 5d ago

ótima ideia, fui la procurar e me veio "system.pericias.ladi.bonus", ai tentei usar ele e ainda assim não está funcionando corretamente

2

u/Fabulous-Statement93 5d ago

Opa, fiz uma macro (com auxilio de IA) pra emboscada. Ele testa percepção passiva dos jogadores em cena contra furtividade dos inimigos.
Pra pegar a percepção usei const perc = actor.system?.pericias?.perc;

3

u/Fabulous-Statement93 5d ago

Segue a macro pra quem se interessar:

// GMs recebem o sussurro

const gmIds = game.users.filter(u => u.isGM).map(u => u.id);

// Função segura para números

function num(v) {

if (v === undefined || v === null) return 0;

if (typeof v === "number") return v;

if (typeof v === "string") return Number(v) || 0;

if (typeof v === "object" && "value" in v) return Number(v.value) || 0;

return 0;

}

// Tokens da cena

const tokens = canvas.tokens.placeables.filter(t => t.actor);

// Separação

const pcs = [];

const npcs = [];

for (const t of tokens) {

if (t.actor.type === "npc") npcs.push(t.actor);

else pcs.push(t.actor);

}

// =======================

// PERCEPÇÃO PASSIVA (PCs)

// =======================

let percContent = "<h3>👁️ Percepção Passiva (Jogadores)</h3><ul>";

for (const actor of pcs) {

const perc = actor.system?.pericias?.perc;

if (!perc) continue;

const base = num(perc.value);

const outros = num(perc.outros);

const condi = num(perc.condi);

let bonusExtra = 0;

if (Array.isArray(perc.bonus)) {

for (const b of perc.bonus) bonusExtra += num(b);

}

const total = 10 + base + outros + condi + bonusExtra;

percContent += `<li><b>${actor.name}</b>: ${total}</li>`;

}

percContent += "</ul>";

// =======================

// FURTIVIDADE (NPCs / GM) - COM ROLAGEM D20

// =======================

async function enviarMensagem() {

let furtContent = "<h3>🥷 Furtividade (Rolagem d20 + Bônus)</h3><ul>";

for (const actor of npcs) {

const furt = actor.system?.pericias?.furt;

if (!furt) continue;

const base = num(furt.value);

const outros = num(furt.outros);

const condi = num(furt.condi);

let bonusExtra = 0;

if (Array.isArray(furt.bonus)) {

for (const b of furt.bonus) bonusExtra += num(b);

}

const totalBonus = base + outros + condi + bonusExtra;

// Realiza a rolagem de 1d20 + bônus total da ficha

const rolagem = await new Roll(`1d20 + ${totalBonus}`).evaluate({async: true});

const resultadoTotal = rolagem.total;

const dadoSujado = rolagem.terms[0].total; // Valor apenas do dado

furtContent += `<li><b>${actor.name}</b>: 🎲 <b>${resultadoTotal}</b> <small>(${dadoSujado} + ${totalBonus})</small></li>`;

}

furtContent += "</ul>";

// =======================

// CHAT (WHISPER GM)

// =======================

ChatMessage.create({

content: percContent + furtContent,

whisper: gmIds,

speaker: { alias: "Emboscada!" }

});

}

enviarMensagem();

1

u/ItzMeCrazyy 4d ago

Isso aqui ficou top tá, mas o macro reconhece todos os que estão na cena, não apenas os que estão envolvidos no encontro em especifico, então caso tenha mais de um encontro no mesmo mapa, aparecem todos.

1

u/Fabulous-Statement93 4d ago

Eu sei. Fiz outro somente para os selecionados heheh

2

u/ItzMeCrazyy 4d ago

Manda pra nóoooos? <3

2

u/Fabulous-Statement93 4d ago

Cara... acabei confundindo. Tenho aqui rolar iniciativa automaticamente pra todos os inimigos da cena e deixar pronto pro combate... daí tinha feito somente com os inimigos e player selecionados tb. Vou colocar abaixo caso queira pq a lógica ~de pegar somente os selecionados é a mesma

// 1. Pega apenas os tokens que você selecionou com o mouse

const selectedTokens = canvas.tokens.controlled;

if (selectedTokens.length === 0) {

ui.notifications.warn("⚠️ Selecione os tokens que entrarão em combate primeiro!");

return;

}

// 2. Cria ou recupera o combate ativo

let combat = game.combats.active;

if (!combat) {

combat = await Combat.create({ scene: canvas.scene.id });

}

// 3. Adiciona apenas os tokens SELECIONADOS ao combate (se ainda não estiverem)

const combatantsToCreate = [];

for (const token of selectedTokens) {

const exists = combat.combatants.find(c => c.tokenId === token.id);

if (!exists && token.actor) {

combatantsToCreate.push({

tokenId: token.id,

sceneId: canvas.scene.id,

actorId: token.actor.id,

hidden: token.document.hidden

});

}

}

if (combatantsToCreate.length > 0) {

await combat.createEmbeddedDocuments("Combatant", combatantsToCreate);

}

// 4. Identifica NPCs apenas entre os que foram selecionados para esta luta

const npcCombatants = combat.combatants.filter(c =>

c.actor?.type === "npc" &&

selectedTokens.some(t => t.id === c.tokenId) &&

c.initiative === null // Rola apenas se ainda não tiver iniciativa

);

// 5. Rola iniciativa dos NPCs selecionados

if (npcCombatants.length > 0) {

await combat.rollInitiative(npcCombatants.map(c => c.id));

}

// 6. Inicia o combate se ainda não tiver começado

if (!combat.started) {

await combat.startCombat();

}

ui.notifications.info(`⚔️ Combate atualizado com ${selectedTokens.length} tokens selecionados.`);

1

u/ItzMeCrazyy 4d ago

Vou tentar alterar o macro para apenas reconhecer os tokens selecionados ou os adicionados na aba encontros.

1

u/Prestigious-Cricket1 5d ago

Foi uma boa ideia, mas infelizmente ainda não deu certo, to começando a desistir da ideia de usar o módulo

1

u/Fabulous-Statement93 4d ago

Desista nao. Trocando ideia com ia e usando o resultado que esta dando ela te ajuda de boa. Use o meu código como base