move functions to methods of DGPercentileRoll cls;

remove unused functions and imports;
sanity rolls should work now
This commit is contained in:
jalensailin
2023-09-18 19:28:38 -04:00
parent 94287fef38
commit 23b148263c
5 changed files with 156 additions and 327 deletions
+10 -175
View File
@@ -2,10 +2,8 @@
import {
DGPercentileRoll,
sendPercentileTestToChat,
sendLethalityTestToChat,
sendDamageRollToChat,
showModifyPercentileTestDialogue,
showModifyDamageRollDialogue,
sendSanityDamageToChat
} from "../roll/roll.js"
@@ -591,10 +589,12 @@ export class DeltaGreenActorSheet extends ActorSheet {
/**
* Handle clickable rolls.
*
* @param {Event} event The originating click event
* @async
* @private
*/
_onRoll(event) {
async _onRoll(event) {
event.preventDefault();
const element = event.currentTarget;
const { dataset } = element;
@@ -609,10 +609,13 @@ export class DeltaGreenActorSheet extends ActorSheet {
case "skill":
case "typedskill":
case "sanity": {
// const confirmRoll = showModifyPercentileTestDialogue(this.actor);
// if (!confirmRoll) return;
const roll = new DGPercentileRoll(dataset.rolltype, dataset.key, this.actor)
sendPercentileTestToChat(roll);
if (event.shiftKey || event.which === 3) {
const dialogData = await roll.showDialog(dataset.key);
if (!dialogData) return;
roll.modifier += dialogData.targetModifier;
}
roll.toChat();
break;
}
@@ -622,7 +625,7 @@ export class DeltaGreenActorSheet extends ActorSheet {
}
const item = this.actor.items.get(dataset.iid);
const roll = new DGPercentileRoll(dataset.rolltype, dataset.key, this.actor, item)
sendPercentileTestToChat(roll);
roll.toChat();
break;
}
@@ -654,174 +657,6 @@ export class DeltaGreenActorSheet extends ActorSheet {
}
}
/**
* Handle clickable rolls.
* @param {Event} event The originating click event
* @private
*/
_onRoll2(event) {
event.preventDefault();
const element = event.currentTarget;
const dataset = element.dataset;
if(event && event.which === 2){
// probably don't want rolls to trigger from a middle mouse click so just kill it here
return;
}
if (dataset.roll) {
let key = dataset.label ? dataset.label : '';
let label = dataset.label ? `${dataset.label}` : '';
let targetVal = "";
let rollType = dataset.rolltype ? dataset.rolltype : '';
//let customTarget = dataset.customtarget ? parseInt(dataset.customtarget, 10) : 50;
//let skillModifier = dataset.skillmodifier ? parseInt(dataset.skillmodifier, 10) : 0; // allow adding a fixed modifier, for example if a weapon has a scope
//let itemName = dataset.itemname ? `${dataset.itemname}` : '';
let itemId = dataset.iid;
let isDamageRoll = false;
let isLethalityRoll = false;
let isSanityDamageRoll = false;
let item;
let customTarget = 0;
let skillModifier = 0;
let itemName;
if(itemId !== null && itemId !== undefined && itemId !== ''){
item = this.actor.items.get(itemId);
customTarget = item.system.customSkillTarget;
skillModifier = item.system.skillModifier;
itemName = item.name;
}
// if shift-click or right click, bring up roll editor dialog
let requestedModifyRoll = (event && event.shiftKey || event.which === 3); //(event && (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey));
// check the 'data-target="something" property to determine how to grab the target for the roll
if(rollType === "skill" || rollType === "typeskill"){
targetVal = parseInt(dataset.target, 10);
targetVal += skillModifier;
label = game.i18n.localize(label).toUpperCase();
if(skillModifier !== 0){
label += " (" + this._formatStringWithLeadingPlus(skillModifier) + "%)";
}
}
else if(rollType === "weaponskill"){
targetVal = dataset.target;
if(targetVal === "custom"){
label = itemName.toUpperCase();
targetVal = customTarget;
}
// some weapons randomly can just use dexterity x5, so try to trap on that
// otherwise roll a regular skill test
else if(targetVal === "dex"){
label = game.i18n.localize("DG.Attributes.dex").toUpperCase() + "x5";
targetVal = this.actor.system.statistics.dex.x5;
}
else if(targetVal === "int"){
label = game.i18n.localize("DG.Attributes.int").toUpperCase() + "x5";
targetVal = this.actor.system.statistics.int.x5;
}
else if(targetVal === "str"){
label = game.i18n.localize("DG.Attributes.str").toUpperCase() + "x5";
targetVal = this.actor.system.statistics.str.x5;
}
else if(targetVal === "con"){
label = game.i18n.localize("DG.Attributes.con").toUpperCase() + "x5";
targetVal = this.actor.system.statistics.con.x5;
}
else if(targetVal === "pow"){
label = game.i18n.localize("DG.Attributes.pow").toUpperCase() + "x5";
targetVal = this.actor.system.statistics.pow.x5;
}
else if(targetVal === "cha"){
label = game.i18n.localize("DG.Attributes.cha").toUpperCase() + "x5";
targetVal = this.actor.system.statistics.cha.x5;
}
else{
label = game.i18n.localize("DG.Skills." + targetVal).toUpperCase();
targetVal = this.actor.system.skills[targetVal].proficiency;
}
targetVal += skillModifier;
if(skillModifier !== 0){
label += " (" + this._formatStringWithLeadingPlus(skillModifier) + "%)";
}
}
else if(dataset.target === "statistic.x5"){
let stat = this.actor.system.statistics[key];
targetVal = stat.x5;
label = game.i18n.localize("DG.Attributes." + key).toUpperCase() + "x5";
targetVal += skillModifier;
if(skillModifier !== 0){
label += " (" + this._formatStringWithLeadingPlus(skillModifier) + "%)";
}
}
else if(rollType === "sanity"){
targetVal = this.actor.system.sanity.value;
label = game.i18n.localize("DG.Attributes.SAN").toUpperCase();
}
else if(rollType === "damage"){
// damage roll, not a skill check
isDamageRoll = true;
}
else if(rollType === "lethality"){
// a lethality roll
isLethalityRoll = true;
targetVal = dataset.target;
}
else if(rollType === 'sanity-damage'){
isSanityDamageRoll = true;
}
if(isDamageRoll){
let diceFormula = dataset.roll;
let skillType = dataset.skill ? dataset.skill : '';
if(this.actor.type === 'agent' && (skillType === 'unarmed_combat' || skillType === 'melee_weapons')){
diceFormula += this.actor.system.statistics.str.meleeDamageBonusFormula;
}
if(requestedModifyRoll){
showModifyDamageRollDialogue(this.actor, label, diceFormula);
}
else{
sendDamageRollToChat(this.actor, label, diceFormula, game.settings.get("core", "rollMode"));
}
}
else if(isSanityDamageRoll){
let lowRollFormula = dataset.roll;
let highRollFormula = dataset.roll2;
sendSanityDamageToChat(this.actor, label, lowRollFormula, highRollFormula, game.settings.get("core", "rollMode"))
}
else{
if(requestedModifyRoll){
showModifyPercentileTestDialogue(this.actor, label, targetVal, isLethalityRoll);
}
else{
if(isLethalityRoll)
{
sendLethalityTestToChat(this.actor, label, targetVal, game.settings.get("core", "rollMode"));
}
else{
sendPercentileTestToChat("skill", dataset.skillkey, this.actor);
}
}
}
}
}
_resetBreakingPoint(event){
event.preventDefault();
+3 -1
View File
@@ -1,9 +1,11 @@
/* globals $ Hooks game CONFIG Actors Items ActorSheet ItemSheet Handlebars Macro ChatMessage ui duplicate */
// Import Modules
import { DeltaGreenActor } from "./actor/actor.js";
import { DeltaGreenActorSheet } from "./actor/actor-sheet.js";
import { DeltaGreenItem } from "./item/item.js";
import { DeltaGreenItemSheet } from "./item/item-sheet.js";
import { sendPercentileTestToChat, sendLethalityTestToChat, sendDamageRollToChat, DGPercentileRoll } from "./roll/roll.js";
import { sendLethalityTestToChat, sendDamageRollToChat, DGPercentileRoll } from "./roll/roll.js";
import { registerSystemSettings } from "./settings.js"
import { preloadHandlebarsTemplates } from "./templates.js";
import { ParseDeltaGreenStatBlock } from "./other/stat-parser-macro.js";
+1 -1
View File
@@ -1,4 +1,4 @@
import { sendPercentileTestToChat, sendLethalityTestToChat, sendDamageRollToChat } from "../roll/roll.js"
import { sendLethalityTestToChat, sendDamageRollToChat } from "../roll/roll.js"
/**
* Extend the basic Item with some very simple modifications.
+140 -148
View File
@@ -9,6 +9,7 @@ export class DGPercentileRoll extends Roll {
this.key = key;
this.actor = actor;
this.item = item;
this.modifier = 0;
switch (rollType) {
case "stat":
this.rollBasis = actor.system.statistics[key]
@@ -64,7 +65,7 @@ export class DGPercentileRoll extends Roll {
// If inhuman and the roll is below the regular (non-x5) value of the stat, it is a critical.
// E.g. a CON of 25, a d100 roll of 21 would be a critical.
if (this.isInhuman && this.total <= (this.target / 5)) {
if (this.isInhuman && this.total <= ((this.target + this.modifier) / 5)) {
isCritical = true;
}
@@ -85,82 +86,147 @@ export class DGPercentileRoll extends Roll {
// A roll of 100 always (critically) fails, even for inhuman rolls.
if (this.total === 100) return false;
return this.total <= this.target;
}
}
export async function sendPercentileTestToChat(roll){
await roll.evaluate({async: true});
let rollMode = game.settings.get("core", "rollMode");
// if using private san rolls, must hide any SAN roll unless user is a GM
const privateSanSetting = game.settings.get("deltagreen", "keepSanityPrivate");
if (privateSanSetting && (roll.key === 'sanity' || roll.key === 'ritual') && !game.user.isGM){
rollMode = 'blindroll';
return this.total <= (this.target + this.modifier);
}
let label = '';
// "Inhuman" stat being rolled. See function for details.
if (roll.isInhuman) {
label = `${game.i18n.localize("DG.Roll.Rolling")} <b>${roll.localizedKey} [${game.i18n.localize("DG.Roll.Inhuman").toUpperCase()}]</b> ${game.i18n.localize("DG.Roll.Target")} ${Math.floor(roll.target / 5)}`;
} else {
label = `${game.i18n.localize("DG.Roll.Rolling")} <b>${roll.localizedKey}</b> ${game.i18n.localize("DG.Roll.Target")} ${roll.target}`;
}
let resultString = '', styleOverride = '';
if (roll.isCritical) {
resultString = `${game.i18n.localize("DG.Roll.Critical")} `;
}
if (roll.isSuccess) {
resultString += `${game.i18n.localize("DG.Roll.Success")}`;
if (roll.isCritical){
resultString = resultString.toUpperCase() + '!';
styleOverride="color: green";
}
} else {
resultString += `${game.i18n.localize("DG.Roll.Failure")}`;
if(roll.isCritical){
resultString = resultString.toUpperCase() + '!';
styleOverride="color: red";
}
}
let html = '';
html += `<div class="dice-roll">`
html += ` <div class="dice-result">`
html += ` <div style="${styleOverride}" class="dice-formula">${resultString}</div>`
html += ` <div class="dice-tooltip">`
html += ` <section class="tooltip-part">`
html += ` <div class="dice">`
html += ` <p class="part-formula">`
html += ` ${roll.formula}`
html += ` <span class="part-total">${roll.total}</span>`
html += ` </p>`
html += ` <ol class="dice-rolls">`
html += ` <li class="roll die ${roll.formula}">${roll.total}</li>`
html += ` </ol>`
html += ` </div>`
html += ` </section>`
html += ` </div>`
html += ` <h4 class="dice-total">${roll.total}</h4>`
html += `</div>`
let chatData = {
speaker: ChatMessage.getSpeaker({actor: roll.actor}),
content: html,
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);
/**
* Shows a dialog that can modify the roll.
*
* @returns {Promise<Object|void>} - the results of the dialog.
*/
async showDialog() {
let isSanCheck = false;
const hideSanTarget = !game.user.isGM && game.settings.get("deltagreen", "keepSanityPrivate");
ChatMessage.create(chatData);
if (this.key === 'sanity' || this.key === 'ritual') {
isSanCheck = true;
}
let backingData = {
data:{
label: this.key,
originalTarget: this.target,
targetModifier: 20,
isSanCheck: isSanCheck,
hideTarget: hideSanTarget
},
};
let template = "systems/deltagreen/templates/dialog/modify-percentile-roll.html";
let html = await renderTemplate(template, backingData);
return new Promise((resolve, reject) => {
new Dialog({
content: html,
title: localizeWithFallback("DG.ModifySkillRollDialogue.Title", "Modify Roll"),
default: "roll",
buttons: {
roll:{
label: localizeWithFallback("DG.Roll.Roll", "Roll"),
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 plusMinus = html.find("[name='plusOrMinus']").val();
if (targetModifier.trim() != "" && !isNaN(targetModifier)){
targetModifier = Math.abs(parseInt(targetModifier));
if(plusMinus === "-"){
targetModifier = -1 * targetModifier;
}
}
resolve({targetModifier, rollMode})
} catch(ex) {
reject(console.log(ex));
}
}
}
}
}).render(true);
});
}
/**
* Evaluates and sends a roll to chat.
* Lays out and styles message based on outcome of the roll.
*
* @returns {void} - the results of the dialog.
*/
async toChat() {
await this.evaluate({async: true});
let rollMode = game.settings.get("core", "rollMode");
// if using private san rolls, must hide any SAN roll unless user is a GM
const privateSanSetting = game.settings.get("deltagreen", "keepSanityPrivate");
if (privateSanSetting && (this.key === 'sanity' || this.key === 'ritual') && !game.user.isGM){
rollMode = 'blindroll';
}
let label = '';
// "Inhuman" stat being rolled. See function for details.
if (this.isInhuman) {
label = `${game.i18n.localize("DG.Roll.Rolling")} <b>${this.localizedKey} [${game.i18n.localize("DG.Roll.Inhuman").toUpperCase()}]</b> ${game.i18n.localize("DG.Roll.Target")} ${Math.floor(this.target + this.modifier / 5)}`;
} else {
label = `${game.i18n.localize("DG.Roll.Rolling")} <b>${this.localizedKey}</b> ${game.i18n.localize("DG.Roll.Target")} ${this.target + this.modifier}`;
}
let resultString = '', styleOverride = '';
if (this.isCritical) {
resultString = `${game.i18n.localize("DG.Roll.Critical")} `;
}
if (this.isSuccess) {
resultString += `${game.i18n.localize("DG.Roll.Success")}`;
if (this.isCritical){
resultString = resultString.toUpperCase() + '!';
styleOverride="color: green";
}
} else {
resultString += `${game.i18n.localize("DG.Roll.Failure")}`;
if(this.isCritical){
resultString = resultString.toUpperCase() + '!';
styleOverride="color: red";
}
}
let html = '';
html += `<div class="dice-roll">`
html += ` <div class="dice-result">`
html += ` <div style="${styleOverride}" class="dice-formula">${resultString}</div>`
html += ` <div class="dice-tooltip">`
html += ` <section class="tooltip-part">`
html += ` <div class="dice">`
html += ` <p class="part-formula">`
html += ` ${this.formula}`
html += ` <span class="part-total">${this.total}</span>`
html += ` </p>`
html += ` <ol class="dice-rolls">`
html += ` <li class="roll die ${this.formula}">${this.total}</li>`
html += ` </ol>`
html += ` </div>`
html += ` </section>`
html += ` </div>`
html += ` <h4 class="dice-total">${this.total}</h4>`
html += `</div>`
let chatData = {
speaker: ChatMessage.getSpeaker({actor: this.actor}),
content: html,
flavor: label,
type: 5, //CHAT_MESSAGE_TYPES.ROLL,
roll: this,
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 sendLethalityTestToChat(actor, weaponName, target, rollMode){
@@ -336,80 +402,6 @@ export async function sendSanityDamageToChat(actor, label, lowFormula, highFormu
ChatMessage.create(chatData, {});
}
export async function showModifyPercentileTestDialogue(actor, label, originalTarget, isLethalityTest){
let template = "systems/deltagreen/templates/dialog/modify-percentile-roll.html";
let isSanCheck = false;
let hideSanTarget = false;
if(label === 'SAN' || label === 'RITUAL'){
isSanCheck = true;
hideSanTarget = game.settings.get("deltagreen", "keepSanityPrivate");
if(game.user.isGM){
hideSanTarget = false;
}
}
let backingData = {
data:{
label: label,
originalTarget: originalTarget,
targetModifier: 20,
isSanCheck: isSanCheck,
hideTarget: hideSanTarget
},
};
let html = await renderTemplate(template, backingData);
new Dialog({
content: html,
title: localizeWithFallback("DG.ModifySkillRollDialogue.Title", "Modify Roll"),
default: "roll",
buttons: {
roll:{
label: localizeWithFallback("DG.Roll.Roll", "Roll"),
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 plusMinus = html.find("[name='plusOrMinus']").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)){
let numericTargetModifier = Math.abs(parseInt(targetModifier));
if(plusMinus === "-"){
numericTargetModifier = -1 * numericTargetModifier;
}
newTarget += numericTargetModifier;
}
if(isLethalityTest){
sendLethalityTestToChat(actor, label, newTarget, rollMode);
}
else{
sendPercentileTestToChat(actor, label, newTarget, rollMode);
}
}
catch(ex){
console.log(ex);
}
}
}
}
}).render(true);
}
export async function showModifyDamageRollDialogue(actor, label, originalFormula){
let template = "systems/deltagreen/templates/dialog/modify-damage-roll.html";
+2 -2
View File
@@ -49,7 +49,7 @@
{{!-- Sanity --}}
<div class="resource-outer-grid-1col">
<label for="system.san.value" class="resource-label rollable"
data-rolltype="sanity" data-roll="d100" data-target="sanity" data-label="SAN" title="{{localize 'DG.Tooltip.SanityLabel'}}"
data-rolltype="sanity" data-key="sanity" title="{{localize 'DG.Tooltip.SanityLabel'}}"
>{{localize 'DG.Attributes.SAN' }} <i class="fas fa-dice"></i></label>
<div class="resource-inner-grid-3col">
@@ -174,7 +174,7 @@
<div class="flex-group-center flex-mid-border">
<div class="">
<div class="physical-stats-outer-grid-3col">
<label class="rollable" data-rolltype="stat" data-key="{{key}}" title="{{localize 'DG.Tooltip.x5AttributeLabel'}}" for="system.statistics.{{key}}.value" class="resource-label">{{localize (concat 'DG.Attributes.' key)}}</label>
<label class="rollable resource-label" data-rolltype="stat" data-key="{{key}}" title="{{localize 'DG.Tooltip.x5AttributeLabel'}}" for="system.statistics.{{key}}.value">{{localize (concat 'DG.Attributes.' key)}}</label>
<input type="text" name="system.statistics.{{key}}.value" value="{{statistic.value}}" data-dtype="Number"/>
<span class="rollable" data-rolltype="stat" data-key="{{key}}" title="{{localize 'DG.Tooltip.x5AttributeLabel'}}">({{numberFormat statistic.x5 decimals=0 sign=false}}%)</span>
</div >