Character Vault
Any Concept / Any System
Compendium
Your System Come To Life
Roll20 for Android
Streamlined for your Tablet
Roll20 for iPad
Streamlined for your Tablet

Personal tools

Difference between revisions of "Select Attributes for Sheet Roll"

From Roll20 Wiki

Jump to: navigation, search
(add sheetworker category)
(Sheet Worker: at least 1 die in pool)
Line 123: Line 123:
 
const getSheetRollPool = function(poolAttributes, values) {
 
const getSheetRollPool = function(poolAttributes, values) {
 
   // Add up attribute values for dice pool
 
   // Add up attribute values for dice pool
   return poolAttributes
+
   const sum = poolAttributes
 
     .map((poolAttribute) => Number(values[poolAttribute]))
 
     .map((poolAttribute) => Number(values[poolAttribute]))
 
     .reduce((sum, value) => sum + value, 0);
 
     .reduce((sum, value) => sum + value, 0);
 +
 +
  // Pool is always at least 1 die
 +
  return Math.max(sum, 1);
 
}
 
}
 
</pre>
 
</pre>

Revision as of 16:57, 12 July 2020

Main Article: Building Character Sheets

This is an example for selecting attributes to be included in a Sheet Roll.

The key components are:

  • Update display of toggle buttons based on the associated flag, using Styling Checkboxes and Radios
  • Attribute name, button name, flag attribute name, and translation key all share the same base value.
  • Displaying the selected attributes (based on translation key)
  • Selected attribute list and dice pool value are stored in hidden input fields.
  • Roll button references the dice pool attribute with Auto-Calculating Values

HTML

<h1>Sheet Roller</h1>
<div class="roller">
  <textarea name="attr_dice_pool_display" tabindex="-1"></textarea>
  <div>
    <input type="text" name="attr_dice_pool" tab-index="-1"></input>
    <button type="roll" value="/roll @{dice_pool}d10"></button>
  </div>
</div>

<h1>Attributes</h1>
<div class="attributes">
  <div>
    <input type="hidden" class="flag" name="attr_intelligence_flag">
    <button type="action" class="toggle" name="act_intelligence" data-i18n="intelligence">Intelligence</button>
    <input type="number" name="attr_intelligence" value="1">
  </div>
  <div>
    <input type="hidden" class="flag" name="attr_wits_flag">
    <button type="action" class="toggle" name="act_wits" data-i18n="wits">Wits</button>
    <input type="number" name="attr_wits" value="1">
  </div>
  <div>
    <input type="hidden" class="flag" name="attr_resolve_flag">
    <button type="action" class="toggle" name="act_resolve" data-i18n="resolve">Resolve</button>
    <input type="number" name="attr_resolve" value="1">
  </div>
</div>

<input type="hidden" name="attr_dice_pool_attributes">
<input type="hidden" name="attr_dice_pool" value="0">

Sheet Worker

const attributes = ["intelligence", "wits", "resolve"];

attributes.forEach((attribute) => {
  on(`clicked:${attribute}`, () => {
    updateSheetRoll(attribute);
  });
});

const attributeChangeEvents = attributes.map((attribute) => `change:${attribute}`);
on(attributeChangeEvents.join(" "), () => {
  updateSheetRollPool();
});

const updateSheetRoll = function(attribute) {
  getAttrs(["dice_pool_attributes", ...attributes], (values) => {
    let poolAttributes = values["dice_pool_attributes"]
      .split(",")
      .filter((poolAttribute) => poolAttribute);

    if (poolAttributes.includes(attribute)) {
      // remove attribute from pool
      poolAttributes = poolAttributes
        .filter((poolAttribute) => poolAttribute !== attribute);
    }
    else {
      // add attribute to back of pool
      poolAttributes = poolAttributes.concat(attribute);
      
      // Truncate pool attributes to 2,
      // removing the oldest selected attributes
      poolAttributes = poolAttributes
        .reverse()
        .slice(0, 2)
        .reverse();
    }

    const pool = getSheetRollPool(poolAttributes, values);

    // Create display list of attributes
    const poolDisplay = poolAttributes
      .map((poolAttribute) => getTranslationByKey(poolAttribute))
      .join(" +\n");

    // Determine flag values
    const flags = attributes
      .map((flagAttribute) => ({
        flag: `${flagAttribute}_flag`,
        value: poolAttributes.includes(flagAttribute) ? 1 : 0
      }))
      .reduce((all, next) => ({ ...all, [next.flag]: next.value }), {});

    setAttrs({
      "dice_pool_attributes": poolAttributes.join(","),
      "dice_pool": pool,
      "dice_pool_display": poolDisplay,
      ...flags
    });
  });
}

const updateSheetRollPool = function() {
  getAttrs(["dice_pool_attributes", ...attributes], (values) => {
    const poolAttributes = values["dice_pool_attributes"]
      .split(",")
      .filter((poolAttribute) => poolAttribute);

    const pool = getSheetRollPool(poolAttributes, values);

    setAttrs({
      "dice_pool": pool
    });
  });
}

const getSheetRollPool = function(poolAttributes, values) {
  // Add up attribute values for dice pool
  const sum = poolAttributes
    .map((poolAttribute) => Number(values[poolAttribute]))
    .reduce((sum, value) => sum + value, 0);

  // Pool is always at least 1 die
  return Math.max(sum, 1);
}

CSS

/* Indicate that the toggle is active */
input.sheet-flag[value="1"] ~ button.sheet-toggle {
  border-color: blue;
  font-weight: bold;
}