swade-fr-content/modules/swade-fr-init.js

434 lines
16 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { SWDELUXStatBlockParser } from "./sw-statblock-parser.js";
import { ClassCounter} from "https://www.uberwald.me/fvtt_appcount/count-class-ready.js"
const __compFolderTranslation = [
{
compendium: 'swade-core-rules.swade-vehicles',
words: [
{ source: 'Vehicles', translation: 'Véhicules' },
{ source: 'Aircraft', translation: 'Avions' },
{ source: 'Civilian', translation: 'Civils' },
{ source: 'Modern Military Aircraft', translation: 'Avions Militaires Modernes' },
{ source: 'World War II Military Aircraft', translation: 'Avions Seconde Guerre Mondiale' },
]
}
]
class FolderTranslate {
static async translateFolders() {
for (let tData of __compFolderTranslation) {
let pack = game.packs.get(tData.compendium);
let wasLocked = false;
if (pack.locked) {
await pack.configure({ locked: false })
wasLocked = true;
}
let folders = await game.CF.FICFolderAPI.loadFolders(tData.compendium);
for (let trans of tData.words) {
let folderToChange = folders.contents.find(f => f.name === trans.source);
if (folderToChange) {
await game.CF.FICFolderAPI.renameFolder(folderToChange, trans.translation);
}
}
if (wasLocked) {
await pack.configure({ locked: true })
}
}
}
}
/************************************************************************************/
Hooks.once('translateCompendiumFolders', () => {
console.log("LOADED !!!!!!")
});
/************************************************************************************/
class swadeFrTranslator {
static getRank(rank) {
if (rank == 'Novice') return 'Novice';
if (rank == 'Seasoned') return 'Aguerri';
if (rank == 'Veteran') return 'Vétéran';
if (rank == 'Heroic') return 'Héroïque';
if (rank == 'Legendary') return 'Légendaire';
return false
}
static getAttribute(attr) {
console.log("Attr is", attr)
if (attr == "Agility") return 'Agilité';
if (attr == "Smarts") return 'Intellect';
if (attr == "Spirit") return 'Ame';
if (attr == "Strength") return 'Force';
if (attr == "Vigor") return 'Vigueur';
return false
}
}
/************************************************************************************/
Hooks.once('init', () => {
console.log("INIT !!!!!!")
if (typeof Babele !== 'undefined') {
console.log("BABELE LOADED !!!");
Babele.get().register({
module: 'swade-fr-content',
lang: 'fr',
dir: 'compendiums'
});
Babele.get().registerConverters({
"gear_skill": (skill) => {
let transl = skill
//console.log("Testing", skill)
if (skill) {
let translated = game.babele.translate("swade-core-rules.swade-skills", { name: skill.trim() }, true)
transl = translated.name || skill.trim()
}
return transl
},
"skill_swid": (swid) => {
if (swid == "combat") return "fighting";
if (swid == "tir") return "shooting";
return swid
},
"category_converter": (category) => {
return game.i18n.localize(category)
},
"edge_requirements": (req) => {
let reqTab = req.split(",")
let results = []
for (let item of reqTab) {
let keyName = item.match(/([\w\s\(\)]+) (d[\w\+]*)/)
//console.log("Keyword", item, keyName)
if (keyName && keyName[2]) { // This is a skill or attribute
let toTranslate = keyName[1].trim()
let attr = swadeFrTranslator.getAttribute(toTranslate)
if (attr) { // Test if attribute
results.push(attr + " " + keyName[2].trim())
} else { // Test if skill
let translated = game.babele.translate("swade-core-rules.swade-skills", { name: toTranslate }, true)
if (!translated.name) {
translated = game.babele.translate("deadlands-core-rules.deadlands-skills", { name: toTranslate }, true)
}
let transResult = translated.name || toTranslate
results.push(transResult + " " + keyName[2].trim())
}
} else { // Rank or edge
let itemName = item.trim()
let rank = swadeFrTranslator.getRank(itemName)
if (rank) {
results.push(rank)
} else {
let translated = game.babele.translate("swade-core-rules.swade-edges", { name: itemName }, true)
if (!translated.name) {
translated = game.babele.translate("deadlands-core-rules.deadlands-edges", { name: itemName }, true)
}
let transResult = translated.name || itemName
results.push(transResult)
}
}
}
//console.log(">>>>>>>>>>>>>>>>>>>>>>>>><REQ !!!!", req, results)
return results.join(", ")
},
"gear_range": (range) => {
if (range) {
if (range == 'Cone Template') return 'Gabarit de cone';
}
return range;
},
"gear_ammo": (ammo) => {
if (ammo) {
if (ammo == 'Arrows/Bolts') return 'Flèches/Carreaux';
if (ammo == 'Canister Shot (Cannon)') return 'Cartouches (Canon)';
if (ammo == 'Shrapnel Shot (Cannon)') return 'Shrapnel (Canon)';
if (ammo == 'Solid Shot (Cannon)') return 'Solide (Canon)';
if (ammo == 'Bullets, Medium') return 'Balles, Moyenne';
if (ammo == 'Shotgun Shells') return 'Cartouche de Shotgun';
if (ammo == 'Laser Battery, Pistol') return 'Batterie pour laser, Pistolet';
if (ammo == 'Laser Battery, Rifle / SMG') return 'Batterie pour laser, Fusil';
}
return ammo;
},
"powers_duration": (duration) => {
if (duration == 'One hour') return '1 heure';
if (duration == 'Instant (slot); 5 (speed)') return 'Instantanée (apathie), 5 (vitesse)';
if (duration == '(boost); Instant (lower)') return '5 (augmentation), Instantanée (diminution)';
if (duration == 'Instant') return 'Instantannée';
if (duration == 'Until the end of the victim\'s next turn') return 'Jusquà la fin du prochain tour de la victime';
if (duration == 'A brief conversation of about five minutes') return 'Une brève conversation d\'environ 5 minutes';
if (duration == '5 (detect), one hour (conceal)') return '5 (détection), 1 heure (dissimulation)';
if (duration == 'Instant (Sound); 5 (Silence)') return 'Instantanée (son), 5 (silence)';
return duration;
},
"powers_range": (range) => {
if (range == 'Smarts x5 (Sound); Smarts (Silence)')
return 'Intellect ×5 (son), Intellect (silence)';
if (range == "Cone Template")
return "Gabarit de cône"
if (range == "Touch")
return "Toucher"
if (range == "Sm")
return "Intellect"
if (range == "Sm x 2" || range == "Sm x2")
return "Intellect x2"
if (range == "Self")
return "Personnel"
return range;
},
"powers_rank": (rank) => {
return swadeFrTranslator.getRank(rank)
}
});
}
});
/* -------------------------------------------- */
export class SwadeFRContentCommands {
static init() {
if (!game.swadeFRContent) {
const swadeFRCommands = new SwadeFRContentCommands()
swadeFRCommands.registerCommand({ path: ["/montremonsecret"], func: (content, msg, params) => SwadeFRContentCommands.enableSecret(), descr: "Affiche les compendiums secrets" });
swadeFRCommands.registerCommand({ path: ["/cachemonsecret"], func: (content, msg, params) => SwadeFRContentCommands.disableSecret(), descr: "Cache les compendiums secrets" });
swadeFRCommands.registerCommand({ path: ["/statparser"], func: (content, msg, params) => SwadeFRContentCommands.statParser(), descr: "Parse SW Delux stat block" });
game.swadeFRContent = { commands: swadeFRCommands }
}
Hooks.on("chatMessage", (html, content, msg) => {
console.log("CHAT PARSER!!!")
if (content[0] == '/') {
let regExp = /(\S+)/g;
let commands = content.match(regExp);
if (game.swadeFRContent.commands.processChatCommand(commands, content, msg)) {
return false;
}
}
return true
})
}
constructor() {
this.commandsTable = {}
}
/* -------------------------------------------- */
registerCommand(command) {
this._addCommand(this.commandsTable, command.path, '', command);
}
/* -------------------------------------------- */
_addCommand(targetTable, path, fullPath, command) {
if (!this._validateCommand(targetTable, path, command)) {
return;
}
const term = path[0];
fullPath = fullPath + term + ' '
if (path.length == 1) {
command.descr = `<strong>${fullPath}</strong>: ${command.descr}`;
targetTable[term] = command;
}
else {
if (!targetTable[term]) {
targetTable[term] = { subTable: {} };
}
this._addCommand(targetTable[term].subTable, path.slice(1), fullPath, command)
}
}
/* -------------------------------------------- */
_validateCommand(targetTable, path, command) {
if (path.length > 0 && path[0] && command.descr && (path.length != 1 || targetTable[path[0]] == undefined)) {
return true;
}
console.warn("Commande invalide", targetTable, path, command);
return false;
}
/* -------------------------------------------- */
/* Manage chat commands */
processChatCommand(commandLine, content = '', msg = {}) {
// Setup new message's visibility
let rollMode = game.settings.get("core", "rollMode");
if (["gmroll", "blindroll"].includes(rollMode)) msg["whisper"] = ChatMessage.getWhisperRecipients("GM");
if (rollMode === "blindroll") msg["blind"] = true;
msg["type"] = 0;
let command = commandLine[0].toLowerCase();
let params = commandLine.slice(1);
return this.process(command, params, content, msg);
}
/* -------------------------------------------- */
process(command, params, content, msg) {
return this._processCommand(this.commandsTable, command, params, content, msg);
}
/* -------------------------------------------- */
static enableSecret() {
game.settings.set("world", "swade-fr-content-hidden-compendiums", true)
}
/* -------------------------------------------- */
static disableSecret() {
game.settings.set("world", "swade-fr-content-hidden-compendiums", false)
}
/* -------------------------------------------- */
static statParser() {
let dialogue = new Dialog({
title: `Import`,
content: `<p>Stab block: <textarea id="swdelux-stat-parser" rows="20" cols="40"></textarea></p>`,
buttons: {
one: {
icon: '',
label: 'Parser !',
callback: (html) => {
let text = html.find('#swdelux-stat-parser').val();
let parser = new SWDELUXStatBlockParser(text);
parser.parse(text);
}
}
}
})
dialogue.render(true)
}
/* -------------------------------------------- */
_processCommand(commandsTable, name, params, content = '', msg = {}, path = "") {
console.log("===> Processing command")
let command = commandsTable[name];
path = path + name + " ";
if (command?.subTable) {
if (params[0]) {
return this._processCommand(command.subTable, params[0], params.slice(1), content, msg, path)
}
else {
this.help(msg, command.subTable);
return true;
}
}
if (command?.func) {
const result = command.func(content, msg, params);
if (result == false) {
BoLCommands._chatAnswer(msg, command.descr);
}
return true;
}
return false;
}
}
/************************************************************************************/
const transFolder = { "Actor": "Acteur", "Edges": "Atouts" }
const subFolder = {
'Social Edges': 'Atouts sociaux', 'Background Edges': 'Atouts de Background', 'Combat Edges': 'Atouts de combat',
'Leadership Edges': 'Atouts de commandement', 'Legendary Edges': 'Atouts légendaires', 'Power Edges': 'Atouts de pouvoir',
'Professional Edges': 'Atouts professionnels', 'Weird Edges': 'Atouts étranges', 'Edges': 'Atouts', 'Hindrances': 'Handicaps', 'Skills': 'Compétences',
'Equipment': 'Equipement', 'Ammo': 'Munitions', 'Armor': 'Armure', 'Common Gear': 'Matériel commun', 'Modern Firearms': 'Armes à feu modernes',
'Personal Weapons': 'Armes', 'Special Weapons': 'Armes spéciales', 'Bullet': 'Balles', 'Cannon': 'Canon', 'Laser Battery': 'Batterie Laser',
'Adventuring Gear': 'Matériel d\'aventure', 'Animals and Tack': 'Animaux', 'Clothing': 'Vêtements', 'Computers & Electronics': 'Ordinateurs et Electroniques',
'Firearms Accessories': 'Accessoires armes à feu', 'Food': 'Nourriture', 'Personal Defense': 'Auto-défense', 'Futuristic': 'Futuriste',
'Medieval & Ancient': 'Médiévale et Antiquité', 'Modern': 'Moderne', 'Shields': 'Boucliers', 'Laser (Futuristic)': 'Laser (Fururiste)',
'Machine Guns': 'Mitraillettes', 'Pistols': 'Pistolets', 'Rifles': 'Fusils', 'Submachine Guns': 'Semi-automatiques', 'Cannons': 'Canons',
'Catapults': 'Catapultes', 'Flamethrowers': 'Lance-flammes', 'Rocket Launchers & Torpedoes': 'Lance roquettes et torpilles',
'Vehicular Weapons': 'Armes de véhicules'
}
/************************************************************************************/
async function loadSecretCompendiums() {
if (game.settings.get("world", "swade-fr-content-hidden-compendiums")) {
console.log(">>>>> Load hidden compendiums!")
/* Load rules */
let urls = ["modules/swade-fr-content/compendiums/swade-core-rules.swade-rules-secret.json"]
const [translations] = await Promise.all(
[Promise.all(urls.map((url) => fetch(url).then((r) => r.json()).catch(e => { })))]);
let metadata = game.data.packs.find(p => p.name == "swade-rules")
if (metadata) {
let translation;
translations.forEach(t => {
if (t) {
translation = t; // the last valid
}
});
if (translation) {
let babele = Babele.get()
let entry = mergeObject(translation, { collection: metadata.id })
babele.translations.push(entry)
console.log(">>>>", babele.translations)
babele.packs.set(metadata.id, new TranslatedCompendium(metadata, entry))
}
}
}
}
/************************************************************************************/
function processItemSwid(actor, item) {
let swid = item.system.swid
let newSwid = swid
if (swid == "combat") newSwid = "fighting";
if (swid == "tir") newSwid = "shooting";
if (swid != newSwid) {
console.log("Item to update", item.name, swid, newSwid)
actor.updateEmbeddedDocuments('Item', [{ _id: item.id, "system.swid": newSwid }])
}
}
/************************************************************************************/
function migrateSwid() {
for (let actor of game.actors) {
for (let item of actor.items) {
if (item.system?.swid) {
processItemSwid(actor, item)
}
}
}
}
/************************************************************************************/
function checkSwidSettings() {
let swidFighting = game.settings.get('swade', 'parryBaseSwid')
if (swidFighting != "fighting") {
ui.notifications.warn("Votre compétence de parade n'est pas positionnée à 'fighting' dans les paramètres de SWADE. Nous vous recommandons de le faire pour éviter des problèmes de calcul de la parade.")
//game.settings.set('swade', 'parryBaseSwid', "fighting")
}
}
/************************************************************************************/
Hooks.once('ready', () => {
console.log(">>>>>>>>>>")
// add hidden register
game.settings.register("world", "swade-fr-content-hidden-compendiums", {
name: "Montrer les compendiums cachés",
scope: "world",
config: false,
default: false,
type: Boolean,
onChange: lang => window.location.reload()
})
SwadeFRContentCommands.init()
migrateSwid()
checkSwidSettings()
//FolderTranslate.translateFolders()
ClassCounter.registerUsageCount("swade-fr-content")
});
/************************************************************************************/
Hooks.once('babele.ready', () => {
console.log(">>>>>>>>>> BABELE READY")
loadSecretCompendiums()
});
console.log(">>>>>>>>>>>> LOADED")