Scripts del Trabajador de Hojas

Añadiendo un Script de Trabajador de Hoja

Para añadir un script de trabajador de hoja a una Hoja de Personaje, simplemente añade el script en la sección "HTML" de la hoja usando el siguiente formato:

<script tipo="text/worker">

en("change:strength", función() {

});

// ... etc

</script>

Ten en cuenta que la etiqueta del script debe tener un tipo de "text/worker" para ser correctamente manejada por el sistema. Cuando el juego se carga, todas las etiquetas de script se eliminan de la plantilla de la hoja por motivos de seguridad. Sin embargo, las etiquetas de script con un tipo de "text/worker" se utilizarán para iniciar un trabajador en segundo plano en la computadora de cada jugador que pueda responder a los valores cambiantes en sus hojas y tomar las acciones necesarias. Todos los scripts de los trabajadores de hojas deben estar contenidos dentro de una sola etiqueta de script.

Más ejemplos completos de los conceptos básicos dirigidos a no programadores

Advertencia sobre el alcance de la variable "global": el alcance de una variable declarada dentro del `<script type="text/worker">` pero fuera de una función actualmente es por jugador, no por personaje. Cambiar su valor lo cambiará para todos los personajes de la sesión del jugador.

Como buena práctica, se deben evitar las cascadas asíncronas siempre que sea posible. En general, es mejor práctica obtener todos los atributos necesarios para los cálculos en un solo getAttrs en lugar de hacer getAttrs -> cálculos -> setAttrs -> getAttrs -> cálculos -> setAttrs…


Trabajadores de hojas vs. Campos de cálculo automático: ¿Cuál debo usar?

No hay una regla estricta sobre esto. Ambas herramientas son capaces de lograr lo mismo. Tomemos un caso de uso hipotético de un atributo "Fuerza", que queremos usar para mantener actualizado un atributo "Modificador de Fuerza". Aquí estarían las diferencias entre las dos herramientas para este caso de uso:

  • Los campos de cálculo automático se recalculan cada vez que se abre una hoja por primera vez. Los campos del Trabajador de Hojas, por otro lado, solo se recalculan cuando cambian sus valores dependientes. Esto significa que las hojas que utilizan la opción del Trabajador de Hojas serán mucho, mucho más rápidas para que los jugadores las abran e interactúen con ellas.
  • Además, los cálculos del Trabajador de Hojas se ejecutan en un proceso en segundo plano, lo que significa que no se crea ningún retraso en la interfaz de usuario mientras se ejecutan los cálculos. Por otro lado, los campos desactivados se ejecutan en el proceso principal y, como tal, pueden causar "bloqueos" o "tartamudeos" si se calculan grandes cantidades de ellos a la vez (por ejemplo, si tienes una hoja muy complicada que utiliza miles de campos desactivados).
  • El campo de Modificador de Fuerza de cálculo automático aparecería desactivado para el jugador. Un campo de Modificador de Fuerza actualizado por un Trabajador de Hojas, por otro lado, sería modificable después de que se haya ejecutado el cálculo (aunque cualquier valor ingresado se sobrescribiría cuando cambie el valor de Fuerza). Entonces, un Trabajador de Hojas sería mejor para respaldar reglas caseras, ya que el jugador simplemente podría modificar el valor de Mod después de que cambie la Fuerza. Por otro lado, el campo de cálculo automático no permitiría un cambio de este tipo, por lo que las reglas se "impondrían" de manera más rigurosa.

En general, nuestra recomendación es que uses campos de cálculo automático con moderación. Dedícate un presupuesto de 500 a 1,000 campos de cálculo automático como máximo. Recomendamos usar la nueva funcionalidad de Sheet Worker para la mayoría de los cálculos, especialmente aquellos que solo necesitan realizarse ocasionalmente (por ejemplo, el valor de tu Fuerza (y por lo tanto tu Modificador de Fuerza) probablemente solo cambie como máximo una vez por sesión cuando el personaje sube de nivel. No es necesario volver a ejecutar el mismo cálculo una y otra vez cada vez que se abre la hoja.


API de Sheet Worker

Eventos

Objeto eventInfo

A muchos de los sucesos se les pasa un objetoeventInfoque le ofrece detalles adicionales sobre las circunstancias del suceso.

Propiedad Descripción
sourceAttribute El atributo original que desencadenó el evento. Es el nombre completo (incluido RowID si está en una sección repetitiva) del atributo que desencadenó originalmente este evento.

Nota: La cadena completa se habrá traducido a minúsculas y, por lo tanto, es posible que no sea adecuada para alimentar directamente getAttrs().

tipoFuente El agente que activó el evento, ya sea jugador o trabajador de hoja
valorAnterior El valor original del atributo en un evento on:change, antes de que el atributo cambiara.
nuevoValor El valor al que ha cambiado el atributo en un evento on:change.
informaciónEliminada Un objeto que contiene los valores de todos los atributos eliminados en un evento remove:repeating_groupname.

 

cambio:<attribute_name>

Te permite escuchar los cambios de atributos específicos, o en el caso de una sección repetida, cualquier cambio en toda la sección. Es muy sencillo:

en("cambio:fuerza cambio:ModFuerza cambio:OtraCosaFuerza", función(eventInfo) {
   //Haz algo aquí
   // eventInfo.previousValue es el valor original del atributo que desencadenó este evento, antes de ser cambiado.
   // eventInfo.newValue es el valor actual del atributo que desencadenó este evento, después de ser cambiado.
});

en("cambio:repeating_spells:nombrehechizo", función(eventInfo) {
   //Haz algo aquí
   // eventInfo.sourceAttribute es el nombre completo (incluyendo ID repetido) del atributo 
   // que originalmente desencadenó este evento, 
   // sin embargo, toda la cadena se habrá traducido a minúsculas y, por lo tanto, podría no ser 
   // adecuada para ser utilizada directamente
   // en getAttrs() u otros usos sin ser desvandalizada primero.
});

en("cambio:repeating_spells", función(eventInfo) {
   //Se activaría cuando se cambie cualquier atributo en la sección de repeating_spells
   // eventInfo.sourceAttribute es el nombre completo (en minúsculas)(incluyendo ID repetido) 
   // del atributo que originalmente desencadenó este evento. 
});

Nota: Todos los nombres de atributos están en minúsculas en los eventos. Entonces, incluso si normalmente te refieres a un atributo como "Strength", utiliza "change:strength" en el escuchador de eventos.

Nota: Esto admite el sufijo "_max" en que tanto "change:strength" como "change:strength_max" generarán un evento, sin embargo, estas dos variaciones parecen ser intercambiables, ya que ambas se generarán cuando cambie "strength" o "strength_max".

Para atributos en campos repetitivos, todos los siguientes se activarían cuando se actualiza el atributo "repeating_spells_SpellName": "change:repeating_spells:spellname", "change:repeating_spells", "change:spellname", "change:spellname_max". Esto te brinda la máxima flexibilidad para elegir a qué "nivel" de cambio quieres vincular tu función.

Los trabajadores de la hoja de personaje también pueden escuchar un evento de cambio de un atributo especial que se modifica cada vez que se reordena una sección repetitiva.

en("change:_reporder:<sectionname>", función(eventInfo) {
   // Donde <sectionname> anterior debería ser un nombre de sección repetitiva, como habilidades o hechizos
});

 

eliminar:repetir_<groupname>

Este es un evento que se activará cada vez que se elimine una fila de una sección de campo repetido. También puedes escuchar cuando se elimine una fila específica si conoces su ID, como en("remove:repeating_inventory:-ABC123")

en("remove:repeating_inventory", función(informaciónEvento) {
     //Se activa cada vez que se elimina una fila de repeating_inventory
     // eventInfo.sourceAttribute es el nombre completo (incluyendo ID) del primer atributo que activó el evento (puedes usar esto para determinar el ID de la fila que se eliminó)
});

La función removed:repeating_<groupname> del eventoinfo incluye una propiedad especial removedInfo que muestra todos los atributos de la sección repetida que ahora se eliminó.

en("remove:repeating_inventory", función(informaciónEvento) {
   console.log(informaciónEvento.removedInfo);
});

 

hoja:abierta

Este evento se activará cada vez que un jugador abra una hoja en una sesión de juego. Debería ser útil para hacer cosas como verificar si se necesitan mejoras en la hoja.

en('hoja:abierta',función(){

// Hacer algo la primera vez que un jugador abra una hoja en una sesión

});

 

haz clic en:<button_name>

Este evento se activará cuando se haga clic en un botón de acción. El nombre del botón debe comenzar con "act_". Por ejemplo:

<button type="action" name="act_activate">¡Activar!</button>

en("clicked:activate", función() {
  console.log("Botón de activación pulsado");
});

 

Funciones

getAttrs(arrayDeNombresDeAtributos, callback) Asíncrono

La función getAttrs te permite obtener los valores de un conjunto de atributos de la hoja. El sufijo "_max" es compatible, por lo que getAttrs( ["Strength", "Strength_max"], func) obtendrá tanto los valores actuales como los máximos de "Strength". Ten en cuenta que la función es asíncrona, lo que significa que no hay garantía de que el orden en el que se realicen múltiples llamadas a getAttrs sea el orden en el que se devolverán los resultados. En su lugar, pasas una función de devolución de llamada que se ejecutará cuando se hayan calculado los valores. La función de devolución de llamada recibe un objeto Javascript simple con una lista de pares clave-valor, uno por cada atributo que hayas solicitado.

Aquí tienes un ejemplo:

en("change:strength", function() {
   getAttrs(["Fuerza", "Nivel"], function(valores) {
      //Hacer algo con valores.Fuerza y/o valores[ "Nivel" ]
   });
});

Los valores en secciones repetitivas requieren un poco de manejo especial. Si el evento en el que te encuentras ya está dentro de una sección repetitiva, simplemente puedes solicitar la variable usando su nombre precedido por el nombre del grupo repetitivo y recibirás el valor en la misma sección repetitiva en la que se activó el evento. Por ejemplo, si tenemos una sección repeating_spells que tiene tanto SpellName, SpellLevel y SpellDamage, entonces:

en("cambio:repeating_spells:spelllevel", función() {
   getAttrs([
      "repeating_spells_SpellDamage",
      "repeating_spells_SpellName"
    ], función(valores) {
      //los valores de repeating_spells_SpellDamage y repeating_spells_SpellName 
//serán de la misma fila de la sección repetida en la que se produjo el cambio de SpellLevel.
   });
});

Por otro lado, si no te encuentras actualmente en una sección repetida, puedes solicitar específicamente el valor de un campo en una fila de la sección repetida especificando su ID manualmente:

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

También puedes solicitar el atributo "_reporder_repeating_<sectionname>" con getAttrs() para obtener una lista de todos los ID en la sección que han sido ordenados. Sin embargo, ten en cuenta que esto puede no incluir la lista completa de todas las IDs en una sección. Se asume que cualquier ID que no esté en la lista y esté en la sección viene después de las IDs ordenadas en orden lexicográfico.

 

setAttrs(valores, opciones, devolución de llamada) Asíncrono

valores - Este es un objeto cuyas propiedades son los nombres de los atributos (sin el prefijo attr_) y cuyos valores son lo que deseas establecer para ese atributo.

opciones - (Opcional) Este es un objeto que especifica el comportamiento opcional para la función. Actualmente, la única opción es "silencioso", lo cual evita la propagación de los eventos de cambio al establecer los atributos suministrados.

devolución de llamada - (Opcional) Esta es una función de devolución de llamada que se ejecutará cuando los atributos establecidos hayan sido actualizados.

La función setAttrs te permite establecer los atributos de la hoja de personaje. Usa el sufijo "_max" para establecer el valor máximo de un atributo. Por ejemplo "Strength_max".

en("cambio:fuerza", función() {
   obtenerAtributos(["Fuerza", "Nivel"], función(valores) {
      establecerAtributos({
          ModFuerza: Math.floor(valores.Fuerza / 2)
      });
   });
});

Nota: Si estás tratando de actualizar un campo de entrada deshabilitado con este método, es posible que encuentres problemas. Una opción es usar este método `setAttrs` para establecer un campo de entrada oculto, luego establecer el campo de entrada deshabilitado en el elemento oculto. En este ejemplo tenemos un atributo llamado voluntad, y queremos calcular el juicio en función de la mitad del atributo voluntad, pero sin permitir que supere los 90. Ver abajo.

<etiqueta>Juicio</etiqueta>
<tipo de entrada="oculto" nombre="attr_foo_judgment" valor="0" />
<tipo de entrada="número" nombre="attr_judgment" valor="@{foo_judgment}" desactivado="true" título="1/2 de voluntad redondeado hacia abajo, máximo 90" />
en("cambio:voluntad", función() {
  obtenerAtributos(["voluntad"], función(valores) {
    establecerAtributos({ foo_judgment: Math.min(90, (valores.voluntad/2)) });
  });
});

Tenga en cuenta que aunque la función setAttrs es asíncrona y no hay garantía de en qué orden se establecerán los atributos reales para múltiples llamadas a setAttrs().

Para secciones repetidas, tienes la opción de usar el nombre de variable simple si el evento original está en una sección repetida, o puedes especificar el nombre completo de la variable de sección repetida incluyendo el ID en cualquier evento.

on("change:repeating_spells:spelllevel", function() {
   getAttrs(["repeating_spells_SpellLevel", "repeating_spells_SpellName"], function(values) {
      setAttrs({
         repeating_spells_SpellDamage: Math.floor(values.repeating_spells_SpellLevel / 2) + 10
      });
   });
});

 

getSectionIDs(section_name,callback) Asincrónico

Esta función te permite obtener una lista de los IDs que existen actualmente para una sección repetida dada. Esto es útil para calcular cosas como el inventario donde puede haber un número variable de filas.

en("cambio:repetición_inventario", función() {
   obtenerIDsSección("inventario", función(idarray) {
      para(var i=0; i < idarray.longitud; i++) {
         //Hacer algo con los IDs
      }
   });
});

Ten en cuenta que puedes usar GetAttrs() (descrito anteriormente) para solicitar el atributo "_reporder_repeating_<sectionname>" y obtener una lista de todos los IDs en la sección que han sido ordenados. Sin embargo, ten en cuenta que esto puede no incluir la lista completa de todos los IDs en una sección. Cualquier ID que no esté en la lista y esté en la sección se asume que viene después de las ID ordenadas en orden lexicográfico.
Es decir, getSectionIDs() obtendrá todas las ID, pero no en el orden en que se muestran al usuario. getAttrs( "_reporder_repeating_<sectionname>", ... ) devolverá una lista de todas las ID que se han movido fuera de su orden lexicográfico normal. Puede utilizar la siguiente función como reemplazo de getSectionIDs para obtener las ID en el orden en que se muestran.

var getSectionIDsOrdered = function (nombreSección, devolución de llamada) {
  'use strict';
  getAttrs([`_reporder_${sectionName}`], function (v) {
    getSectionIDs(nombreSección, 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()

Una función síncrona que devuelve inmediatamente un nuevo ID aleatorio que puedes usar para crear una nueva fila de sección repetida. Si utilizas setAttrs() y pasas el ID de una fila de sección repetida que no existe, se creará una con ese ID.

Aquí tienes un ejemplo que puedes usar para crear una nueva fila en una sección repetida:

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

 

removeRepeatingRow( RowID )

Una función síncrona que eliminará inmediatamente todos los atributos asociados con un determinado RowID y luego eliminará la fila de la hoja de personaje. El RowID debe tener el formato "repeating_<sectionname>_<rowid>". Por ejemplo, "repeating_skills_-KbjuRmBRiJNeAJBJeh2".

Aquí tienes un ejemplo de cómo limpiar una lista de resumen cuando cambia la lista original:

en("change:repeating_inventory", función() {
   obtenerIDsSección("repeating_inventorysummary", función(idarray) {
      para(var i=0; i < idarray.length; i++) {
        eliminarFilaRepetida("repeating_inventorysummary_" + idarray[i]);
      }
   });
});

 

getTranslationByKey([key])

Una función síncrona que devuelve inmediatamente la cadena de traducción relacionada con la clave dada. Si no existe la clave, se devolverá false y se mostrará un mensaje en la consola que enumera la clave específica que no se encontró en la traducción JSON.

Aquí tienes un ejemplo que puedes usar para obtener una cadena de traducción del JSON de traducción: Con el siguiente JSON de traducción

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

 

getTranslationLanguage()

Una función síncrona que devuelve inmediatamente el código de idioma de 2 caracteres para el idioma seleccionado por el usuario.

Aquí tienes un ejemplo que puedes usar para obtener el idioma de traducción:

var translationLang = getTranslationLanguage(); // "en" , for an account using English

 

setDefaultToken(valores)

Una función que permite al autor de la hoja determinar qué atributos se establecen en el personaje que se suelta del compendio. Al establecer el token predeterminado después de soltar un compendio, esta función puede establecer cualquier atributo en el token predeterminado para vincular atributos importantes específicos de esa hoja de personaje, como attr_hit_points.

La lista de atributos de token que se pueden establecer mediante setDefaultToken es:

["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 más información sobre estos atributos y lo que hacen, consulte la página de objetos de la API.

Aquí tienes un ejemplo:

on("hoja:compendium-drop", function() {
    var default_attr = {};
    default_attr["width"] = 70;
    default_attr["height"] = 70;
    default_attr["bar1_value"] = 10;
    default_attr["bar1_max"] = 15;
    setDefaultToken(default_attr);
});
¿Fue útil este artículo?
Usuarios a los que les pareció útil: 17 de 32