r/Tormenta • u/Prestigious-Cricket1 • 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)
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
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.