fix autofixable ESLint errors and format js files
This commit is contained in:
+481
-305
File diff suppressed because it is too large
Load Diff
+180
-180
@@ -3,7 +3,6 @@
|
||||
* @extends {Actor}
|
||||
*/
|
||||
export class DeltaGreenActor extends Actor {
|
||||
|
||||
/**
|
||||
* Augment the basic actor data with additional dynamic data.
|
||||
*/
|
||||
@@ -11,41 +10,38 @@ export class DeltaGreenActor extends Actor {
|
||||
super.prepareData();
|
||||
|
||||
const actorData = this;
|
||||
const system = actorData.system;
|
||||
const flags = actorData.flags;
|
||||
const { system } = actorData;
|
||||
const { flags } = actorData;
|
||||
|
||||
//console.log('actor.js prepareData');
|
||||
//console.log(this);
|
||||
// console.log('actor.js prepareData');
|
||||
// console.log(this);
|
||||
|
||||
// Make separate methods for each Actor type (character, npc, etc.) to keep
|
||||
// things organized.
|
||||
if (actorData.type === 'agent'){
|
||||
if (actorData.type === "agent") {
|
||||
this._prepareAgentData(this);
|
||||
}
|
||||
else if(actorData.type === 'unnatural'){
|
||||
} else if (actorData.type === "unnatural") {
|
||||
this._prepareUnnaturalData(this);
|
||||
}
|
||||
else if(actorData.type === 'npc'){
|
||||
} else if (actorData.type === "npc") {
|
||||
this._prepareNpcData(this);
|
||||
}
|
||||
else if(actorData.type === 'vehicle'){
|
||||
} else if (actorData.type === "vehicle") {
|
||||
this._prepareVehicleData(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} agent
|
||||
*
|
||||
* @param {*} agent
|
||||
*/
|
||||
|
||||
_prepareVehicleData(actor){
|
||||
let actorData = actor;
|
||||
_prepareVehicleData(actor) {
|
||||
const actorData = actor;
|
||||
|
||||
// calculate total armor rating
|
||||
// calculate total armor rating
|
||||
let protection = 0;
|
||||
for (let i of actor.items) {
|
||||
if (i.type === 'armor') {
|
||||
if(i.system.equipped === true){
|
||||
for (const i of actor.items) {
|
||||
if (i.type === "armor") {
|
||||
if (i.system.equipped === true) {
|
||||
protection += i.system.protection;
|
||||
}
|
||||
}
|
||||
@@ -56,74 +52,76 @@ export class DeltaGreenActor extends Actor {
|
||||
console.log(actor);
|
||||
}
|
||||
|
||||
_prepareNpcData(actor){
|
||||
const { system } = actor;
|
||||
|
||||
// Loop through ability scores, and add their modifiers to our sheet output.
|
||||
for (let [key, statistic] of Object.entries(system.statistics)) {
|
||||
// the x5 is just whatever the raw statistic is x 5 to turn it into a d100 percentile
|
||||
statistic.x5 = statistic.value * 5;
|
||||
}
|
||||
|
||||
// initialize sanity, don't set these afterwards, as they need to be manually edited
|
||||
if(system.sanity.value >= 100){
|
||||
system.sanity.value = system.statistics.pow.x5
|
||||
system.sanity.currentBreakingPoint = system.sanity.value - system.statistics.pow.value;
|
||||
};
|
||||
|
||||
system.sanity.max = 99 - system.skills.unnatural.proficiency;
|
||||
|
||||
system.wp.max = system.statistics.pow.value;
|
||||
|
||||
system.health.max = Math.ceil((system.statistics.con.value + system.statistics.str.value) / 2);
|
||||
|
||||
system.skills.ritual = {
|
||||
label: "Ritual",
|
||||
proficiency: 99 - system.sanity.value,
|
||||
cannotBeImprovedByFailure: true,
|
||||
failure: false
|
||||
};
|
||||
|
||||
if(system.skills.ritual.proficiency > 99){
|
||||
system.skills.ritual.proficiency = 99
|
||||
}
|
||||
else if(system.skills.ritual.proficiency < 1){
|
||||
system.skills.ritual.proficiency = 1
|
||||
}
|
||||
|
||||
// calculate total armor rating
|
||||
let protection = 0;
|
||||
for (let i of actor.items) {
|
||||
if (i.type === 'armor') {
|
||||
if(i.system.equipped === true){
|
||||
protection += i.system.protection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
system.health.protection = protection;
|
||||
|
||||
console.log(actor);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} agent
|
||||
*/
|
||||
_prepareUnnaturalData(actor){
|
||||
_prepareNpcData(actor) {
|
||||
const { system } = actor;
|
||||
|
||||
// Loop through ability scores, and add their modifiers to our sheet output.
|
||||
for (let [key, statistic] of Object.entries(system.statistics)) {
|
||||
for (const [key, statistic] of Object.entries(system.statistics)) {
|
||||
// the x5 is just whatever the raw statistic is x 5 to turn it into a d100 percentile
|
||||
statistic.x5 = statistic.value * 5;
|
||||
}
|
||||
|
||||
// initialize sanity, don't set these afterwards, as they need to be manually edited
|
||||
if (system.sanity.value >= 100) {
|
||||
system.sanity.value = system.statistics.pow.x5;
|
||||
system.sanity.currentBreakingPoint =
|
||||
system.sanity.value - system.statistics.pow.value;
|
||||
}
|
||||
|
||||
system.sanity.max = 99 - system.skills.unnatural.proficiency;
|
||||
|
||||
system.wp.max = system.statistics.pow.value;
|
||||
|
||||
system.health.max = Math.ceil(
|
||||
(system.statistics.con.value + system.statistics.str.value) / 2,
|
||||
);
|
||||
|
||||
system.skills.ritual = {
|
||||
label: "Ritual",
|
||||
proficiency: 99 - system.sanity.value,
|
||||
cannotBeImprovedByFailure: true,
|
||||
failure: false,
|
||||
};
|
||||
|
||||
if (system.skills.ritual.proficiency > 99) {
|
||||
system.skills.ritual.proficiency = 99;
|
||||
} else if (system.skills.ritual.proficiency < 1) {
|
||||
system.skills.ritual.proficiency = 1;
|
||||
}
|
||||
|
||||
// calculate total armor rating
|
||||
let protection = 0;
|
||||
for (const i of actor.items) {
|
||||
if (i.type === "armor") {
|
||||
if (i.system.equipped === true) {
|
||||
protection += i.system.protection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
system.health.protection = protection;
|
||||
|
||||
console.log(actor);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} agent
|
||||
*/
|
||||
_prepareUnnaturalData(actor) {
|
||||
const { system } = actor;
|
||||
|
||||
// Loop through ability scores, and add their modifiers to our sheet output.
|
||||
for (const [key, statistic] of Object.entries(system.statistics)) {
|
||||
// the x5 is just whatever the raw statistic is x 5 to turn it into a d100 percentile
|
||||
statistic.x5 = statistic.value * 5;
|
||||
}
|
||||
|
||||
// calculate total armor rating
|
||||
let protection = 0;
|
||||
for (let i of actor.items) {
|
||||
if (i.type === 'armor') {
|
||||
if(i.system.equipped === true){
|
||||
for (const i of actor.items) {
|
||||
if (i.type === "armor") {
|
||||
if (i.system.equipped === true) {
|
||||
protection += i.system.protection;
|
||||
}
|
||||
}
|
||||
@@ -138,94 +136,96 @@ export class DeltaGreenActor extends Actor {
|
||||
* Prepare Agent type specific data
|
||||
*/
|
||||
_prepareAgentData(agent) {
|
||||
|
||||
const { system } = agent;
|
||||
|
||||
// Make modifications to data here. For example:
|
||||
|
||||
// Loop through ability scores, and add their modifiers to our sheet output.
|
||||
for (let [key, statistic] of Object.entries(system.statistics)) {
|
||||
for (const [key, statistic] of Object.entries(system.statistics)) {
|
||||
// the x5 is just whatever the raw statistic is x 5 to turn it into a d100 percentile
|
||||
statistic.x5 = statistic.value * 5;
|
||||
}
|
||||
|
||||
|
||||
// The ritual skill is from the Handler's Guide, it is for activating a ritual and is always equal to 99 - current sanity.
|
||||
// The rules can be found on page 166, under 'Ritual Activation'.
|
||||
system.skills.ritual = {
|
||||
label: "Ritual",
|
||||
proficiency: 99 - system.sanity.value,
|
||||
cannotBeImprovedByFailure: true,
|
||||
failure: false
|
||||
failure: false,
|
||||
};
|
||||
|
||||
if(system.skills.ritual.proficiency > 99){
|
||||
system.skills.ritual.proficiency = 99
|
||||
}
|
||||
else if(system.skills.ritual.proficiency < 1){
|
||||
system.skills.ritual.proficiency = 1
|
||||
if (system.skills.ritual.proficiency > 99) {
|
||||
system.skills.ritual.proficiency = 99;
|
||||
} else if (system.skills.ritual.proficiency < 1) {
|
||||
system.skills.ritual.proficiency = 1;
|
||||
}
|
||||
|
||||
// The unnatural skill is sort of special
|
||||
// It cannot be improved via failure, so add in a special property to reflect this
|
||||
// Mostly to make it easy to deactivate the failure checkbox in the GUI
|
||||
for (let [key, skill] of Object.entries(system.skills)){
|
||||
if(key === 'unnatural'){
|
||||
for (const [key, skill] of Object.entries(system.skills)) {
|
||||
if (key === "unnatural") {
|
||||
skill.cannotBeImprovedByFailure = true;
|
||||
}
|
||||
else if(key === 'luck'){
|
||||
} else if (key === "luck") {
|
||||
skill.cannotBeImprovedByFailure = true;
|
||||
}
|
||||
else if(key === 'ritual'){
|
||||
} else if (key === "ritual") {
|
||||
skill.cannotBeImprovedByFailure = true;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
skill.cannotBeImprovedByFailure = false;
|
||||
}
|
||||
|
||||
// For ritual skill, it's calculated, so add some logic to turn off changing that entirely.
|
||||
if(key === 'ritual'){
|
||||
if (key === "ritual") {
|
||||
skill.isCalculatedValue = true;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
skill.isCalculatedValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
system.wp.max = system.statistics.pow.value;
|
||||
|
||||
system.health.max = Math.ceil((system.statistics.con.value + system.statistics.str.value) / 2);
|
||||
system.health.max = Math.ceil(
|
||||
(system.statistics.con.value + system.statistics.str.value) / 2,
|
||||
);
|
||||
|
||||
// initialize sanity, don't set these afterwards, as they need to be manually edited
|
||||
if(system.sanity.value >= 100){
|
||||
system.sanity.value = system.statistics.pow.x5
|
||||
system.sanity.currentBreakingPoint = system.sanity.value - system.statistics.pow.value;
|
||||
};
|
||||
if (system.sanity.value >= 100) {
|
||||
system.sanity.value = system.statistics.pow.x5;
|
||||
system.sanity.currentBreakingPoint =
|
||||
system.sanity.value - system.statistics.pow.value;
|
||||
}
|
||||
|
||||
system.sanity.max = 99 - system.skills.unnatural.proficiency;
|
||||
|
||||
|
||||
// Sanity Loss Adaptations Logic
|
||||
let adaptations = system.sanity.adaptations;
|
||||
const { adaptations } = system.sanity;
|
||||
|
||||
if (adaptations.violence.incident1 && adaptations.violence.incident2 && adaptations.violence.incident3){
|
||||
if (
|
||||
adaptations.violence.incident1 &&
|
||||
adaptations.violence.incident2 &&
|
||||
adaptations.violence.incident3
|
||||
) {
|
||||
system.sanity.adaptations.violence.isAdapted = true;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
system.sanity.adaptations.violence.isAdapted = false;
|
||||
}
|
||||
|
||||
if (adaptations.helplessness.incident1 && adaptations.helplessness.incident2 && adaptations.helplessness.incident3){
|
||||
if (
|
||||
adaptations.helplessness.incident1 &&
|
||||
adaptations.helplessness.incident2 &&
|
||||
adaptations.helplessness.incident3
|
||||
) {
|
||||
system.sanity.adaptations.helplessness.isAdapted = true;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
system.sanity.adaptations.helplessness.isAdapted = false;
|
||||
}
|
||||
|
||||
// calculate total armor rating
|
||||
let protection = 0;
|
||||
for (let i of agent.items) {
|
||||
if (i.type === 'armor') {
|
||||
if(i.system.equipped === true){
|
||||
for (const i of agent.items) {
|
||||
if (i.type === "armor") {
|
||||
if (i.system.equipped === true) {
|
||||
protection += i.system.protection;
|
||||
}
|
||||
}
|
||||
@@ -236,25 +236,22 @@ export class DeltaGreenActor extends Actor {
|
||||
// Damage Bonus/Malus From Strength in Hand-to-hand Combat (melee/unarmed)
|
||||
let bonus = 0;
|
||||
let sbonus = "";
|
||||
let strength = system.statistics.str;
|
||||
const strength = system.statistics.str;
|
||||
|
||||
if(strength.value < 5){
|
||||
if (strength.value < 5) {
|
||||
sbonus = "-2";
|
||||
bonus = -2;
|
||||
}
|
||||
else if(strength.value < 9){
|
||||
} else if (strength.value < 9) {
|
||||
sbonus = "-1";
|
||||
bonus = -1;
|
||||
}
|
||||
else if(strength.value > 12 && strength.value < 17){
|
||||
} else if (strength.value > 12 && strength.value < 17) {
|
||||
sbonus = "+1";
|
||||
bonus = 1;
|
||||
}
|
||||
else if(strength.value > 16){
|
||||
} else if (strength.value > 16) {
|
||||
sbonus = "+2";
|
||||
bonus = 2;
|
||||
}
|
||||
|
||||
|
||||
system.statistics.str.meleeDamageBonus = bonus;
|
||||
system.statistics.str.meleeDamageBonusFormula = sbonus;
|
||||
|
||||
@@ -262,95 +259,98 @@ export class DeltaGreenActor extends Actor {
|
||||
}
|
||||
|
||||
/** @override */
|
||||
static async create(data, options={}) {
|
||||
static async create(data, options = {}) {
|
||||
data.prototypeToken = data.prototypeToken || {};
|
||||
if ( data.type === "agent" ) {
|
||||
mergeObject(data.prototypeToken, {
|
||||
actorLink: true // this will make the 'Link Actor Data' option for a token is checked by default. So changes to the token sheet will reflect to the actor sheet.
|
||||
}, {overwrite: false});
|
||||
if (data.type === "agent") {
|
||||
mergeObject(
|
||||
data.prototypeToken,
|
||||
{
|
||||
actorLink: true, // this will make the 'Link Actor Data' option for a token is checked by default. So changes to the token sheet will reflect to the actor sheet.
|
||||
},
|
||||
{ overwrite: false },
|
||||
);
|
||||
}
|
||||
return super.create(data, options);
|
||||
}
|
||||
|
||||
async AddUnarmedAttackItemIfMissing(){
|
||||
try{
|
||||
|
||||
async AddUnarmedAttackItemIfMissing() {
|
||||
try {
|
||||
let alreadyAdded = false;
|
||||
|
||||
for(let item of this.items){
|
||||
|
||||
let flag = await item.getFlag('deltagreen', 'SystemName');
|
||||
for (const item of this.items) {
|
||||
const flag = await item.getFlag("deltagreen", "SystemName");
|
||||
|
||||
if(flag === 'unarmed-attack' || item.name === 'Unarmed Attack'){
|
||||
if (flag === "unarmed-attack" || item.name === "Unarmed Attack") {
|
||||
alreadyAdded = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(alreadyAdded === true){ return; };
|
||||
if (alreadyAdded === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
let handToHandPack = await game.packs.get('deltagreen.hand-to-hand-weapons');
|
||||
let itemIndex = await handToHandPack.getIndex();
|
||||
let toAdd = []; // createEmbeddedDocument expects an array
|
||||
const handToHandPack = await game.packs.get(
|
||||
"deltagreen.hand-to-hand-weapons",
|
||||
);
|
||||
const itemIndex = await handToHandPack.getIndex();
|
||||
const toAdd = []; // createEmbeddedDocument expects an array
|
||||
|
||||
for(let idx of itemIndex){
|
||||
let _temp = await handToHandPack.getDocument(idx._id);
|
||||
|
||||
if(_temp.name === 'Unarmed Attack'){
|
||||
for (const idx of itemIndex) {
|
||||
const _temp = await handToHandPack.getDocument(idx._id);
|
||||
|
||||
if (_temp.name === "Unarmed Attack") {
|
||||
toAdd.push(_temp);
|
||||
}
|
||||
}
|
||||
|
||||
let newItems = await this.createEmbeddedDocuments("Item", toAdd);
|
||||
|
||||
for(let item of newItems){
|
||||
await item.setFlag('deltagreen','AutoAdded', true);
|
||||
|
||||
if(item.name === 'Unarmed Attack'){
|
||||
await item.setFlag('deltagreen','SystemName', 'unarmed-attack');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(ex){
|
||||
console.log('Error adding unarmed strike item to Actor.')
|
||||
|
||||
const newItems = await this.createEmbeddedDocuments("Item", toAdd);
|
||||
|
||||
for (const item of newItems) {
|
||||
await item.setFlag("deltagreen", "AutoAdded", true);
|
||||
|
||||
if (item.name === "Unarmed Attack") {
|
||||
await item.setFlag("deltagreen", "SystemName", "unarmed-attack");
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
console.log("Error adding unarmed strike item to Actor.");
|
||||
console.log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
async AddBaseVehicleItemsIfMissing(){
|
||||
try{
|
||||
let flag = await this.getFlag('deltagreen', 'DefaultVehicleArmorAdded');
|
||||
async AddBaseVehicleItemsIfMissing() {
|
||||
try {
|
||||
const flag = await this.getFlag("deltagreen", "DefaultVehicleArmorAdded");
|
||||
|
||||
if(flag !== null && flag !== undefined && flag !== true){
|
||||
console.log('found a flag');
|
||||
if (flag !== null && flag !== undefined && flag !== true) {
|
||||
console.log("found a flag");
|
||||
console.log(flag);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
// mark the actor so that we don't accidently do this again later, or if we want to fix/change something on it in the future
|
||||
this.setFlag('deltagreen', 'DefaultVehicleArmorAdded', true);
|
||||
|
||||
let toAdd = []; // createEmbeddedDocument expects an array
|
||||
this.setFlag("deltagreen", "DefaultVehicleArmorAdded", true);
|
||||
|
||||
let armor = await Item.create({type:"armor", name:"Vehicle Frame"});
|
||||
const toAdd = []; // createEmbeddedDocument expects an array
|
||||
|
||||
const armor = await Item.create({
|
||||
type: "armor",
|
||||
name: "Vehicle Frame",
|
||||
});
|
||||
|
||||
// this is the current default, but set it anyways in case it gets changed later.
|
||||
armor.system.protection = 3;
|
||||
|
||||
toAdd.push(armor);
|
||||
|
||||
// create the item on the actor
|
||||
let newItems = await this.createEmbeddedDocuments("Item", toAdd);
|
||||
|
||||
for(let item of newItems){
|
||||
await item.setFlag('deltagreen','AutoAdded', true);
|
||||
}
|
||||
|
||||
// create the item on the actor
|
||||
const newItems = await this.createEmbeddedDocuments("Item", toAdd);
|
||||
|
||||
for (const item of newItems) {
|
||||
await item.setFlag("deltagreen", "AutoAdded", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(ex){
|
||||
} catch (ex) {
|
||||
console.log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+205
-203
@@ -6,20 +6,19 @@ import { DeltaGreenActorSheet } from "./actor/actor-sheet.js";
|
||||
import { DeltaGreenItem } from "./item/item.js";
|
||||
import { DeltaGreenItemSheet } from "./item/item-sheet.js";
|
||||
import * as DGRolls from "./roll/roll.js";
|
||||
import { registerSystemSettings } from "./settings.js"
|
||||
import { registerSystemSettings } from "./settings.js";
|
||||
import { preloadHandlebarsTemplates } from "./templates.js";
|
||||
import { ParseDeltaGreenStatBlock } from "./other/stat-parser-macro.js";
|
||||
import DGUtils from "./other/utility-functions.js";
|
||||
|
||||
Hooks.once('init', async function() {
|
||||
|
||||
Hooks.once("init", async function () {
|
||||
game.deltagreen = {
|
||||
DeltaGreenActor,
|
||||
DeltaGreenItem,
|
||||
rollItemMacro,
|
||||
rollItemSkillCheckMacro,
|
||||
rollSkillMacro,
|
||||
ParseDeltaGreenStatBlock
|
||||
ParseDeltaGreenStatBlock,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -28,11 +27,11 @@ Hooks.once('init', async function() {
|
||||
*/
|
||||
CONFIG.Combat.initiative = {
|
||||
formula: "@statistics.dex.value",
|
||||
decimals: 0
|
||||
decimals: 0,
|
||||
};
|
||||
|
||||
// Register custom dice rolls
|
||||
Object.values(DGRolls).forEach((cls) => CONFIG.Dice.rolls.push(cls))
|
||||
Object.values(DGRolls).forEach((cls) => CONFIG.Dice.rolls.push(cls));
|
||||
|
||||
// Register System Settings
|
||||
registerSystemSettings();
|
||||
@@ -44,28 +43,33 @@ Hooks.once('init', async function() {
|
||||
// Register sheet application classes
|
||||
Actors.unregisterSheet("core", ActorSheet);
|
||||
Items.unregisterSheet("core", ItemSheet);
|
||||
Actors.registerSheet("deltagreen", DeltaGreenActorSheet, { makeDefault: true });
|
||||
Actors.registerSheet("deltagreen", DeltaGreenActorSheet, {
|
||||
makeDefault: true,
|
||||
});
|
||||
Items.registerSheet("deltagreen", DeltaGreenItemSheet, { makeDefault: true });
|
||||
|
||||
|
||||
// Preload Handlebars Templates
|
||||
preloadHandlebarsTemplates();
|
||||
|
||||
// Add Handlebars helpers
|
||||
Handlebars.registerHelper('localizeWithFallback', function(value, fallbackValue) {
|
||||
return DGUtils.localizeWithFallback(value, fallbackValue);
|
||||
});
|
||||
Handlebars.registerHelper(
|
||||
"localizeWithFallback",
|
||||
function (value, fallbackValue) {
|
||||
return DGUtils.localizeWithFallback(value, fallbackValue);
|
||||
},
|
||||
);
|
||||
|
||||
Handlebars.registerHelper('concat', function() {
|
||||
var outStr = '';
|
||||
for (var arg in arguments) {
|
||||
if (typeof arguments[arg] != 'object') {
|
||||
Handlebars.registerHelper("concat", function () {
|
||||
let outStr = "";
|
||||
for (let arg in arguments) {
|
||||
if (typeof arguments[arg] !== "object") {
|
||||
outStr += arguments[arg];
|
||||
}
|
||||
}
|
||||
return outStr;
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('toLowerCase', function(str) {
|
||||
Handlebars.registerHelper("toLowerCase", function (str) {
|
||||
try {
|
||||
return str.toLowerCase();
|
||||
} catch (error) {
|
||||
@@ -73,7 +77,7 @@ Hooks.once('init', async function() {
|
||||
}
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('toUpperCase', function(str) {
|
||||
Handlebars.registerHelper("toUpperCase", function (str) {
|
||||
try {
|
||||
return str.toUpperCase();
|
||||
} catch (error) {
|
||||
@@ -81,62 +85,62 @@ Hooks.once('init', async function() {
|
||||
}
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('if_eq', function(a, b, opts) {
|
||||
Handlebars.registerHelper("if_eq", function (a, b, opts) {
|
||||
if (a == b) {
|
||||
return opts.fn(this);
|
||||
return opts.fn(this);
|
||||
} else {
|
||||
return opts.inverse(this);
|
||||
return opts.inverse(this);
|
||||
}
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('if_not_eq', function(a, b, opts) {
|
||||
if (a != b) { return opts.fn(this); }
|
||||
Handlebars.registerHelper("if_not_eq", function (a, b, opts) {
|
||||
if (a != b) {
|
||||
return opts.fn(this);
|
||||
}
|
||||
return opts.inverse(this);
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('if_gt', function(a, b, trueVal, falseVal) {
|
||||
Handlebars.registerHelper("if_gt", function (a, b, trueVal, falseVal) {
|
||||
if (a > b) {
|
||||
return trueVal;
|
||||
return trueVal;
|
||||
} else {
|
||||
return falseVal;
|
||||
return falseVal;
|
||||
}
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('cite_ahb', function(page) {
|
||||
Handlebars.registerHelper("cite_ahb", function (page) {
|
||||
return `See page ${page} of the Agent's Handbook.`;
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('formatLethality', function(lethality) {
|
||||
Handlebars.registerHelper("formatLethality", function (lethality) {
|
||||
if (lethality > 0) {
|
||||
return lethality.toString() + "%";
|
||||
}
|
||||
else {
|
||||
return `${lethality.toString() }%`;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Is this used anywhere?
|
||||
Handlebars.registerHelper('getActorSkillProp', function(actorData, skillName, prop) {
|
||||
try{
|
||||
if(skillName != "" && prop != ""){
|
||||
let skills = actorData.data.skills;
|
||||
let skill = skills[skillName];
|
||||
let propVal = skill[prop];
|
||||
return propVal;
|
||||
}
|
||||
else{
|
||||
Handlebars.registerHelper(
|
||||
"getActorSkillProp",
|
||||
function (actorData, skillName, prop) {
|
||||
try {
|
||||
if (skillName != "" && prop != "") {
|
||||
const skills = actorData.data.skills;
|
||||
let skill = skills[skillName];
|
||||
const propVal = skill[prop];
|
||||
return propVal;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
} catch (ex) {
|
||||
console.log(ex);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
catch(ex){
|
||||
console.log(ex);
|
||||
return "";
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
Handlebars.registerHelper('getAvailableRollModes', function() {
|
||||
Handlebars.registerHelper("getAvailableRollModes", function () {
|
||||
try {
|
||||
return CONFIG.Dice.rollModes;
|
||||
} catch (error) {
|
||||
@@ -144,7 +148,7 @@ Hooks.once('init', async function() {
|
||||
}
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('getDefaultRollMode', function() {
|
||||
Handlebars.registerHelper("getDefaultRollMode", function () {
|
||||
try {
|
||||
return game.settings.get("core", "rollMode");
|
||||
} catch (error) {
|
||||
@@ -152,44 +156,41 @@ Hooks.once('init', async function() {
|
||||
}
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('calculateHandToHandCombatDamageFormulaBonus', function(strength) {
|
||||
try {
|
||||
let bonus = "";
|
||||
Handlebars.registerHelper(
|
||||
"calculateHandToHandCombatDamageFormulaBonus",
|
||||
function (strength) {
|
||||
try {
|
||||
let bonus = "";
|
||||
|
||||
if(strength.value < 5){
|
||||
bonus = " - 2";
|
||||
}
|
||||
else if(strength.value < 9){
|
||||
bonus = " - 1";
|
||||
}
|
||||
else if(strength.value > 12 && strength < 17){
|
||||
bonus = " + 1";
|
||||
}
|
||||
else if(strength.value > 16){
|
||||
bonus = " + 2";
|
||||
}
|
||||
|
||||
return bonus;
|
||||
if (strength.value < 5) {
|
||||
bonus = " - 2";
|
||||
} else if (strength.value < 9) {
|
||||
bonus = " - 1";
|
||||
} else if (strength.value > 12 && strength < 17) {
|
||||
bonus = " + 1";
|
||||
} else if (strength.value > 16) {
|
||||
bonus = " + 2";
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
return bonus;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
Handlebars.registerHelper('localizeWeaponSkill', function(skill) {
|
||||
Handlebars.registerHelper("localizeWeaponSkill", function (skill) {
|
||||
let label = skill;
|
||||
|
||||
try {
|
||||
|
||||
if(skill === 'dex'){
|
||||
if (skill === "dex") {
|
||||
label = game.i18n.localize("DG.Attributes.dex");
|
||||
}
|
||||
if(skill === 'DG.Skills.custom'){
|
||||
label = game.i18n.localize('DG.ItemWindow.Custom');
|
||||
if (skill === "DG.Skills.custom") {
|
||||
label = game.i18n.localize("DG.ItemWindow.Custom");
|
||||
} else {
|
||||
label = game.i18n.localize(`DG.Skills.${ skill}`);
|
||||
}
|
||||
else{
|
||||
label = game.i18n.localize("DG.Skills." + skill);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
@@ -197,37 +198,37 @@ Hooks.once('init', async function() {
|
||||
return label;
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('hideSkillBasedOnProficiencyAndUserChoice', function(hideUntrainedSkills, proficiency) {
|
||||
let showValue = true;
|
||||
Handlebars.registerHelper(
|
||||
"hideSkillBasedOnProficiencyAndUserChoice",
|
||||
function (hideUntrainedSkills, proficiency) {
|
||||
let showValue = true;
|
||||
|
||||
try {
|
||||
|
||||
if(hideUntrainedSkills === false){
|
||||
showValue = true;
|
||||
}
|
||||
else{
|
||||
if(proficiency > 0){
|
||||
try {
|
||||
if (hideUntrainedSkills === false) {
|
||||
showValue = true;
|
||||
} else {
|
||||
if (proficiency > 0) {
|
||||
showValue = true;
|
||||
} else {
|
||||
showValue = false;
|
||||
}
|
||||
}
|
||||
else{
|
||||
showValue = false;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
return showValue;
|
||||
return showValue;
|
||||
},
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
// looks at system setting for what font to use and returns the class that is then used in the handlebars template that
|
||||
// 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() {
|
||||
let setting = game.settings.get("deltagreen", "characterSheetFont");
|
||||
Handlebars.registerHelper("getFontFamilySystemSettingClass", function () {
|
||||
const setting = game.settings.get("deltagreen", "characterSheetFont");
|
||||
|
||||
const characterSheetStyle = game.settings.get("deltagreen", "characterSheetStyle");
|
||||
);
|
||||
|
||||
let characterSheetStyle = game.settings.get("deltagreen", "characterSheetStyle");
|
||||
|
||||
/*
|
||||
if(setting === "TypeWriterCondensed"){
|
||||
return "typewriter-condensed-font";
|
||||
@@ -251,7 +252,7 @@ Hooks.once('init', async function() {
|
||||
return "martel-font";
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
if(characterSheetStyle === "cowboy"){
|
||||
return "special-elite-font";
|
||||
@@ -262,35 +263,29 @@ Hooks.once('init', async function() {
|
||||
*/
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('getCharacterSheetStyle', function() {
|
||||
Handlebars.registerHelper("getCharacterSheetStyle", function () {
|
||||
const characterSheetStyle = game.settings.get("deltagreen", "characterSheetStyle");
|
||||
);
|
||||
|
||||
let characterSheetStyle = game.settings.get("deltagreen", "characterSheetStyle");
|
||||
|
||||
if(characterSheetStyle === "cowboy"){
|
||||
if (characterSheetStyle === "cowboy") {
|
||||
return "cowboy-style";
|
||||
}
|
||||
else if(characterSheetStyle === "outlaw"){
|
||||
} else if (characterSheetStyle === "outlaw") {
|
||||
return "outlaw-style";
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
return "program-style";
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('keepSanityPrivate', function() {
|
||||
|
||||
Handlebars.registerHelper("keepSanityPrivate", function () {
|
||||
let setting = false;
|
||||
|
||||
try{
|
||||
try {
|
||||
setting = game.settings.get("deltagreen", "keepSanityPrivate");
|
||||
|
||||
if(game.user.isGM){
|
||||
if (game.user.isGM) {
|
||||
setting = false;
|
||||
}
|
||||
|
||||
}
|
||||
catch(ex){
|
||||
} catch (ex) {
|
||||
setting = false;
|
||||
}
|
||||
|
||||
@@ -298,37 +293,34 @@ Hooks.once('init', async function() {
|
||||
});
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('playerHasGamemasterPrivileges', function(){
|
||||
Handlebars.registerHelper("playerHasGamemasterPrivileges", function () {
|
||||
return game.user.isGM;
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('showImpossibleLandscapesContent', function() {
|
||||
|
||||
Handlebars.registerHelper("showImpossibleLandscapesContent", function () {
|
||||
let result = false;
|
||||
let setting = game.settings.get("deltagreen", "showImpossibleLandscapesContent");
|
||||
const setting = game.settings.get("deltagreen", "showImpossibleLandscapesContent");
|
||||
|
||||
if(game.user.isGM === true && setting === true){
|
||||
if (game.user.isGM === true && setting === true) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
Hooks.once("ready", async function() {
|
||||
Hooks.once("ready", async function () {
|
||||
// Wait to register hotbar drop hook on ready so that modules could register earlier if they want to
|
||||
Hooks.on("hotbarDrop", (bar, data, slot) => createDeltaGreenMacro(data, slot));
|
||||
Hooks.on("hotbarDrop", (bar, data, slot) =>
|
||||
createDeltaGreenMacro(data, slot),
|
||||
);
|
||||
});
|
||||
|
||||
Hooks.on("ready", ()=> {
|
||||
|
||||
//let backgroundImageSetting = game.settings.get("deltagreen", "characterSheetBackgroundImageSetting");
|
||||
//let characterSheetStyle = game.settings.get("deltagreen", "characterSheetStyle");
|
||||
|
||||
Hooks.on("ready", () => {
|
||||
// let backgroundImageSetting = game.settings.get("deltagreen", "characterSheetBackgroundImageSetting");
|
||||
// let characterSheetStyle = game.settings.get("deltagreen", "characterSheetStyle");
|
||||
//let customCss = "";
|
||||
|
||||
//let customStyle = document.createElement("style");
|
||||
//customStyle.id = "dg-custom-css";
|
||||
|
||||
// let customStyle = document.createElement("style");
|
||||
// customStyle.id = "dg-custom-css";
|
||||
/*
|
||||
if(backgroundImageSetting === "OldPaper1"){
|
||||
customCss += `div.deltagreen.sheet.actor section.window-content{
|
||||
@@ -341,7 +333,6 @@ Hooks.on("ready", ()=> {
|
||||
}`;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
if(characterSheetStyle === "cowboy"){
|
||||
customCss += `div.deltagreen.sheet.actor section.window-content{
|
||||
@@ -360,7 +351,6 @@ Hooks.on("ready", ()=> {
|
||||
//document.querySelector("head").appendChild(customStyle);
|
||||
}
|
||||
*/
|
||||
|
||||
});
|
||||
|
||||
Hooks.on("preCreateItem", (item) => {
|
||||
@@ -368,68 +358,62 @@ Hooks.on("preCreateItem", (item) => {
|
||||
console.log(item.img);
|
||||
console.log(item.type);
|
||||
|
||||
if(item.img === 'icons/svg/item-bag.svg'){
|
||||
|
||||
if(item.type === 'bond'){
|
||||
item.updateSource({ img: 'systems/deltagreen/assets/icons/person-black-bg.svg'});
|
||||
}
|
||||
else{
|
||||
item.updateSource({ img: 'systems/deltagreen/assets/icons/swap-bag-black-bg.svg'});
|
||||
if (item.img === "icons/svg/item-bag.svg") {
|
||||
if (item.type === "bond") {
|
||||
item.updateSource({
|
||||
img: "systems/deltagreen/assets/icons/person-black-bg.svg",
|
||||
});
|
||||
} else {
|
||||
item.updateSource({
|
||||
img: "systems/deltagreen/assets/icons/swap-bag-black-bg.svg",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Hooks.on("renderSidebarTab", async (app, html) => {
|
||||
if (app.options.id == "actors") {
|
||||
let button = $("<button class='import-cd'><i class='fas fa-file-import'></i> Parse Stat Block</button>")
|
||||
const button = $("<button class='import-cd'><i class='fas fa-file-import'></i> Parse Stat Block</button>")
|
||||
|
||||
button.click(function () {
|
||||
ParseDeltaGreenStatBlock()
|
||||
ParseDeltaGreenStatBlock();
|
||||
});
|
||||
|
||||
html.find(".directory-footer").append(button);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// Note - this event is fired on ALL connected clients...
|
||||
Hooks.on('createActor', async function(actor, options, userId){
|
||||
try{
|
||||
|
||||
Hooks.on("createActor", async function (actor, options, userId) {
|
||||
try {
|
||||
// use this to trap on if this hook is firing for the same user that triggered the create
|
||||
// can put logic specific to a particular user session below
|
||||
if (userId !== game.user.id) return;
|
||||
|
||||
if (actor !== null){
|
||||
|
||||
if(actor.type === 'agent'){
|
||||
if (actor !== null) {
|
||||
if (actor.type === "agent") {
|
||||
// update the default type skill of Art - Painting's labels to try to be localized
|
||||
// since I really backed myself into a corner on this with my implementation of it...
|
||||
console.log('createActor Hook');
|
||||
console.log("createActor Hook");
|
||||
|
||||
let artLabel = game.i18n.translations.DG?.TypeSkills?.Art ?? "Art";
|
||||
let paintingLabel = game.i18n.translations.DG?.TypeSkills?.Subskills?.Painting ?? "Painting";
|
||||
const artLabel = game.i18n.translations.DG?.TypeSkills?.Art ?? "Art";
|
||||
const paintingLabel = game.i18n.translations.DG?.TypeSkills?.Subskills?.Painting ?? "Painting";
|
||||
|
||||
let updatedData = duplicate(actor.system);
|
||||
const updatedData = duplicate(actor.system);
|
||||
updatedData.typedSkills.tskill_01.group = artLabel;
|
||||
updatedData.typedSkills.tskill_01.label = paintingLabel;
|
||||
|
||||
actor.update({"data": updatedData});
|
||||
|
||||
|
||||
actor.update({ data: updatedData });
|
||||
|
||||
// throw on an unarmed strike item for convenience
|
||||
actor.AddUnarmedAttackItemIfMissing();
|
||||
}
|
||||
else if(actor.type === 'unnatural'){
|
||||
} else if (actor.type === "unnatural") {
|
||||
// Do nothing.
|
||||
}
|
||||
else if(actor.type === 'vehicle'){
|
||||
} else if (actor.type === "vehicle") {
|
||||
actor.AddBaseVehicleItemsIfMissing();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
catch(ex){
|
||||
} catch (ex) {
|
||||
console.log(ex);
|
||||
}
|
||||
});
|
||||
@@ -448,25 +432,25 @@ Hooks.on('createActor', async function(actor, options, userId){
|
||||
async function createDeltaGreenMacro(data, slot) {
|
||||
// Definitely should not be doing assignments in conditionals but if we fix this, it breaks macro creation.
|
||||
// eslint-disable-next-line no-cond-assign
|
||||
if (data.type = "Item" && data.itemData.type !== "weapon") return;
|
||||
//if (!("data" in data)) return ui.notifications.warn("You can only create macro buttons for owned Items");
|
||||
if ((data.type = "Item" && data.itemData.type !== "weapon")) return;
|
||||
// if (!("data" in data)) return ui.notifications.warn("You can only create macro buttons for owned Items");
|
||||
const item = data.itemData;
|
||||
|
||||
// Create the macro command
|
||||
let command = '// Uncomment line below to also roll skill check if desired.'
|
||||
command += '\n' + `//game.deltagreen.rollItemSkillCheckMacro("${item._id}");`;
|
||||
command += '\n' + `game.deltagreen.rollItemMacro("${item._id}");`;
|
||||
let command = "// Uncomment line below to also roll skill check if desired.";
|
||||
command += "\n" + `//game.deltagreen.rollItemSkillCheckMacro("${item._id}");`;
|
||||
command += "\n" + `game.deltagreen.rollItemMacro("${item._id}");`;
|
||||
|
||||
//let macro = game.macros.entities.find(m => (m.name === data.name) && (m.command === command));
|
||||
//if (!macro) {
|
||||
let macro = await Macro.create({
|
||||
// let macro = game.macros.entities.find(m => (m.name === data.name) && (m.command === command));
|
||||
// if (!macro) {
|
||||
const macro = await Macro.create({
|
||||
name: data.itemData.name,
|
||||
type: "script",
|
||||
img: data.itemData.img,
|
||||
command: command,
|
||||
flags: { "deltagreen.itemMacro": true }
|
||||
});
|
||||
//}
|
||||
// }
|
||||
|
||||
game.user.assignHotbarMacro(macro, slot);
|
||||
return false;
|
||||
@@ -483,17 +467,21 @@ async function rollItemMacro(itemId) {
|
||||
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.');
|
||||
|
||||
let item = actor ? actor.items.find(i => i._id === itemId) : null;
|
||||
if (!actor)
|
||||
return ui.notifications.warn("Must have an Actor selected first.");
|
||||
|
||||
let item = actor ? actor.items.find((i) => i._id === itemId) : null;
|
||||
|
||||
// for backwards compatibility with older macros, where I unwisely set it to use name instead of id
|
||||
if(!item){
|
||||
item = actor ? actor.items.find(i => i.name === itemId) : null;
|
||||
}
|
||||
if (!item) {
|
||||
item = actor ? actor.items.find((i) => i.name === itemId) : null;
|
||||
}
|
||||
|
||||
if (!item) return ui.notifications.warn(`Your controlled Actor does not have an item named ${itemId}`);
|
||||
if (!item)
|
||||
return ui.notifications.warn(
|
||||
`Your controlled Actor does not have an item named ${itemId}`,
|
||||
);
|
||||
|
||||
// Trigger the item roll
|
||||
const r = await item.roll();
|
||||
@@ -507,35 +495,49 @@ function rollItemSkillCheckMacro(itemId) {
|
||||
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.');
|
||||
if (!actor)
|
||||
return ui.notifications.warn("Must have an Actor selected first.");
|
||||
|
||||
let item = actor ? actor.items.find(i => i._id === itemId) : null;
|
||||
let item = actor ? actor.items.find((i) => i._id === itemId) : null;
|
||||
|
||||
// for backwards compatibility with older macros, where I unwisely set it to use name instead of id
|
||||
if(!item){
|
||||
item = actor ? actor.items.find(i => i.name === itemId) : null;
|
||||
}
|
||||
if (!item) {
|
||||
item = actor ? actor.items.find((i) => i.name === itemId) : null;
|
||||
}
|
||||
|
||||
if (!item) return ui.notifications.warn(`Your controlled Actor does not have an item '${item.name}'`);
|
||||
if (!item)
|
||||
return ui.notifications.warn(
|
||||
`Your controlled Actor does not have an item '${item.name}'`,
|
||||
);
|
||||
|
||||
let skillName = item.system.skill.toString();
|
||||
const skillName = item.system.skill.toString();
|
||||
|
||||
const roll = new DGRolls.DGPercentileRoll("1D100", {}, { rollType: "weapon", key: skillName, actor, item });
|
||||
return actor.sheet.processRoll({}, roll)}
|
||||
const roll = new DGRolls.DGPercentileRoll(
|
||||
"1D100",
|
||||
{},
|
||||
{ rollType: "weapon", key: skillName, actor, item },
|
||||
);
|
||||
return actor.sheet.processRoll({}, roll);
|
||||
}
|
||||
|
||||
function rollSkillMacro(skillName) {
|
||||
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.');
|
||||
|
||||
let skill = actor.system.skills[skillName];
|
||||
if (!actor)
|
||||
return ui.notifications.warn("Must have an Actor selected first.");
|
||||
|
||||
if(!skill) return ui.notifications.warn('Bad skill name passed to macro.');
|
||||
const skill = actor.system.skills[skillName];
|
||||
|
||||
const roll = new DGRolls.DGPercentileRoll("1D100", {}, { rollType: "skill", key: skillName, actor });
|
||||
actor.sheet.processRoll({}, roll)
|
||||
if (!skill) return ui.notifications.warn("Bad skill name passed to macro.");
|
||||
|
||||
const roll = new DGRolls.DGPercentileRoll(
|
||||
"1D100",
|
||||
{},
|
||||
{ rollType: "skill", key: skillName, actor },
|
||||
);
|
||||
actor.sheet.processRoll({}, roll);
|
||||
// sendPercentileTestToChat(actor, translatedSkillLabel, skill.proficiency);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,21 +3,26 @@
|
||||
* @extends {ItemSheet}
|
||||
*/
|
||||
export class DeltaGreenItemSheet extends ItemSheet {
|
||||
|
||||
/** @override */
|
||||
static get defaultOptions() {
|
||||
return mergeObject(super.defaultOptions, {
|
||||
classes: ["deltagreen", "sheet", "item"],
|
||||
width: 520,
|
||||
height: 600,
|
||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "attributes" }]
|
||||
tabs: [
|
||||
{
|
||||
navSelector: ".sheet-tabs",
|
||||
contentSelector: ".sheet-body",
|
||||
initial: "attributes",
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
const path = "systems/deltagreen/templates/item";
|
||||
|
||||
|
||||
// unique item sheet by type, like `weapon-sheet.html`.
|
||||
return `${path}/item-${this.item.type}-sheet.html`;
|
||||
}
|
||||
@@ -27,7 +32,10 @@ export class DeltaGreenItemSheet extends ItemSheet {
|
||||
/** @override */
|
||||
async getData() {
|
||||
const data = super.getData();
|
||||
data.enrichedDescription = await TextEditor.enrichHTML(this.object.system.description, {async: true});
|
||||
data.enrichedDescription = await TextEditor.enrichHTML(
|
||||
this.object.system.description,
|
||||
{ async: true },
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
+13
-5
@@ -16,7 +16,7 @@ export class DeltaGreenItem extends Item {
|
||||
// Get the Item's data
|
||||
const itemData = this;
|
||||
const actorData = this.actor || {};
|
||||
const system = itemData.system;
|
||||
const { system } = itemData;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -32,17 +32,25 @@ export class DeltaGreenItem extends Item {
|
||||
|
||||
let roll;
|
||||
if (item.system.isLethal) {
|
||||
roll = new DGLethalityRoll("1D100", {}, { rollType: "lethality", actor, item })
|
||||
roll = new DGLethalityRoll(
|
||||
"1D100",
|
||||
{},
|
||||
{ rollType: "lethality", actor, item },
|
||||
);
|
||||
} else {
|
||||
// regular damage roll
|
||||
let diceFormula = item.system.damage;
|
||||
let skillType = item.system.skill;
|
||||
const skillType = item.system.skill;
|
||||
|
||||
if (skillType === 'unarmed_combat' || skillType === 'melee_weapons') {
|
||||
if (skillType === "unarmed_combat" || skillType === "melee_weapons") {
|
||||
diceFormula += actorSystemData.statistics.str.meleeDamageBonusFormula;
|
||||
}
|
||||
|
||||
roll = new DGDamageRoll(diceFormula, {}, { rollType: "damage", actor, item })
|
||||
roll = new DGDamageRoll(
|
||||
diceFormula,
|
||||
{},
|
||||
{ rollType: "damage", actor, item },
|
||||
);
|
||||
}
|
||||
return actor.sheet.processRoll({}, roll);
|
||||
}
|
||||
|
||||
+363
-176
@@ -1,185 +1,372 @@
|
||||
// call this within a world as: game.deltagreen.ParseDeltaGreenStatBlock()
|
||||
function GetTypeSkillRatingsFromInput(inputText){
|
||||
|
||||
let matchStr = "(Art|Craft|Foreign Language|Native Language|Military Science|Pilot|Science)\\s?\\((\\w.*?)\\)\\s?(\\d?\\d)%";
|
||||
function GetTypeSkillRatingsFromInput(inputText) {
|
||||
const matchStr =
|
||||
"(Art|Craft|Foreign Language|Native Language|Military Science|Pilot|Science)\\s?\\((\\w.*?)\\)\\s?(\\d?\\d)%";
|
||||
|
||||
inputText = inputText.replace(/[\n\r]/g, ' ')
|
||||
inputText = inputText.replace(/[\n\r]/g, " ");
|
||||
|
||||
let re = new RegExp(matchStr, "gi");
|
||||
|
||||
let matches = [];
|
||||
let match;
|
||||
|
||||
try{
|
||||
while(match = re.exec(inputText)){
|
||||
matches.push({group: match[1], label: match[2], proficiency: parseInt(match[3]), failure: false});
|
||||
}
|
||||
const re = new RegExp(matchStr, "gi");
|
||||
|
||||
const matches = [];
|
||||
let match;
|
||||
|
||||
try {
|
||||
while ((match = re.exec(inputText))) {
|
||||
matches.push({
|
||||
group: match[1],
|
||||
label: match[2],
|
||||
proficiency: parseInt(match[3]),
|
||||
failure: false,
|
||||
});
|
||||
}
|
||||
catch(ex){
|
||||
console.log('GetAttributeFromInput Error');
|
||||
console.log(ex);
|
||||
}
|
||||
|
||||
return matches;
|
||||
} catch (ex) {
|
||||
console.log("GetAttributeFromInput Error");
|
||||
console.log(ex);
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
function GetAttributeFromInput(inputText, attribute){
|
||||
|
||||
let matchStr = "(?:" + attribute + "\\s)(\\d\\d?)";
|
||||
let re = new RegExp(matchStr, "i");
|
||||
let results = inputText.match(re);
|
||||
let attributeScore = 10;
|
||||
|
||||
try{
|
||||
if(results != null && results.length > 1){
|
||||
attributeScore = parseInt(results[1]);
|
||||
}
|
||||
else{
|
||||
attributeScore = 0;
|
||||
}
|
||||
function GetAttributeFromInput(inputText, attribute) {
|
||||
const matchStr = `(?:${attribute}\\s)(\\d\\d?)`;
|
||||
const re = new RegExp(matchStr, "i");
|
||||
const results = inputText.match(re);
|
||||
let attributeScore = 10;
|
||||
|
||||
try {
|
||||
if (results != null && results.length > 1) {
|
||||
attributeScore = parseInt(results[1]);
|
||||
} else {
|
||||
attributeScore = 0;
|
||||
}
|
||||
catch(ex){
|
||||
console.log('GetAttributeFromInput Error');
|
||||
console.log(ex);
|
||||
}
|
||||
|
||||
return attributeScore;
|
||||
} catch (ex) {
|
||||
console.log("GetAttributeFromInput Error");
|
||||
console.log(ex);
|
||||
}
|
||||
|
||||
return attributeScore;
|
||||
}
|
||||
|
||||
function GetSkillRatingsFromInput(inputText, skill){
|
||||
|
||||
let matchStr = "(?:" + skill + "\\s)(\\d\\d?)";
|
||||
let re = new RegExp(matchStr, "i");
|
||||
let results = inputText.match(re);
|
||||
let skillValue = 0;
|
||||
|
||||
try{
|
||||
if(results != null && results.length > 1){
|
||||
skillValue = parseInt(results[1]);
|
||||
}
|
||||
function GetSkillRatingsFromInput(inputText, skill) {
|
||||
const matchStr = `(?:${skill}\\s)(\\d\\d?)`;
|
||||
const re = new RegExp(matchStr, "i");
|
||||
const results = inputText.match(re);
|
||||
let skillValue = 0;
|
||||
|
||||
try {
|
||||
if (results != null && results.length > 1) {
|
||||
skillValue = parseInt(results[1]);
|
||||
}
|
||||
catch(ex){
|
||||
console.log('GetAttributeFromInput Error');
|
||||
console.log(ex);
|
||||
}
|
||||
|
||||
return skillValue;
|
||||
} catch (ex) {
|
||||
console.log("GetAttributeFromInput Error");
|
||||
console.log(ex);
|
||||
}
|
||||
|
||||
return skillValue;
|
||||
}
|
||||
|
||||
async function RegexParseNpcStatBlock(inputStr, actorType){
|
||||
let actorData = {};
|
||||
async function RegexParseNpcStatBlock(inputStr, actorType) {
|
||||
const actorData = {};
|
||||
|
||||
let shortDescription = "";
|
||||
|
||||
actorData.type = actorType;
|
||||
actorData.data = {};
|
||||
actorData.data.statistics = {};
|
||||
actorData.data.skills = {};
|
||||
actorData.data.typedSkills = {};
|
||||
actorData.data.physical = {};
|
||||
let shortDescription = "";
|
||||
|
||||
actorData.data.health = {value: 10, min: 0, max: 10};
|
||||
actorData.data.wp = {value: 10, min: 0, max: 10};
|
||||
|
||||
let tempStr = "";
|
||||
let arr = [];
|
||||
|
||||
tempStr = inputStr.split(/\r?\n/);
|
||||
|
||||
if(tempStr.length > 1){
|
||||
actorData.name = tempStr[0];
|
||||
shortDescription = tempStr[1];
|
||||
}
|
||||
else{
|
||||
actorData.name = "Unknown";
|
||||
}
|
||||
actorData.type = actorType;
|
||||
actorData.data = {};
|
||||
actorData.data.statistics = {};
|
||||
actorData.data.skills = {};
|
||||
actorData.data.typedSkills = {};
|
||||
actorData.data.physical = {};
|
||||
|
||||
if(actorType === 'agent'){
|
||||
actorData.data.physical = {description: shortDescription, wounds: "", firstAidAttempted: false}
|
||||
}
|
||||
else if(actorType === 'npc' || actorType === 'unnatural'){
|
||||
actorData.data.shortDescription = shortDescription;
|
||||
}
|
||||
|
||||
actorData.data.statistics.str = {value: GetAttributeFromInput(inputStr, "STR"), distinguishing_feature: ""};
|
||||
actorData.data.statistics.con = {value: GetAttributeFromInput(inputStr, "CON"), distinguishing_feature: ""};
|
||||
actorData.data.statistics.dex = {value: GetAttributeFromInput(inputStr, "DEX"), distinguishing_feature: ""};
|
||||
actorData.data.statistics.int = {value: GetAttributeFromInput(inputStr, "INT"), distinguishing_feature: ""};
|
||||
actorData.data.statistics.pow = {value: GetAttributeFromInput(inputStr, "POW"), distinguishing_feature: ""};
|
||||
actorData.data.statistics.cha = {value: GetAttributeFromInput(inputStr, "CHA"), distinguishing_feature: ""};
|
||||
actorData.data.health = { value: 10, min: 0, max: 10 };
|
||||
actorData.data.wp = { value: 10, min: 0, max: 10 };
|
||||
|
||||
if(actorType === 'npc' || actorType === 'unnatural'){
|
||||
// don't want to try to set HP/SAN for player characters
|
||||
actorData.data.health = {min: 0, max: GetAttributeFromInput(inputStr, "HP"), value: GetAttributeFromInput(inputStr, "HP")};
|
||||
actorData.data.sanity = {max: actorData.data.statistics.pow.value * 5, value: GetAttributeFromInput(inputStr, "SAN"), currentBreakingPoint: GetAttributeFromInput(inputStr, "BREAKING POINT")};
|
||||
actorData.data.wp = {max: actorData.data.statistics.pow.value, value: GetAttributeFromInput(inputStr, "WP"), min: 0};
|
||||
}
|
||||
let tempStr = "";
|
||||
let arr = [];
|
||||
|
||||
actorData.data.skills.accounting = {"label": "Accounting", proficiency: GetSkillRatingsFromInput(inputStr, "ACCOUNTING"), failure: false};
|
||||
actorData.data.skills.alertness = {"label": "Alertness", proficiency: GetSkillRatingsFromInput(inputStr, "ALERTNESS"), failure: false};
|
||||
actorData.data.skills.anthropology = {"label": "Anthropology", proficiency: GetSkillRatingsFromInput(inputStr, "ANTHROPOLOGY"), failure: false};
|
||||
actorData.data.skills.archeology = {"label": "Archeology", proficiency: GetSkillRatingsFromInput(inputStr, "ARCHEOLOGY|ARCHAEOLOGY"), failure: false}; // damn you british spellings
|
||||
actorData.data.skills.artillery = {"label": "Artillery", proficiency: GetSkillRatingsFromInput(inputStr, "ARTILLERY"), failure: false};
|
||||
actorData.data.skills.athletics = {"label": "Athletics", proficiency: GetSkillRatingsFromInput(inputStr, "ATHLETICS"), failure: false};
|
||||
actorData.data.skills.bureaucracy = {"label": "Bureaucracy", proficiency: GetSkillRatingsFromInput(inputStr, "BUREAUCRACY"), failure: false};
|
||||
actorData.data.skills.computer_science = {"label": "Computer Science", proficiency: GetSkillRatingsFromInput(inputStr, "COMPUTER SCIENCE"), failure: false};
|
||||
actorData.data.skills.criminology = {"label": "Criminology", proficiency: GetSkillRatingsFromInput(inputStr, "CRIMINOLOGY"), failure: false};
|
||||
actorData.data.skills.demolitions = {"label": "Demolitions", proficiency: GetSkillRatingsFromInput(inputStr, "DEMOLITIONS"), failure: false};
|
||||
actorData.data.skills.disguise = {"label": "Disguise", proficiency: GetSkillRatingsFromInput(inputStr, "DISGUISE"), failure: false};
|
||||
actorData.data.skills.dodge = {"label": "Dodge", proficiency: GetSkillRatingsFromInput(inputStr, "DODGE"), failure: false};
|
||||
actorData.data.skills.drive = {"label": "Drive", proficiency: GetSkillRatingsFromInput(inputStr, "DRIVE"), failure: false};
|
||||
tempStr = inputStr.split(/\r?\n/);
|
||||
|
||||
// Impossible Landscapes seems to favor 'Driving' as the name for this instead for some
|
||||
if(actorData.data.skills.drive.proficiency === 0){
|
||||
actorData.data.skills.drive = {"label": "Drive", proficiency: GetSkillRatingsFromInput(inputStr, "DRIVING"), failure: false};
|
||||
}
|
||||
if (tempStr.length > 1) {
|
||||
actorData.name = tempStr[0];
|
||||
shortDescription = tempStr[1];
|
||||
} else {
|
||||
actorData.name = "Unknown";
|
||||
}
|
||||
|
||||
actorData.data.skills.firearms = {"label": "Firearms", proficiency: GetSkillRatingsFromInput(inputStr, "FIREARMS"), failure: false};
|
||||
actorData.data.skills.first_aid = {"label": "First Adi", proficiency: GetSkillRatingsFromInput(inputStr, "FIRST AID"), failure: false};
|
||||
actorData.data.skills.forensics = {"label": "Forensics", proficiency: GetSkillRatingsFromInput(inputStr, "FORENSICS"), failure: false};
|
||||
actorData.data.skills.heavy_machinery = {"label": "Heavy Machinery", proficiency: GetSkillRatingsFromInput(inputStr, "HEAVY MACHINERY"), failure: false}; // template.json has typo on heavy machinery...
|
||||
actorData.data.skills.heavy_weapons = {"label": "Heavy Weapons", proficiency: GetSkillRatingsFromInput(inputStr, "HEAVY WEAPONS"), failure: false};
|
||||
actorData.data.skills.history = {"label": "History", proficiency: GetSkillRatingsFromInput(inputStr, "HISTORY"), failure: false};
|
||||
actorData.data.skills.humint = {"label": "HUMINT", proficiency: GetSkillRatingsFromInput(inputStr, "HUMINT"), failure: false};
|
||||
actorData.data.skills.law = {"label": "Law", proficiency: GetSkillRatingsFromInput(inputStr, "LAW"), failure: false};
|
||||
actorData.data.skills.medicine = {"label": "Medicine", proficiency: GetSkillRatingsFromInput(inputStr, "MEDICINE"), failure: false};
|
||||
actorData.data.skills.melee_weapons = {"label": "Melee Weapons", proficiency: GetSkillRatingsFromInput(inputStr, "MELEE WEAPONS"), failure: false};
|
||||
actorData.data.skills.navigate = {"label": "Navigate", proficiency: GetSkillRatingsFromInput(inputStr, "NAVIGATE"), failure: false};
|
||||
actorData.data.skills.occult = {"label": "Occult", proficiency: GetSkillRatingsFromInput(inputStr, "OCCULT"), failure: false};
|
||||
actorData.data.skills.persuade = {"label": "Persuade", proficiency: GetSkillRatingsFromInput(inputStr, "PERSUADE"), failure: false};
|
||||
actorData.data.skills.pharmacy = {"label": "Pharmacy", proficiency: GetSkillRatingsFromInput(inputStr, "PHARMACY"), failure: false};
|
||||
actorData.data.skills.psychotherapy = {"label": "Psychotherapy", proficiency: GetSkillRatingsFromInput(inputStr, "PSYCHOTHERAPY"), failure: false};
|
||||
actorData.data.skills.ride = {"label": "Ride", proficiency: GetSkillRatingsFromInput(inputStr, "RIDE"), failure: false};
|
||||
actorData.data.skills.search = {"label": "Search", proficiency: GetSkillRatingsFromInput(inputStr, "SEARCH"), failure: false};
|
||||
actorData.data.skills.sigint = {"label": "SIGINT", proficiency: GetSkillRatingsFromInput(inputStr, "SIGINT"), failure: false};
|
||||
actorData.data.skills.stealth = {"label": "Stealth", proficiency: GetSkillRatingsFromInput(inputStr, "STEALTH"), failure: false};
|
||||
actorData.data.skills.surgery = {"label": "Surgery", proficiency: GetSkillRatingsFromInput(inputStr, "SURGERY"), failure: false};
|
||||
actorData.data.skills.survival = {"label": "Survival", proficiency: GetSkillRatingsFromInput(inputStr, "SURVIVAL"), failure: false};
|
||||
actorData.data.skills.swim = {"label": "Swim", proficiency: GetSkillRatingsFromInput(inputStr, "SWIM"), failure: false};
|
||||
actorData.data.skills.unarmed_combat = {"label": "Unarmed Combat", proficiency: GetSkillRatingsFromInput(inputStr, "UNARMED COMBAT"), failure: false};
|
||||
actorData.data.skills.unnatural = {"label": "Unnatural", proficiency: GetSkillRatingsFromInput(inputStr, "UNNATURAL"), failure: false};
|
||||
if (actorType === "agent") {
|
||||
actorData.data.physical = {
|
||||
description: shortDescription,
|
||||
wounds: "",
|
||||
firstAidAttempted: false,
|
||||
};
|
||||
} else if (actorType === "npc" || actorType === "unnatural") {
|
||||
actorData.data.shortDescription = shortDescription;
|
||||
}
|
||||
|
||||
// some npcs/unnatural have other skills
|
||||
if(GetSkillRatingsFromInput(inputStr, "FLIGHT") > 0){
|
||||
actorData.data.skills.flight = {"label": "Flight", proficiency: GetSkillRatingsFromInput(inputStr, "FLIGHT"), failure: false};
|
||||
}
|
||||
|
||||
arr = GetTypeSkillRatingsFromInput(inputStr);
|
||||
actorData.data.statistics.str = {
|
||||
value: GetAttributeFromInput(inputStr, "STR"),
|
||||
distinguishing_feature: "",
|
||||
};
|
||||
actorData.data.statistics.con = {
|
||||
value: GetAttributeFromInput(inputStr, "CON"),
|
||||
distinguishing_feature: "",
|
||||
};
|
||||
actorData.data.statistics.dex = {
|
||||
value: GetAttributeFromInput(inputStr, "DEX"),
|
||||
distinguishing_feature: "",
|
||||
};
|
||||
actorData.data.statistics.int = {
|
||||
value: GetAttributeFromInput(inputStr, "INT"),
|
||||
distinguishing_feature: "",
|
||||
};
|
||||
actorData.data.statistics.pow = {
|
||||
value: GetAttributeFromInput(inputStr, "POW"),
|
||||
distinguishing_feature: "",
|
||||
};
|
||||
actorData.data.statistics.cha = {
|
||||
value: GetAttributeFromInput(inputStr, "CHA"),
|
||||
distinguishing_feature: "",
|
||||
};
|
||||
|
||||
for (let index = 0; index < arr.length; ++index) {
|
||||
const element = arr[index];
|
||||
actorData.data.typedSkills['tskill_' + index.toString()] = element;
|
||||
}
|
||||
|
||||
console.log(actorData);
|
||||
if (actorType === "npc" || actorType === "unnatural") {
|
||||
// don't want to try to set HP/SAN for player characters
|
||||
actorData.data.health = {
|
||||
min: 0,
|
||||
max: GetAttributeFromInput(inputStr, "HP"),
|
||||
value: GetAttributeFromInput(inputStr, "HP"),
|
||||
};
|
||||
actorData.data.sanity = {
|
||||
max: actorData.data.statistics.pow.value * 5,
|
||||
value: GetAttributeFromInput(inputStr, "SAN"),
|
||||
currentBreakingPoint: GetAttributeFromInput(inputStr, "BREAKING POINT"),
|
||||
};
|
||||
actorData.data.wp = {
|
||||
max: actorData.data.statistics.pow.value,
|
||||
value: GetAttributeFromInput(inputStr, "WP"),
|
||||
min: 0,
|
||||
};
|
||||
}
|
||||
|
||||
const newActors = await Actor.createDocuments([actorData]);
|
||||
actorData.data.skills.accounting = {
|
||||
label: "Accounting",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "ACCOUNTING"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.alertness = {
|
||||
label: "Alertness",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "ALERTNESS"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.anthropology = {
|
||||
label: "Anthropology",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "ANTHROPOLOGY"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.archeology = {
|
||||
label: "Archeology",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "ARCHEOLOGY|ARCHAEOLOGY"),
|
||||
failure: false,
|
||||
}; // damn you british spellings
|
||||
actorData.data.skills.artillery = {
|
||||
label: "Artillery",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "ARTILLERY"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.athletics = {
|
||||
label: "Athletics",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "ATHLETICS"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.bureaucracy = {
|
||||
label: "Bureaucracy",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "BUREAUCRACY"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.computer_science = {
|
||||
label: "Computer Science",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "COMPUTER SCIENCE"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.criminology = {
|
||||
label: "Criminology",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "CRIMINOLOGY"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.demolitions = {
|
||||
label: "Demolitions",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "DEMOLITIONS"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.disguise = {
|
||||
label: "Disguise",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "DISGUISE"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.dodge = {
|
||||
label: "Dodge",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "DODGE"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.drive = {
|
||||
label: "Drive",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "DRIVE"),
|
||||
failure: false,
|
||||
};
|
||||
|
||||
newActors[0].sheet.render(true);
|
||||
// Impossible Landscapes seems to favor 'Driving' as the name for this instead for some
|
||||
if (actorData.data.skills.drive.proficiency === 0) {
|
||||
actorData.data.skills.drive = {
|
||||
label: "Drive",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "DRIVING"),
|
||||
failure: false,
|
||||
};
|
||||
}
|
||||
|
||||
actorData.data.skills.firearms = {
|
||||
label: "Firearms",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "FIREARMS"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.first_aid = {
|
||||
label: "First Adi",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "FIRST AID"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.forensics = {
|
||||
label: "Forensics",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "FORENSICS"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.heavy_machinery = {
|
||||
label: "Heavy Machinery",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "HEAVY MACHINERY"),
|
||||
failure: false,
|
||||
}; // template.json has typo on heavy machinery...
|
||||
actorData.data.skills.heavy_weapons = {
|
||||
label: "Heavy Weapons",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "HEAVY WEAPONS"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.history = {
|
||||
label: "History",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "HISTORY"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.humint = {
|
||||
label: "HUMINT",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "HUMINT"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.law = {
|
||||
label: "Law",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "LAW"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.medicine = {
|
||||
label: "Medicine",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "MEDICINE"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.melee_weapons = {
|
||||
label: "Melee Weapons",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "MELEE WEAPONS"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.navigate = {
|
||||
label: "Navigate",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "NAVIGATE"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.occult = {
|
||||
label: "Occult",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "OCCULT"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.persuade = {
|
||||
label: "Persuade",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "PERSUADE"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.pharmacy = {
|
||||
label: "Pharmacy",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "PHARMACY"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.psychotherapy = {
|
||||
label: "Psychotherapy",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "PSYCHOTHERAPY"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.ride = {
|
||||
label: "Ride",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "RIDE"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.search = {
|
||||
label: "Search",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "SEARCH"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.sigint = {
|
||||
label: "SIGINT",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "SIGINT"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.stealth = {
|
||||
label: "Stealth",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "STEALTH"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.surgery = {
|
||||
label: "Surgery",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "SURGERY"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.survival = {
|
||||
label: "Survival",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "SURVIVAL"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.swim = {
|
||||
label: "Swim",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "SWIM"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.unarmed_combat = {
|
||||
label: "Unarmed Combat",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "UNARMED COMBAT"),
|
||||
failure: false,
|
||||
};
|
||||
actorData.data.skills.unnatural = {
|
||||
label: "Unnatural",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "UNNATURAL"),
|
||||
failure: false,
|
||||
};
|
||||
|
||||
// some npcs/unnatural have other skills
|
||||
if (GetSkillRatingsFromInput(inputStr, "FLIGHT") > 0) {
|
||||
actorData.data.skills.flight = {
|
||||
label: "Flight",
|
||||
proficiency: GetSkillRatingsFromInput(inputStr, "FLIGHT"),
|
||||
failure: false,
|
||||
};
|
||||
}
|
||||
|
||||
arr = GetTypeSkillRatingsFromInput(inputStr);
|
||||
|
||||
for (let index = 0; index < arr.length; ++index) {
|
||||
const element = arr[index];
|
||||
actorData.data.typedSkills[`tskill_${index.toString()}`] = element;
|
||||
}
|
||||
|
||||
console.log(actorData);
|
||||
|
||||
const newActors = await Actor.createDocuments([actorData]);
|
||||
|
||||
newActors[0].sheet.render(true);
|
||||
}
|
||||
|
||||
async function GetUserInput(){
|
||||
const content = `<form>
|
||||
async function GetUserInput() {
|
||||
const content = `<form>
|
||||
<div class="form-group">
|
||||
<label>Actor Type: </label>
|
||||
<div class="form-fields">
|
||||
@@ -197,25 +384,25 @@ async function GetUserInput(){
|
||||
</div>
|
||||
</div>
|
||||
</form>`;
|
||||
|
||||
new Dialog({
|
||||
title: "Stat Block Parser", // Change the title if you want.
|
||||
content,
|
||||
buttons: {
|
||||
roll: {
|
||||
label: "PARSE",
|
||||
callback: async (html) => {
|
||||
const textInput = html.find("[name=parse-input]")[0].value;
|
||||
|
||||
const actorType = html.find("[name=actor-type]")[0].value;
|
||||
|
||||
RegexParseNpcStatBlock(textInput, actorType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).render(true);
|
||||
new Dialog({
|
||||
title: "Stat Block Parser", // Change the title if you want.
|
||||
content,
|
||||
buttons: {
|
||||
roll: {
|
||||
label: "PARSE",
|
||||
callback: async (html) => {
|
||||
const textInput = html.find("[name=parse-input]")[0].value;
|
||||
|
||||
const actorType = html.find("[name=actor-type]")[0].value;
|
||||
|
||||
RegexParseNpcStatBlock(textInput, actorType);
|
||||
},
|
||||
},
|
||||
},
|
||||
}).render(true);
|
||||
}
|
||||
|
||||
export async function ParseDeltaGreenStatBlock(){
|
||||
GetUserInput();
|
||||
}
|
||||
export async function ParseDeltaGreenStatBlock() {
|
||||
GetUserInput();
|
||||
}
|
||||
|
||||
@@ -1,27 +1,25 @@
|
||||
/* globals game */
|
||||
|
||||
|
||||
export default class DGUtils {
|
||||
/**
|
||||
* Attempt to localize a keyword, and gracefully fallback to something else if the key does not exist.
|
||||
* This way people using incomplete translations will not as many crashes or bugs when playing against a newly updated system.
|
||||
*
|
||||
* @param {String} key - localization key
|
||||
*
|
||||
* @param {String} key - localization key
|
||||
* @param {String} fallback - string to fall back to if translation does not exist for key
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
static localizeWithFallback(key, fallback){
|
||||
static localizeWithFallback(key, fallback) {
|
||||
try {
|
||||
let translatedValue = game.i18n.localize(key);
|
||||
const translatedValue = game.i18n.localize(key);
|
||||
if (translatedValue != key) {
|
||||
return translatedValue;
|
||||
} else {
|
||||
console.warn(`Untranslated localization key '${key}'.`);
|
||||
// can't have single quotes in a handlebars string literal input, so sort of hack in an escape character for them.
|
||||
fallback = fallback.replace("'", "'");
|
||||
return fallback;
|
||||
return translatedValue;
|
||||
}
|
||||
} catch(ex) {
|
||||
console.warn(`Untranslated localization key '${key}'.`);
|
||||
// can't have single quotes in a handlebars string literal input, so sort of hack in an escape character for them.
|
||||
fallback = fallback.replace("'", "'");
|
||||
return fallback;
|
||||
} catch (ex) {
|
||||
console.warn(ex);
|
||||
return fallback;
|
||||
}
|
||||
@@ -29,12 +27,12 @@ export default class DGUtils {
|
||||
|
||||
/**
|
||||
* Format a number with a leading plus.
|
||||
*
|
||||
* @param {Number} number
|
||||
*
|
||||
* @param {Number} number
|
||||
* @returns {String} - the stringified number with a leading plus if applicable
|
||||
*
|
||||
*
|
||||
*/
|
||||
static formatStringWithLeadingPlus(number){
|
||||
return number > 0 ? `+${number}` : number.toString() ;
|
||||
static formatStringWithLeadingPlus(number) {
|
||||
return number > 0 ? `+${number}` : number.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+227
-177
@@ -1,13 +1,13 @@
|
||||
/* globals game Roll ChatMessage AudioHelper renderTemplate Dialog */
|
||||
|
||||
import DGUtils from "../other/utility-functions.js"
|
||||
import DGUtils from "../other/utility-functions.js";
|
||||
|
||||
export class DGRoll extends Roll {
|
||||
/**
|
||||
* NOTE: This class will rarely be called on its own. It should generally be extended. Look to DGPercentileRoll as an example.
|
||||
*
|
||||
*
|
||||
* Customize our roll with some useful information, passed in the `options` Object.
|
||||
*
|
||||
*
|
||||
* @param {string} formula Unused - The string formula to parse (from Foundry)
|
||||
* @param {Object} data Unused - The data object against which to parse attributes within the formula
|
||||
* @param {Object} [options] Additional data which is preserved in the database
|
||||
@@ -27,24 +27,27 @@ export class DGRoll extends Roll {
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple function that actually creates the message and sends it to chat.
|
||||
*
|
||||
* Simple function that actually creates the message and sends it to chat.
|
||||
*
|
||||
* Broke this out so multiple functions can use it.
|
||||
*
|
||||
*
|
||||
* @returns {Promise<ChatMessage>} - the created chat message.
|
||||
*/
|
||||
async createMessage(content, flavor, rollMode) {
|
||||
let chatData = {
|
||||
const chatData = {
|
||||
speaker: ChatMessage.getSpeaker({ actor: this.actor }),
|
||||
content,
|
||||
flavor,
|
||||
type: 5, //CHAT_MESSAGE_TYPES.ROLL,
|
||||
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);
|
||||
AudioHelper.play(
|
||||
{ src: "sounds/dice.wav", volume: 0.8, autoplay: true, loop: false },
|
||||
true,
|
||||
);
|
||||
return ChatMessage.create(chatData);
|
||||
}
|
||||
}
|
||||
@@ -52,15 +55,15 @@ export class DGRoll extends Roll {
|
||||
export class DGPercentileRoll extends DGRoll {
|
||||
/**
|
||||
* Creates D100 rolls, the base die of the system.
|
||||
*
|
||||
* This constructor embeds the following info into the roll:
|
||||
* 1. Target number that the roll needs to beat.
|
||||
* 2. Localized name for the roll.
|
||||
*
|
||||
*
|
||||
* This constructor embeds the following info into the roll:
|
||||
* 1. Target number that the roll needs to beat.
|
||||
* 2. Localized name for the roll.
|
||||
*
|
||||
* Note: In order for all of our custom data to persist, our constructor must use the same parameters as its parent class.
|
||||
* So, even though percentile rolls will always have a formula of "1d100" and we don't use the `data` object,
|
||||
* we still have to keep them as parameters.
|
||||
*
|
||||
*
|
||||
* @param {string} formula Unused - The string formula to parse (from Foundry) - Always "1d100" for percentile rolls.
|
||||
* @param {Object} data Unused - The data object against which to parse attributes within the formula
|
||||
* @param {Object} [options] Additional data which is preserved in the database
|
||||
@@ -81,7 +84,7 @@ export class DGPercentileRoll extends DGRoll {
|
||||
this.target = this.actor.system.statistics[this.key].x5;
|
||||
this.localizedKey = game.i18n.localize(`DG.Attributes.${this.key}`);
|
||||
break;
|
||||
case "skill":
|
||||
case "skill":
|
||||
// Set up a target number and localized roll based on whether the skill is regular or typed.
|
||||
if (skillKeys.includes(this.key)) {
|
||||
this.target = this.actor.system.skills[this.key].proficiency;
|
||||
@@ -113,7 +116,7 @@ export class DGPercentileRoll extends DGRoll {
|
||||
// Add a the weapon's internal modifier.
|
||||
this.modifier += this.item.system.skillModifier;
|
||||
break;
|
||||
case "luck":
|
||||
case "luck":
|
||||
this.target = 50;
|
||||
this.localizedKey = game.i18n.localize("DG.Luck");
|
||||
break;
|
||||
@@ -124,59 +127,64 @@ export class DGPercentileRoll extends DGRoll {
|
||||
|
||||
/**
|
||||
* Shows a dialog that can modify the roll.
|
||||
*
|
||||
*
|
||||
* @returns {Promise<Object|void>} - the results of the dialog.
|
||||
*/
|
||||
async showDialog() {
|
||||
async showDialog() {
|
||||
let isSanCheck = false;
|
||||
const hideSanTarget = !game.user.isGM && game.settings.get("deltagreen", "keepSanityPrivate");
|
||||
|
||||
if (this.key === 'sanity' || this.key === 'ritual') {
|
||||
const hideSanTarget =
|
||||
!game.user.isGM && game.settings.get("deltagreen", "keepSanityPrivate");
|
||||
|
||||
if (this.key === "sanity" || this.key === "ritual") {
|
||||
isSanCheck = true;
|
||||
}
|
||||
|
||||
let backingData = {
|
||||
data:{
|
||||
|
||||
const backingData = {
|
||||
data: {
|
||||
label: this.localizedKey,
|
||||
originalTarget: this.target,
|
||||
targetModifier: 20,
|
||||
isSanCheck: isSanCheck,
|
||||
hideTarget: hideSanTarget
|
||||
isSanCheck,
|
||||
hideTarget: hideSanTarget,
|
||||
},
|
||||
};
|
||||
|
||||
let template = "systems/deltagreen/templates/dialog/modify-percentile-roll.html";
|
||||
let html = await renderTemplate(template, backingData);
|
||||
|
||||
const template =
|
||||
"systems/deltagreen/templates/dialog/modify-percentile-roll.html";
|
||||
const html = await renderTemplate(template, backingData);
|
||||
return new Promise((resolve, reject) => {
|
||||
new Dialog({
|
||||
content: html,
|
||||
title: DGUtils.localizeWithFallback("DG.ModifySkillRollDialogue.Title", "Modify Roll"),
|
||||
title: DGUtils.localizeWithFallback(
|
||||
"DG.ModifySkillRollDialogue.Title",
|
||||
"Modify Roll",
|
||||
),
|
||||
default: "roll",
|
||||
buttons: {
|
||||
roll:{
|
||||
roll: {
|
||||
label: DGUtils.localizeWithFallback("DG.Roll.Roll", "Roll"),
|
||||
callback: html => {
|
||||
callback: (html) => {
|
||||
try {
|
||||
let targetModifier = html.find("[name='targetModifier']").val(); // this is text as a heads up
|
||||
|
||||
let rollMode = html.find("[name='rollMode']").val();
|
||||
|
||||
let plusMinus = html.find("[name='plusOrMinus']").val();
|
||||
|
||||
if (targetModifier.trim() != "" && !isNaN(targetModifier)){
|
||||
let targetModifier = html.find("[name='targetModifier']").val(); // this is text as a heads up
|
||||
|
||||
const rollMode = html.find("[name='rollMode']").val();
|
||||
|
||||
const plusMinus = html.find("[name='plusOrMinus']").val();
|
||||
|
||||
if (targetModifier.trim() != "" && !isNaN(targetModifier)) {
|
||||
targetModifier = Math.abs(parseInt(targetModifier));
|
||||
|
||||
if(plusMinus === "-"){
|
||||
|
||||
if (plusMinus === "-") {
|
||||
targetModifier = -1 * targetModifier;
|
||||
}
|
||||
}
|
||||
resolve({targetModifier, rollMode})
|
||||
} catch(ex) {
|
||||
resolve({ targetModifier, rollMode });
|
||||
} catch (ex) {
|
||||
reject(console.log(ex));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}).render(true);
|
||||
});
|
||||
}
|
||||
@@ -184,74 +192,93 @@ export class DGPercentileRoll extends DGRoll {
|
||||
/**
|
||||
* Prepares data for a chat message and then passes that data
|
||||
* to a method that actually creates a ChatMessage.
|
||||
*
|
||||
*
|
||||
* Lays out and styles message based on outcome of the roll.
|
||||
*
|
||||
*
|
||||
* @returns {Promise<ChatMessage>} - the created chat message.
|
||||
*/
|
||||
async toChat() {
|
||||
let rollMode = this.options.rollMode || game.settings.get("core", "rollMode");
|
||||
|
||||
let rollMode =
|
||||
this.options.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';
|
||||
const privateSanSetting = game.settings.get(
|
||||
"deltagreen",
|
||||
"keepSanityPrivate",
|
||||
);
|
||||
if (
|
||||
privateSanSetting &&
|
||||
(this.key === "sanity" || this.key === "ritual") &&
|
||||
!game.user.isGM
|
||||
) {
|
||||
rollMode = "blindroll";
|
||||
}
|
||||
|
||||
let label = `${game.i18n.localize("DG.Roll.Rolling")} <b>${this.localizedKey}</b> ${game.i18n.localize("DG.Roll.Target")} ${this.target + this.modifier}`;
|
||||
|
||||
let label = `${game.i18n.localize("DG.Roll.Rolling")} <b>${
|
||||
this.localizedKey
|
||||
}</b> ${game.i18n.localize("DG.Roll.Target")} ${
|
||||
this.target + this.modifier
|
||||
}`;
|
||||
// "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")} ${this.target + this.modifier}`;
|
||||
label = `${game.i18n.localize("DG.Roll.Rolling")} <b>${
|
||||
this.localizedKey
|
||||
} [${game.i18n
|
||||
.localize("DG.Roll.Inhuman")
|
||||
.toUpperCase()}]</b> ${game.i18n.localize("DG.Roll.Target")} ${
|
||||
this.target + this.modifier
|
||||
}`;
|
||||
}
|
||||
if (this.modifier) {
|
||||
label += ` (${DGUtils.formatStringWithLeadingPlus(this.modifier)}%)`
|
||||
label += ` (${DGUtils.formatStringWithLeadingPlus(this.modifier)}%)`;
|
||||
}
|
||||
|
||||
let resultString = '', styleOverride = '';
|
||||
|
||||
let resultString = "";
|
||||
let 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";
|
||||
|
||||
if (this.isCritical) {
|
||||
resultString = `${resultString.toUpperCase()}!`;
|
||||
styleOverride = "color: green";
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
resultString += `${game.i18n.localize("DG.Roll.Failure")}`;
|
||||
|
||||
if(this.isCritical){
|
||||
resultString = resultString.toUpperCase() + '!';
|
||||
styleOverride="color: red";
|
||||
|
||||
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 += ` <header class="part-header flexrow">`
|
||||
html += ` <span class="part-formula">`
|
||||
html += ` ${this.formula}`
|
||||
html += ` </span>`
|
||||
html += ` <span class="part-total">`
|
||||
html += ` ${this.total}`
|
||||
html += ` </span>`
|
||||
html += ` </header>`
|
||||
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 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 += ` <header class="part-header flexrow">`;
|
||||
html += ` <span class="part-formula">`;
|
||||
html += ` ${this.formula}`;
|
||||
html += ` </span>`;
|
||||
html += ` <span class="part-total">`;
|
||||
html += ` ${this.total}`;
|
||||
html += ` </span>`;
|
||||
html += ` </header>`;
|
||||
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>`;
|
||||
|
||||
return this.createMessage(html, label, rollMode);
|
||||
}
|
||||
|
||||
@@ -261,28 +288,28 @@ export class DGPercentileRoll extends DGRoll {
|
||||
* For an inhuman check, the roll succeeds except on a roll of 100 which fails AND fumbles.
|
||||
* If the roll is a matching digit roll, it is a critical as normal.
|
||||
* Also, if 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.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
get isInhuman() {
|
||||
if (this.target + this.modifier > 99 && this.type === "stat") {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a roll result is critical.
|
||||
* If roll has not been evaluated, return null.
|
||||
*
|
||||
* @returns {null|Boolean}
|
||||
*
|
||||
* @returns {null|Boolean}
|
||||
*/
|
||||
get isCritical() {
|
||||
// If roll isn't evaluated, return null.
|
||||
if (!this.total) {
|
||||
return null;
|
||||
}
|
||||
let isCritical = false
|
||||
let isCritical = false;
|
||||
|
||||
// 1, 100, or any matching dice are a crit, i.e. 11, 22, 33...99.
|
||||
if (this.total === 1 || this.total === 100 || this.total % 11 === 0) {
|
||||
@@ -290,9 +317,9 @@ export class DGPercentileRoll extends DGRoll {
|
||||
isCritical = true;
|
||||
}
|
||||
|
||||
// If inhuman and the roll is below the regular (non-x5) value of the stat, it is a critical.
|
||||
// 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 + this.modifier) / 5)) {
|
||||
if (this.isInhuman && this.total <= (this.target + this.modifier) / 5) {
|
||||
isCritical = true;
|
||||
}
|
||||
|
||||
@@ -302,8 +329,8 @@ export class DGPercentileRoll extends DGRoll {
|
||||
/**
|
||||
* Determines if a roll succeeded.
|
||||
* If roll has not been evaluated, return null.
|
||||
*
|
||||
* @returns {null|Boolean}
|
||||
*
|
||||
* @returns {null|Boolean}
|
||||
*/
|
||||
get isSuccess() {
|
||||
// If roll isn't evaluated, return null.
|
||||
@@ -313,7 +340,7 @@ export class DGPercentileRoll extends DGRoll {
|
||||
|
||||
// A roll of 100 always (critically) fails, even for inhuman rolls.
|
||||
if (this.total === 100) return false;
|
||||
return this.total <= (this.target + this.modifier);
|
||||
return this.total <= this.target + this.modifier;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,11 +348,11 @@ export class DGLethalityRoll extends DGPercentileRoll {
|
||||
/**
|
||||
* See constructor for DGPercentileRoll. This theoretically could be done in the parent class'
|
||||
* constructor, but since Lethality rolls needs its own class for custom methods anyway,
|
||||
* we will set the target and localized key here.
|
||||
*
|
||||
* @param {String} formula
|
||||
* @param {Object} data
|
||||
* @param {Object} options
|
||||
* we will set the target and localized key here.
|
||||
*
|
||||
* @param {String} formula
|
||||
* @param {Object} data
|
||||
* @param {Object} options
|
||||
*/
|
||||
constructor(formula, data, options) {
|
||||
super(formula, data, options);
|
||||
@@ -335,34 +362,40 @@ export class DGLethalityRoll extends DGPercentileRoll {
|
||||
|
||||
/**
|
||||
* Prepares data for a chat message and then passes that data
|
||||
* to a method that actually creates a ChatMessage.
|
||||
*
|
||||
* to a method that actually creates a ChatMessage.
|
||||
*
|
||||
* Lays out and styles message based on outcome of the roll.
|
||||
*
|
||||
*
|
||||
* Overrides `DGPercentileRoll.toChat()`
|
||||
*
|
||||
*
|
||||
* @returns {Promise<ChatMessage>} - the created chat message.
|
||||
* @override
|
||||
*/
|
||||
async toChat() {
|
||||
const rollMode = this.options.rollMode || game.settings.get("core", "rollMode");
|
||||
let resultString = '';
|
||||
let styleOverride = '';
|
||||
if(this.total <= this.target){
|
||||
async toChat() {
|
||||
const rollMode =
|
||||
this.options.rollMode || game.settings.get("core", "rollMode");
|
||||
let resultString = "";
|
||||
let styleOverride = "";
|
||||
if (this.total <= this.target) {
|
||||
resultString = `${game.i18n.localize("DG.Roll.Lethal").toUpperCase()}`;
|
||||
styleOverride="color: red";
|
||||
}
|
||||
else{
|
||||
styleOverride = "color: red";
|
||||
} else {
|
||||
resultString = `${game.i18n.localize("DG.Roll.Failure")}`;
|
||||
}
|
||||
|
||||
const { nonLethalDamage } = this;
|
||||
let label = `${game.i18n.localize("DG.Roll.Rolling")} <b>${game.i18n.localize("DG.Roll.Lethality").toUpperCase()}</b> ${game.i18n.localize("DG.Roll.For")} <b>${this.item.name.toUpperCase()}</b> ${game.i18n.localize("DG.Roll.Target")} ${this.target + this.modifier}`;
|
||||
let label = `${game.i18n.localize("DG.Roll.Rolling")} <b>${game.i18n
|
||||
.localize("DG.Roll.Lethality")
|
||||
.toUpperCase()}</b> ${game.i18n.localize(
|
||||
"DG.Roll.For",
|
||||
)} <b>${this.item.name.toUpperCase()}</b> ${game.i18n.localize(
|
||||
"DG.Roll.Target",
|
||||
)} ${this.target + this.modifier}`;
|
||||
if (this.modifier) {
|
||||
label += ` (${DGUtils.formatStringWithLeadingPlus(this.modifier)}%)`
|
||||
label += ` (${DGUtils.formatStringWithLeadingPlus(this.modifier)}%)`;
|
||||
}
|
||||
|
||||
let html = '';
|
||||
|
||||
let html = "";
|
||||
html += `<div class="dice-roll">`;
|
||||
html += ` <div class="dice-result">`;
|
||||
html += ` <div style="${styleOverride}" class="dice-formula">${resultString}</div>`;
|
||||
@@ -396,7 +429,9 @@ export class DGLethalityRoll extends DGPercentileRoll {
|
||||
html += ` </div>`;
|
||||
html += ` </section>`;
|
||||
html += ` </div>`;
|
||||
html += ` <h4 class="dice-total">${this.total} (${nonLethalDamage.total} ${game.i18n.localize("DG.Roll.Damage")})</h4>`;
|
||||
html += ` <h4 class="dice-total">${this.total} (${
|
||||
nonLethalDamage.total
|
||||
} ${game.i18n.localize("DG.Roll.Damage")})</h4>`;
|
||||
html += `</div>`;
|
||||
|
||||
return this.createMessage(html, label, rollMode);
|
||||
@@ -405,12 +440,12 @@ export class DGLethalityRoll extends DGPercentileRoll {
|
||||
/**
|
||||
* Calculates the damage for when a lethality roll fails.
|
||||
* If roll has not been evaluated, return null.
|
||||
*
|
||||
*
|
||||
* See full rules on page 57 of agent's handbook.
|
||||
*
|
||||
*
|
||||
* Note, this getter does not actually care if the roll has failed.
|
||||
*
|
||||
* @returns {null|Object} - return data about the non-lethal damage.
|
||||
*
|
||||
* @returns {null|Object} - return data about the non-lethal damage.
|
||||
*/
|
||||
get nonLethalDamage() {
|
||||
if (!this.total) {
|
||||
@@ -420,7 +455,8 @@ export class DGLethalityRoll extends DGPercentileRoll {
|
||||
// Try to determine what the d100 result would be as if it was two d10's being rolled.
|
||||
const totalString = this.total.toString();
|
||||
const digits = totalString.length;
|
||||
let die1, die2;
|
||||
let die1;
|
||||
let die2;
|
||||
switch (digits) {
|
||||
case 1:
|
||||
// If one digit in the result, one die is a 10, and the other is the result.
|
||||
@@ -428,7 +464,10 @@ export class DGLethalityRoll extends DGPercentileRoll {
|
||||
break;
|
||||
case 2:
|
||||
// If two digits in the result, each die is the value of one of the digits. If one of those digits is 0, make it 10.
|
||||
[die1, die2] = totalString.split("").map((digit) => parseInt(digit)).map((digit) => digit || 10);
|
||||
[die1, die2] = totalString
|
||||
.split("")
|
||||
.map((digit) => parseInt(digit))
|
||||
.map((digit) => digit || 10);
|
||||
break;
|
||||
case 3:
|
||||
// If three digits in the result (aka result === 100), each die is a 10.
|
||||
@@ -439,7 +478,7 @@ export class DGLethalityRoll extends DGPercentileRoll {
|
||||
}
|
||||
|
||||
const total = die1 + die2;
|
||||
return { die1, die2, total }
|
||||
return { die1, die2, total };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,70 +486,77 @@ export class DGDamageRoll extends DGRoll {
|
||||
/**
|
||||
* Prepares data for a chat message and then passes that data
|
||||
* to a method that actually creates a ChatMessage.
|
||||
*
|
||||
*
|
||||
* @returns {Promise<ChatMessage>} - the created chat message.
|
||||
* @override
|
||||
*/
|
||||
async toChat() {
|
||||
const rollMode = this.options.rollMode || game.settings.get("core", "rollMode");
|
||||
const rollMode =
|
||||
this.options.rollMode || game.settings.get("core", "rollMode");
|
||||
let label = this.formula;
|
||||
try{
|
||||
label = `${this.item.name}: ${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>`;
|
||||
}
|
||||
catch{
|
||||
try {
|
||||
label = `${this.item.name}: ${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>`;
|
||||
} catch {
|
||||
label = `Rolling <b>DAMAGE</b> for <b>${label.toUpperCase()}</b>`;
|
||||
}
|
||||
return this.createMessage(this.total, label, rollMode);
|
||||
}
|
||||
|
||||
async showDialog() {
|
||||
let template = "systems/deltagreen/templates/dialog/modify-damage-roll.html";
|
||||
let backingData = {
|
||||
data:{
|
||||
const template =
|
||||
"systems/deltagreen/templates/dialog/modify-damage-roll.html";
|
||||
const backingData = {
|
||||
data: {
|
||||
label: this.item?.name,
|
||||
originalFormula: this.formula,
|
||||
outerModifier: "2 * ",
|
||||
innerModifier: "+ 0"
|
||||
innerModifier: "+ 0",
|
||||
},
|
||||
};
|
||||
|
||||
let html = await renderTemplate(template, backingData);
|
||||
const html = await renderTemplate(template, backingData);
|
||||
return new Promise((resolve, reject) => {
|
||||
new Dialog({
|
||||
content: html,
|
||||
title: game.i18n.localize("DG.ModifySkillRollDialogue.Title"),
|
||||
default: "roll",
|
||||
buttons: {
|
||||
roll:{
|
||||
roll: {
|
||||
label: game.i18n.translations.DG.Roll.Roll,
|
||||
|
||||
callback: html => {
|
||||
try{
|
||||
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();
|
||||
callback: (html) => {
|
||||
try {
|
||||
const 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
|
||||
const modifiedBaseRoll = html
|
||||
.find("[name='originalFormula']")
|
||||
.val(); // this is text as a heads up
|
||||
const rollMode = html.find("[name='targetRollMode']").val();
|
||||
|
||||
if(innerModifier.replace(" ", "") === "+0"){
|
||||
if (innerModifier.replace(" ", "") === "+0") {
|
||||
innerModifier = "";
|
||||
}
|
||||
|
||||
let newFormula = "";
|
||||
if(outerModifier.trim() != ""){
|
||||
newFormula += outerModifier + "(" + modifiedBaseRoll + innerModifier.trim() + ")";
|
||||
}
|
||||
else{
|
||||
if (outerModifier.trim() != "") {
|
||||
newFormula += `${outerModifier}(${modifiedBaseRoll}${innerModifier.trim()})`;
|
||||
} else {
|
||||
newFormula += modifiedBaseRoll + innerModifier.trim();
|
||||
}
|
||||
|
||||
resolve({newFormula, rollMode})
|
||||
}
|
||||
catch(ex){
|
||||
resolve({ newFormula, rollMode });
|
||||
} catch (ex) {
|
||||
reject(console.log(ex));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}).render(true);
|
||||
});
|
||||
}
|
||||
@@ -520,22 +566,26 @@ export class DGSanityDamageRoll extends DGRoll {
|
||||
/**
|
||||
* Prepares data for a chat message and then passes that data
|
||||
* to a method that actually creates a ChatMessage.
|
||||
*
|
||||
*
|
||||
* @returns {Promise<ChatMessage>} - the created chat message.
|
||||
* @override
|
||||
*/
|
||||
async toChat() {
|
||||
const rollMode = this.options.rollMode || game.settings.get("core", "rollMode");
|
||||
const rollMode =
|
||||
this.options.rollMode || game.settings.get("core", "rollMode");
|
||||
|
||||
const [lowDie, highDie] = this.terms[0].terms.map((formula) => {
|
||||
return Roll.parse(formula)[0] || { faces: parseInt(formula), number: 1 };
|
||||
});
|
||||
|
||||
const [lowResult, highResult] = this.damageResults;
|
||||
|
||||
const flavor = `Rolling <b>${DGUtils.localizeWithFallback('DG.Generic.SanDamage', 'SAN DAMAGE')}</b> For <b>${lowDie.formula} / ${highDie.formula}</b>`;
|
||||
|
||||
let html = '';
|
||||
|
||||
const flavor = `Rolling <b>${DGUtils.localizeWithFallback(
|
||||
"DG.Generic.SanDamage",
|
||||
"SAN DAMAGE",
|
||||
)}</b> For <b>${lowDie.formula} / ${highDie.formula}</b>`;
|
||||
|
||||
let html = "";
|
||||
html += `<div class="dice-roll">`;
|
||||
html += ` <div class="dice-result">`;
|
||||
html += ` <div class="dice-formula">${lowDie.formula} / ${highDie.formula}</div>`;
|
||||
@@ -568,22 +618,22 @@ export class DGSanityDamageRoll extends DGRoll {
|
||||
html += ` </div>`;
|
||||
html += ` </section>`;
|
||||
html += ` </div>`;
|
||||
html += ` <h4 class="dice-total">${lowResult} / ${highResult}</h4>`
|
||||
html += ` <h4 class="dice-total">${lowResult} / ${highResult}</h4>`;
|
||||
html += `</div>`;
|
||||
return this.createMessage(html, flavor, rollMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the two results for a sanity damage roll.
|
||||
*
|
||||
*
|
||||
* Returns null if the roll has not been evaluated.
|
||||
*
|
||||
*
|
||||
* @returns {null|Array<Number>} - Array of result numbers
|
||||
*/
|
||||
get damageResults() {
|
||||
if (!this.total) return null;
|
||||
|
||||
const [lowResult, highResult] = this.terms[0].results;
|
||||
return [lowResult?.result, highResult?.result]
|
||||
return [lowResult?.result, highResult?.result];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-6
@@ -15,7 +15,7 @@ export const registerSystemSettings = function () {
|
||||
default: "program", // The default value for the setting
|
||||
onChange: (value) => {
|
||||
// A callback function which triggers when the setting is changed
|
||||
//console.log(value)
|
||||
// console.log(value)
|
||||
},
|
||||
});
|
||||
|
||||
@@ -44,11 +44,10 @@ export const registerSystemSettings = function () {
|
||||
default: "1d4", // The default value for the setting, per the most recent errata.
|
||||
onChange: (value) => {
|
||||
// A callback function which triggers when the setting is changed
|
||||
//console.log(value)
|
||||
// console.log(value)
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
// These two settings are obsolete now
|
||||
game.settings.register("deltagreen", "showImpossibleLandscapesContent", {
|
||||
name: "Show Impossible Landscapes Content",
|
||||
@@ -73,12 +72,12 @@ export const registerSystemSettings = function () {
|
||||
TypeWriterCondensed:
|
||||
"Condensed Typewriter (Modern, Small Typewriter Font)",
|
||||
PublicSans: "Public Sans (US Government-style sans serif font)",
|
||||
//"atwriter": "Another Typewriter (Alternate Old-style Typewriter Font)"
|
||||
// "atwriter": "Another Typewriter (Alternate Old-style Typewriter Font)"
|
||||
},
|
||||
default: "SpecialElite", // The default value for the setting
|
||||
onChange: (value) => {
|
||||
// A callback function which triggers when the setting is changed
|
||||
//console.log(value)
|
||||
// console.log(value)
|
||||
},
|
||||
});
|
||||
|
||||
@@ -97,7 +96,7 @@ export const registerSystemSettings = function () {
|
||||
default: "OldPaper1", // The default value for the setting
|
||||
onChange: (value) => {
|
||||
// A callback function which triggers when the setting is changed
|
||||
//console.log(value)
|
||||
// console.log(value)
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
+12
-12
@@ -3,15 +3,15 @@
|
||||
* Pre-loaded templates are compiled and cached for fast access when rendering
|
||||
* @return {Promise}
|
||||
*/
|
||||
export const preloadHandlebarsTemplates = async function() {
|
||||
return loadTemplates([
|
||||
"systems/deltagreen/templates/actor/actor-sheet.html",
|
||||
"systems/deltagreen/templates/actor/limited-sheet.html",
|
||||
"systems/deltagreen/templates/actor/unnatural-sheet.html",
|
||||
"systems/deltagreen/templates/actor/npc-sheet.html",
|
||||
"systems/deltagreen/templates/actor/cv-partial.html",
|
||||
"systems/deltagreen/templates/dialog/modify-percentile-roll.html",
|
||||
"systems/deltagreen/templates/actor/vehicle-sheet.html",
|
||||
"systems/deltagreen/templates/actor/help-and-licensing-partial.html"
|
||||
]);
|
||||
};
|
||||
export const preloadHandlebarsTemplates = async function () {
|
||||
return loadTemplates([
|
||||
"systems/deltagreen/templates/actor/actor-sheet.html",
|
||||
"systems/deltagreen/templates/actor/limited-sheet.html",
|
||||
"systems/deltagreen/templates/actor/unnatural-sheet.html",
|
||||
"systems/deltagreen/templates/actor/npc-sheet.html",
|
||||
"systems/deltagreen/templates/actor/cv-partial.html",
|
||||
"systems/deltagreen/templates/dialog/modify-percentile-roll.html",
|
||||
"systems/deltagreen/templates/actor/vehicle-sheet.html",
|
||||
"systems/deltagreen/templates/actor/help-and-licensing-partial.html",
|
||||
]);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user