/**
* A simple and flexible system for world-building using an arbitrary collection of character and item attributes
* Author: Atropos
* Software License: GNU GPLv3
*/
// Import Modules
import { registerSystemSettings } from "./settings.js";
import { preloadHandlebarsTemplates } from "./blades-templates.js";
import { bladesRoll, simpleRollPopup } from "./blades-roll.js";
import { BladesHelpers } from "./blades-helpers.js";
import { BladesActor } from "./blades-actor.js";
import { BladesItem } from "./blades-item.js";
import { BladesItemSheet } from "./blades-item-sheet.js";
import { BladesActorSheet } from "./blades-actor-sheet.js";
import { BladesActiveEffect } from "./blades-active-effect.js";
import { BladesCrewSheet } from "./blades-crew-sheet.js";
import { BladesClockSheet } from "./blades-clock-sheet.js";
import { BladesNPCSheet } from "./blades-npc-sheet.js";
import { BladesFactionSheet } from "./blades-faction-sheet.js";
import { BeamVehicleSheet } from "./beam-vehicle-sheet.js";
import * as migrations from "./migration.js";
window.BladesHelpers = BladesHelpers;
/* -------------------------------------------- */
/* Foundry VTT Initialization */
/* -------------------------------------------- */
Hooks.once("init", async function() {
console.log(`Initializing Blades In the Dark System`);
game.blades = {
dice: bladesRoll
};
game.system.bladesClocks = {
sizes: [ 4, 6, 8 ]
};
CONFIG.Item.documentClass = BladesItem;
CONFIG.Actor.documentClass = BladesActor;
CONFIG.ActiveEffect.documentClass = BladesActiveEffect;
// Register System Settings
registerSystemSettings();
// Register sheet application classes
Actors.unregisterSheet("core", ActorSheet);
Actors.registerSheet("blades", BladesActorSheet, { types: ["character"], makeDefault: true });
Actors.registerSheet("blades", BladesCrewSheet, { types: ["crew"], makeDefault: true });
Actors.registerSheet("blades", BladesFactionSheet, { types: ["factions"], makeDefault: true });
Actors.registerSheet("blades", BladesClockSheet, { types: ["\uD83D\uDD5B clock"], makeDefault: true });
Actors.registerSheet("blades", BladesNPCSheet, { types: ["npc"], makeDefault: true });
Actors.registerSheet("blades", BeamVehicleSheet, { types: ["vehicle"], makeDefault: true });
Items.unregisterSheet("core", ItemSheet);
Items.registerSheet("blades", BladesItemSheet, {makeDefault: true});
await preloadHandlebarsTemplates();
Actors.registeredSheets.forEach(element => console.log(element.Actor.name));
// Is the value Turf side.
Handlebars.registerHelper('is_turf_side', function(value, options) {
if (["left", "right", "top", "bottom"].includes(value)) {
return options.fn(this);
} else {
return options.inverse(this);
}
});
// Multiboxes.
Handlebars.registerHelper('multiboxes', function(selected, options) {
let html = options.fn(this);
// Fix for single non-array values.
if ( !Array.isArray(selected) ) {
selected = [selected];
}
if (typeof selected !== 'undefined') {
selected.forEach(selected_value => {
if (selected_value !== false) {
let escapedValue = RegExp.escape(Handlebars.escapeExpression(selected_value));
let rgx = new RegExp(' value=\"' + escapedValue + '\"');
let oldHtml = html;
html = html.replace(rgx, "$& checked");
while( ( oldHtml === html ) && ( escapedValue >= 0 ) ){
escapedValue--;
rgx = new RegExp(' value=\"' + escapedValue + '\"');
html = html.replace(rgx, "$& checked");
}
}
});
}
return html;
});
// Trauma Counter
Handlebars.registerHelper('traumacounter', function(selected, options) {
let html = options.fn(this);
var count = 0;
for (const trauma in selected) {
if (selected[trauma] === true) {
count++;
}
}
if (count > 4) count = 4;
const rgx = new RegExp(' value=\"' + count + '\"');
return html.replace(rgx, "$& checked");
});
// NotEquals handlebar.
Handlebars.registerHelper('noteq', (a, b, options) => {
return (a !== b) ? options.fn(this) : '';
});
// ReputationTurf handlebar.
Handlebars.registerHelper('repturf', (turfs_amount, options) => {
let html = options.fn(this);
var turfs_amount_int = parseInt(turfs_amount);
// Can't be more than 6.
if (turfs_amount_int > 6) {
turfs_amount_int = 6;
}
for (let i = 13 - turfs_amount_int; i <= 12; i++) {
const rgx = new RegExp(' value=\"' + i + '\"');
html = html.replace(rgx, "$& disabled");
}
return html;
});
Handlebars.registerHelper('crew_vault_coins', (max_coins, options) => {
let html = options.fn(this);
for (let i = 1; i <= max_coins; i++) {
html += "";
}
return html;
});
Handlebars.registerHelper('crew_experience', (_id, options) => {
let html = options.fn(this);
for (let i = 1; i <= 10; i++) {
html += ``;
}
return html;
});
// Enrich the HTML replace /n with
Handlebars.registerHelper('html', (options) => {
let text = options.hash['text'].replace(/\n/g, "
");
return new Handlebars.SafeString(text);
});
// "N Times" loop for handlebars.
// Block is executed N times starting from n=1.
//
// Usage:
// {{#times_from_1 10}}
// {{this}}
// {{/times_from_1}}
Handlebars.registerHelper('times_from_1', function(n, block) {
var accum = '';
for (var i = 1; i <= n; ++i) {
accum += block.fn(i);
}
return accum;
});
// "N Times" loop for handlebars.
// Block is executed N times starting from n=0.
//
// Usage:
// {{#times_from_0 10}}
// {{this}}
// {{/times_from_0}}
Handlebars.registerHelper('times_from_0', function(n, block) {
var accum = '';
for (var i = 0; i <= n; ++i) {
accum += block.fn(i);
}
return accum;
});
// Concat helper
// https://gist.github.com/adg29/f312d6fab93652944a8a1026142491b1
// Usage: (concat 'first 'second')
Handlebars.registerHelper('concat', function() {
var outStr = '';
for(var arg in arguments){
if(typeof arguments[arg]!='object'){
outStr += arguments[arg];
}
}
return outStr;
});
/**
* @inheritDoc
* Takes label from Selected option instead of just plain value.
*/
Handlebars.registerHelper('selectOptionsWithLabel', function(choices, options) {
const localize = options.hash['localize'] ?? false;
let selected = options.hash['selected'] ?? null;
let blank = options.hash['blank'] || null;
selected = selected instanceof Array ? selected.map(String) : [String(selected)];
// Create an option
const option = (key, object) => {
if ( localize ) object.label = game.i18n.localize(object.label);
let isSelected = selected.includes(key);
html += ``
};
// Create the options
let html = "";
if ( blank ) option("", blank);
Object.entries(choices).forEach(e => option(...e));
return new Handlebars.SafeString(html);
});
/**
* Create appropriate Blades clock
*/
Handlebars.registerHelper('blades-clock', function(parameter_name, type, current_value, uniq_id) {
let html = '';
if (current_value === null || current_value === 'null') {
current_value = 0;
}
if (parseInt(current_value) > parseInt(type)) {
current_value = type;
}
// Label for 0
html += ``;
html += `