more fixes, async rolls, roll mode choice
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
After Width: | Height: | Size: 608 KiB |
|
After Width: | Height: | Size: 550 KiB |
|
After Width: | Height: | Size: 600 KiB |
|
After Width: | Height: | Size: 606 KiB |
|
Before Width: | Height: | Size: 468 KiB After Width: | Height: | Size: 627 KiB |
|
After Width: | Height: | Size: 586 KiB |
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -217,5 +217,8 @@
|
||||
"DG.Roll.Inhuman": "人ならざるもの",
|
||||
"DG.Tooltip.BreakPoint": "現在のブレーキポイント。初めの数値は「正気 ー 判断力」。",
|
||||
"DG.Tooltip.BreakPointReset": "ブレーキポイントをレセットする。新しい数値は「正気 ー 判断力」。",
|
||||
"DG.Skills.ritual": "秘儀"
|
||||
"DG.Skills.ritual": "秘儀",
|
||||
|
||||
"DG.RollMode": "ロールモード",
|
||||
"DG.Bonds.Relationship": "関係"
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
*/
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -324,7 +324,8 @@
|
||||
"templates":[
|
||||
"base"
|
||||
],
|
||||
"score": 10
|
||||
"score": 10,
|
||||
"relationship": ""
|
||||
},
|
||||
"gear":{
|
||||
"templates":["base"],
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||