diff --git a/lang/en.json b/lang/en.json
index f6f43b9..8a2f345 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -207,7 +207,7 @@
"DG.ModifySkillRollDialogue.Title": "Modify Roll",
"DG.ModifySkillRollDialogue.Test": "Test:",
"DG.ModifySkillRollDialogue.OriginalTarget": "Original Target:",
- "DG.ModifySkillRollDialogue.TargetModifier": "Modify Target:",
+ "DG.ModifySkillRollDialogue.TargetModifier": "Modify Target (+/-):",
"DG.ModifySkillRollDialogue.ModifierTooltip": "Give a positive or negative modifier here to add/subtract from the target for the skill check.",
"DG.ModifyDamageRollDialogue.Weapon": "Weapon:",
diff --git a/lang/ja.json b/lang/ja.json
index 638e25f..46a4e59 100644
--- a/lang/ja.json
+++ b/lang/ja.json
@@ -207,7 +207,7 @@
"DG.ModifySkillRollDialogue.Title": "ロールの変更",
"DG.ModifySkillRollDialogue.Test": "テスト:",
"DG.ModifySkillRollDialogue.OriginalTarget": "元のターゲット:",
- "DG.ModifySkillRollDialogue.TargetModifier": "変換:",
+ "DG.ModifySkillRollDialogue.TargetModifier": "変換(+/-):",
"DG.ModifySkillRollDialogue.ModifierTooltip": "スキルチェックのターゲットに加算/減算します。",
"DG.ModifyDamageRollDialogue.Weapon": "武器:",
diff --git a/module/actor/actor-sheet.js b/module/actor/actor-sheet.js
index 20cf667..c5c6ec1 100644
--- a/module/actor/actor-sheet.js
+++ b/module/actor/actor-sheet.js
@@ -322,13 +322,19 @@ export class DeltaGreenActorSheet extends ActorSheet {
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
+ let inhuman_flag = false; // inhuman_flag to be used for stats above 20
if(rollType === "skill" || rollType === "typeskill"){
targetVal = dataset.target;
label = game.i18n.localize(label).toUpperCase();
}
else if(dataset.target === "statistic.x5"){
let stat = this.actor.data.data.statistics[key];
- targetVal = stat.x5;
+ if (stat.value>=20){
+ targetVal = stat.value;
+ inhuman_flag = true; // you use the value instead of the x5 but you set the inhuman_flag to true
+ }else{
+ targetVal = stat.x5;
+ }
label = game.i18n.localize("DG.Attributes." + key).toUpperCase();
}
else if(rollType === "sanity"){
@@ -356,7 +362,7 @@ export class DeltaGreenActorSheet extends ActorSheet {
}
else{
if(requestedModifyRoll){
- showModifyPercentileTestDialogue(this.actor, label, targetVal, isLethalityRoll);
+ showModifyPercentileTestDialogue(this.actor, label, targetVal, isLethalityRoll,inhuman_flag);
}
else{
if(isLethalityRoll)
@@ -364,7 +370,7 @@ export class DeltaGreenActorSheet extends ActorSheet {
sendLethalityTestToChat(this.actor, label, targetVal);
}
else{
- sendPercentileTestToChat(this.actor, label, targetVal);
+ sendPercentileTestToChat(this.actor, label, targetVal,inhuman_flag);
}
}
}
diff --git a/module/deltagreen.js b/module/deltagreen.js
index 9ee2a76..0b58375 100644
--- a/module/deltagreen.js
+++ b/module/deltagreen.js
@@ -13,6 +13,7 @@ Hooks.once('init', async function() {
DeltaGreenActor,
DeltaGreenItem,
rollItemMacro,
+ rollItemSkillCheckMacro,
rollSkillMacro
};
@@ -155,6 +156,9 @@ function rollItemMacro(itemName) {
let actor;
if (speaker.token) actor = game.actors.tokens[speaker.token];
if (!actor) actor = game.actors.get(speaker.actor);
+
+ if(!actor) return ui.notifications.warn('Must have an Actor selected first.');
+
const item = actor ? actor.items.find(i => i.name === itemName) : null;
if (!item) return ui.notifications.warn(`Your controlled Actor does not have an item named ${itemName}`);
@@ -162,6 +166,31 @@ function rollItemMacro(itemName) {
return item.roll();
}
+function rollItemSkillCheckMacro(itemName) {
+ const speaker = ChatMessage.getSpeaker();
+ let actor;
+ if (speaker.token) actor = game.actors.tokens[speaker.token];
+ if (!actor) actor = game.actors.get(speaker.actor);
+
+ if(!actor) return ui.notifications.warn('Must have an Actor selected first.');
+
+ const item = actor ? actor.items.find(i => i.name === itemName) : null;
+ if (!item) return ui.notifications.warn(`Your controlled Actor does not have an item named ${itemName}`);
+
+ let skillName = item.data.data.skill.toString();
+
+ let skill = actor.data.data.skills[skillName];
+ let translatedSkillLabel = "";
+
+ try{
+ translatedSkillLabel = game.i18n.localize("DG.Skills." + skillName)
+ }
+ catch{
+ translatedSkillLabel = skillName;
+ }
+
+ sendPercentileTestToChat(actor, translatedSkillLabel, skill.proficiency);
+}
function rollSkillMacro(skillName) {
const speaker = ChatMessage.getSpeaker();
@@ -175,5 +204,14 @@ function rollSkillMacro(skillName) {
if(!skill) return ui.notifications.warn('Bad skill name passed to macro.');
- sendPercentileTestToChat(actor, skill.label, skill.proficiency);
+ let translatedSkillLabel = "";
+
+ try{
+ translatedSkillLabel = game.i18n.localize("DG.Skills." + skillName)
+ }
+ catch{
+ translatedSkillLabel = skillName;
+ }
+
+ sendPercentileTestToChat(actor, translatedSkillLabel, skill.proficiency);
}
\ No newline at end of file
diff --git a/module/roll/roll.js b/module/roll/roll.js
index 53a98af..39b58de 100644
--- a/module/roll/roll.js
+++ b/module/roll/roll.js
@@ -1,18 +1,31 @@
-export function sendPercentileTestToChat(actor, skill, target){
- let roll = new Roll('1D100', actor.data.data).roll();
- let total = roll.total;
- let isCritical = false;
- let isSuccess = false;
- let html = '';
- let label = `${game.i18n.localize("DG.Roll.Rolling")} ${skill} ${game.i18n.localize("DG.Roll.Target")} ${target}`;
- let resultString = '';
- let styleOverride = '';
+export function sendPercentileTestToChat(actor, skill, target, inhuman_flag=false){ // flag check if the stat is above 20
+ let roll = new Roll('1D100', actor.data.data).roll();
+ let total = roll.total;
+ let isCritical = false;
+ let isSuccess = false;
+ let html = '';
+ let label = `${game.i18n.localize("DG.Roll.Rolling")} ${skill} ${game.i18n.localize("DG.Roll.Target")} ${target}`;
+ let resultString = '';
+ let styleOverride = '';
- isCritical = skillCheckResultIsCritical(total);
-
- if(total <= target){
- isSuccess = true;
- }
+ isCritical = skillCheckResultIsCritical(total); // up to this point everything works as intended
+
+ if (inhuman_flag){ // pag 188 of the Handler guide: inhuman stats
+ //an entity with a stat at 20 or higher succeeds at any stat test except with a roll of 100, which fails
+ //and fumbles. It gets a critical success on any success with matching digits, and with any roll equal
+ //to or less than the stat’s value.
+
+ if(total <= 99){
+ isSuccess = true;
+ if(total <= target){
+ isCritical = true;
+ }
+ }
+ }else{ // general case
+ if(total <= target){
+ isSuccess = true;
+ }
+ }
if(isCritical){
resultString = `${game.i18n.localize("DG.Roll.Critical")} `;
@@ -167,6 +180,18 @@ export function sendLethalityTestToChat(actor, weaponName, target){
type: CHAT_MESSAGE_TYPES.ROLL,
roll: roll,
rollMode: game.settings.get("core", "rollMode")
+ });
+ }
+
+ export async function showModifyPercentileTestDialogue(actor, label, originalTarget, isLethalityTest,inhuman_flag=false){
+
+ let template = "systems/deltagreen/templates/dialog/modify-percentile-roll.html";
+ let backingData = {
+ data:{
+ label: label,
+ originalTarget: originalTarget,
+ targetModifier: 20
+ },
};
// play the dice rolling sound, like a regular in-chat roll
@@ -223,7 +248,17 @@ export async function showModifyPercentileTestDialogue(actor, label, originalTar
if(targetModifier.trim() != "" && !isNaN(targetModifier)){
newTarget += parseInt(targetModifier);
}
-
+ 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)){
+ newTarget += parseInt(targetModifier);
+ }
+
+ if(isLethalityTest){
+ sendLethalityTestToChat(actor, label, newTarget);
+ }
+ else{
+ sendPercentileTestToChat(actor, label, newTarget,inhuman_flag); //take care of inhuman stat, by default the value is false
+ }
if(isLethalityTest){
sendLethalityTestToChat(actor, label, newTarget);
}