Devido às diferenças entre a infraestrutura de folhas legada e a infraestrutura de folhas do Beacon, nem todos os scripts Mod existentes funcionam com as folhas do Beacon de forma imediata. As notas abaixo irão ajudá-lo a atualizar os scripts para que funcionem com as folhas Beacon (por exemplo, D&D 2024). Atualizámos também vários scripts essenciais, pelo que estão disponíveis exemplos e scripts prontos a utilizar para os vossos jogos. Scripts que foram atualizados:
- Iniciativa do Grupo
- TokenMod
- Verificação de grupo
- Informações sobre o estado
Para muitos scripts, torná-los compatíveis com a folha de 2024 resume-se a duas alterações: a forma como obtém e define atributos e a forma como analisa os modelos de lançamento e as mensagens de chat. Este documento apresenta ambas as opções e aborda também problemas comuns, para que possa atualizar um script de modo a que funcione tanto com a folha D&D 2014 como com a folha D&D 2024.
As propriedades calculadas do Beacon e os atributos personalizados user.* requerem o Mod Script Sandbox v1.5 (Campaign().sandboxVersion === "1.5"). A versão 1.5 é a sandbox predefinida atual. Os métodos getSheetItem e setSheetItem existem tanto na v1.0 como na v1.5. Na versão 1.0, recorrem às funções get/set de atributos antigas, pelo que os jogos que não dispõem de uma folha Beacon continuam a funcionar. Na versão 1.5, também leem e escrevem propriedades calculadas do Beacon e os campos user.*. Apenas para o Mod Script Sandbox v1.5. getComputed, setComputed e performAction (consulte «Mod Scripts: Documentação das funções»).
Se o menu suspenso da sandbox de um jogo ainda apresentar as etiquetas «Padrão» e «Experimental», confirme a sandbox em execução através de Campaign().sandboxVersion, em vez de se basear na etiqueta. As propriedades computadas do Beacon necessitam do valor «1,5».
Atualização de get/set
A principal alteração entre o acesso aos dados da folha de 2014 e da folha de 2024, em termos de código, é a forma como se obtêm e definem os atributos. Existe agora um conjunto de funções assíncronas denominadas «getSheetItem » e «setSheetItem». Aqui está um exemplo de utilização das novas funções:
const getDeathSaveSuccess = async (id) => {
const firstSuccess = await getSheetItem(characterId, "deathsave_succ1");
log(`O primeiro sucesso é ${firstSuccess}`);
}
Se pretender obter o valor máximo de um atributo (caso exista um valor máximo), pode passar a propriedade «max», como em getSheetItem(characterId, "deathsave_succ1", "max");.
Irá reparar no código acima que a função ` getDeathSaveSuccess ` está marcada como «async». Todas as funções que utilizam o `getSheetItem` devem utilizar este padrão «async/await» ou recorrer a promessas. Eis a mesma função reescrita como uma promessa:
const getDeathSaveSuccess = (id) => {
getSheetItem(characterId, "deathsave_succ1").then((firstSuccess) => {
log(`O primeiro sucesso é ${firstSuccess}`);
});
}
Se estiver a tentar obter vários valores de uma só vez (ou um a seguir ao outro) e o resto do seu código depender desses dados, pode aguardar cada valor individualmente ou utilizar o `Promise.all` para resolver todas as promessas de uma só vez e obter os valores finais. Caso contrário, o valor que receberá será uma promessa pendente, e não o valor real do atributo.
const getSuccesses = (id) => {
const promises = [];
promises.push(getSheetItem(characterId, "deathsave_succ1"));
promises.push(getSheetItem(characterId, "deathsave_succ2"));
promises.push(getSheetItem(characterId, "deathsave_succ3"));
Promise.all(promises).then((results) => {
log(`O primeiro sucesso é ${results[0]}, o segundo sucesso é ${results[1]}, o terceiro sucesso é ${results[2]}`);
});
}
O código assíncrono pode ter várias implicações na forma como escreve um script, dependendo da forma como o estruturou. Por exemplo, se um script utilizar atualmente a função `getAttrByName` no interior de uma instrução `replace` ou `map`, terá de ser dividido num ciclo mais adequado à programação assíncrona, uma vez que essas funções não aguardam que um valor seja devolvido antes de prosseguirem.
Voltemos à frase: «Se estiver a tentar obter vários valores de uma só vez ou um após o outro e o resto do seu código depender desses dados.» O resto do seu código nem sempre depende desse valor. Na maioria das vezes, isso acontecerá se estiver a utilizar o `getSheetItem`, porque pretende fazer algo com o atributo que está a obter. No caso do método inverso, o `setSheetItem`, muitas vezes não é necessário aguardar que este termine. Nesse caso, pode ignorar as implicações da assíncronia e simplesmente chamá-la normalmente. O atributo será atualizado em segundo plano enquanto o seu script continua a ser executado.
A função `setSheetItem ` funciona da mesma forma que a função ` getSheetItem`, mas inclui um argumento adicional para o valor a definir:
setSheetItem(characterId, "hp", 10);
setSheetItem(characterId, "hp", 20, "max");
Atualização da análise da lista de papéis
Outro aspeto que muitos scripts da 5.ª edição apresentam e que necessita de uma atualização é a análise dos lançamentos. As mensagens enviadas para o chat têm um formato diferente e têm de ser analisadas de forma diferente para se obterem resultados ou detalhes sobre o conteúdo. A equipa de desenvolvimento adicionou alguns atributos de dados ao código HTML, o que reduz a necessidade de uma análise exaustiva do código HTML. Se necessitar de dados mais complexos, poderá ainda ter de os extrair da mensagem enviada para o chat. A seguir, apresentam-se algumas necessidades comuns.
Para obter o resultado de um lançamento no modelo de lançamento padrão:
const rollResultMatch = msg.content.match(/data-result="(.+?)"/);
Para verificar de que tipo de rolo se trata com base no título:
const deathSaveMatch = msgContent.match(/header__title">Insira aqui o cabeçalho<\/div>/);
Para verificar a descrição da jogada e obter informações como o nível do feitiço ou o tipo de dano:
const spellLevelMatch = msgContent.match(/header__subtitle">Level (.+?) /);
Uma vez que a folha de 2024 ainda se encontra em fase de desenvolvimento ativo, os modelos de rolo poderão sofrer alterações e exigir novas atualizações do script. Não podemos garantir que a análise do HTML através de cadeias de caracteres se mantenha estável para sempre, mas estamos a trabalhar no sentido de criar modelos mais padronizados à medida que a folha de cálculo for evoluindo. Os exemplos acima apresentam expressões regulares um pouco rígidas, por uma questão de simplicidade; recomendamos uma correspondência mais flexível e o uso de caracteres curinga para tornar a sua correspondência mais robusta enquanto os modelos ainda se encontram em fase de desenvolvimento.
Problemas comuns
Erro: Não foi encontrado nenhum atributo ou campo da folha para o character_id (A SUA ID AQUI) com o nome (O SEU ATRIBUTO AQUI)
Causa provável: Está a utilizar o Mod Script Sandbox v1.0 em vez da v1.5 e está a tentar aceder a uma propriedade calculada do Beacon. Confirme se Campaign().sandboxVersion é «1.5». Se o menu suspenso da sandbox continuar a apresentar as opções «Padrão» e «Experimental», é possível que a indicação esteja desatualizada; reinicie o sistema e verifique o valor de sandboxVersion (bem como o registo de reinício), em vez de se basear apenas no menu suspenso.
O resultado de getSheetItem está a registar um objeto vazio em vez de um valor.
Causa provável: não estar a aguardar ou a utilizar .then na função getSheetItem. É necessário aguardar o retorno do valor antes de prosseguir com o código.