initial import

This commit is contained in:
Nicolas Delaforge
2021-07-08 10:12:12 +02:00
parent 689b01c11e
commit 9f907c9417
74 changed files with 2908 additions and 0 deletions

83
module/system/config.js Normal file
View File

@ -0,0 +1,83 @@
export const System = {};
System.label = "Barbarians of Lemuria";
System.name = "bol";
System.rootPath = "/systems/" + System.name;
System.dataPath = System.rootPath + "/data";
System.templatesPath = System.rootPath + "/templates";
System.debugMode = true;
export const BOL = {};
BOL.itemProperties = {
"equipable": "BOL.properties.equipable",
"stackable": "BOL.properties.stackable",
"unique": "BOL.properties.unique",
"tailored": "BOL.properties.tailored",
"2h": "BOL.properties.2H",
"predilection": "BOL.properties.predilection",
"ranged": "BOL.properties.ranged",
"proficient": "BOL.properties.proficient",
"finesse": "BOL.properties.finesse",
"two-handed": "BOL.properties.two-handed",
"equipment": "BOL.properties.equipment",
"weapon": "BOL.properties.weapon",
"protection": "BOL.properties.protection",
"reloadable": "BOL.properties.reloadable",
"bow": "BOL.properties.bow",
"crossbow": "BOL.properties.crossbow",
"powder": "BOL.properties.powder",
"throwing": "BOL.properties.throwing",
"dr": "BOL.properties.dr",
"sneak": "BOL.properties.sneak",
"powerful": "BOL.properties.powerful",
"critscience": "BOL.properties.critscience",
"specialization": "BOL.properties.specialization",
"effects": "BOL.properties.effects",
"activable": "BOL.properties.activable",
"2H": "BOL.properties.2H",
"13strmin": "BOL.properties.13strmin",
"bashing": "BOL.properties.bashing",
"sling": "BOL.properties.sling",
"spell": "BOL.properties.spell",
"profile": "BOL.properties.profile",
"prestige": "BOL.properties.prestige",
"alternative": "BOL.properties.alternative",
"consumable": "BOL.properties.consumable",
"racial": "BOL.properties.racial",
"creature" : "BOL.properties.creature"
};
BOL.itemCategories = {
"other": "BOL.category.other",
"armor": "BOL.category.armor",
"shield": "BOL.category.shield",
"melee": "BOL.category.melee",
"ranged": "BOL.category.ranged",
"spell": "BOL.category.spell",
"jewel": "BOL.category.jewel",
"scroll": "BOL.category.scroll",
"wand": "BOL.category.wand",
"ammunition": "BOL.category.ammunition",
"consumable": "BOL.category.consumable",
"container": "BOL.category.container",
"mount": "BOL.category.mount",
"currency": "BOL.category.currency",
"trapping": "BOL.category.trapping"
}
BOL.itemIcons = {
"item": "icons/containers/chest/chest-worn-oak-tan.webp",
"capacity":"icons/sundries/scrolls/scroll-plain-tan-red.webp",
"species": "icons/environment/people/group.webp",
"profile": "icons/sundries/documents/blueprint-axe.webp",
"path": "icons/sundries/books/book-embossed-gold-red.webp"
}
BOL.actorIcons = {
"npc": "icons/environment/people/commoner.webp",
"encounter":"icons/svg/mystery-man-black.svg",
"loot": "icons/containers/bags/sack-simple-leather-brown.webp"
}
BOL.debug = false;

103
module/system/data.js Normal file
View File

@ -0,0 +1,103 @@
import {System} from "./config.js";
export class DataLoader {
/**
* Loads JSON data from a filepath
* @param filepath
* @returns {Promise<any>}
*/
static async loadJson(filepath) {
// Load an external JSON data file which contains data for import
const response = await fetch(filepath);
return await response.json();
}
/**
* Get a pack from a packName
* @param filepath
* @returns {Promise<any>}
*/
static findPack(packName) {
// Reference a Compendium pack by it's collection ID
console.log(`${System.name}.${packName}`);
return game.packs.find(p => p.collection === `${System.name}.${packName}`);
}
/**
* Clears data from a given pack
* @param pack
* @returns {Promise<boolean>}
*/
static async clearPack(pack) {
const packItems = await pack.getDocuments();
try {
// Delete all current compendium entries
for (let item of packItems) {
let options = {};
const document = await pack.getDocument(id);
options.pack = pack.collection;
return document.delete(options);
// await pack.deleteEntity(item.id);
}
}
catch (ex) {
return false;
}
return true;
}
/**
* Loads data from a JSON file into pack.
* JSON file should be located inside the System.dataPath folder and its name should the same as the pack name.
* @param packName
* @returns {Promise<void>}
*/
static async loadData(packName) {
console.info(`Importing ${packName}...`);
// Find pack from his pack name
let pack = this.findPack(packName);
// Get entity type to populate the proper collection
console.log(pack);
const entity = pack.metadata.entity;
// Unlock the pack
// pack.locked = false;
// Clear the current pack
await this.clearPack(pack);
// Load data from JSON files
const filepath = `${System.dataPath}/fr/json/${packName}.json`;
const content = await this.loadJson(filepath);
/* Import databases to compendiums */
switch(entity){
case "Item" : {
// Create temporary items from JSON
let newItems = await Item.create(content);
// Make sure items are iteratable
newItems = newItems instanceof Array ? newItems : [newItems];
for (let item of newItems) {
// Import into compendium
await pack.importDocument(item);
}
// pack.locked = true;
break;
}
case "Actor" : {
// Create temporary items from JSON
let newActors = await Actor.create(content);
// Make sure items are iteratable
newActors = newActors instanceof Array ? newActors : [newActors];
for (let actor of newActors) {
// Import into compendium
await pack.importDocument(actor);
}
pack.locked = true;
break;
}
}
console.info(`${packName} imported.`);
}
}

103
module/system/helpers.js Normal file
View File

@ -0,0 +1,103 @@
export const registerHandlebarsHelpers = function () {
Handlebars.registerHelper('isNull', function (val) {
return val == null;
});
Handlebars.registerHelper('isEmpty', function (list) {
if (list) return list.length == 0;
else return 0;
});
Handlebars.registerHelper('notEmpty', function (list) {
return list.length > 0;
});
Handlebars.registerHelper('isNegativeOrNull', function (val) {
return val <= 0;
});
Handlebars.registerHelper('isNegative', function (val) {
return val < 0;
});
Handlebars.registerHelper('isPositive', function (val) {
return val > 0;
});
Handlebars.registerHelper('equals', function (val1, val2) {
return val1 == val2;
});
Handlebars.registerHelper('neq', function (val1, val2) {
return val1 !== val2;
});
Handlebars.registerHelper('gt', function (val1, val2) {
return val1 > val2;
});
Handlebars.registerHelper('lt', function (val1, val2) {
return val1 < val2;
});
Handlebars.registerHelper('gte', function (val1, val2) {
return val1 >= val2;
});
Handlebars.registerHelper('lte', function (val1, val2) {
return val1 <= val2;
});
Handlebars.registerHelper('and', function (val1, val2) {
return val1 && val2;
});
Handlebars.registerHelper('or', function (val1, val2) {
return val1 || val2;
});
Handlebars.registerHelper('not', function (cond) {
return !cond;
});
Handlebars.registerHelper('count', function (list) {
return list.length;
});
Handlebars.registerHelper('isEnabled', function (configKey) {
return game.settings.get("bol", configKey);
});
Handlebars.registerHelper('split', function (str, separator, keep) {
return str.split(separator)[keep];
});
// If you need to add Handlebars helpers, here are a few useful examples:
Handlebars.registerHelper('concat', function () {
var outStr = '';
for (var arg in arguments) {
if (typeof arguments[arg] != 'object') {
outStr += arguments[arg];
}
}
return outStr;
});
Handlebars.registerHelper('add', function (a, b) {
return parseInt(a) + parseInt(b);
});
Handlebars.registerHelper('valueAtIndex', function (arr, idx) {
return arr[idx];
});
Handlebars.registerHelper('includesKey', function (items, type, key) {
// console.log(items);
return items.filter(i => i.type === type).map(i => i.data.key).includes(key);
});
Handlebars.registerHelper('includes', function (array, val) {
return array.includes(val);
});
}

202
module/system/hooks.js Normal file
View File

@ -0,0 +1,202 @@
export default function registerHooks() {
// Hooks.on("getChatLogEntryContext", (html, options) => {
// let canApplyDamage = li => li.find("h2.damage").length;
// let canApplyHealing = li => li.find("h2.heal").length;
// options.push(
// {
// name: game.i18n.localize("COF.ui.applyDamage"),
// icon: '<i class="fas fa-user-minus"></i>',
// condition: canApplyDamage,
// callback: li => {
// const dmg = parseInt(li.find(".dice-total").text());
// Hitpoints.applyToTargets(-dmg);
// }
// },
// {
// name: game.i18n.localize("COF.ui.applyDamage"),
// icon: '<i class="fas fa-user-minus"></i>',
// condition: canApplyHealing,
// callback: li => {
// const dmg = parseInt(li.find(".dice-total").text());
// Hitpoints.applyToTargets(-dmg);
// }
// },
// {
// name: game.i18n.localize("COF.ui.applyHalfDamage"),
// icon: '<i class="fas fa-user-shield"></i>',
// condition: canApplyDamage,
// callback: li => {
// const dmg = Math.ceil(parseInt(li.find(".dice-total").text()) / 2);
// Hitpoints.applyToTargets(-dmg);
// }
// },
// {
// name: game.i18n.localize("COF.ui.applyDoubleDamage"),
// icon: '<i class="fas fa-user-injured"></i>',
// condition: canApplyDamage,
// callback: li => {
// const dmg = parseInt(li.find(".dice-total").text())*2;
// Hitpoints.applyToTargets(-dmg);
// }
// },
// {
// name: game.i18n.localize("COF.ui.applyHealing"),
// icon: '<i class="fas fa-user-plus"></i>',
// condition: canApplyDamage,
// callback: li => {
// const dmg = parseInt(li.find(".dice-total").text());
// Hitpoints.applyToTargets(dmg);
// }
// },
// {
// name: game.i18n.localize("COF.ui.applyHealing"),
// icon: '<i class="fas fa-user-plus"></i>',
// condition: canApplyHealing,
// callback: li => {
// const dmg = parseInt(li.find(".dice-total").text());
// Hitpoints.applyToTargets(dmg);
// }
// }
// );
// });
//
// /**
// * Create a macro when dropping an entity on the hotbar
// * Item - open roll dialog for item
// * Actor - open actor sheet
// * Journal - open journal sheet
// */
//
// Hooks.on("hotbarDrop", async (bar, data, slot) => {
// // Create item macro if rollable item - weapon, spell, prayer, trait, or skill
// if (data.type == "Item") {
// let item = data.data;
// let command = `let onlyDamage = false;\nlet customLabel = "";\nlet skillDescription = "";\nlet dmgDescription = "";\n\nif (event) {\n if (event.shiftKey) onlyDamage = true;\n}\n\ngame.cof.macros.rollItemMacro("${item._id}", "${item.name}", "${item.type}", 0, 0, 0, onlyDamage, customLabel, skillDescription, dmgDescription);`;
//
// let macro = game.macros.entities.find(m => (m.name === item.name) && (m.command === command));
// if (!macro) {
// macro = await Macro.create({
// name: item.name,
// type : "script",
// img: item.img,
// command : command
// }, {displaySheet: false})
// }
// game.user.assignHotbarMacro(macro, slot);
// }
// // Create a macro to open the actor sheet of the actor dropped on the hotbar
// else if (data.type == "Actor") {
// let actor = game.actors.get(data.id);
// let command = `game.actors.get("${data.id}").sheet.render(true)`
// let macro = game.macros.entities.find(m => (m.name === actor.name) && (m.command === command));
// if (!macro) {
// macro = await Macro.create({
// name: actor.data.name,
// type: "script",
// img: actor.data.img,
// command: command
// }, {displaySheet: false})
// game.user.assignHotbarMacro(macro, slot);
// }
// }
// // Create a macro to open the journal sheet of the journal dropped on the hotbar
// else if (data.type == "JournalEntry") {
// let journal = game.journal.get(data.id);
// let command = `game.journal.get("${data.id}").sheet.render(true)`
// let macro = game.macros.entities.find(m => (m.name === journal.name) && (m.command === command));
// if (!macro) {
// macro = await Macro.create({
// name: journal.data.name,
// type: "script",
// img: (journal.data.img) ? journal.data.img : "icons/svg/book.svg",
// command: command
// }, {displaySheet: false})
// game.user.assignHotbarMacro(macro, slot);
// }
// }
// return false;
// });
//
//
// /**
// * Intercepte les commandes de chat
// * /stat - Jet de caractéristique
// * /skill stat - Jet de caractéristique
// * /stats - Génère les caractéristiques d'un personnage
// */
//
// Hooks.on("chatMessage", (html, content, msg) => {
// let regExp;
// regExp = /(\S+)/g;
// let commands = content.match(regExp);
// let command = (commands.length>0 && commands[0].split("/").length > 0) ? commands[0].split("/")[1].trim() : null;
// let arg1 = (commands.length > 1) ? commands[1].trim() : null;
// const actor = game.cof.macros.getSpeakersActor();
//
// const validCommands = ["for", "str", "dex", "con", "int", "sag", "wis", "cha", "atc", "melee", "atd", "ranged", "atm", "magic"];
//
// if(command && validCommands.includes(command)) {
// game.cof.macros.rollStatMacro(actor, command, 0, 0, null);
// return false;
// }
// else if(command && command === "skill") {
// if(arg1 && validCommands.includes(arg1)) {
// game.cof.macros.rollStatMacro(actor, arg1, 0, 0, null);
// } else {
// ui.notifications.error("Vous devez préciser la caractéristique à tester, par exemple \"/skill str\".");
// }
// return false;
// }
// else if(command && command === "stats") {
// CharacterGeneration.statsCommand();
// return false;
// }
// });
//
// Hooks.on("renderChatMessage", (message, html, data) => {
// // Affiche ou non les boutons d'application des dommages
// if (game.settings.get("cof", "displayChatDamageButtonsToAll")) {
// html.find(".apply-dmg").click(ev => Hitpoints.onClickChatMessageApplyButton(ev, html, data));
// }
// else {
// if (game.user.isGM){
// html.find(".apply-dmg").click(ev => Hitpoints.onClickChatMessageApplyButton(ev, html, data));
// }
// else {
// html.find(".apply-dmg").each((i, btn) => {
// btn.style.display = "none"
// });
// }
// }
// });
// Hooks.on("preCreateChatMessage", (data, options, user) => {
// console.debug("preCreateChatMessage");
// // console.log(data,options,user);
// return true;
// });
// Hooks.on("createChatMessage", (message, options, user) => {
// console.debug("createChatMessage");
// // console.log(message,options,user);
// return true;
// });
// Hooks.on("updateChatMessage", (message, update, options, user) => {
// console.debug("updateChatMessage");
// // console.log(message,update,options,user);
// return true;
// });
// Hooks.on("renderItemSheet", (app, html, data) => {
// console.debug("renderItemSheet");
// return true;
// });
// Hooks.on("renderChatLog", (app, html, data) => {
// console.debug("renderChatLog");
// return true;
// });
// Hooks.on('dropCanvasData', function (canvas, dropData) {
// console.debug("dropCanvasData");
// return true;
// });
}

13
module/system/settings.js Normal file
View File

@ -0,0 +1,13 @@
export const registerSystemSettings = function() {
game.settings.register("bol", "displayDifficulty", {
name: "Affiche la difficulté",
hint: "Active l'affichage de la difficulté sur les jets de compétences/attributs et d'armes.",
scope: "world",
config: true,
default: true,
type: Boolean,
onChange: lang => window.location.reload()
});
};

View File

@ -0,0 +1,63 @@
/**
* Define a set of template paths to pre-load
* Pre-loaded templates are compiled and cached for fast access when rendering
* @return {Promise}
*/
export const preloadHandlebarsTemplates = async function () {
// Define template paths to load
const templatePaths = [
// ACTOR
"systems/cof/templates/actors/actor-sheet.hbs",
"systems/cof/templates/actors/loot-sheet.hbs",
"systems/cof/templates/actors/parts/actor-details.hbs",
"systems/cof/templates/actors/parts/actor-tabs.hbs",
"systems/cof/templates/actors/parts/actor-description.hbs",
"systems/cof/templates/actors/parts/capacities/actor-capacities.hbs",
"systems/cof/templates/actors/parts/capacities/actor-paths.hbs",
"systems/cof/templates/actors/parts/combat/actor-combat.hbs",
"systems/cof/templates/actors/parts/combat/actor-combat-item.hbs",
"systems/cof/templates/actors/parts/combat/encounter-combat.hbs",
"systems/cof/templates/actors/parts/details/actor-details.hbs",
"systems/cof/templates/actors/parts/details/encounter-details.hbs",
"systems/cof/templates/actors/parts/inventory/actor-inventory.hbs",
"systems/cof/templates/actors/parts/inventory/actor-inventory-item.hbs",
"systems/cof/templates/actors/parts/stats/actor-stats.hbs",
"systems/cof/templates/actors/parts/stats/encounter-stats.hbs",
"systems/cof/templates/actors/parts/stats/actor-attacks.hbs",
"systems/cof/templates/actors/parts/stats/actor-attributes.hbs",
"systems/cof/templates/actors/parts/stats/actor-recovery.hbs",
"systems/cof/templates/actors/parts/stats/actor-resources.hbs",
"systems/cof/templates/actors/parts/stats/actor-vitality.hbs",
"systems/cof/templates/actors/parts/stats/actor-defence.hbs",
"systems/cof/templates/actors/parts/stats/actor-init.hbs",
// EFFECTS
"systems/cof/templates/effects/effects.hbs",
"systems/cof/templates/effects/effects-item.hbs",
// DIALOGS
"systems/cof/templates/dialogs/parts/roll-dmg-fields.hbs",
// ITEMS PROPERTIES
"systems/cof/templates/items/parts/properties/item-properties.hbs",
// ITEMS DETAILS
"systems/cof/templates/items/parts/details/item-details.hbs",
"systems/cof/templates/items/parts/details/capacity-details.hbs",
"systems/cof/templates/items/parts/details/path-details.hbs",
"systems/cof/templates/items/parts/details/profile-details.hbs",
"systems/cof/templates/items/parts/details/ranged-details.hbs",
"systems/cof/templates/items/parts/details/species-details.hbs",
"systems/cof/templates/items/parts/details/equipment-details.hbs",
"systems/cof/templates/items/parts/details/protection-details.hbs",
"systems/cof/templates/items/parts/details/spell-details.hbs",
"systems/cof/templates/items/parts/details/weapon-details.hbs",
"systems/cof/templates/items/parts/details/usage-details.hbs",
"systems/cof/templates/items/parts/details/effects-details.hbs",
];
// Load the template parts
return loadTemplates(templatePaths);
};