Initial push
23
README.md
Normal file
@ -0,0 +1,23 @@
|
||||
# Système Foundry pour Mournblade (French RPG, Titam France/Sombres Projets)
|
||||
|
||||
## EN
|
||||
|
||||
Unofficial system for Mournblade (French version from Titam France).
|
||||
|
||||
Books are mandatory to play and are available at : http://www.titam-france.fr
|
||||
|
||||
## FR
|
||||
|
||||
Système non-officiel pour le JDR Mournblade (Titam France).
|
||||
|
||||
Ce système a été autorisé par Ludospherik ( http://www.ludospherik.fr/ ), merci à eux !
|
||||
|
||||
Les livres du jeu sont nécessaires pour jouer, et sont disponibles ici : http://www.titam-france.fr
|
||||
|
||||
# Credits
|
||||
|
||||
Mournblade, le jeu de rôle de Sword & Sorcery, is a property of Titam France/Sombres Projets.
|
||||
|
||||
# Developmement
|
||||
|
||||
LeRatierBretonnien
|
BIN
assets/fonts/CentaurMT.otf
Normal file
BIN
assets/fonts/Chaparral Pro Regular.ttf
Normal file
BIN
assets/fonts/CharlemagneStd-Bold.otf
Normal file
BIN
assets/icons/adresse.webp
Normal file
After Width: | Height: | Size: 7.6 KiB |
BIN
assets/icons/arme.webp
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
assets/icons/bonneaventure.webp
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
assets/icons/capacite.webp
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/icons/clairvoyance.webp
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/icons/competence.webp
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
assets/icons/don.webp
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
assets/icons/eclat.webp
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
assets/icons/equipement.webp
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
assets/icons/heritage.webp
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/icons/monnaie.webp
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
assets/icons/origine.webp
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/icons/pacte.webp
Normal file
After Width: | Height: | Size: 8.9 KiB |
BIN
assets/icons/predilection.webp
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
assets/icons/presence.webp
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
assets/icons/profession.webp
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
assets/icons/protection.webp
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
assets/icons/puissance.webp
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
assets/icons/rune.webp
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
assets/icons/tendance.webp
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
assets/icons/traitchaotique.webp
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/icons/trempe.webp
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
assets/logos/mournblade_logo_chaos.webp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/logos/mournblade_logo_texte.webp
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
assets/tokens/token_chaos.webp
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
assets/tokens/token_chaos2.webp
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
assets/tokens/token_chaos3.webp
Normal file
After Width: | Height: | Size: 53 KiB |
BIN
assets/tokens/token_loi.webp
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
assets/tokens/token_loi2.webp
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
assets/tokens/token_loi3.webp
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
assets/tokens/token_loi4.webp
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
assets/ui/fond_mournblade.webp
Normal file
After Width: | Height: | Size: 236 KiB |
BIN
assets/ui/pc_sheet_bg.webp
Normal file
After Width: | Height: | Size: 11 KiB |
170
modules/hawkmoon-actor-sheet.js
Normal file
@ -0,0 +1,170 @@
|
||||
/**
|
||||
* Extend the basic ActorSheet with some very simple modifications
|
||||
* @extends {ActorSheet}
|
||||
*/
|
||||
|
||||
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
||||
import { HawkmoonRollDialog } from "./hawkmoon-roll-dialog.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class HawkmoonActorSheet extends ActorSheet {
|
||||
|
||||
/** @override */
|
||||
static get defaultOptions() {
|
||||
|
||||
return mergeObject(super.defaultOptions, {
|
||||
classes: ["fvtt-hawkmoon", "sheet", "actor"],
|
||||
template: "systems/fvtt-hawkmoon-cyd/templates/actor-sheet.html",
|
||||
width: 640,
|
||||
height: 720,
|
||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "stats" }],
|
||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
|
||||
editScore: false
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async getData() {
|
||||
const objectData = duplicate(this.object)
|
||||
|
||||
let formData = {
|
||||
title: this.title,
|
||||
id: objectData.id,
|
||||
type: objectData.type,
|
||||
img: objectData.img,
|
||||
name: objectData.name,
|
||||
editable: this.isEditable,
|
||||
cssClass: this.isEditable ? "editable" : "locked",
|
||||
system: objectData.system,
|
||||
effects: this.object.effects.map(e => foundry.utils.deepClone(e.data)),
|
||||
limited: this.object.limited,
|
||||
skills: this.actor.getSkills(),
|
||||
armes: duplicate(this.actor.getWeapons()),
|
||||
protections: duplicate(this.actor.getArmors()),
|
||||
dons: duplicate(this.actor.getDons()),
|
||||
alignement: this.actor.getAlignement(),
|
||||
aspect: this.actor.getAspect(),
|
||||
marge: this.actor.getMarge(),
|
||||
tendances:duplicate(this.actor.getTendances()),
|
||||
runes:duplicate(this.actor.getRunes()),
|
||||
origine: duplicate(this.actor.getOrigine() || {}),
|
||||
heritage: duplicate(this.actor.getHeritage() || {}),
|
||||
metier: duplicate(this.actor.getMetier() || {}),
|
||||
combat: this.actor.getCombatValues(),
|
||||
equipements: duplicate(this.actor.getEquipments()),
|
||||
description: await TextEditor.enrichHTML(this.object.system.biodata.description, {async: true}),
|
||||
options: this.options,
|
||||
owner: this.document.isOwner,
|
||||
editScore: this.options.editScore,
|
||||
isGM: game.user.isGM
|
||||
}
|
||||
this.formData = formData;
|
||||
|
||||
console.log("PC : ", formData, this.object);
|
||||
return formData;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
// Everything below here is only needed if the sheet is editable
|
||||
if (!this.options.editable) return;
|
||||
|
||||
// Update Inventory Item
|
||||
html.find('.item-edit').click(ev => {
|
||||
const li = $(ev.currentTarget).parents(".item")
|
||||
let itemId = li.data("item-id")
|
||||
const item = this.actor.items.get( itemId )
|
||||
item.sheet.render(true)
|
||||
})
|
||||
// Delete Inventory Item
|
||||
html.find('.item-delete').click(ev => {
|
||||
const li = $(ev.currentTarget).parents(".item");
|
||||
HawkmoonUtility.confirmDelete(this, li);
|
||||
})
|
||||
html.find('.edit-item-data').change(ev => {
|
||||
const li = $(ev.currentTarget).parents(".item")
|
||||
let itemId = li.data("item-id")
|
||||
let itemType = li.data("item-type")
|
||||
let itemField = $(ev.currentTarget).data("item-field")
|
||||
let dataType = $(ev.currentTarget).data("dtype")
|
||||
let value = ev.currentTarget.value
|
||||
this.actor.editItemField(itemId, itemType, itemField, dataType, value)
|
||||
})
|
||||
|
||||
html.find('.quantity-minus').click(event => {
|
||||
const li = $(event.currentTarget).parents(".item");
|
||||
this.actor.incDecQuantity( li.data("item-id"), -1 );
|
||||
} );
|
||||
html.find('.quantity-plus').click(event => {
|
||||
const li = $(event.currentTarget).parents(".item");
|
||||
this.actor.incDecQuantity( li.data("item-id"), +1 );
|
||||
} );
|
||||
|
||||
html.find('.roll-attribut').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
let attrKey = li.data("attr-key")
|
||||
this.actor.rollAttribut(attrKey)
|
||||
})
|
||||
html.find('.roll-competence').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
let attrKey = $(event.currentTarget).data("attr-key")
|
||||
let compId = li.data("item-id")
|
||||
this.actor.rollCompetence(attrKey, compId)
|
||||
})
|
||||
html.find('.roll-rune').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
let runeId = li.data("item-id")
|
||||
this.actor.rollRune(runeId)
|
||||
})
|
||||
html.find('.roll-arme-offensif').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
let armeId = li.data("item-id")
|
||||
this.actor.rollArmeOffensif(armeId)
|
||||
})
|
||||
html.find('.roll-arme-degats').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
let armeId = li.data("item-id")
|
||||
this.actor.rollArmeDegats(armeId)
|
||||
})
|
||||
|
||||
|
||||
html.find('.lock-unlock-sheet').click((event) => {
|
||||
this.options.editScore = !this.options.editScore;
|
||||
this.render(true);
|
||||
});
|
||||
html.find('.item-equip').click(ev => {
|
||||
const li = $(ev.currentTarget).parents(".item");
|
||||
this.actor.equipItem( li.data("item-id") );
|
||||
this.render(true);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
setPosition(options = {}) {
|
||||
const position = super.setPosition(options);
|
||||
const sheetBody = this.element.find(".sheet-body");
|
||||
const bodyHeight = position.height - 192;
|
||||
sheetBody.css("height", bodyHeight);
|
||||
return position;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/*async _onDropItem(event, dragData) {
|
||||
let item = await HawkmoonUtility.searchItem( dragData)
|
||||
this.actor.preprocessItem( event, item, true )
|
||||
super._onDropItem(event, dragData)
|
||||
}*/
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
_updateObject(event, formData) {
|
||||
// Update the Actor
|
||||
return this.object.update(formData);
|
||||
}
|
||||
}
|
505
modules/hawkmoon-actor.js
Normal file
@ -0,0 +1,505 @@
|
||||
/* -------------------------------------------- */
|
||||
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
||||
import { HawkmoonRollDialog } from "./hawkmoon-roll-dialog.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
|
||||
const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8]
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/**
|
||||
* Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
|
||||
* @extends {Actor}
|
||||
*/
|
||||
export class HawkmoonActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/**
|
||||
* Override the create() function to provide additional SoS functionality.
|
||||
*
|
||||
* This overrided create() function adds initial items
|
||||
* Namely: Basic skills, money,
|
||||
*
|
||||
* @param {Object} data Barebones actor data which this function adds onto.
|
||||
* @param {Object} options (Unused) Additional options which customize the creation workflow.
|
||||
*
|
||||
*/
|
||||
|
||||
static async create(data, options) {
|
||||
|
||||
// Case of compendium global import
|
||||
if (data instanceof Array) {
|
||||
return super.create(data, options);
|
||||
}
|
||||
// If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
|
||||
if (data.items) {
|
||||
let actor = super.create(data, options);
|
||||
return actor;
|
||||
}
|
||||
|
||||
if (data.type == 'personnage') {
|
||||
const skills = await HawkmoonUtility.loadCompendium("fvtt-hawkmoon-cyd.skills")
|
||||
data.items = skills.map(i => i.toObject())
|
||||
}
|
||||
if (data.type == 'pnj') {
|
||||
}
|
||||
|
||||
return super.create(data, options);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
prepareArme(arme) {
|
||||
arme = duplicate(arme)
|
||||
let combat = this.getCombatValues()
|
||||
if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
|
||||
arme.system.competence = duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
|
||||
arme.system.attrKey = "pui"
|
||||
arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
|
||||
arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
|
||||
if (arme.system.isdefense) {
|
||||
arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.bonusmaniementdef
|
||||
}
|
||||
}
|
||||
if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
|
||||
arme.system.competence = duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
|
||||
arme.system.attrKey = "adr"
|
||||
arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
|
||||
arme.system.totalDegats = arme.system.degats
|
||||
if (arme.system.isdefense) {
|
||||
arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.bonusmaniementdef
|
||||
}
|
||||
}
|
||||
return arme
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
prepareBouclier(bouclier) {
|
||||
bouclier = duplicate(bouclier)
|
||||
let combat = this.getCombatValues()
|
||||
bouclier.system.competence = duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
|
||||
bouclier.system.attrKey = "pui"
|
||||
bouclier.system.totalDegats = bouclier.system.degats + "+" + combat.bonusDegatsTotal
|
||||
bouclier.system.totalOffensif = this.system.attributs.pui.value + bouclier.system.competence.system.niveau
|
||||
bouclier.system.isdefense = true
|
||||
bouclier.system.bonusmaniementoff = 0
|
||||
bouclier.system.totalDefensif = combat.defenseTotal + bouclier.system.competence.system.niveau + bouclier.system.bonusdefense
|
||||
return bouclier
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getWeapons() {
|
||||
let armes = []
|
||||
for (let arme of this.items) {
|
||||
if (arme.type == "arme") {
|
||||
armes.push(this.prepareArme(arme))
|
||||
}
|
||||
if (arme.type == "bouclier") {
|
||||
armes.push(this.prepareBouclier(arme))
|
||||
}
|
||||
}
|
||||
return armes
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getDons() {
|
||||
return this.items.filter(item => item.type == "don")
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getTendances() {
|
||||
return this.items.filter(item => item.type == "tendance")
|
||||
}
|
||||
getRunes() {
|
||||
return this.items.filter(item => item.type == "rune")
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getEquipments() {
|
||||
return this.items.filter(item => item.type == "equipement")
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getArmors() {
|
||||
return this.items.filter(item => item.type == "protection")
|
||||
}
|
||||
getOrigine() {
|
||||
return this.items.find(item => item.type == "origine")
|
||||
}
|
||||
getMetier() {
|
||||
return this.items.find(item => item.type == "metier")
|
||||
}
|
||||
getHeritage() {
|
||||
return this.items.find(item => item.type == "heritage")
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getSkills() {
|
||||
let comp = []
|
||||
for (let item of this.items) {
|
||||
item = duplicate(item)
|
||||
if (item.type == "competence") {
|
||||
item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
|
||||
item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
|
||||
item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
|
||||
if (item.system.niveau == 0) {
|
||||
item.system.attribut1total -= 3
|
||||
item.system.attribut2total -= 3
|
||||
item.system.attribut3total -= 3
|
||||
}
|
||||
item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
|
||||
item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
|
||||
item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
|
||||
comp.push(item)
|
||||
}
|
||||
}
|
||||
return comp.sort(function (a, b) {
|
||||
let fa = a.name.toLowerCase(),
|
||||
fb = b.name.toLowerCase();
|
||||
if (fa < fb) {
|
||||
return -1;
|
||||
}
|
||||
if (fa > fb) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
})
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getAspect() {
|
||||
return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
|
||||
}
|
||||
getMarge() {
|
||||
return Math.abs( this.system.balance.loi - this.system.balance.chaos)
|
||||
}
|
||||
getAlignement() {
|
||||
return (this.system.balance.loi > this.system.balance.chaos) ? "loyal" : "chaotique"
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getDefenseBase() {
|
||||
return this.system.attributs.tre.value + 5
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getVitesseBase() {
|
||||
return 5 + __vitesseBonus[this.system.attributs.adr.value]
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getCombatValues() {
|
||||
let combat = {
|
||||
initBase: this.system.attributs.adr.value,
|
||||
initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
|
||||
bonusDegats: this.getBonusDegats(),
|
||||
bonusDegatsTotal: this.getBonusDegats() + this.system.combat.bonusdegats,
|
||||
vitesseBase: this.getVitesseBase(),
|
||||
vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
|
||||
defenseBase: this.getDefenseBase(),
|
||||
defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus
|
||||
}
|
||||
return combat
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
prepareBaseData() {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async prepareData() {
|
||||
super.prepareData();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
prepareDerivedData() {
|
||||
|
||||
if (this.type == 'personnage') {
|
||||
let newSante = this.system.sante.bonus + (this.system.attributs.pui.value + this.system.attributs.tre.value) * 2 + 5
|
||||
if (this.system.sante.base != newSante) {
|
||||
this.update({ 'system.sante.base': newSante })
|
||||
}
|
||||
let newAme = (this.system.attributs.cla.value + this.system.attributs.tre.value) * this.system.biodata.amemultiplier + 5
|
||||
if (this.system.ame.fullmax != newAme) {
|
||||
this.update({ 'system.ame.fullmax': newAme })
|
||||
}
|
||||
}
|
||||
|
||||
super.prepareDerivedData()
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_preUpdate(changed, options, user) {
|
||||
|
||||
super._preUpdate(changed, options, user);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getItemById(id) {
|
||||
let item = this.items.find(item => item.id == id);
|
||||
if (item) {
|
||||
item = duplicate(item)
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async equipItem(itemId) {
|
||||
let item = this.items.find(item => item.id == itemId)
|
||||
if (item && item.system) {
|
||||
let update = { _id: item.id, "system.equipped": !item.system.equipped }
|
||||
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
editItemField(itemId, itemType, itemField, dataType, value) {
|
||||
let item = this.items.find(item => item.id == itemId)
|
||||
if (item) {
|
||||
console.log("Item ", item, itemField, dataType, value)
|
||||
if (dataType.toLowerCase() == "number") {
|
||||
value = Number(value)
|
||||
} else {
|
||||
value = String(value)
|
||||
}
|
||||
let update = { _id: item.id, [`system.${itemField}`]: value };
|
||||
this.updateEmbeddedDocuments("Item", [update])
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getBonneAventure() {
|
||||
return this.system.bonneaventure.actuelle
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
changeBonneAventure(value) {
|
||||
let newBA = this.system.bonneaventure.actuelle
|
||||
newBA += value
|
||||
this.update({ 'system.bonneaventure.actuelle': newBA })
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getEclat() {
|
||||
return this.system.eclat.value
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
changeEclat(value) {
|
||||
let newE = this.system.eclat.value
|
||||
newE += value
|
||||
this.update({ 'system.eclat.value': newE })
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
canEclatDoubleD20() {
|
||||
return (this.getAlignement() == "loyal" && this.system.eclat.value > 0)
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
subPointsAme(runeMode, value) {
|
||||
let ame = duplicate(this.system.ame)
|
||||
if(runeMode == "prononcer") {
|
||||
ame.value -= value
|
||||
} else {
|
||||
ame.currentmax -= value
|
||||
}
|
||||
this.update( {'system.ame': ame})
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
compareName(a, b) {
|
||||
if (a.name < b.name) {
|
||||
return -1;
|
||||
}
|
||||
if (a.name > b.name) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getAttribute(attrKey) {
|
||||
return this.system.attributes[attrKey]
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getBonusDegats() {
|
||||
return __degatsBonus[this.system.attributs.pui.value]
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async equipGear(equipmentId) {
|
||||
let item = this.items.find(item => item.id == equipmentId);
|
||||
if (item && item.system.data) {
|
||||
let update = { _id: item.id, "system.equipped": !item.system.equipped };
|
||||
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getSubActors() {
|
||||
let subActors = [];
|
||||
for (let id of this.system.subactors) {
|
||||
subActors.push(duplicate(game.actors.get(id)));
|
||||
}
|
||||
return subActors;
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
async addSubActor(subActorId) {
|
||||
let subActors = duplicate(this.system.subactors);
|
||||
subActors.push(subActorId);
|
||||
await this.update({ 'system.subactors': subActors });
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
async delSubActor(subActorId) {
|
||||
let newArray = [];
|
||||
for (let id of this.system.subactors) {
|
||||
if (id != subActorId) {
|
||||
newArray.push(id);
|
||||
}
|
||||
}
|
||||
await this.update({ 'system.subactors': newArray });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async incDecQuantity(objetId, incDec = 0) {
|
||||
let objetQ = this.items.get(objetId)
|
||||
if (objetQ) {
|
||||
let newQ = objetQ.system.quantity + incDec;
|
||||
const updated = await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantity': newQ }]); // pdates one EmbeddedEntity
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getCompetence(compId) {
|
||||
return this.items.get(compId)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async setPredilectionUsed(compId, predIdx) {
|
||||
let comp = this.items.get(compId)
|
||||
let pred = duplicate(comp.system.predilections)
|
||||
pred[predIdx].used = true
|
||||
await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getInitiativeScore( ) {
|
||||
return Number(this.system.attributs.adr.value) + Number(this.system.combat.initbonus)
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getBestDefenseValue() {
|
||||
let defenseList = this.items.filter(item => (item.type =="arme" || item.type == "bouclier") && item.system.equipped)
|
||||
let maxDef = 0
|
||||
let bestArme
|
||||
for(let arme of defenseList) {
|
||||
if (arme.type == "arme" && arme.system.isdefense) {
|
||||
arme = this.prepareArme(arme)
|
||||
}
|
||||
if (arme.type == "bouclier" ) {
|
||||
arme = this.prepareBouclier(arme)
|
||||
}
|
||||
if ( arme.system.totalDefensif > maxDef) {
|
||||
maxDef = arme.system.totalDefensif
|
||||
bestArme = duplicate(arme)
|
||||
}
|
||||
}
|
||||
return bestArme
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
|
||||
let rollData = HawkmoonUtility.getBasicRollData()
|
||||
rollData.alias = this.name
|
||||
rollData.actorImg = this.img
|
||||
rollData.actorId = this.id
|
||||
rollData.img = this.img
|
||||
rollData.canEclatDoubleD20 = this.canEclatDoubleD20()
|
||||
rollData.doubleD20 = false
|
||||
rollData.attributs = HawkmoonUtility.getAttributs()
|
||||
|
||||
if (attrKey) {
|
||||
rollData.attrKey = attrKey
|
||||
if (attrKey != "tochoose") {
|
||||
rollData.actionImg = "systems/fvtt-mournblade/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
|
||||
rollData.attr = duplicate(this.system.attributs[attrKey])
|
||||
}
|
||||
}
|
||||
if (compId) {
|
||||
rollData.competence = duplicate(this.items.get(compId) || {})
|
||||
rollData.actionImg = rollData.competence?.img
|
||||
}
|
||||
if (compName) {
|
||||
rollData.competence = duplicate(this.items.find( item => item.name.toLowerCase() == compName.toLowerCase()) || {})
|
||||
rollData.actionImg = rollData.competence?.img
|
||||
}
|
||||
return rollData
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollAttribut(attrKey) {
|
||||
let rollData = this.getCommonRollData(attrKey)
|
||||
let rollDialog = await HawkmoonRollDialog.create(this, rollData)
|
||||
rollDialog.render(true)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollCompetence(attrKey, compId) {
|
||||
let rollData = this.getCommonRollData(attrKey, compId)
|
||||
console.log("RollDatra", rollData)
|
||||
let rollDialog = await HawkmoonRollDialog.create(this, rollData)
|
||||
rollDialog.render(true)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollRune(runeId) {
|
||||
let comp = this.items.find(comp => comp.type == "competence" && comp.name.toLowerCase() == "savoir : runes")
|
||||
if ( !comp) {
|
||||
ui.notifications.warn("La compétence Savoirs : Runes n'a pas été trouvée, abandon.")
|
||||
return
|
||||
}
|
||||
let rollData = this.getCommonRollData("cla", undefined, "Savoir : Runes")
|
||||
rollData.rune = duplicate(this.items.get(runeId) || {})
|
||||
rollData.difficulte = rollData.rune?.system?.seuil || 0
|
||||
rollData.runemode = "prononcer"
|
||||
rollData.runeame = 1
|
||||
console.log("runeData", rollData)
|
||||
let rollDialog = await HawkmoonRollDialog.create(this, rollData)
|
||||
rollDialog.render(true)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollArmeOffensif(armeId) {
|
||||
let arme = this.items.get(armeId)
|
||||
if (arme.type == "arme") {
|
||||
arme = this.prepareArme(arme)
|
||||
}
|
||||
if (arme.type == "bouclier") {
|
||||
arme = this.prepareBouclier(arme)
|
||||
}
|
||||
let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
|
||||
rollData.arme = arme
|
||||
console.log("ARME!", rollData)
|
||||
let rollDialog = await HawkmoonRollDialog.create(this, rollData)
|
||||
rollDialog.render(true)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollArmeDegats(armeId) {
|
||||
let arme = this.items.get(armeId)
|
||||
if (arme.type == "arme") {
|
||||
arme = this.prepareArme(arme)
|
||||
}
|
||||
if (arme.type == "bouclier") {
|
||||
arme = this.prepareBouclier(arme)
|
||||
}
|
||||
let roll = new Roll(arme.system.totalDegats).roll({ async: false })
|
||||
await HawkmoonUtility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
|
||||
let rollData = {
|
||||
arme: arme,
|
||||
finalResult: roll.total,
|
||||
alias: this.name,
|
||||
actorImg: this.img,
|
||||
actorId: this.id,
|
||||
actionImg: arme.img,
|
||||
}
|
||||
HawkmoonUtility.createChatWithRollMode(rollData.alias, {
|
||||
content: await renderTemplate(`systems/fvtt-mournblade/templates/chat-degats-result.html`, rollData)
|
||||
})
|
||||
|
||||
}
|
||||
}
|
27
modules/hawkmoon-combat.js
Normal file
@ -0,0 +1,27 @@
|
||||
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class HawkmoonCombat extends Combat {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollInitiative(ids, formula = undefined, messageOptions = {} ) {
|
||||
ids = typeof ids === "string" ? [ids] : ids;
|
||||
for (let cId = 0; cId < ids.length; cId++) {
|
||||
const c = this.combatants.get(ids[cId]);
|
||||
let id = c._id || c.id;
|
||||
let initBonus = c.actor ? c.actor.getInitiativeScore() : 0
|
||||
let roll = new Roll("1d10 + "+initBonus).roll({ async: false})
|
||||
await HawkmoonUtility.showDiceSoNice(roll, game.settings.get("core", "rollMode"))
|
||||
//console.log("Init bonus", initBonus, roll.total)
|
||||
await this.updateEmbeddedDocuments("Combatant", [ { _id: id, initiative: roll.total } ]);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_onUpdate(changed, options, userId) {
|
||||
}
|
||||
|
||||
|
||||
}
|
123
modules/hawkmoon-commands.js
Normal file
@ -0,0 +1,123 @@
|
||||
/* -------------------------------------------- */
|
||||
|
||||
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
||||
import { HawkmoonRollDialog } from "./hawkmoon-roll-dialog.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class HawkmoonCommands {
|
||||
|
||||
static init() {
|
||||
if (!game.system.mournblade.commands) {
|
||||
//const HawkmoonCommands = new HawkmoonCommands()
|
||||
//HawkmoonCommands.registerCommand({ path: ["/char"], func: (content, msg, params) => HawkmoonCommands.createChar(msg), descr: "Create a new character" });
|
||||
//game.system.mournblade.commands = HawkmoonCommands
|
||||
}
|
||||
}
|
||||
|
||||
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("HawkmoonCommands._validateCommand failed ", 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);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_processCommand(commandsTable, name, params, content = '', msg = {}, path = "") {
|
||||
console.log("===> Processing command")
|
||||
let command = commandsTable[name];
|
||||
path = path + name + " ";
|
||||
if (command && 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 && command.func) {
|
||||
const result = command.func(content, msg, params);
|
||||
if (result == false) {
|
||||
RdDCommands._chatAnswer(msg, command.descr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async createChar(msg) {
|
||||
game.system.Hawkmoon.creator = new HawkmoonActorCreate();
|
||||
game.system.Hawkmoon.creator.start();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _chatAnswer(msg, content) {
|
||||
msg.whisper = [game.user.id];
|
||||
msg.content = content;
|
||||
ChatMessage.create(msg);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async poolRoll( msg) {
|
||||
let rollData = HawkmoonUtility.getBasicRollData()
|
||||
rollData.alias = "Dice Pool Roll",
|
||||
rollData.mode = "generic"
|
||||
rollData.title = `Dice Pool Roll`;
|
||||
|
||||
let rollDialog = await HawkmoonRollDialog.create( this, rollData);
|
||||
rollDialog.render( true );
|
||||
}
|
||||
|
||||
}
|
178
modules/hawkmoon-item-sheet.js
Normal file
@ -0,0 +1,178 @@
|
||||
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
||||
|
||||
/**
|
||||
* Extend the basic ItemSheet with some very simple modifications
|
||||
* @extends {ItemSheet}
|
||||
*/
|
||||
export class HawkmoonItemSheet extends ItemSheet {
|
||||
|
||||
/** @override */
|
||||
static get defaultOptions() {
|
||||
|
||||
return mergeObject(super.defaultOptions, {
|
||||
classes: ["fvtt-hawkmoon", "sheet", "item"],
|
||||
template: "systems/fvtt-hawkmoon-cyd/templates/item-sheet.html",
|
||||
dragDrop: [{ dragSelector: null, dropSelector: null }],
|
||||
width: 620,
|
||||
height: 550
|
||||
//tabs: [{navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "description"}]
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_getHeaderButtons() {
|
||||
let buttons = super._getHeaderButtons();
|
||||
// Add "Post to chat" button
|
||||
// We previously restricted this to GM and editable items only. If you ever find this comment because it broke something: eh, sorry!
|
||||
buttons.unshift(
|
||||
{
|
||||
class: "post",
|
||||
icon: "fas fa-comment",
|
||||
onclick: ev => { }
|
||||
})
|
||||
return buttons
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
setPosition(options = {}) {
|
||||
const position = super.setPosition(options);
|
||||
const sheetBody = this.element.find(".sheet-body");
|
||||
const bodyHeight = position.height - 192;
|
||||
sheetBody.css("height", bodyHeight);
|
||||
if (this.item.type.includes('weapon')) {
|
||||
position.width = 640;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async getData() {
|
||||
const objectData = duplicate(this.object)
|
||||
let formData = {
|
||||
title: this.title,
|
||||
id: this.id,
|
||||
type: objectData.type,
|
||||
img: objectData.img,
|
||||
name: objectData.name,
|
||||
editable: this.isEditable,
|
||||
cssClass: this.isEditable ? "editable" : "locked",
|
||||
attributs: HawkmoonUtility.getAttributs(),
|
||||
system: objectData.system,
|
||||
limited: this.object.limited,
|
||||
options: this.options,
|
||||
owner: this.document.isOwner,
|
||||
description: await TextEditor.enrichHTML(this.object.system.description, {async: true}),
|
||||
mr: (this.object.type == 'specialisation'),
|
||||
isGM: game.user.isGM
|
||||
}
|
||||
|
||||
if ( objectData.type == "don") {
|
||||
formData.sacrifice = await TextEditor.enrichHTML(this.object.system.sacrifice, {async: true})
|
||||
}
|
||||
//this.options.editable = !(this.object.origin == "embeddedItem");
|
||||
console.log("ITEM DATA", formData, this);
|
||||
return formData;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_getHeaderButtons() {
|
||||
let buttons = super._getHeaderButtons();
|
||||
buttons.unshift({
|
||||
class: "post",
|
||||
icon: "fas fa-comment",
|
||||
onclick: ev => this.postItem()
|
||||
});
|
||||
return buttons
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
postItem() {
|
||||
let chatData = duplicate(HawkmoonUtility.data(this.item));
|
||||
if (this.actor) {
|
||||
chatData.actor = { id: this.actor.id };
|
||||
}
|
||||
// Don't post any image for the item (which would leave a large gap) if the default image is used
|
||||
if (chatData.img.includes("/blank.png")) {
|
||||
chatData.img = null;
|
||||
}
|
||||
// JSON object for easy creation
|
||||
chatData.jsondata = JSON.stringify(
|
||||
{
|
||||
compendium: "postedItem",
|
||||
payload: chatData,
|
||||
});
|
||||
|
||||
renderTemplate('systems/fvtt-Hawkmoon-rpg/templates/post-item.html', chatData).then(html => {
|
||||
let chatOptions = HawkmoonUtility.chatDataSetup(html);
|
||||
ChatMessage.create(chatOptions)
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
// Everything below here is only needed if the sheet is editable
|
||||
if (!this.options.editable) return;
|
||||
|
||||
|
||||
// Update Inventory Item
|
||||
html.find('.item-edit').click(ev => {
|
||||
const li = $(ev.currentTarget).parents(".item")
|
||||
const item = this.object.options.actor.getOwnedItem(li.data("item-id"))
|
||||
item.sheet.render(true);
|
||||
});
|
||||
|
||||
html.find('.delete-subitem').click(ev => {
|
||||
this.deleteSubitem(ev);
|
||||
})
|
||||
html.find('.edit-prediction').change(ev => {
|
||||
const li = $(ev.currentTarget).parents(".prediction-item")
|
||||
let index = li.data("prediction-index")
|
||||
let pred = duplicate(this.object.system.predilections)
|
||||
pred[index].name = ev.currentTarget.value
|
||||
this.object.update( { 'data.predilections': pred })
|
||||
})
|
||||
html.find('.delete-prediction').click(ev => {
|
||||
const li = $(ev.currentTarget).parents(".prediction-item")
|
||||
let index = li.data("prediction-index")
|
||||
let pred = duplicate(this.object.system.predilections)
|
||||
pred.splice(index,1)
|
||||
this.object.update( { 'data.predilections': pred })
|
||||
})
|
||||
html.find('.use-prediction').change(ev => {
|
||||
const li = $(ev.currentTarget).parents(".prediction-item")
|
||||
let index = li.data("prediction-index")
|
||||
let pred = duplicate(this.object.system.predilections)
|
||||
pred[index].used = ev.currentTarget.checked
|
||||
this.object.update( { 'data.predilections': pred })
|
||||
})
|
||||
html.find('#add-predilection').click(ev => {
|
||||
let pred = duplicate(this.object.system.predilections)
|
||||
pred.push( { name: "Nouvelle prédilection", used: false })
|
||||
this.object.update( { 'data.predilections': pred })
|
||||
})
|
||||
// Update Inventory Item
|
||||
html.find('.item-delete').click(ev => {
|
||||
const li = $(ev.currentTarget).parents(".item");
|
||||
let itemId = li.data("item-id");
|
||||
let itemType = li.data("item-type");
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
get template() {
|
||||
let type = this.item.type;
|
||||
return `systems/fvtt-mournblade/templates/item-${type}-sheet.html`;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/** @override */
|
||||
_updateObject(event, formData) {
|
||||
return this.object.update(formData);
|
||||
}
|
||||
}
|
31
modules/hawkmoon-item.js
Normal file
@ -0,0 +1,31 @@
|
||||
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
||||
|
||||
export const defaultItemImg = {
|
||||
competence: "systems/fvtt-hawkmoon-cyd/assets/icons/competence.webp",
|
||||
arme: "systems/fvtt-hawkmoon-cyd/assets/icons/arme.webp",
|
||||
capacite: "systems/fvtt-hawkmoon-cyd/assets/icons/capacite.webp",
|
||||
don: "systems/fvtt-hawkmoon-cyd/assets/icons/don.webp",
|
||||
equipement: "systems/fvtt-hawkmoon-cyd/assets/icons/equipement.webp",
|
||||
monnaie: "systems/fvtt-hawkmoon-cyd/assets/icons/monnaie.webp",
|
||||
pacte: "systems/fvtt-hawkmoon-cyd/assets/icons/pacte.webp",
|
||||
predilection: "systems/fvtt-hawkmoon-cyd/assets/icons/predilection.webp",
|
||||
protection: "systems/fvtt-hawkmoon-cyd/assets/icons/protection.webp",
|
||||
rune: "systems/fvtt-hawkmoon-cyd/assets/icons/rune.webp",
|
||||
tendance: "systems/fvtt-hawkmoon-cyd/assets/icons/tendance.webp",
|
||||
traitchaotique: "systems/fvtt-hawkmoon-cyd/assets/icons/traitchaotique.webp",
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend the basic ItemSheet with some very simple modifications
|
||||
* @extends {ItemSheet}
|
||||
*/
|
||||
export class HawkmoonItem extends Item {
|
||||
|
||||
constructor(data, context) {
|
||||
if (!data.img) {
|
||||
data.img = defaultItemImg[data.type];
|
||||
}
|
||||
super(data, context);
|
||||
}
|
||||
|
||||
}
|
134
modules/hawkmoon-main.js
Normal file
@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Hawkmoon system
|
||||
* Author: Uberwald
|
||||
* Software License: Prop
|
||||
*/
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Import Modules
|
||||
import { HawkmoonActor } from "./hawkmoon-actor.js";
|
||||
import { HawkmoonItemSheet } from "./hawkmoon-item-sheet.js";
|
||||
import { HawkmoonActorSheet } from "./hawkmoon-actor-sheet.js";
|
||||
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
||||
import { HawkmoonCombat } from "./hawkmoon-combat.js";
|
||||
import { HawkmoonItem } from "./hawkmoon-item.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Initialization */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/************************************************************************************/
|
||||
Hooks.once("init", async function () {
|
||||
console.log(`Initializing Hawkmoon RPG`);
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// preload handlebars templates
|
||||
HawkmoonUtility.preloadHandlebarsTemplates();
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Set an initiative formula for the system
|
||||
CONFIG.Combat.initiative = {
|
||||
formula: "1d6",
|
||||
decimals: 1
|
||||
};
|
||||
|
||||
/* -------------------------------------------- */
|
||||
game.socket.on("system.fvtt-hawkmoon-cyd", data => {
|
||||
HawkmoonUtility.onSocketMesssage(data);
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Define custom Entity classes
|
||||
CONFIG.Combat.documentClass = HawkmoonCombat
|
||||
CONFIG.Actor.documentClass = HawkmoonActor
|
||||
CONFIG.Item.documentClass = HawkmoonItem
|
||||
game.system.hawkmon = {
|
||||
HawkmoonUtility
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Register sheet application classes
|
||||
Actors.unregisterSheet("core", ActorSheet);
|
||||
Actors.registerSheet("fvtt-hawkmoon-cyd", HawkmoonActorSheet, { types: ["personnage"], makeDefault: true })
|
||||
//Actors.registerSheet("fvtt-hawkmoon-cyd", HawkmoonNPCSheet, { types: ["npc"], makeDefault: false });
|
||||
|
||||
Items.unregisterSheet("core", ItemSheet);
|
||||
Items.registerSheet("fvtt-hawkmoon-cyd", HawkmoonItemSheet, { makeDefault: true })
|
||||
|
||||
HawkmoonUtility.init();
|
||||
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
function welcomeMessage() {
|
||||
ChatMessage.create({
|
||||
user: game.user.id,
|
||||
whisper: [game.user.id],
|
||||
content: `<div id="welcome-message-Hawkmoon"><span class="rdd-roll-part">
|
||||
<strong>Bienvenue dans Hawkmoon !</strong>
|
||||
<p>Les livres de Hawkmoon sont nécessaires pour jouer : https://www.titam-france.fr</p>
|
||||
<p>Hawkmoon est jeude rôle publié par Titam France/Sombres projets, tout les droits leur appartiennent.<p>
|
||||
` });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// Register world usage statistics
|
||||
function registerUsageCount( registerKey ) {
|
||||
if ( game.user.isGM ) {
|
||||