Scripts do Trabalhador de Folhas

Adicionar um Script de Trabalhador de Planilha

Para adicionar um script de trabalhador de planilha a uma Ficha de Personagem, simplesmente adicione o script na seção "HTML" da planilha usando o seguinte formato:

<script tipo="text/worker">

em("change:strength", função() {

});

// ... etc

</script>

Observe que a tag do script deve ter um tipo de "text/worker" para ser tratada corretamente pelo sistema. Quando o jogo é carregado, todas as tags de script são removidas do modelo da planilha por motivos de segurança. No entanto, as tags de script com um tipo de "text/worker" serão usadas para iniciar um worker em segundo plano no computador de cada jogador que pode responder a valores em suas fichas que mudam e agir conforme necessário. Todos os scripts de sheetworker precisam estar contidos em uma única tag de script.

Mais exemplos abrangentes dos conceitos básicos voltados para não programadores

Aviso sobre o escopo de variável "global": o escopo de uma variável declarada dentro do `<script type="text/worker">` mas fora de uma função são atualmente por jogador, não por personagem. Alterar o valor dele irá alterá-lo para todos os personagens da sessão do jogador.

Como prática recomendada, as cascadas assíncronas devem ser evitadas sempre que possível. Geralmente, é uma prática melhor obter todos os atributos necessários para cálculos em um único getAttrs em vez de fazer getAttrs -> cálculos -> setAttrs -> getAttrs -> cálculos -> setAttrs…


Sheetworkers vs. Campos de Cálculo Automático: Qual devo usar?

Não há uma regra rígida e rápida sobre isso. Ambas essas ferramentas são capazes de alcançar a mesma coisa. Vamos pegar um caso de uso hipotético de um atributo "Força", que queremos usar para manter um atributo "Modificador de Força" atualizado. Aqui estão as diferenças entre as duas ferramentas para esse caso de uso:

  • Os campos de cálculo automático são todos recalculados toda vez que uma ficha é aberta pela primeira vez. Os campos do Trabalhador de Fichas, por outro lado, só são recalculados quando seus valores dependentes mudam. Isso significa que fichas que utilizam a opção Trabalhador de Fichas serão muito, muito mais rápidas para os jogadores abrir e interagir.
  • Além disso, os cálculos do Trabalhador de Fichas são executados em um processo em segundo plano, o que significa que não há atraso na interface do usuário enquanto os cálculos são executados. Campos desativados, por outro lado, são executados no processo principal e, como tal, podem causar "travamentos" ou "gagueiras" se houver um grande número deles sendo calculados de uma vez (por exemplo, se você tiver uma ficha muito complicada usando milhares de campos desativados).
  • O campo Modificador de Força de cálculo automático apareceria desativado para o jogador. Um campo Modificador de Força atualizado por um Trabalhador de Fichas, por outro lado, seria modificável após o cálculo ser executado (embora qualquer valor inserido seja sobrescrito quando o valor de Força mudar). Portanto, um Trabalhador de Fichas seria mais adequado para suportar regras caseiras, já que o jogador poderia simplesmente modificar o valor Mod após a mudança de Força. Por outro lado, o campo de cálculo automático não permitiria tal alteração, portanto as regras seriam "impostas" de forma mais rígida.

Em geral, nossa recomendação é que você use campos de cálculo automático com parcimônia. Dê a si mesmo um orçamento de no máximo 500 a 1.000 campos de cálculo automático. Recomendamos o uso da nova funcionalidade Sheet Worker para a maioria dos cálculos, especialmente cálculos que só precisam ser realizados raramente (por exemplo, seu valor de Força (e, portanto, seu Modificador de Força) provavelmente só muda no máximo uma vez por sessão quando o personagem sobe de nível. Não há necessidade de executar o mesmo cálculo repetidamente toda vez que a ficha é aberta.


API do Sheet Worker

Eventos

Objeto eventInfo

A muitos dos eventos é passado um objetoeventInfoque lhe dá detalhes adicionais sobre as circunstâncias do evento.

Propriedade Descrição
sourceAttribute O atributo original que desencadeou o evento. É o nome completo (incluindo RowID, se estiver em uma seção repetida) do atributo que originalmente desencadeou este evento.

Nota: A string inteira foi traduzida em minúsculas e, portanto, pode não ser adequada para ser inserida diretamente em getAttrs().

tipoOrigem O agente que desencadeou o evento, seja ojogadorou oassistente de ficha
valorAnterior O valor original do atributo em um eventoon:change, antes que o atributo tenha sido alterado.
novoValor O valor para o qual o atributo em um eventoon:changefoi alterado.
infoRemovida Um objeto contendo os valores de todos os atributos removidos em um eventoremove:repeating_groupname

 

change:<attribute_name>

Permite que você escute as mudanças de atributos específicos, ou no caso de uma seção repetida, quaisquer mudanças na seção inteira. É muito simples:

em("change:strength change:StrengthMod change:StrengthOtherThing", função(eventInfo) {
   //Faça algo aqui
   // eventInfo.previousValue é o valor original do atributo que acionou esse evento, antes de ser alterado.
   // eventInfo.newValue é o valor atual do atributo que acionou esse evento, após ser alterado.
});

em("change:repeating_spells:spellname", função(eventInfo) {
   //Faça algo aqui
   // eventInfo.sourceAttribute é o nome completo (incluindo ID repetido) do atributo 
   // que acionou originalmente esse evento, 
   // no entanto, a string inteira será traduzida para minúsculas e, portanto, pode não ser 
   // adequada para ser alimentada diretamente
   // em getAttrs() ou outros usos sem ser desfigurada primeiro.
});

em("change:repeating_spells", função(eventInfo) {
   //Seria acionado quando qualquer atributo na seção repeating_spells for alterado
   // eventInfo.sourceAttribute é o nome completo (em minúsculas)(incluindo ID repetido) 
   // do atributo que acionou originalmente esse evento. 
});

Note: All attribute names are lowercased in events. Portanto, mesmo que você normalmente se refira a um atributo como "Strength", use "change:strength" no ouvinte de eventos.

Observação: Isso suporta o sufixo "_max" de forma que "change:strength" ou "change:strength_max" disparará um evento, no entanto, essas duas variações parecem ser intercambiáveis, ou seja, ambas disparam quando "strength" ou "strength_max" mudam.

Para atributos em campos repetidos, todos os seguintes seriam acionados quando o atributo "repeating_spells_SpellName" é atualizado: "change:repeating_spells:spellname", "change:repeating_spells", "change:spellname", "change:spellname_max". Isso oferece a você máxima flexibilidade na escolha do "nível" de evento de mudança ao qual você deseja vincular sua função.

Sheetworkers também podem ouvir um evento de mudança de um atributo especial que é modificado sempre que uma seção repetida é reordenada.

em("change:_reporder:<sectionname>", função(eventInfo) {
   // Onde <sectionname> acima deve ser o nome de uma seção repetida, como habilidades ou magias
});

 

remover:repeating_<groupname>

Este é um evento que será ativado sempre que uma linha for excluída de uma seção de campo repetido. Você também pode ouvir a exclusão de uma linha específica se souber o seu ID, como em ("remove:repeating_inventory:-ABC123")

em("remove:repeating_inventory", função(eventInfo) {
     //Disparado sempre que uma linha é removida de repeating_inventory
     // eventInfo.sourceAttribute é o nome completo (incluindo ID) do primeiro atributo que acionou o evento (você pode usar isso para determinar o ID da linha que foi excluída)
});

A função removed:repeating_<groupname> do eventinfo inclui uma propriedade especial removedInfo que exibe todos os atributos da seção repetida agora removida.

em("remove:repeating_inventory", função(eventinfo) {
   console.log(eventinfo.removedInfo);
});

 

folha:aberta

Este evento será acionado sempre que uma folha for aberta por um jogador em uma sessão de jogo. Deve ser útil para fazer coisas como verificar se há atualizações necessárias na folha.

em('folha:aberta',função(){

// Faça algo na primeira vez que a folha for aberta por um jogador em uma sessão

});

 

clicado:<button_name>

Este evento será acionado quando um botão de ação for clicado. O nome do botão precisará começar com "act_". Por exemplo:

<button type="action" name="act_activate">Ativar!</button>

on("clicked:activate", function() {
  console.log("Activate button clicked");
});

 

Funções

getAttrs(arrayDeNomesDeAtributos, retorno) Assíncrono

A função getAttrs permite que você obtenha os valores de um conjunto de atributos da planilha. O sufixo "_max" é suportado, entãogetAttrs(["Força", "Força_max"], func)irá obter tanto os valores atuais quanto os máximos de "Força". Observe que a função é assíncrona, o que significa que não há garantia de que a ordem em que várias chamadas de getAttrs são feitas seja a ordem em que os resultados serão retornados. Em vez disso, você passa uma função de retorno que será executada quando os valores forem calculados. A função de retorno recebe um objeto simples do Javascript com uma lista de pares chave-valor, um para cada atributo solicitado.

Aqui está um exemplo:

em("change:strength", função() {
   getAttrs(["Força", "Nível"], função(valores) {
      //Faça algo com valores.Força e/ou valores[ "Nível" ]
   });
});

Valores em seções repetitivas requerem um tratamento especial. Se o evento em que você está já estiver dentro de uma seção repetitiva, você pode simplesmente solicitar a variável usando seu nome precedido pelo nome do grupo repetitivo e receberá o valor na mesma seção repetitiva em que o evento foi acionado. Por exemplo, se tivermos uma seção repeating_spells que tenha tanto SpellName, SpellLevel e SpellDamage, então:

em("change:repeating_spells:spelllevel", função() {
   obterAtributos([
      "repeating_spells_SpellDamage",
      "repeating_spells_SpellName"
    ], função(valores) {
      //values.repeating_spells_SpellDamage e values.repeating_spells_SpellName 
//ambos serão da mesma linha da seção repetida em que o SpellLevel que mudou está.
   });
});

Por outro lado, se você não estiver atualmente em uma seção repetida, você pode solicitar especificamente o valor de um campo em uma linha de seção repetida, especificando seu ID manualmente:

obterAtributos(["repeating_spells_-ABC123_SpellDamage"]...

Você também pode solicitar o atributo "_reporder_repeating_<sectionname>" com getAttrs() para obter uma lista de todos os IDs na seção que foram ordenados. No entanto, observe que isso pode não incluir a lista completa de todos os IDs em uma seção. Quaisquer IDs que não estejam na lista e que estejam na seção são considerados como vindo após os IDs ordenados em ordem lexicográfica.

 

setAttrs(valores, opções, retorno de chamada) Assíncrono

valores - Este é um objeto cujas propriedades são os nomes dos atributos (sem o prefixo attr_) e cujos valores são o que você deseja definir para esse atributo.

opções - (Opcional) Este é um objeto que especifica o comportamento opcional para a função. Atualmente, a única opção é "silent", que impede a propagação de eventos de alteração ao definir os atributos fornecidos.

retorno de chamada - (Opcional) Esta é uma função de retorno de chamada que será executada quando os atributos definidos forem atualizados.

A função setAttrs permite que você defina os atributos da ficha de personagem. Use o sufixo "_max" para definir o valor máximo de um atributo. Por exemplo "Strength_max".

em("change:strength", função() {
   getAttrs(["Força", "Nível"], função(valores) {
      setAttrs({
          ModForça: Math.floor(valores.Força / 2)
      });
   });
});

Nota: Se você estiver tentando atualizar um campo de entrada desabilitado com este método, você pode encontrar problemas. Uma opção é usar este método `setAttrs` para definir um campo de entrada oculto e, em seguida, definir o campo de entrada desabilitado para o elemento oculto. Neste exemplo, temos um atributo chamado vontade, e queremos calcular o julgamento com base em 1/2 da estatística de vontade, mas sem permitir que ela exceda 90. Veja abaixo.

<rótulo>Julgamento</rótulo>
<tipo de entrada="hidden" nome="attr_foo_judgment" valor="0" />
<tipo de entrada="number" nome="attr_judgment" valor="@{foo_judgment}" desativado="true" título="1/2 da vontade arredondada para baixo, máximo 90" />
em("change:will", function() {
  getAttrs(["will"], function(values) {
    setAttrs({ foo_judgment: Math.min(90, (values.will/2)) });
  });
});

Observe que, embora setAttrs seja uma função assíncrona, não há garantia de em qual ordem os atributos reais serão definidos para várias chamadas de setAttrs().

Para seções repetitivas, você tem a opção de usar o nome da variável simples se o evento original estiver em uma seção repetitiva, ou pode especificar o nome completo da variável da seção repetitiva, incluindo o ID em qualquer evento.

em("change:repeating_spells:spelllevel", função() {
   getAttrs(["repeating_spells_SpellLevel", "repeating_spells_SpellName"], função(valores) {
      setAttrs({
         repeating_spells_SpellDamage: Math.chão(valores.repeating_spells_SpellLevel / 2) + 10
      });
   });
});

 

getSectionIDs(nome_da_seção, callback) Assíncrono

Esta função permite obter uma lista dos IDs que atualmente existem para uma determinada seção repetitiva. Isso é útil para calcular coisas como inventário, onde pode haver um número variável de linhas.

em("change:repeating_inventory", função() {
   getSectionIDs("inventário", função(idarray) {
      para(var i=0; i < idarray.length; i++) {
         //Fazer algo com os IDs
      }
   });
});

Observe que você pode usar GetAttrs() (descrito acima) para solicitar o atributo "_reporder_repeating_<sectionname>" para obter uma lista de todos os IDs na seção que foram ordenados. No entanto, observe que isso pode não incluir a lista completa de todos os IDs em uma seção. Quaisquer IDs que não estão na lista e estão na seção são assumidos como vindo após os IDs ordenados em ordem lexicográfica.
Ou seja, getSectionIDs() irá obter todos os IDs - mas não na ordem em que são exibidos para o usuário. getAttrs( "_reporder_repeating_<sectionname>", ... ) irá retornar uma lista de todos os IDs que foram movidos para fora de sua ordem lexicográfica normal. Você pode usar a seguinte função como substituição para getSectionIDs para obter os IDs na ordem em que eles são exibidos.

var getSectionIDsOrdered = function (sectionName, callback) {
  'use strict';
  getAttrs([`_reporder_${sectionName}`], function (v) {
    getSectionIDs(sectionName, function (idArray) {
      let reporderArray = v[`_reporder_${sectionName}`] ? v[`_reporder_${sectionName}`].toLowerCase().split(',') : [],
        ids = [...new Set(reporderArray.filter(x => idArray.includes(x)).concat(idArray))];
      callback(ids);
    });
  });
};

 

generateRowID()

Uma função síncrona que retorna imediatamente um novo ID aleatório que você pode usar para criar uma nova linha de seção repetida. Se você usar setAttrs() e passar o ID de uma linha de seção repetida que não existe, uma será criada com esse ID.

Aqui está um exemplo que você pode usar para criar uma nova linha em uma seção repetida:

var newrowid = generateRowID();
var newrowattrs = {};
newrowattrs["repeating_inventory_" + newrowid + "_weight"] = "testnewrow";
setAttrs(newrowattrs);

 

removeRepeatingRow( RowID )

Uma função síncrona que removerá imediatamente todos os atributos associados a um determinado RowID e, em seguida, removerá a linha da ficha de personagem. O RowID deve estar no formato "repeating_<sectionname>_<rowid>". Por exemplo, "repeating_skills_-KbjuRmBRiJNeAJBJeh2".

Aqui está um exemplo de limpar uma lista de resumo quando a lista original muda:

on("change:repeating_inventory", function() {
   getSectionIDs("repeating_inventorysummary", function(idarray) {
      for(var i=0; i < idarray.length; i++) {
        removeRepeatingRow("repeating_inventorysummary_" + idarray[i]);
      }
   });
});

 

getTranslationByKey([key])

Uma função síncrona que retorna imediatamente a sequência de tradução relacionada à chave fornecida. Se a chave não existir, será retornado false e uma mensagem no console será exibida, listando a chave específica que não foi encontrada no JSON de tradução.

Aqui está um exemplo que você pode usar para buscar uma sequência de tradução do JSON de tradução: Com o seguinte JSON de tradução

{
    "str": "Força",
    "dex": "Destreza"
}
var strTranslation = getTranslationByKey('str'); // "Strength"
var dexTranslation = getTranslationByKey('dex'); // "Dexterity"
var intTranslation = getTranslationByKey('int'); // false

 

getTranslationLanguage()

Uma função síncrona que retorna imediatamente o código de idioma de 2 caracteres para o idioma selecionado pelo usuário.

Aqui está um exemplo que você pode usar para buscar o idioma de tradução:

var translationLang = getTranslationLanguage(); // "en" , para uma conta que usa inglês

 

setDefaultToken(valores)

Uma função que permite ao autor da planilha determinar quais atributos são definidos no personagem solto do compêndio. Ao definir o token padrão após soltar do compêndio, esta função pode definir quaisquer atributos no token padrão para vincular atributos importantes específicos da ficha de personagem, como attr_hit_points.

A lista de atributos de token que podem ser definidos por setDefaultToken são:

["bar1_value","bar1_max","bar2_value","bar2_max","bar3_value","bar3_max","aura1_square","aura1_radius","aura1_color","aura2_square","aura2_radius","aura2_color",
"tint_color","showname","showplayers_name","playersedit_name","showplayers_bar1","playersedit_bar1","showplayers_bar2","playersedit_bar2","showplayers_bar3",
"playersedit_bar3","showplayers_aura1","playersedit_aura1","showplayers_aura2","playersedit_aura2","light_radius","light_dimradius","light_angle","light_otherplayers",
"light_hassight","light_losangle","light_multiplier"]

Para obter mais informações sobre estes atributos e o que fazem, consulte a página de objectos da API.

Aqui está um exemplo:

em("folha:compendio-queda", função() {
    var default_attr = {};
    default_attr["largura"] = 70;
    default_attr["altura"] = 70;
    default_attr["barra1_valor"] = 10;
    default_attr["barra1_max"] = 15;
    setDefaultToken(default_attr);
});
Este artigo foi útil?
Utilizadores que acharam útil: 17 de 31