Para muitos scripts, actualizá-los para serem compatíveis com a folha de 2024 resume-se a mudar duas coisas: como obtém e define atributos e como analisa modelos de rolo/mensagens de chat. Este documento irá guiá-lo através de ambos, bem como solucionar alguns problemas comuns para que possa atualizar qualquer script para ser compatível com a folha D&D2014 e a folha D&D2024.
Quando o seu script é atualizado desta forma, em jogos com fichas Beacon como D&D2024, os GMs terão de usar o servidor Experimental API para usar todas as funcionalidades mais recentes. O servidor Experimental tem todas as mesmas funcionalidades que o servidor Predefinido, por isso não deve quebrar quaisquer outros scripts para fazer esta mudança, mas pode querer chamar a atenção para isso na descrição do script para que os seus utilizadores saibam. Se não existir uma folha Beacon, o servidor predefinido continuará a funcionar com estas funções, uma vez que voltará a utilizar as funções antigas de obtenção e definição de atributos.
Atualização Definição/Obtenção
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 obtém e define atributos. Existe agora um novo conjunto de funções assíncronas denominadas getSheetItem
e setSheetItem
. Eis 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 (se existir um máximo), pode passar a propriedade max, como em getSheetItem(characterId, "deathsave_succ1",
" max");
.
Repare que no código acima, getDeathSaveSuccess
está marcado como assíncrono. Todas as funções que usem getSheetItem
terão de usar este padrão async/await ou usar promessas. Aqui está a mesma função acima, 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 após o outro e o resto do seu código depender desses dados, pode aguardar
cada valor individualmente ou utilizar Promise.all
para resolver todas as promessas de uma só vez e obter o valor final. Se não o fizer, o valor que irá receber será apenas 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 muitas ramificações na forma como escreve um script, dependendo da forma como o estruturou. Por exemplo, se houver um script que esteja a utilizar getAttrByName
dentro de um replace
ou map
, terá de ser dividido num ciclo mais assíncrono, porque essas funções não esperam pelo retorno de um valor antes de continuar.
Vamos recuar até ao momento em que escrevi "Se está a tentar obter vários valores de uma só vez ou um após o outro e o resto do seu código depende de ter esses dados". O resto do seu código nem sempre depende de ter esse valor. Na maior parte das vezes, vai depender desse valor se estiver a utilizar getSheetItem
, porque vai querer fazer alguma coisa com qualquer atributo que esteja a obter. No entanto, muitas vezes, para o inverso, setSheetItem
, não precisa de esperar que termine. Nesse caso, pode ignorar as ramificações do facto de estas funções serem assíncronas e chamá-las normalmente. O atributo será atualizado em segundo plano enquanto o seu script prossegue.
A função setSheetItem
funciona da mesma forma que getSheetItem
, mas inclui um argumento extra para determinar o atributo a definir.
setSheetItem(characterId, "hp", 10);
setSheetItem(characterId, "hp", 20, "max");
Atualização da análise de rolos
A outra coisa que muitos scripts da 5e fazem e que precisa de ser actualizada é a análise dos lançamentos. Os rolos que são enviados para o chat têm um formato completamente diferente e terão de ser analisados de forma diferente para obter resultados ou saber pormenores sobre o conteúdo. A equipa de desenvolvimento adicionou alguns atributos de dados ao HTML que minimizam a necessidade de uma análise extensiva do HTML, mas se precisar de dados mais complexos, poderá ter de os analisar a partir da mensagem enviada para o chat. Descrevemos abaixo algumas necessidades comuns para o ajudar a começar.
Para obter o resultado de um lançamento no nosso modelo de lançamento standard:
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 o cabeçalho aqui<\/div>/);
Para verificar a legenda do lançamento para saber coisas 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 desenvolvimento ativo, é possível que haja alterações nos modelos de rolagem que exijam novas actualizações dos seus scripts. Não podemos prometer que a análise de cadeias de caracteres do HTML se manterá estável para sempre, mas estamos a trabalhar para obter modelos mais padronizados à medida que desenvolvemos mais a folha. Os exemplos acima são um pouco rígidos no seu regex para simplificar, mas recomendamos a utilização de correspondência difusa e wildcards para tornar a sua correspondência mais robusta enquanto os modelos de rolo ainda estão em fluxo.
Problemas comuns
"Erro: Não foi encontrado qualquer atributo ou campo de folha para character_id (O SEU ID AQUI) denominado (O SEU ATRIBUTO AQUI)"
Causa provável: Provavelmente está na API predefinida em vez da API experimental e está a tentar aceder a uma propriedade computada do Beacon. Quando clicar em "Reiniciar servidor", certifique-se de que a mensagem de reinício da API inclui a palavra EXPERIMENTAL e não DEFAULT. Se o menu suspenso estiver definido como Experimental, mas os registos de reinício indicarem DEFAULT, volte a mudar para Default, reinicie e, em seguida, volte a mudar para Experimental e reinicie novamente. Trata-se de um problema conhecido com a alternância entre Predefinição e Experimental que estamos atualmente a investigar.
O resultado de getSheetItem está a registar um objeto vazio em vez de um valor
Causa provável: não aguardar ou utilizar .then na função getSheetItem. Tem de esperar que o valor seja devolvido antes de avançar com o código.