/** * Lethal Fantasy RPG System * Author: LeRatierBretonnien/Uberwald */ import { SYSTEM } from "./module/config/system.mjs" globalThis.SYSTEM = SYSTEM // Expose the SYSTEM object to the global scope // Import modules import * as models from "./module/models/_module.mjs" import * as documents from "./module/documents/_module.mjs" import * as applications from "./module/applications/_module.mjs" import { LethalFantasyCombatTracker, LethalFantasyCombat } from "./module/applications/combat.mjs" import { Macros } from "./module/macros.mjs" import { setupTextEnrichers } from "./module/enrichers.mjs" import { default as LethalFantasyUtils } from "./module/utils.mjs" export class ClassCounter { static printHello() { console.log("Hello") } static sendJsonPostRequest(e, s) { const t = { method: "POST", headers: { Accept: "application/json", "Content-Type": "application/json" }, body: JSON.stringify(s) }; return fetch(e, t).then((e => { if (!e.ok) throw new Error("La requête a échoué avec le statut " + e.status); return e.json() })).catch((e => { throw console.error("Erreur envoi de la requête:", e), e })) } static registerUsageCount(e = game.system.id, s = {}) { if (game.user.isGM) { game.settings.register(e, "world-key", { name: "Unique world key", scope: "world", config: !1, default: "", type: String }); let t = game.settings.get(e, "world-key"); null != t && "" != t && "NONE" != t && "none" != t.toLowerCase() || (t = foundry.utils.randomID(32), game.settings.set(e, "world-key", t)); let a = { name: e, system: game.system.id, worldKey: t, version: game.system.version, language: game.settings.get("core", "language"), remoteAddr: game.data.addresses.remote, nbInstalledModules: game.modules.size, nbActiveModules: game.modules.filter((e => e.active)).length, nbPacks: game.world.packs.size, nbUsers: game.users.size, nbScenes: game.scenes.size, nbActors: game.actors.size, nbPlaylist: game.playlists.size, nbTables: game.tables.size, nbCards: game.cards.size, optionsData: s, foundryVersion: `${game.release.generation}.${game.release.build}` }; this.sendJsonPostRequest("https://www.uberwald.me/fvtt_appcount/count_post.php", a) } } } Hooks.once("init", function () { console.info("Lethal Fantasy RPG | Initializing System") console.info(SYSTEM.ASCII) globalThis.lethalFantasy = game.system game.system.CONST = SYSTEM // Expose the system API game.system.api = { applications, models, documents, } CONFIG.ui.combat = LethalFantasyCombatTracker CONFIG.Combat.documentClass = LethalFantasyCombat; CONFIG.Actor.documentClass = documents.LethalFantasyActor CONFIG.Actor.dataModels = { character: models.LethalFantasyCharacter, monster: models.LethalFantasyMonster, } CONFIG.Item.documentClass = documents.LethalFantasyItem CONFIG.Item.dataModels = { skill: models.LethalFantasySkill, gift: models.LethalFantasyGift, weapon: models.LethalFantasyWeapon, armor: models.LethalFantasyArmor, shield: models.LethalFantasyShield, spell: models.LethalFantasySpell, vulnerability: models.LethalFantasyVulnerability, equipment: models.LethalFantasyEquipment, miracle: models.LethalFantasyMiracle } // Register sheet application classes foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet) foundry.documents.collections.Actors.registerSheet("lethalFantasy", applications.LethalFantasyCharacterSheet, { types: ["character"], makeDefault: true }) foundry.documents.collections.Actors.registerSheet("lethalFantasy", applications.LethalFantasyMonsterSheet, { types: ["monster"], makeDefault: true }) foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ActorSheet) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasySkillSheet, { types: ["skill"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyGiftSheet, { types: ["gift"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyVulnerabilitySheet, { types: ["vulnerability"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyWeaponSheet, { types: ["weapon"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasySpellSheet, { types: ["spell"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyArmorSheet, { types: ["armor"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyShieldSheet, { types: ["shield"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyEquipmentSheet, { types: ["equipment"], makeDefault: true }) foundry.documents.collections.Items.registerSheet("lethalFantasy", applications.LethalFantasyMiracleSheet, { types: ["miracle"], makeDefault: true }) // Other Document Configuration CONFIG.ChatMessage.documentClass = documents.LethalFantasyChatMessage // Dice system configuration CONFIG.Dice.rolls.push(documents.LethalFantasyRoll) game.settings.register("lethalFantasy", "worldKey", { name: "Unique world key", scope: "world", config: false, type: String, default: "", }) // Activate socket handler game.socket.on(`system.${SYSTEM.id}`, LethalFantasyUtils.handleSocketEvent) setupTextEnrichers() LethalFantasyUtils.registerHandlebarsHelpers() LethalFantasyUtils.setHookListeners() console.info("LETHAL FANTASY | System Initialized") }) /** * Perform one-time configuration of system configuration objects.f */ function preLocalizeConfig() { const localizeConfigObject = (obj, keys) => { for (let o of Object.values(obj)) { for (let k of keys) { o[k] = game.i18n.localize(o[k]) } } } } Hooks.once("ready", function () { console.info("LETHAL FANTASY | Ready") if (!SYSTEM.DEV_MODE) { registerWorldCount("lethalFantasy") } _showUserGuide() /** * */ async function _showUserGuide() { if (game.user.isGM) { const newVer = game.system.version } } }) // Test if version below 13 let hookName = "renderChatMessage" if (foundry.utils.isNewerVersion(game.version, "12.0",)) { hookName = "renderChatMessageHTML" } Hooks.on(hookName, (message, html, data) => { const typeMessage = data.message.flags.lethalFantasy?.typeMessage // Message de demande de jet de dés if (typeMessage === "askRoll") { // Affichage des boutons de jet de dés uniquement pour les joueurs if (game.user.isGM) { html.find(".ask-roll-dice").each((i, btn) => { btn.style.display = "none" }) } else { html.find(".ask-roll-dice").click((event) => { const btn = $(event.currentTarget) const type = btn.data("type") const value = btn.data("value") const avantage = btn.data("avantage") ?? "=" const character = game.user.character if (type === SYSTEM.ROLL_TYPE.RESOURCE) character.rollResource(value) else if (type === SYSTEM.ROLL_TYPE.SAVE) character.rollSave(value, avantage) }) } } }) Hooks.on("getCombatTrackerEntryContext", (html, options) => { LethalFantasyUtils.pushCombatOptions(html, options); }); /** * Create a macro when dropping an entity on the hotbar * Item - open roll dialog * Actor - open actor sheet * Journal - open journal sheet */ Hooks.on("hotbarDrop", (bar, data, slot) => { if (["Actor", "Item", "JournalEntry", "roll", "rollDamage", "rollAttack"].includes(data.type)) { Macros.createLethalFantasyMacro(data, slot); return false } }) /** * Register world usage statistics * @param {string} registerKey */ async function registerWorldCount(registerKey) { if (game.user.isGM) { try { ClassCounter.registerUsageCount(game.system.id, {}) } catch { console.log("No usage log ") } } }