more fixes, async rolls, roll mode choice

This commit is contained in:
TheLastScrub
2021-06-04 22:17:08 -07:00
parent 584eb59e56
commit 657f509073
21 changed files with 135 additions and 56 deletions
+7
View File
@@ -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.
+9 -4
View File
@@ -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;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 608 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 468 KiB

After

Width:  |  Height:  |  Size: 627 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 KiB

+6 -3
View File
@@ -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"
}
+4 -1
View File
@@ -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"
}
+4 -1
View File
@@ -217,5 +217,8 @@
"DG.Roll.Inhuman": "人ならざるもの",
"DG.Tooltip.BreakPoint": "現在のブレーキポイント。初めの数値は「正気 ー 判断力」。",
"DG.Tooltip.BreakPointReset": "ブレーキポイントをレセットする。新しい数値は「正気 ー 判断力」。",
"DG.Skills.ritual": "秘儀"
"DG.Skills.ritual": "秘儀",
"DG.RollMode": "ロールモード",
"DG.Bonds.Relationship": "関係"
}
+3 -3
View File
@@ -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"));
}
}
}
+18 -2
View File
@@ -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() {
+1 -1
View File
@@ -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
+53 -31
View File
@@ -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")} <b>${game.i18n.localize("DG.Roll.Damage").toUpperCase()}</b> ${game.i18n.localize("DG.Roll.For")} <b>${label.toUpperCase()}</b>`;
@@ -222,14 +245,21 @@ export function sendDamageRollToChat(actor, label, diceFormula){
catch{
label = `Rolling <b>DAMAGE</b> for <b>${label.toUpperCase()}</b>`
}
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'
*/
}
+4 -4
View File
@@ -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"
}
+2 -1
View File
@@ -324,7 +324,8 @@
"templates":[
"base"
],
"score": 10
"score": 10,
"relationship": ""
},
"gear":{
"templates":["base"],
+7 -5
View File
@@ -213,15 +213,15 @@
<li class="item flexrow" data-item-id="{{item.id}}">
<h4 class="item-name"
{{#if item.data.crossedOut}}
{{#if item.data.data.crossedOut}}
style="text-decoration: line-through;"
{{/if}}
>
{{item.name}}
</h4>
{{#if item.data.crossedOut}}
<h4 class="item-name">{{item.data.disorder}}</h4>
{{#if item.data.data.crossedOut}}
<h4 class="item-name">{{item.data.data.disorder}}</h4>
{{/if}}
<div class="item-controls">
@@ -405,7 +405,8 @@
<ol class="items-list">
<li class="item flexrow item-header">
<div class="item-name">{{localize 'DG.Bonds.Name'}}</div>
<div class="item-name">{{localize 'DG.Bonds.Score'}}</div>
<div class="item-name">{{localize 'DG.Bonds.Relationship'}}</div>
<div class="item-name">{{localize 'DG.Bonds.Score'}}</div>
<div class="item-controls">
<a class="item-control item-create" title="Create item" data-type="bond"><i class="fas fa-plus"></i> {{localize 'DG.Generic.AddButtonLabel'}}</a>
</div>
@@ -417,7 +418,8 @@
<li class="item flexrow" data-item-id="{{item.id}}">
<h4 style="word-wrap: break-word;" class="item-name">{{item.name}}</h4>
<span>{{item.data.data.score}}</span>
<span>{{item.data.data.relationship}}</span>
<span>{{item.data.data.score}}</span>
<div class="item-controls">
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
+6
View File
@@ -10,4 +10,10 @@
<input class="damage-roll-formula-part" type="text" name="innerModifier" value="{{data.innerModifier}}" title="{{localize 'DG.ModifyDamageRollDialogue.InnerModifierTooltip'}}" />
<span>)</span>
</div>
<div class="damage-modify-roll-mode">
<label for="targetRollMode">{{ localize "DG.RollMode" }}:</label>
<select name="targetRollMode">
{{selectOptions (getAvailableRollModes) selected=(getDefaultRollMode) localize=true}}
</select>
</div>
</form>
@@ -8,5 +8,10 @@
<span>{{localize 'DG.ModifySkillRollDialogue.TargetModifier'}}</span>
<input class="numeric-label-field" type="number" name="targetModifier" value="{{data.targetModifier}}" title="{{localize 'DG.ModifySkillRollDialogue.ModifierTooltip'}}" />
<label for="targetRollMode">{{ localize "DG.RollMode" }}:</label>
<select name="targetRollMode">
{{selectOptions (getAvailableRollModes) selected=(getDefaultRollMode) localize=true}}
</select>
</div>
</form>
+6
View File
@@ -12,6 +12,12 @@
title="{{localize 'DG.ItemWindow.Bonds.ScoreTooltip'}}"
/>
</div>
<div class="resource">
<label class="resource-label">Relationship</label>
<input type="text" name="data.relationship" value="{{data.data.relationship}}" data-dtype="String"
/>
</div>
</div>
</div>
</header>