diff --git a/CHANGELOG.md b/CHANGELOG.md index af42112..436e892 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ## Release/Patch Notes +### Verion 1.0.0 - 2021-06-03 [BREAKING CHANGE: COMPATIBILE WITH FOUNDRY 0.8.6 OR HIGHER ONLY!] + + * Changes to support 0.8.x Foundry + * Revamped data model for actor sheet. + * Rolls asynchronous now +* Enhancement - Added option to choose roll mode in the roll modifier dialogue for both percentile/lethality tests and damage rolls. + ### Version 0.9.9 - 2021-03-27 * Fix - [GitHub #23] - Localization mistake, had two spaces in between "Critical" and "Success" or "Failure" in chat cards. diff --git a/css/dialogue.css b/css/dialogue.css index 1995119..6a71691 100644 --- a/css/dialogue.css +++ b/css/dialogue.css @@ -8,13 +8,13 @@ grid-gap: 10px 15px; } - .numeric-label-field{ +.numeric-label-field{ width: 50px !important; text-align: center !important; } - .damage-modify-label-grid{ +.damage-modify-label-grid{ display: grid; grid-template-columns: auto auto; align-content: left; @@ -23,7 +23,8 @@ padding: 10px; grid-gap: 10px 15px; } - .damage-modify-formula-modify-grid{ + +.damage-modify-formula-modify-grid{ display: grid; grid-template-columns: auto auto auto auto auto auto; align-content: left; @@ -33,7 +34,11 @@ grid-gap: 10px 15px; } - .damage-roll-formula-part{ +.damage-roll-formula-part{ min-width: 100px !important; text-align: center !important; +} + +.damage-modify-roll-mode{ + padding: 10px; } \ No newline at end of file diff --git a/documentation/images/agent_sheet_cv.png b/documentation/images/agent_sheet_cv.png new file mode 100644 index 0000000..60980b8 Binary files /dev/null and b/documentation/images/agent_sheet_cv.png differ diff --git a/documentation/images/agent_sheet_gear.png b/documentation/images/agent_sheet_gear.png new file mode 100644 index 0000000..3b23bbd Binary files /dev/null and b/documentation/images/agent_sheet_gear.png differ diff --git a/documentation/images/agent_sheet_mental.png b/documentation/images/agent_sheet_mental.png new file mode 100644 index 0000000..7462760 Binary files /dev/null and b/documentation/images/agent_sheet_mental.png differ diff --git a/documentation/images/agent_sheet_physical.png b/documentation/images/agent_sheet_physical.png new file mode 100644 index 0000000..ef75ebc Binary files /dev/null and b/documentation/images/agent_sheet_physical.png differ diff --git a/documentation/images/agent_sheet_skills_tab.png b/documentation/images/agent_sheet_skills_tab.png index 54329a3..97eeb55 100644 Binary files a/documentation/images/agent_sheet_skills_tab.png and b/documentation/images/agent_sheet_skills_tab.png differ diff --git a/documentation/images/agents_sheet_contacts.png b/documentation/images/agents_sheet_contacts.png new file mode 100644 index 0000000..917ab0a Binary files /dev/null and b/documentation/images/agents_sheet_contacts.png differ diff --git a/lang/en.json b/lang/en.json index 85f13a6..098ae94 100644 --- a/lang/en.json +++ b/lang/en.json @@ -154,8 +154,8 @@ "DG.Tooltip.DistinguishingFeature": "Distinguishing Feature (fill out if score is 13 or higher, or 8 or lower).", "DG.Tooltip.x5AttributeLabel": "Click to roll a x5 check.", "DG.Tooltip.FirstAidAttempted": "Once an agent receives first aid, they cannot benefit from it again until they receive further damage from a different source.", - "DG.Tooltip.AdaptedToViolence": "Being adapted to violence means your Agent’s empathy suffers as they come to view violence as nothing but another tool to be wielded. He or she permanently loses 1D6 CHA and the same amount from each of their Bonds.", - "DG.Tooltip.AdaptedToHelplessness": "Being adapted to helplessness means your Agent’s personal drive suffers as they pull back from the world around them. As soon as your Agent becomes adapted to helplessness, he or she permanently loses 1D6 POW.", + "DG.Tooltip.AdaptedToViolence": "Being adapted to violence means your Agent’s empathy suffers as they come to view violence as nothing but another tool to be wielded. Agent permanently loses 1D6 CHA and the same amount from each of their Bonds.", + "DG.Tooltip.AdaptedToHelplessness": "Being adapted to helplessness means your Agent’s personal drive suffers as they pull back from the world around them. As soon as your Agent becomes adapted to helplessness, agent permanently loses 1D6 POW.", "DG.Tooltip.ToggleEquippedState": "Click to toggle whether this item is equipped or not.", "DG.Gear.Expense.Incidental": "Incidental", @@ -217,5 +217,8 @@ "DG.Roll.Inhuman": "Inhuman", "DG.Tooltip.BreakPoint": "The current breaking point, reset when current sanity falls to or below this value. The starting breaking point is SAN - POW.", "DG.Tooltip.BreakPointReset": "Reset breaking point to be current SAN - WP.", - "DG.Skills.ritual": "Ritual" + "DG.Skills.ritual": "Ritual", + + "DG.RollMode": "Roll Mode", + "DG.Bonds.Relationship": "Relationship" } \ No newline at end of file diff --git a/lang/es.json b/lang/es.json index 0446f20..0dd80b0 100644 --- a/lang/es.json +++ b/lang/es.json @@ -217,5 +217,8 @@ "DG.Roll.Inhuman": "Inhumano", "DG.Tooltip.BreakPoint": "El Punto de Ruptura actual, actualizar cuando la Cordura actual sea igual o inferior a este valor. El Punto de Ruptura inicial es COR - POD.", "DG.Tooltip.BreakPointReset": "Actualizar el Punto de Ruptura al valor actual de COR - PVOL.", - "DG.Skills.ritual": "Ritual" + "DG.Skills.ritual": "Ritual", + + "DG.RollMode": "Modo rollo", + "DG.Bonds.Relationship": "Relación" } \ No newline at end of file diff --git a/lang/ja.json b/lang/ja.json index e7e4a78..9294315 100644 --- a/lang/ja.json +++ b/lang/ja.json @@ -217,5 +217,8 @@ "DG.Roll.Inhuman": "人ならざるもの", "DG.Tooltip.BreakPoint": "現在のブレーキポイント。初めの数値は「正気 ー 判断力」。", "DG.Tooltip.BreakPointReset": "ブレーキポイントをレセットする。新しい数値は「正気 ー 判断力」。", - "DG.Skills.ritual": "秘儀" + "DG.Skills.ritual": "秘儀", + + "DG.RollMode": "ロールモード", + "DG.Bonds.Relationship": "関係" } \ No newline at end of file diff --git a/module/actor/actor-sheet.js b/module/actor/actor-sheet.js index 7e22d1a..52d9a25 100644 --- a/module/actor/actor-sheet.js +++ b/module/actor/actor-sheet.js @@ -359,7 +359,7 @@ export class DeltaGreenActorSheet extends ActorSheet { showModifyDamageRollDialogue(this.actor, label, dataset.roll); } else{ - sendDamageRollToChat(this.actor, label, dataset.roll); + sendDamageRollToChat(this.actor, label, dataset.roll, game.settings.get("core", "rollMode")); } } else{ @@ -369,10 +369,10 @@ export class DeltaGreenActorSheet extends ActorSheet { else{ if(isLethalityRoll) { - sendLethalityTestToChat(this.actor, label, targetVal); + sendLethalityTestToChat(this.actor, label, targetVal, game.settings.get("core", "rollMode")); } else{ - sendPercentileTestToChat(this.actor, label, targetVal); + sendPercentileTestToChat(this.actor, label, targetVal, game.settings.get("core", "rollMode")); } } } diff --git a/module/deltagreen.js b/module/deltagreen.js index 37afff9..8d84635 100644 --- a/module/deltagreen.js +++ b/module/deltagreen.js @@ -30,8 +30,8 @@ Hooks.once('init', async function() { registerSystemSettings(); // Define custom Entity classes - CONFIG.Actor.entityClass = DeltaGreenActor; - CONFIG.Item.entityClass = DeltaGreenItem; + CONFIG.Actor.documentClass = DeltaGreenActor; + CONFIG.Item.documentClass = DeltaGreenItem; // Register sheet application classes Actors.unregisterSheet("core", ActorSheet); @@ -117,6 +117,22 @@ Hooks.once('init', async function() { }); + Handlebars.registerHelper('getAvailableRollModes', function() { + try { + return CONFIG.Dice.rollModes; + } catch (error) { + console.log(error); + } + }); + + Handlebars.registerHelper('getDefaultRollMode', function() { + try { + return game.settings.get("core", "rollMode"); + } catch (error) { + console.log(error); + } + }); + // looks at system setting for what font to use and returns the class that is then used in the handlebars template that // generates the character sheet. Handlebars.registerHelper('getFontFamilySystemSettingClass', function() { diff --git a/module/item/item.js b/module/item/item.js index 643ddfe..c03991f 100644 --- a/module/item/item.js +++ b/module/item/item.js @@ -30,7 +30,7 @@ export class DeltaGreenItem extends Item { const itemData = item.data; if(item.data.isLethal){ - sendLethalityTestToChat(this.actor, item.name, item.data.lethality) + sendLethalityTestToChat(this.actor, item.name, item.data.lethality, game.settings.get("core", "rollMode")) } else{ // regular damage roll diff --git a/module/roll/roll.js b/module/roll/roll.js index 2706166..2625216 100644 --- a/module/roll/roll.js +++ b/module/roll/roll.js @@ -1,7 +1,11 @@ import {localizeWithFallback} from "../other/utility-functions.js" -export function sendPercentileTestToChat(actor, skill, target){ - let roll = new Roll('1D100', actor.data.data).evaluate(false); +export async function sendPercentileTestToChat(actor, skill, target, rollMode){ + //let roll = new Roll('1D100', actor.data.data).evaluate(false); + let roll = new Roll('1D100', actor.data.data) + + await roll.evaluate({async: true}); + let total = roll.total; let isCritical = false; let isSuccess = false; @@ -11,6 +15,10 @@ export function sendPercentileTestToChat(actor, skill, target){ let styleOverride = ''; let inhumanCriticalThreshold = 0; + if(rollMode == null || rollMode === ""){ + rollMode = game.settings.get("core", "rollMode"); + } + // "Inhuman" stat being rolled, logic is different per page 188 of the Handler's Guide. // Note - originally implemented by Uriele, but my attempt at merging conficts went poorly, so re-implementing. // For an inhuman check, the roll succeeds except on a roll of 100 which fails AND fumbles. @@ -98,12 +106,12 @@ export function sendPercentileTestToChat(actor, skill, target){ flavor: label, type: 5, //CHAT_MESSAGE_TYPES.ROLL, roll: roll, - rollMode: game.settings.get("core", "rollMode") + rollMode: rollMode }; // play the dice rolling sound, like a regular in-chat roll AudioHelper.play({src: "sounds/dice.wav", volume: 0.8, autoplay: true, loop: false}, true); - + ChatMessage.create(chatData, {}); } @@ -122,11 +130,19 @@ export function skillCheckResultIsCritical(rollResult){ return isCritical; } -export function sendLethalityTestToChat(actor, weaponName, target){ - let roll = new Roll('1D100', actor.data.data).evaluate(false); +export async function sendLethalityTestToChat(actor, weaponName, target, rollMode){ + //let roll = new Roll('1D100', actor.data.data).evaluate(false); + + let roll = new Roll('1D100', actor.data.data); + + await roll.evaluate({async: true}); + let isCritical = false; let skillCheckTotal = roll.total; + if(rollMode == null || rollMode === ""){ + rollMode = game.settings.get("core", "rollMode"); + } // page 57 of agent's handbook // For a failed lethality check, the damage on the tens die is a 10 for a roll of '0'. E.g. '30' + '0' = 13 damage. @@ -204,7 +220,7 @@ export function sendLethalityTestToChat(actor, weaponName, target){ flavor: label, type: 5, //CHAT_MESSAGE_TYPES.ROLL, roll: roll, - rollMode: game.settings.get("core", "rollMode") + rollMode: rollMode }; // play the dice rolling sound, like a regular in-chat roll @@ -213,8 +229,15 @@ export function sendLethalityTestToChat(actor, weaponName, target){ ChatMessage.create(chatData, {}); } -export function sendDamageRollToChat(actor, label, diceFormula){ +export async function sendDamageRollToChat(actor, label, diceFormula, rollMode){ + + if(rollMode == null || rollMode === ""){ + rollMode = game.settings.get("core", "rollMode"); + } + let roll = new Roll(diceFormula, actor.data.data); + + await roll.evaluate({async: true}); try{ label = `${game.i18n.localize("DG.Roll.Rolling")} ${game.i18n.localize("DG.Roll.Damage").toUpperCase()} ${game.i18n.localize("DG.Roll.For")} ${label.toUpperCase()}`; @@ -222,14 +245,21 @@ export function sendDamageRollToChat(actor, label, diceFormula){ catch{ label = `Rolling DAMAGE for ${label.toUpperCase()}` } - - roll.evaluate(false).toMessage({ - speaker: ChatMessage.getSpeaker({ actor: actor }), - flavor: label, - type: 5, //CHAT_MESSAGE_TYPES.ROLL, - roll: roll, - rollMode: game.settings.get("core", "rollMode") - }); + + let chatData = { + speaker: ChatMessage.getSpeaker({actor: actor}), + content: roll.total, + flavor: label, + type: 5, //CHAT_MESSAGE_TYPES.ROLL, + roll: roll, + rollMode: rollMode + }; + + // play the dice rolling sound, like a regular in-chat roll + AudioHelper.play({src: "sounds/dice.wav", volume: 0.8, autoplay: true, loop: false}, true); + + ChatMessage.create(chatData, {}); + } export async function showModifyPercentileTestDialogue(actor, label, originalTarget, isLethalityTest){ @@ -256,6 +286,8 @@ export async function showModifyPercentileTestDialogue(actor, label, originalTar callback: html => { try{ let targetModifier = html.find("[name='targetModifier']").val(); // this is text as a heads up + + let rollMode = html.find("[name='targetRollMode']").val(); let newTarget = parseInt(originalTarget); // this should be an int, but technically the incoming value is text, so parse it just to be safe if(targetModifier.trim() != "" && !isNaN(targetModifier)){ @@ -263,10 +295,10 @@ export async function showModifyPercentileTestDialogue(actor, label, originalTar } if(isLethalityTest){ - sendLethalityTestToChat(actor, label, newTarget); + sendLethalityTestToChat(actor, label, newTarget, rollMode); } else{ - sendPercentileTestToChat(actor, label, newTarget); + sendPercentileTestToChat(actor, label, newTarget, rollMode); } } catch(ex){ @@ -306,6 +338,7 @@ export async function showModifyDamageRollDialogue(actor, label, originalFormula let outerModifier = html.find("[name='outerModifier']").val(); // this is text as a heads up let innerModifier = html.find("[name='innerModifier']").val(); // this is text as a heads up let modifiedBaseRoll = html.find("[name='originalFormula']").val(); // this is text as a heads up + let rollMode = html.find("[name='targetRollMode']").val(); if(innerModifier.replace(" ", "") === "+0"){ innerModifier = ""; @@ -319,7 +352,7 @@ export async function showModifyDamageRollDialogue(actor, label, originalFormula newRoll += modifiedBaseRoll + innerModifier.trim(); } - sendDamageRollToChat(actor, label, newRoll); + sendDamageRollToChat(actor, label, newRoll, rollMode); } catch(ex){ console.log(ex); @@ -358,15 +391,4 @@ export function skillIsStatTest(skillName){ catch(ex){ return false; } -} - -/* rollMode Options -> CONFIG.Dice.rollModes - - game.i18n.localize("CHAT.RollBlind") -> "Blind GM Roll" - {{selectOptions rollModes selected=defaultRollMode localize=true}} - - roll -> 'Public Roll' - gmroll -> 'Private GM Roll' - blindroll -> 'Blind GM Roll' - selfroll -> 'Self Roll' - */ \ No newline at end of file +} \ No newline at end of file diff --git a/system.json b/system.json index b48c085..115d6cb 100644 --- a/system.json +++ b/system.json @@ -1,10 +1,10 @@ { "name": "deltagreen", "title": "Delta Green (Unofficial)", - "description": "Fan-made Foundry VTT system for Delta Green: The Role Playing Game for Foundry VTT. Based on the rules in the Agent's Handbook (https://www.drivethrurpg.com/product/181674/Delta-Green-Agents-Handbook). Made with the permission of but neither affiliated with nor endorsed by Arc Dream Publishing or the Delta Green Partnership.", + "description": "Fan-made Foundry VTT system for Delta Green: The Role Playing Game for Foundry VTT. Based on the rules in the Agent's Handbook (https://www.drivethrurpg.com/product/181674/Delta-Green-Agents-Handbook) [*NOT* Call of Cthulu]. Made with the permission of but neither affiliated with nor endorsed by Arc Dream Publishing or the Delta Green Partnership.", "version": "1.0.0", - "minimumCoreVersion": "0.8.1", - "compatibleCoreVersion": "0.8.1", + "minimumCoreVersion": "0.8.6", + "compatibleCoreVersion": "0.8.6", "templateVersion": 2, "author": "TheLastScrub (https://github.com/TheLastScrub)", "esmodules": ["module/deltagreen.js"], @@ -59,6 +59,6 @@ "secondaryTokenAttribute": "wp", "url": "https://github.com/TheLastScrub/delta-green-foundry-vtt-system-unofficial", "manifest": "https://github.com/TheLastScrub/delta-green-foundry-vtt-system-unofficial/raw/master/system.json", - "download": "https://github.com/TheLastScrub/delta-green-foundry-vtt-system-unofficial/archive/v0.9.9.zip", + "download": "https://github.com/TheLastScrub/delta-green-foundry-vtt-system-unofficial/archive/v1.0.0.zip", "license": "LICENSE.txt" } diff --git a/template.json b/template.json index e83cad4..9ba9592 100644 --- a/template.json +++ b/template.json @@ -324,7 +324,8 @@ "templates":[ "base" ], - "score": 10 + "score": 10, + "relationship": "" }, "gear":{ "templates":["base"], diff --git a/templates/actor/actor-sheet.html b/templates/actor/actor-sheet.html index 8975827..266e04b 100644 --- a/templates/actor/actor-sheet.html +++ b/templates/actor/actor-sheet.html @@ -213,15 +213,15 @@
  • {{item.name}}

    - {{#if item.data.crossedOut}} -

    {{item.data.disorder}}

    + {{#if item.data.data.crossedOut}} +

    {{item.data.data.disorder}}

    {{/if}}
    @@ -405,7 +405,8 @@
    1. {{localize 'DG.Bonds.Name'}}
      -
      {{localize 'DG.Bonds.Score'}}
      +
      {{localize 'DG.Bonds.Relationship'}}
      +
      {{localize 'DG.Bonds.Score'}}
      @@ -417,7 +418,8 @@
    2. {{item.name}}

      - {{item.data.data.score}} + {{item.data.data.relationship}} + {{item.data.data.score}}
      diff --git a/templates/dialog/modify-damage-roll.html b/templates/dialog/modify-damage-roll.html index 180d510..91b7f14 100644 --- a/templates/dialog/modify-damage-roll.html +++ b/templates/dialog/modify-damage-roll.html @@ -10,4 +10,10 @@ )
      +
      + + +
      \ No newline at end of file diff --git a/templates/dialog/modify-percentile-roll.html b/templates/dialog/modify-percentile-roll.html index fc65128..26d74f4 100644 --- a/templates/dialog/modify-percentile-roll.html +++ b/templates/dialog/modify-percentile-roll.html @@ -8,5 +8,10 @@ {{localize 'DG.ModifySkillRollDialogue.TargetModifier'}} + + +
    \ No newline at end of file diff --git a/templates/item/item-bond-sheet.html b/templates/item/item-bond-sheet.html index 85aad29..9aea8a0 100644 --- a/templates/item/item-bond-sheet.html +++ b/templates/item/item-bond-sheet.html @@ -12,6 +12,12 @@ title="{{localize 'DG.ItemWindow.Bonds.ScoreTooltip'}}" /> +
    + + +