Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0aba87a9de | |||
| 0cb764f1f3 | |||
| 81c1848e87 | |||
| c172e20244 | |||
| d4f024f910 | |||
| 3eab0ded89 | |||
| 7d9aaa0085 | |||
| fcf5c10346 | |||
| 71b384c963 | |||
| f0a74d5daa | |||
| 9eb97a1acd | |||
| 391b99b18f | |||
| ff9acaab65 | |||
| 60978a67b2 | |||
| 5894cf043f | |||
| 0fd2130fb1 | |||
| 001f0cffa8 | |||
| 05ca6e1763 | |||
| d3f014fcca | |||
| 679b3208cd | |||
| 871a18a0ee | |||
| 264c49eb06 | |||
| 9349c54966 | |||
| 274efac2b5 | |||
| 7a7398f8ca | |||
| 93600f7e13 | |||
| a6fa3afbee |
@@ -0,0 +1,63 @@
|
|||||||
|
name: Release Creation
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- run: echo "💡 The ${{ gitea.repository }} repository will cloned to the runner."
|
||||||
|
|
||||||
|
#- uses: actions/checkout@v3
|
||||||
|
- uses: RouxAntoine/checkout@v3.5.4
|
||||||
|
|
||||||
|
# get part of the tag after the `v`
|
||||||
|
- name: Extract tag version number
|
||||||
|
id: get_version
|
||||||
|
uses: battila7/get-version-action@v2
|
||||||
|
|
||||||
|
# Substitute the Manifest and Download URLs in the system.json
|
||||||
|
- name: Substitute Manifest and Download Links For Versioned Ones
|
||||||
|
id: sub_manifest_link_version
|
||||||
|
uses: microsoft/variable-substitution@v1
|
||||||
|
with:
|
||||||
|
files: 'system.json'
|
||||||
|
env:
|
||||||
|
version: ${{steps.get_version.outputs.version-without-v}}
|
||||||
|
url: https://www.uberwald.me/gitea/${{gitea.repository}}
|
||||||
|
manifest: https://www.uberwald.me/gitea/public/fvtt-hawkmoon-cyd/releases/download/latest/system.json
|
||||||
|
download: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/fvtt-hawkmoon-cyd.zip
|
||||||
|
|
||||||
|
# Create a zip file with all files required by the module to add to the release
|
||||||
|
- run: |
|
||||||
|
apt update -y
|
||||||
|
apt install -y zip
|
||||||
|
|
||||||
|
- run: zip -r ./fvtt-hawkmoon-cyd.zip system.json README.md LICENCE.txt assets/ lang/ modules/ packs/ styles/ templates/
|
||||||
|
|
||||||
|
- name: setup go
|
||||||
|
uses: https://github.com/actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version: '>=1.20.1'
|
||||||
|
|
||||||
|
- name: Use Go Action
|
||||||
|
id: use-go-action
|
||||||
|
uses: https://gitea.com/actions/release-action@main
|
||||||
|
with:
|
||||||
|
files: |-
|
||||||
|
./fvtt-hawkmoon-cyd.zip
|
||||||
|
system.json
|
||||||
|
api_key: '${{secrets.ALLOW_PUSH_RELEASE}}'
|
||||||
|
|
||||||
|
- name: Publish to Foundry server
|
||||||
|
uses: https://github.com/djlechuck/foundryvtt-publish-package-action@v1
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.FOUNDRYVTT_RELEASE_TOKEN }}
|
||||||
|
id: 'fvtt-hawkmoon-cyd'
|
||||||
|
version: ${{github.event.release.tag_name}}
|
||||||
|
manifest: 'https://www.uberwald.me/gitea/public/fvtt-hawkmoon-cyd/releases/download/latest/system.json'
|
||||||
|
notes: 'https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/fvtt-hawkmoon-cyd.zip'
|
||||||
|
compatibility-minimum: '13'
|
||||||
|
compatibility-verified: '14'
|
||||||
@@ -8,3 +8,4 @@ todo.md
|
|||||||
/jsconfig.json
|
/jsconfig.json
|
||||||
/package.json
|
/package.json
|
||||||
/package-lock.json
|
/package-lock.json
|
||||||
|
.github/
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
<a class="item" data-tab="equipement">Equipement</a>
|
<a class="item" data-tab="equipement">Equipement</a>
|
||||||
<a class="item" data-tab="biodata">Bio&Notes</a>
|
<a class="item" data-tab="biodata">Bio&Notes</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
<hr>
|
||||||
|
|
||||||
{{!-- Sheet Body --}}
|
{{!-- Sheet Body --}}
|
||||||
<section class="sheet-body">
|
<section class="sheet-body">
|
||||||
@@ -239,7 +240,7 @@
|
|||||||
|
|
||||||
<div class="flexcol item-name-label">
|
<div class="flexcol item-name-label">
|
||||||
|
|
||||||
<span class="item-name-label competence-name"><a class="roll-competence item-field-label-short"
|
<span class="item-name-label competence-name"><a class="roll-competence "
|
||||||
data-attr-key="tochoose">{{skill.name}}</a></span>
|
data-attr-key="tochoose">{{skill.name}}</a></span>
|
||||||
|
|
||||||
<span class="predilection-text">
|
<span class="predilection-text">
|
||||||
@@ -627,9 +628,6 @@
|
|||||||
<span>
|
<span>
|
||||||
<h3>Description</h3>
|
<h3>Description</h3>
|
||||||
</span>
|
</span>
|
||||||
<div class="medium-editor item-text-long-line">
|
|
||||||
{{editor description target="system.biodata.description" button=true owner=owner editable=editable}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -0,0 +1,254 @@
|
|||||||
|
<div class="hawkmoon-chat-result">
|
||||||
|
{{!-- Header avec acteur --}}
|
||||||
|
<div class="chat-result-header">
|
||||||
|
{{#if actorImg}}
|
||||||
|
<img class="actor-icon" src="{{actorImg}}" alt="{{alias}}" />
|
||||||
|
{{/if}}
|
||||||
|
<div class="header-info">
|
||||||
|
<h4 class="actor-name">{{alias}}</h4>
|
||||||
|
{{#if competence}}
|
||||||
|
<div class="action-title">
|
||||||
|
<i class="fas fa-dice-d20"></i>
|
||||||
|
{{competence.name}}
|
||||||
|
{{#if arme}}• {{arme.name}}{{/if}}
|
||||||
|
</div>
|
||||||
|
{{else if actionImg}}
|
||||||
|
<div class="action-title">
|
||||||
|
<i class="fas fa-dice-d20"></i>
|
||||||
|
{{attr.label}}{{#if attr2}} + {{attr2.label}}{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{!-- Résultat principal --}}
|
||||||
|
<div class="result-main">
|
||||||
|
<div class="result-display">
|
||||||
|
<div class="dice-result">
|
||||||
|
<i class="fas fa-dice"></i>
|
||||||
|
<span class="dice-value">{{diceResult}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="total-result">
|
||||||
|
<span class="total-label">Total</span>
|
||||||
|
<span class="total-value">{{finalResult}}</span>
|
||||||
|
</div>
|
||||||
|
{{#if difficulte}}
|
||||||
|
<div class="difficulty">
|
||||||
|
<span class="difficulty-label">SD</span>
|
||||||
|
<span class="difficulty-value">{{difficulte}}</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{!-- Badge de résultat --}}
|
||||||
|
{{#if difficulte}}
|
||||||
|
<div class="result-badge-container">
|
||||||
|
{{#if isHeroique}}
|
||||||
|
<div class="result-badge heroique">
|
||||||
|
<i class="fas fa-star"></i> HÉROÏQUE !
|
||||||
|
</div>
|
||||||
|
{{else if isDramatique}}
|
||||||
|
<div class="result-badge dramatique">
|
||||||
|
<i class="fas fa-skull"></i> DRAMATIQUE !
|
||||||
|
</div>
|
||||||
|
{{else if isSuccess}}
|
||||||
|
<div class="result-badge success">
|
||||||
|
<i class="fas fa-check"></i> Succès
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="result-badge failure">
|
||||||
|
<i class="fas fa-times"></i> Échec
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{!-- Détails du jet --}}
|
||||||
|
<div class="result-details">
|
||||||
|
<div class="details-section">
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">Formule:</span>
|
||||||
|
<span class="detail-value">{{diceFormula}}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">{{attr.label}}:</span>
|
||||||
|
<span class="detail-value">{{attr.value}}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if attr2}}
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">{{attr2.label}}:</span>
|
||||||
|
<span class="detail-value">{{attr2.value}}</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if competence}}
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">{{competence.name}}:</span>
|
||||||
|
<span class="detail-value">{{competence.system.niveau}}</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if selectedMaitrise}}
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">Maîtrise:</span>
|
||||||
|
<span class="detail-value">{{selectedMaitrise.name}}</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if arme}}
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">Arme:</span>
|
||||||
|
<span class="detail-value">{{arme.name}} (+{{arme.system.bonusmaniementoff}})</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if bonusRoll}}
|
||||||
|
<div class="detail-row bonus">
|
||||||
|
<span class="detail-label">{{textBonus}}:</span>
|
||||||
|
<span class="detail-value">+{{bonusRoll.total}}</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{!-- Effets et conséquences --}}
|
||||||
|
{{#if isSuccess}}
|
||||||
|
<div class="result-effects">
|
||||||
|
{{#if attaqueDesarme}}
|
||||||
|
<div class="effect-item">
|
||||||
|
<i class="fas fa-hand-sparkles"></i>
|
||||||
|
{{#if isHeroique}}
|
||||||
|
Vous récupérez l'arme de votre adversaire dans votre main !
|
||||||
|
{{else}}
|
||||||
|
Vous désarmez votre adversaire ! Son arme tombe hors de sa portée.
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if immobiliser}}
|
||||||
|
<div class="effect-item">
|
||||||
|
<i class="fas fa-lock"></i>
|
||||||
|
{{#if isHeroique}}
|
||||||
|
Votre cible est immobilisée, et vous pouvez faire une action complexe.
|
||||||
|
{{else}}
|
||||||
|
Votre cible est immobilisée.
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if desengager}}
|
||||||
|
<div class="effect-item">
|
||||||
|
<i class="fas fa-running"></i>
|
||||||
|
Vous vous désengagez de votre adversaire.
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if repousser}}
|
||||||
|
<div class="effect-item">
|
||||||
|
<i class="fas fa-hand-rock"></i>
|
||||||
|
{{#if isHeroique}}
|
||||||
|
Votre cible est repoussée de 3 mètres et tombe au sol.
|
||||||
|
{{else}}
|
||||||
|
Votre cible tombe au sol.
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if assomer}}
|
||||||
|
<div class="effect-item">
|
||||||
|
<i class="fas fa-dizzy"></i>
|
||||||
|
{{#if isHeroique}}
|
||||||
|
Votre cible est assomée pour [[/r 1d10+10]] minutes.
|
||||||
|
{{else}}
|
||||||
|
Votre cible est assomée pour [[/r 1d10]] minutes.
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if coupBas}}
|
||||||
|
<div class="effect-item">
|
||||||
|
<i class="fas fa-shoe-prints"></i>
|
||||||
|
La cible a reçu 2 adversités bleues et a perdu 1 niveau de combativité.
|
||||||
|
{{#if isHeroique}}
|
||||||
|
<br><strong>Et votre cible perd sa prochaine action complexe.</strong>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if arme}}
|
||||||
|
{{#if contenir}}
|
||||||
|
<div class="effect-item">
|
||||||
|
<i class="fas fa-shield-alt"></i>
|
||||||
|
{{#if isHeroique}}
|
||||||
|
Aucun dégât, mais tous les adversaires dont le SD + 10 est atteint ne peuvent déclarer d'attaque contre vous lors de leur prochaine action complexe.
|
||||||
|
{{else}}
|
||||||
|
Aucun dégât, mais la cible ne peut pas déclarer d'attaque contre vous lors de sa prochaine action complexe.
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
{{#if (eq nbCombativitePerdu "vaincu")}}
|
||||||
|
<div class="effect-item victory">
|
||||||
|
<i class="fas fa-trophy"></i>
|
||||||
|
<strong>Votre adversaire est vaincu !</strong>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="effect-item">
|
||||||
|
<i class="fas fa-heart-broken"></i>
|
||||||
|
Votre adversaire a perdu {{nbCombativitePerdu}} État de Combativité.
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (not arme.system.onlevelonly)}}
|
||||||
|
<div class="damage-buttons">
|
||||||
|
<button class="chat-card-button roll-chat-degat">
|
||||||
|
<i class="fas fa-burst"></i> Dégâts de l'arme
|
||||||
|
</button>
|
||||||
|
{{#if coupDevastateur}}
|
||||||
|
<button class="chat-card-button roll-chat-degat-devastateur">
|
||||||
|
<i class="fas fa-explosion"></i> Dégâts avec Coup Dévastateur
|
||||||
|
</button>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{!-- Avertissements --}}
|
||||||
|
{{#if attaqueCharge}}
|
||||||
|
<div class="result-warning">
|
||||||
|
<i class="fas fa-exclamation-triangle"></i>
|
||||||
|
Vous avez chargé : vos adversaires bénéficient de +3 pour vous attaquer.
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if desengager}}
|
||||||
|
{{#if (not isSuccess)}}
|
||||||
|
<div class="result-warning">
|
||||||
|
<i class="fas fa-exclamation-triangle"></i>
|
||||||
|
Vous ne parvenez pas à vous désengager, votre adversaire a un bonus de +3 pour vous attaquer.
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if isInit}}
|
||||||
|
<div class="result-info">
|
||||||
|
<i class="fas fa-flag"></i> Initiative stockée !
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{!-- Prédilections --}}
|
||||||
|
{{#each predilections as |pred key|}}
|
||||||
|
{{#if (and (and pred.acquise (not pred.maitrise)) (not pred.used))}}
|
||||||
|
<div class="predilection-section">
|
||||||
|
<button class="chat-card-button predilection-reroll" data-predilection-index="{{key}}">
|
||||||
|
<i class="fas fa-redo"></i> Prédilection : {{pred.name}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
@@ -3,8 +3,8 @@
|
|||||||
* @extends {ActorSheet}
|
* @extends {ActorSheet}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
import { HawkmoonUtility } from "../modules/hawkmoon-utility.js";
|
||||||
import { HawkmoonAutomation } from "./hawkmoon-automation.js";
|
import { HawkmoonAutomation } from "../modules/hawkmoon-automation.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class HawkmoonActorSheet extends foundry.appv1.sheets.ActorSheet {
|
export class HawkmoonActorSheet extends foundry.appv1.sheets.ActorSheet {
|
||||||
@@ -36,6 +36,7 @@ export class HawkmoonActorSheet extends foundry.appv1.sheets.ActorSheet {
|
|||||||
editable: this.isEditable,
|
editable: this.isEditable,
|
||||||
cssClass: this.isEditable ? "editable" : "locked",
|
cssClass: this.isEditable ? "editable" : "locked",
|
||||||
system: objectData.system,
|
system: objectData.system,
|
||||||
|
systemFields: this.document.system.schema.fields,
|
||||||
effects: this.object.effects.map(e => foundry.utils.deepClone(e.data)),
|
effects: this.object.effects.map(e => foundry.utils.deepClone(e.data)),
|
||||||
limited: this.object.limited,
|
limited: this.object.limited,
|
||||||
skills: this.actor.getSkills(),
|
skills: this.actor.getSkills(),
|
||||||
@@ -56,7 +57,7 @@ export class HawkmoonActorSheet extends foundry.appv1.sheets.ActorSheet {
|
|||||||
nbCombativite: this.actor.system.sante.nbcombativite,
|
nbCombativite: this.actor.system.sante.nbcombativite,
|
||||||
combativiteList: HawkmoonUtility.getCombativiteList(this.actor.system.sante.nbcombativite),
|
combativiteList: HawkmoonUtility.getCombativiteList(this.actor.system.sante.nbcombativite),
|
||||||
initiative: this.actor.getFlag("world", "last-initiative") || -1,
|
initiative: this.actor.getFlag("world", "last-initiative") || -1,
|
||||||
description: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.description, {async: true}),
|
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.description, {async: true}),
|
||||||
habitat: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.habitat, {async: true}),
|
habitat: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.habitat, {async: true}),
|
||||||
options: this.options,
|
options: this.options,
|
||||||
owner: this.document.isOwner,
|
owner: this.document.isOwner,
|
||||||
@@ -66,7 +67,6 @@ export class HawkmoonActorSheet extends foundry.appv1.sheets.ActorSheet {
|
|||||||
}
|
}
|
||||||
this.formData = formData;
|
this.formData = formData;
|
||||||
|
|
||||||
console.log("PC : ", formData, this.object);
|
|
||||||
return formData;
|
return formData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3,8 +3,8 @@
|
|||||||
* @extends {ActorSheet}
|
* @extends {ActorSheet}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
import { HawkmoonUtility } from "../modules/hawkmoon-utility.js";
|
||||||
import { HawkmoonAutomation } from "./hawkmoon-automation.js";
|
import { HawkmoonAutomation } from "../modules/hawkmoon-automation.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
const __ALLOWED_ITEM_CELLULE = { "talent": 1, "ressource": 1, "contact": 1, "equipement": 1, "protection": 1, "artefact": 1, "arme": 1, "monnaie": 1 }
|
const __ALLOWED_ITEM_CELLULE = { "talent": 1, "ressource": 1, "contact": 1, "equipement": 1, "protection": 1, "artefact": 1, "arme": 1, "monnaie": 1 }
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { HawkmoonActorSheet } from "./hawkmoon-actor-sheet.js";
|
import { HawkmoonActorSheet } from "./hawkmoon-actor-sheet.js";
|
||||||
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
import { HawkmoonUtility } from "../modules/hawkmoon-utility.js";
|
||||||
import { HawkmoonAutomation } from "./hawkmoon-automation.js";
|
import { HawkmoonAutomation } from "../modules/hawkmoon-automation.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class HawkmoonCreatureSheet extends HawkmoonActorSheet {
|
export class HawkmoonCreatureSheet extends HawkmoonActorSheet {
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
import { HawkmoonUtility } from "../modules/hawkmoon-utility.js";
|
||||||
|
|
||||||
export class HawkmoonRollDialog extends Dialog {
|
export class HawkmoonRollDialog extends Dialog {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async create(actor, rollData ) {
|
static async create(actor, rollData) {
|
||||||
|
|
||||||
let options = { classes: ["HawkmoonDialog"], width: 320, height: 'fit-content', 'z-index': 99999 };
|
let options = { classes: ["HawkmoonDialog"], width: 420, height: 'fit-content', 'z-index': 99999 };
|
||||||
let html = await foundry.applications.handlebars.renderTemplate('systems/fvtt-hawkmoon-cyd/templates/roll-dialog-generic.html', rollData);
|
let html = await foundry.applications.handlebars.renderTemplate('systems/fvtt-hawkmoon-cyd/templates/roll-dialog-generic.html', rollData);
|
||||||
|
|
||||||
return new HawkmoonRollDialog(actor, rollData, html, options );
|
return new HawkmoonRollDialog(actor, rollData, html, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -18,20 +18,21 @@ export class HawkmoonRollDialog extends Dialog {
|
|||||||
content: html,
|
content: html,
|
||||||
buttons: {
|
buttons: {
|
||||||
rolld10: {
|
rolld10: {
|
||||||
icon: '<i class="fas fa-check"></i>',
|
icon: '<i class="fas fa-check"></i>',
|
||||||
label: "Lancer 1d10",
|
label: "Lancer 1d10",
|
||||||
callback: () => { this.roll("d10") }
|
callback: () => { this.roll("d10") }
|
||||||
},
|
},
|
||||||
rolld20: {
|
rolld20: {
|
||||||
icon: '<i class="fas fa-check"></i>',
|
icon: '<i class="fas fa-check"></i>',
|
||||||
label: "Lancer 1d20",
|
label: "Lancer 1d20",
|
||||||
callback: () => { this.roll("d20") }
|
callback: () => { this.roll("d20") }
|
||||||
},
|
},
|
||||||
cancel: {
|
cancel: {
|
||||||
icon: '<i class="fas fa-times"></i>',
|
icon: '<i class="fas fa-times"></i>',
|
||||||
label: "Annuler",
|
label: "Annuler",
|
||||||
callback: () => { this.close() }
|
callback: () => { this.close() }
|
||||||
} },
|
}
|
||||||
|
},
|
||||||
close: close
|
close: close
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,9 +43,9 @@ export class HawkmoonRollDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
roll ( dice) {
|
roll(dice) {
|
||||||
this.rollData.mainDice = dice
|
this.rollData.mainDice = dice
|
||||||
HawkmoonUtility.rollHawkmoon( this.rollData )
|
HawkmoonUtility.rollHawkmoon(this.rollData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -57,20 +58,20 @@ export class HawkmoonRollDialog extends Dialog {
|
|||||||
}
|
}
|
||||||
$(function () { onLoad(); });
|
$(function () { onLoad(); });
|
||||||
|
|
||||||
html.find('#modificateur').change(async (event) => {
|
html.find('#modificateur').change(async (event) => {
|
||||||
this.rollData.modificateur = Number(event.currentTarget.value)
|
this.rollData.modificateur = Number(event.currentTarget.value)
|
||||||
})
|
})
|
||||||
html.find('#difficulte').change( (event) => {
|
html.find('#difficulte').change((event) => {
|
||||||
console.log("Difficulte: " + event.currentTarget.value)
|
console.log("Difficulte: " + event.currentTarget.value)
|
||||||
this.rollData.difficulte = Number(event.currentTarget.value)
|
this.rollData.difficulte = Number(event.currentTarget.value)
|
||||||
})
|
})
|
||||||
html.find('#attrKey').change(async (event) => {
|
html.find('#attrKey').change(async (event) => {
|
||||||
this.rollData.attrKey = String(event.currentTarget.value)
|
this.rollData.attrKey = String(event.currentTarget.value)
|
||||||
})
|
})
|
||||||
html.find('#attrKey2').change(async (event) => {
|
html.find('#attrKey2').change(async (event) => {
|
||||||
this.rollData.attrKey2 = String(event.currentTarget.value)
|
this.rollData.attrKey2 = String(event.currentTarget.value)
|
||||||
})
|
})
|
||||||
html.find('#select-maitrise').change(async (event) => {
|
html.find('#select-maitrise').change(async (event) => {
|
||||||
this.rollData.maitriseId = String(event.currentTarget.value)
|
this.rollData.maitriseId = String(event.currentTarget.value)
|
||||||
})
|
})
|
||||||
html.find('#competence-talents').change((event) => {
|
html.find('#competence-talents').change((event) => {
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<li
|
||||||
|
class="item flexrow list-item list-item-shadow"
|
||||||
|
data-item-id="{{equip._id}}"
|
||||||
|
>
|
||||||
|
<a class="item-edit item-name-img" title="Edit Item"
|
||||||
|
><img class="sheet-competence-img" src="{{equip.img}}"
|
||||||
|
/></a>
|
||||||
|
{{#if (eq level 1)}}
|
||||||
|
<span class="item-name-label">{{equip.name}}</span>
|
||||||
|
{{else}}
|
||||||
|
<span class="item-name-label-level2">{{equip.name}}</span>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<span class="item-field-label-long"
|
||||||
|
><label>
|
||||||
|
{{equip.system.quantity}} (<a class="quantity-minus plus-minus-button">
|
||||||
|
-</a
|
||||||
|
>/<a class="quantity-plus plus-minus-button">+</a>)
|
||||||
|
</label>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="item-filler"> </div>
|
||||||
|
<div class="item-controls item-controls-fixed">
|
||||||
|
{{#if (eq level 1)}}
|
||||||
|
<a class="item-control item-equip" title="Worn"
|
||||||
|
>{{#if equip.system.equipped}}<i class="fas fa-circle"></i>{{else}}<i
|
||||||
|
class="fas fa-genderless"
|
||||||
|
></i
|
||||||
|
>{{/if}}</a
|
||||||
|
>
|
||||||
|
{{/if}}
|
||||||
|
<a class="item-control item-delete" title="Delete Item"
|
||||||
|
><i class="fas fa-trash"></i
|
||||||
|
></a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
@@ -0,0 +1,334 @@
|
|||||||
|
<form class="skill-roll-dialog">
|
||||||
|
<header class="roll-dialog-header">
|
||||||
|
{{#if img}}
|
||||||
|
<img class="actor-icon" src="{{img}}" data-edit="img" title="{{name}}" />
|
||||||
|
{{/if}}
|
||||||
|
<h1 class="dialog-roll-title roll-dialog-header">{{title}}</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="flexcol">
|
||||||
|
<div class="flexrow">
|
||||||
|
{{#if (eq attrKey "tochoose")}}
|
||||||
|
<span class="roll-dialog-label"><strong>Attribut</strong></span>
|
||||||
|
<select
|
||||||
|
class="status-small-label color-class-common"
|
||||||
|
id="attrKey"
|
||||||
|
type="text"
|
||||||
|
name="attrKey"
|
||||||
|
value="attrKey"
|
||||||
|
data-dtype="string"
|
||||||
|
>
|
||||||
|
{{selectOptions attributs selected=attrKey}}
|
||||||
|
</select>
|
||||||
|
{{else}}
|
||||||
|
<span class="roll-dialog-label"><strong>{{attr.label}}</strong></span>
|
||||||
|
<span class="small-label roll-dialog-label">{{attr.value}}</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if nbAdversites}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label"><strong>Malus d'adversités</strong></span>
|
||||||
|
<span class="small-label roll-dialog-label">- {{nbAdversites}}</span>
|
||||||
|
</div>
|
||||||
|
{{/if}} {{#if competence}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label"><strong>{{competence.name}}</strong></span>
|
||||||
|
<span class="small-label roll-dialog-label"><strong>{{competence.system.niveau}}</strong></span>
|
||||||
|
</div>
|
||||||
|
{{#if maitrises}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label"><strong>Maîtrise</strong></span>
|
||||||
|
<select
|
||||||
|
class="status-small-label color-class-common"
|
||||||
|
id="select-maitrise"
|
||||||
|
type="text"
|
||||||
|
name="select-maitrise"
|
||||||
|
value="maitriseId"
|
||||||
|
data-dtype="string"
|
||||||
|
>
|
||||||
|
{{selectOptions maitrises selected=maitriseId valueAttr="key"
|
||||||
|
nameAttr="key" labelAttr="label"}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{/if}} {{else}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label"><strong>Second Attribut</strong></span>
|
||||||
|
<select
|
||||||
|
class="status-small-label color-class-common"
|
||||||
|
id="attrKey2"
|
||||||
|
type="text"
|
||||||
|
name="attrKey2"
|
||||||
|
value="attrKey2"
|
||||||
|
data-dtype="string"
|
||||||
|
>
|
||||||
|
{{#select attrKey2}}
|
||||||
|
<option value="none">Aucun</option>
|
||||||
|
{{#each attributs as |attrLabel attrKey|}}
|
||||||
|
<option value="{{attrKey}}">{{attrLabel}}</option>
|
||||||
|
{{/each}} {{/select}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{/if}} {{#if (count talents)}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label"><strong></strong>Talents</strong></span>
|
||||||
|
<select
|
||||||
|
class="flex1"
|
||||||
|
name="competence-talents"
|
||||||
|
id="competence-talents"
|
||||||
|
data-type="String"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
{{#each talents as |talent key|}}
|
||||||
|
<option value="{{talent._id}}">{{talent.name}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{/if}} {{#if conditionsCommunes}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">En surplomb, défenseur au sol (+3)?</span>
|
||||||
|
<input type="checkbox" id="defenseur-au-sol" {{checked defenseurAuSol}} />
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Défenseur aveuglé (+10)?</span>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="defenseur-aveugle"
|
||||||
|
{{checked
|
||||||
|
defenseurAveugle}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Défenseur de dos (+5)?</span>
|
||||||
|
<input type="checkbox" id="defenseur-de-dos" {{checked defenseurDeDos}} />
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Défenseur immobilisé (+5)?</span>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="defenseur-immobilise"
|
||||||
|
{{checked
|
||||||
|
defenseurImmobilise}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{{/if}} {{#if (or immobiliser repousser)}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Cible consciente?</span>
|
||||||
|
<input type="checkbox" id="cibleconsciente" {{checked cibleconsciente}} />
|
||||||
|
</div>
|
||||||
|
{{/if}} {{#if arme}} {{#if arme.system.isMelee}} {{#if bonusArmeNaturelle}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Arme naturelle/fortune en défense</span>
|
||||||
|
<span class="small-label roll-dialog-label">{{bonusArmeNaturelle}}</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">En surplomb, défenseur au sol (+3)?</span>
|
||||||
|
<input type="checkbox" id="defenseur-au-sol" {{checked defenseurAuSol}} />
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label"
|
||||||
|
>Attaquants multiples (après le premier) (+3)?</span
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="attaquants-multiple"
|
||||||
|
{{checked
|
||||||
|
attaquantsMultiples}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{{#if hasAmbidextre}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label"
|
||||||
|
>Première attaque avec deux armes (-3)?</span
|
||||||
|
>
|
||||||
|
<input type="checkbox" id="ambidextre-1" {{checked attaqueAmbidextre1}} />
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label"
|
||||||
|
>Seconde attaque avec deux armes (-6)?</span
|
||||||
|
>
|
||||||
|
<input type="checkbox" id="ambidextre-2" {{checked attaqueAmbidextre2}} />
|
||||||
|
</div>
|
||||||
|
{{/if}} {{#if hasFeinte}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label"
|
||||||
|
>Feinte (<strong>cout : 1 BA</strong>) ?</span
|
||||||
|
>
|
||||||
|
<input type="checkbox" id="feinte" {{checked feinte}} />
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label"><strong></strong>Soutiens</strong></span>
|
||||||
|
<select
|
||||||
|
class="status-small-label color-class-common"
|
||||||
|
name="soutiens"
|
||||||
|
id="soutiens"
|
||||||
|
data-type="Number"
|
||||||
|
>
|
||||||
|
{{selectOptions config.optionsSoutiens selected=soutiens valueAttr="key"
|
||||||
|
nameAttr="key" labelAttr="label"}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Défenseur aveuglé (+10)?</span>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="defenseur-aveugle"
|
||||||
|
{{checked
|
||||||
|
defenseurAveugle}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Défenseur de dos (+5)?</span>
|
||||||
|
<input type="checkbox" id="defenseur-de-dos" {{checked defenseurDeDos}} />
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label"
|
||||||
|
>Défenseur dans espace restreint (+3)?</span
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="defenseur-restreint"
|
||||||
|
{{checked
|
||||||
|
defenseurRestreint}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Défenseur immobilisé (+5)?</span>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="defenseur-immobilise"
|
||||||
|
{{checked
|
||||||
|
defenseurImmobilise}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Charge ?</span>
|
||||||
|
<input type="checkbox" id="attaque-charge" {{checked attaqueCharge}} />
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Contenir?</span>
|
||||||
|
<input type="checkbox" id="contenir" {{checked contenir}} />
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Désarmer (SD+10)?</span>
|
||||||
|
<input type="checkbox" id="attaque-desarme" {{checked attaqueDesarme}} />
|
||||||
|
</div>
|
||||||
|
{{#if isMonte}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Charge de cavalerie?</span>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="charge-cavalerie"
|
||||||
|
{{checked
|
||||||
|
chargeCavalerie}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{{/if}} {{else}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Tireur en déplacement ?</span>
|
||||||
|
<select
|
||||||
|
class="item-field-label-long"
|
||||||
|
type="text"
|
||||||
|
id="tireur-deplacement"
|
||||||
|
data-dtype="string"
|
||||||
|
>
|
||||||
|
{{selectOptions config.optionsTireurDeplacement
|
||||||
|
selected=tireurDeplacement valueAttr="key" nameAttr="key"
|
||||||
|
labelAttr="label"}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Couvert de la cible ?</span>
|
||||||
|
<select
|
||||||
|
class="item-field-label-long"
|
||||||
|
type="text"
|
||||||
|
id="cible-couvert"
|
||||||
|
data-dtype="string"
|
||||||
|
>
|
||||||
|
{{selectOptions config.optionsCouvert selected=cibleCouvert
|
||||||
|
valueAttr="key" nameAttr="key" labelAttr="label"}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Cible se déplace vite (SD+3)?</span>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="tireur-cible-deplace"
|
||||||
|
{{checked
|
||||||
|
cibleDeplace}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Cible corps à corps (SD+3)?</span>
|
||||||
|
<input type="checkbox" id="tireur-cible-cac" {{checked cibleCaC}} />
|
||||||
|
</div>
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Taille de la cible ?</span>
|
||||||
|
<select
|
||||||
|
class="item-field-label-long"
|
||||||
|
type="text"
|
||||||
|
id="taille-cible"
|
||||||
|
data-dtype="string"
|
||||||
|
>
|
||||||
|
{{selectOptions config.optionsTailleCible selected=tailleCible
|
||||||
|
valueAttr="key" nameAttr="key" labelAttr="label"}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{/if}} {{/if}}
|
||||||
|
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Bonus/Malus </span>
|
||||||
|
<select
|
||||||
|
class="roll-dialog-label"
|
||||||
|
id="bonus-malus-context"
|
||||||
|
type="text"
|
||||||
|
value="{{bonusMalusContext}}"
|
||||||
|
data-dtype="Number"
|
||||||
|
>
|
||||||
|
{{selectOptions config.optionsBonusMalus selected=bonusMalusContext
|
||||||
|
valueAttr="key" nameAttr="key" labelAttr="label"}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if (or armeDefense arme.system.isDistance)}} {{#if
|
||||||
|
arme.system.isDistance}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">SD de distance</span>
|
||||||
|
<select
|
||||||
|
class="item-field-label-long"
|
||||||
|
type="text"
|
||||||
|
id="distance-tir"
|
||||||
|
data-dtype="string"
|
||||||
|
>
|
||||||
|
{{selectOptions config.optionsDistanceTir selected=distanceTir
|
||||||
|
valueAttr="key" nameAttr="key" labelAttr="label"}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="flexrow">
|
||||||
|
{{#if desengager}}
|
||||||
|
<span class="roll-dialog-label">C. Offensive adversaire </span>
|
||||||
|
{{else}}
|
||||||
|
<span class="roll-dialog-label">C. Défensive adversaire</span>
|
||||||
|
{{/if}}
|
||||||
|
<span class="roll-dialog-label"><strong>{{difficulte}}</strong> </span>
|
||||||
|
</div>
|
||||||
|
{{/if}} {{else}} {{#if isInit}} {{else}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<span class="roll-dialog-label">Difficulté : </span>
|
||||||
|
<select
|
||||||
|
class="roll-dialog-label"
|
||||||
|
id="difficulte"
|
||||||
|
type="text"
|
||||||
|
name="difficulte"
|
||||||
|
data-dtype="String"
|
||||||
|
>
|
||||||
|
{{selectOptions config.optionsDifficulte selected=difficulte
|
||||||
|
valueAttr="key" nameAttr="key" labelAttr="label"}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{/if}} {{/if}}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+35
@@ -0,0 +1,35 @@
|
|||||||
|
const gulp = require('gulp');
|
||||||
|
const less = require('gulp-less');
|
||||||
|
const sourcemaps = require('gulp-sourcemaps');
|
||||||
|
|
||||||
|
// Paths
|
||||||
|
const paths = {
|
||||||
|
styles: {
|
||||||
|
src: 'less/**/*.less',
|
||||||
|
dest: 'styles/'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Compile LESS to CSS
|
||||||
|
function styles() {
|
||||||
|
return gulp.src('less/hawkmoon.less')
|
||||||
|
.pipe(sourcemaps.init())
|
||||||
|
.pipe(less())
|
||||||
|
.pipe(sourcemaps.write('.'))
|
||||||
|
.pipe(gulp.dest(paths.styles.dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch files
|
||||||
|
function watchFiles() {
|
||||||
|
gulp.watch(paths.styles.src, styles);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define complex tasks
|
||||||
|
const build = gulp.series(styles);
|
||||||
|
const watch = gulp.series(build, watchFiles);
|
||||||
|
|
||||||
|
// Export tasks
|
||||||
|
exports.styles = styles;
|
||||||
|
exports.build = build;
|
||||||
|
exports.watch = watch;
|
||||||
|
exports.default = build;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// Main LESS file for Hawkmoon system
|
||||||
|
// Temporarily importing the full converted simple.css while we refactor
|
||||||
|
|
||||||
|
@import "simple-converted";
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,177 @@
|
|||||||
|
import { HawkmoonUtility } from "../hawkmoon-utility.js"
|
||||||
|
import { HAWKMOON_CONFIG } from "../hawkmoon-config.js"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dialogue de jet de dé pour Hawkmoon - Version DialogV2
|
||||||
|
*/
|
||||||
|
export class HawkmoonRollDialog {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and display the roll dialog
|
||||||
|
* @param {HawkmoonActor} actor - The actor making the roll
|
||||||
|
* @param {Object} rollData - Data for the roll
|
||||||
|
* @returns {Promise<HawkmoonRollDialog>}
|
||||||
|
*/
|
||||||
|
static async create(actor, rollData) {
|
||||||
|
// Préparer le contexte pour le template
|
||||||
|
const context = {
|
||||||
|
...rollData,
|
||||||
|
difficulte: String(rollData.difficulte || 0), // Convertir en string pour matcher les options du select
|
||||||
|
img: actor.img,
|
||||||
|
name: actor.name,
|
||||||
|
config: HAWKMOON_CONFIG,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si attrKey est "tochoose", préparer la liste des attributs sélectionnables
|
||||||
|
if (rollData.attrKey === "tochoose") {
|
||||||
|
context.selectableAttributes = actor.system.attributs
|
||||||
|
// Ne pas changer attrKey ni attr - l'utilisateur doit choisir
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rendre le template en HTML
|
||||||
|
const content = await foundry.applications.handlebars.renderTemplate(
|
||||||
|
"systems/fvtt-hawkmoon-cyd/templates/roll-dialog-generic.hbs",
|
||||||
|
context
|
||||||
|
)
|
||||||
|
|
||||||
|
// Utiliser DialogV2.wait avec le HTML rendu
|
||||||
|
return foundry.applications.api.DialogV2.wait({
|
||||||
|
window: { title: "Test de Capacité", icon: "fa-solid fa-dice-d20" },
|
||||||
|
classes: ["hawkmoon-roll-dialog"],
|
||||||
|
position: { width: 480 },
|
||||||
|
modal: false, // Permettre l'interaction avec le canvas pour garder la cible sélectionnée
|
||||||
|
content,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
action: "rolld10",
|
||||||
|
label: "Lancer 1d10",
|
||||||
|
icon: "fa-solid fa-dice-d10",
|
||||||
|
default: true,
|
||||||
|
callback: (event, button, dialog) => {
|
||||||
|
this._updateRollDataFromForm(rollData, button.form.elements, actor)
|
||||||
|
rollData.mainDice = "d10"
|
||||||
|
HawkmoonUtility.rollHawkmoon(rollData)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: "rolld20",
|
||||||
|
label: "Lancer 1d20",
|
||||||
|
icon: "fa-solid fa-dice-d20",
|
||||||
|
callback: (event, button, dialog) => {
|
||||||
|
this._updateRollDataFromForm(rollData, button.form.elements, actor)
|
||||||
|
rollData.mainDice = "d20"
|
||||||
|
HawkmoonUtility.rollHawkmoon(rollData)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
rejectClose: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mettre à jour rollData avec les valeurs du formulaire
|
||||||
|
* @param {Object} rollData - L'objet rollData à mettre à jour
|
||||||
|
* @param {HTMLFormControlsCollection} formElements - Les éléments du formulaire
|
||||||
|
* @param {HawkmoonActor} actor - L'acteur pour récupérer les attributs
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static _updateRollDataFromForm(rollData, formElements, actor) {
|
||||||
|
// Attributs
|
||||||
|
if (formElements.attrKey) {
|
||||||
|
rollData.attrKey = formElements.attrKey.value
|
||||||
|
// Si l'attribut a changé, mettre à jour rollData.attr
|
||||||
|
if (rollData.attrKey !== "tochoose" && rollData.attrKey !== "none" && actor) {
|
||||||
|
rollData.attr = foundry.utils.duplicate(actor.system.attributs[rollData.attrKey])
|
||||||
|
rollData.actionImg = "systems/fvtt-hawkmoon-cyd/assets/icons/" + actor.system.attributs[rollData.attrKey].labelnorm + ".webp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (formElements.attrKey2) {
|
||||||
|
rollData.attrKey2 = formElements.attrKey2.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modificateurs de base
|
||||||
|
if (formElements.difficulte) {
|
||||||
|
rollData.difficulte = Number(formElements.difficulte.value)
|
||||||
|
}
|
||||||
|
if (formElements.modificateur) {
|
||||||
|
rollData.modificateur = Number(formElements.modificateur.value)
|
||||||
|
}
|
||||||
|
if (formElements.soutiens) {
|
||||||
|
rollData.soutiens = Number(formElements.soutiens.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compétence
|
||||||
|
if (formElements.maitrise) {
|
||||||
|
rollData.maitriseId = formElements.maitrise.value
|
||||||
|
}
|
||||||
|
if (formElements.talents) {
|
||||||
|
// Récupérer toutes les options sélectionnées (select multiple)
|
||||||
|
const selectedOptions = Array.from(formElements.talents.selectedOptions)
|
||||||
|
rollData.selectedTalents = selectedOptions.map(opt => opt.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modificateurs de tir
|
||||||
|
if (formElements.tailleCible) {
|
||||||
|
rollData.tailleCible = formElements.tailleCible.value
|
||||||
|
}
|
||||||
|
if (formElements.tireurDeplacement) {
|
||||||
|
rollData.tireurDeplacement = formElements.tireurDeplacement.value
|
||||||
|
}
|
||||||
|
if (formElements.cibleCouvert) {
|
||||||
|
rollData.cibleCouvert = formElements.cibleCouvert.value
|
||||||
|
}
|
||||||
|
if (formElements.distanceTir) {
|
||||||
|
rollData.distanceTir = formElements.distanceTir.value
|
||||||
|
}
|
||||||
|
if (formElements.cibleDeplace) {
|
||||||
|
rollData.cibleDeplace = formElements.cibleDeplace.checked
|
||||||
|
}
|
||||||
|
if (formElements.cibleCaC) {
|
||||||
|
rollData.cibleCaC = formElements.cibleCaC.checked
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modificateurs de combat (checkboxes)
|
||||||
|
if (formElements.defenseurAuSol) {
|
||||||
|
rollData.defenseurAuSol = formElements.defenseurAuSol.checked
|
||||||
|
}
|
||||||
|
if (formElements.ambidextre1) {
|
||||||
|
rollData.ambidextre1 = formElements.ambidextre1.checked
|
||||||
|
}
|
||||||
|
if (formElements.ambidextre2) {
|
||||||
|
rollData.ambidextre2 = formElements.ambidextre2.checked
|
||||||
|
}
|
||||||
|
if (formElements.attaqueMonte) {
|
||||||
|
rollData.attaqueMonte = formElements.attaqueMonte.checked
|
||||||
|
}
|
||||||
|
if (formElements.defenseurAveugle) {
|
||||||
|
rollData.defenseurAveugle = formElements.defenseurAveugle.checked
|
||||||
|
}
|
||||||
|
if (formElements.defenseurDeDos) {
|
||||||
|
rollData.defenseurDeDos = formElements.defenseurDeDos.checked
|
||||||
|
}
|
||||||
|
if (formElements.defenseurRestreint) {
|
||||||
|
rollData.defenseurRestreint = formElements.defenseurRestreint.checked
|
||||||
|
}
|
||||||
|
if (formElements.defenseurImmobilise) {
|
||||||
|
rollData.defenseurImmobilise = formElements.defenseurImmobilise.checked
|
||||||
|
}
|
||||||
|
if (formElements.attaqueCharge) {
|
||||||
|
rollData.attaqueCharge = formElements.attaqueCharge.checked
|
||||||
|
}
|
||||||
|
if (formElements.chargeCavalerie) {
|
||||||
|
rollData.chargeCavalerie = formElements.chargeCavalerie.checked
|
||||||
|
}
|
||||||
|
if (formElements.attaquantsMultiple) {
|
||||||
|
rollData.attaquantsMultiple = formElements.attaquantsMultiple.checked
|
||||||
|
}
|
||||||
|
if (formElements.feinte) {
|
||||||
|
rollData.feinte = formElements.feinte.checked
|
||||||
|
}
|
||||||
|
if (formElements.contenir) {
|
||||||
|
rollData.contenir = formElements.contenir.checked
|
||||||
|
}
|
||||||
|
if (formElements.attaqueDesarme) {
|
||||||
|
rollData.attaqueDesarme = formElements.attaqueDesarme.checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
export { default as HawkmoonTalentSheet } from "./talent-sheet.mjs"
|
||||||
|
export { default as HawkmoonCompetenceSheet } from "./competence-sheet.mjs"
|
||||||
|
export { default as HawkmoonArmeSheet } from "./arme-sheet.mjs"
|
||||||
|
export { default as HawkmoonProtectionSheet } from "./protection-sheet.mjs"
|
||||||
|
export { default as HawkmoonHistoriqueSheet } from "./historique-sheet.mjs"
|
||||||
|
export { default as HawkmoonProfilSheet } from "./profil-sheet.mjs"
|
||||||
|
export { default as HawkmoonEquipementSheet } from "./equipement-sheet.mjs"
|
||||||
|
export { default as HawkmoonMonnaieSheet } from "./monnaie-sheet.mjs"
|
||||||
|
export { default as HawkmoonArtefactSheet } from "./artefact-sheet.mjs"
|
||||||
|
export { default as HawkmoonRessourceSheet } from "./ressource-sheet.mjs"
|
||||||
|
export { default as HawkmoonContactSheet } from "./contact-sheet.mjs"
|
||||||
|
export { default as HawkmoonMutationSheet } from "./mutation-sheet.mjs"
|
||||||
|
|
||||||
|
// Actor sheets
|
||||||
|
export { default as HawkmoonPersonnageSheet } from "./personnage-sheet.mjs"
|
||||||
|
export { default as HawkmoonCreatureSheet } from "./creature-sheet.mjs"
|
||||||
|
export { default as HawkmoonCelluleSheet } from "./cellule-sheet.mjs"
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import HawkmoonItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class HawkmoonArmeSheet extends HawkmoonItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["arme"],
|
||||||
|
position: {
|
||||||
|
width: 640,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["arme-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-hawkmoon-cyd/templates/item-arme-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import HawkmoonItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class HawkmoonArtefactSheet extends HawkmoonItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["artefact"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["artefact-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-hawkmoon-cyd/templates/item-artefact-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,547 @@
|
|||||||
|
const { HandlebarsApplicationMixin } = foundry.applications.api
|
||||||
|
|
||||||
|
import { HawkmoonUtility } from "../../hawkmoon-utility.js"
|
||||||
|
import { HawkmoonAutomation } from "../../hawkmoon-automation.js"
|
||||||
|
|
||||||
|
export default class HawkmoonActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {
|
||||||
|
/**
|
||||||
|
* Different sheet modes.
|
||||||
|
* @enum {number}
|
||||||
|
*/
|
||||||
|
static SHEET_MODES = { EDIT: 0, PLAY: 1 }
|
||||||
|
|
||||||
|
constructor(options = {}) {
|
||||||
|
super(options)
|
||||||
|
this.#dragDrop = this.#createDragDropHandlers()
|
||||||
|
this._sheetMode = this.constructor.SHEET_MODES.PLAY // Commencer en mode visualisation
|
||||||
|
}
|
||||||
|
|
||||||
|
#dragDrop
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["fvtt-hawkmoon-cyd", "sheet", "actor"],
|
||||||
|
position: {
|
||||||
|
width: 640,
|
||||||
|
height: 720,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
resizable: true,
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
submitOnChange: true,
|
||||||
|
closeOnSubmit: false,
|
||||||
|
},
|
||||||
|
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: "form" }],
|
||||||
|
actions: {
|
||||||
|
//editImage: HawkmoonActorSheet.#onEditImage,
|
||||||
|
toggleSheet: HawkmoonActorSheet.#onToggleSheet,
|
||||||
|
editItem: HawkmoonActorSheet.#onEditItem,
|
||||||
|
deleteItem: HawkmoonActorSheet.#onDeleteItem,
|
||||||
|
createItem: HawkmoonActorSheet.#onCreateItem,
|
||||||
|
equipItem: HawkmoonActorSheet.#onEquipItem,
|
||||||
|
modifyQuantity: HawkmoonActorSheet.#onModifyQuantity,
|
||||||
|
modifyAdversite: HawkmoonActorSheet.#onModifyAdversite,
|
||||||
|
rollInitiative: HawkmoonActorSheet.#onRollInitiative,
|
||||||
|
rollAttribut: HawkmoonActorSheet.#onRollAttribut,
|
||||||
|
rollCompetence: HawkmoonActorSheet.#onRollCompetence,
|
||||||
|
rollArmeOffensif: HawkmoonActorSheet.#onRollArmeOffensif,
|
||||||
|
rollArmeDegats: HawkmoonActorSheet.#onRollArmeDegats,
|
||||||
|
rollAssommer: HawkmoonActorSheet.#onRollAssommer,
|
||||||
|
rollCoupBas: HawkmoonActorSheet.#onRollCoupBas,
|
||||||
|
rollImmobiliser: HawkmoonActorSheet.#onRollImmobiliser,
|
||||||
|
rollRepousser: HawkmoonActorSheet.#onRollRepousser,
|
||||||
|
rollDesengager: HawkmoonActorSheet.#onRollDesengager,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the sheet currently in 'Play' mode?
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
get isPlayMode() {
|
||||||
|
// Initialize if not set
|
||||||
|
if (this._sheetMode === undefined) this._sheetMode = this.constructor.SHEET_MODES.PLAY
|
||||||
|
return this._sheetMode === this.constructor.SHEET_MODES.PLAY
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the sheet currently in 'Edit' mode?
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
get isEditMode() {
|
||||||
|
// Initialize if not set
|
||||||
|
if (this._sheetMode === undefined) this._sheetMode = this.constructor.SHEET_MODES.PLAY
|
||||||
|
return this._sheetMode === this.constructor.SHEET_MODES.EDIT
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tab groups state
|
||||||
|
* @type {object}
|
||||||
|
*/
|
||||||
|
tabGroups = { primary: "principal" }
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const actor = this.document
|
||||||
|
|
||||||
|
const context = {
|
||||||
|
actor: actor,
|
||||||
|
system: actor.system,
|
||||||
|
source: actor.toObject(),
|
||||||
|
fields: actor.schema.fields,
|
||||||
|
systemFields: actor.system.schema.fields,
|
||||||
|
isEditable: this.isEditable,
|
||||||
|
isEditMode: this.isEditMode,
|
||||||
|
isPlayMode: this.isPlayMode,
|
||||||
|
isGM: game.user.isGM,
|
||||||
|
config: CONFIG.HAWKMOON,
|
||||||
|
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.description || "", { async: true }),
|
||||||
|
enrichedHabitat: await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.habitat || "", { async: true }),
|
||||||
|
}
|
||||||
|
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
_onRender(context, options) {
|
||||||
|
super._onRender(context, options)
|
||||||
|
|
||||||
|
// Activate drag & drop handlers
|
||||||
|
this.#dragDrop.forEach(d => d.bind(this.element))
|
||||||
|
|
||||||
|
// Manual tab navigation
|
||||||
|
const html = this.element
|
||||||
|
const tabLinks = html.querySelectorAll('a.item[data-tab]')
|
||||||
|
const tabContents = html.querySelectorAll('.tab[data-tab]')
|
||||||
|
|
||||||
|
// Hide all tabs initially
|
||||||
|
tabContents.forEach(tab => {
|
||||||
|
tab.classList.remove('active')
|
||||||
|
tab.style.display = 'none'
|
||||||
|
})
|
||||||
|
|
||||||
|
// Show active tab
|
||||||
|
const activeTab = this.tabGroups.primary
|
||||||
|
const activeTabContent = html.querySelector(`.tab[data-tab="${activeTab}"]`)
|
||||||
|
if (activeTabContent) {
|
||||||
|
activeTabContent.classList.add('active')
|
||||||
|
activeTabContent.style.display = 'block'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activate the corresponding nav link
|
||||||
|
tabLinks.forEach(link => {
|
||||||
|
if (link.dataset.tab === activeTab) {
|
||||||
|
link.classList.add('active')
|
||||||
|
} else {
|
||||||
|
link.classList.remove('active')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Tab click handler
|
||||||
|
tabLinks.forEach(link => {
|
||||||
|
link.addEventListener('click', (event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
const tab = link.dataset.tab
|
||||||
|
|
||||||
|
// Update state
|
||||||
|
this.tabGroups.primary = tab
|
||||||
|
|
||||||
|
// Hide all tabs
|
||||||
|
tabContents.forEach(t => {
|
||||||
|
t.classList.remove('active')
|
||||||
|
t.style.display = 'none'
|
||||||
|
})
|
||||||
|
|
||||||
|
// Show selected tab
|
||||||
|
const selectedTab = html.querySelector(`.tab[data-tab="${tab}"]`)
|
||||||
|
if (selectedTab) {
|
||||||
|
selectedTab.classList.add('active')
|
||||||
|
selectedTab.style.display = 'block'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update nav links
|
||||||
|
tabLinks.forEach(l => {
|
||||||
|
if (l.dataset.tab === tab) {
|
||||||
|
l.classList.add('active')
|
||||||
|
} else {
|
||||||
|
l.classList.remove('active')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Inline item editing
|
||||||
|
html.querySelectorAll('.edit-item-data').forEach(input => {
|
||||||
|
input.addEventListener('change', (event) => {
|
||||||
|
const li = event.target.closest('.item')
|
||||||
|
const itemId = li.dataset.itemId
|
||||||
|
const itemType = li.dataset.itemType
|
||||||
|
const itemField = event.target.dataset.itemField
|
||||||
|
const dataType = event.target.dataset.dtype
|
||||||
|
const value = event.target.value
|
||||||
|
this.actor.editItemField(itemId, itemType, itemField, dataType, value)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// #region Drag & Drop
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create drag-and-drop workflow handlers for this Application
|
||||||
|
* @returns {DragDrop[]} An array of DragDrop handlers
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
#createDragDropHandlers() {
|
||||||
|
return this.options.dragDrop.map((d) => {
|
||||||
|
d.permissions = {
|
||||||
|
dragstart: this._canDragStart.bind(this),
|
||||||
|
drop: this._canDragDrop.bind(this),
|
||||||
|
}
|
||||||
|
d.callbacks = {
|
||||||
|
dragstart: this._onDragStart.bind(this),
|
||||||
|
drop: this._onDrop.bind(this),
|
||||||
|
}
|
||||||
|
return new foundry.applications.ux.DragDrop(d)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define whether a user is able to begin a dragstart workflow for a given drag selector
|
||||||
|
* @param {string} selector The candidate HTML selector for dragging
|
||||||
|
* @returns {boolean} Can the current user drag this selector?
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
_canDragStart(selector) {
|
||||||
|
return this.isEditable
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define whether a user is able to conclude a drag-and-drop workflow for a given drop selector
|
||||||
|
* @param {string} selector The candidate HTML selector for the drop target
|
||||||
|
* @returns {boolean} Can the current user drop on this selector?
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
_canDragDrop(selector) {
|
||||||
|
return this.isEditable
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback actions which occur at the beginning of a drag start workflow.
|
||||||
|
* @param {DragEvent} event The originating DragEvent
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
_onDragStart(event) {
|
||||||
|
const li = event.currentTarget.closest(".item")
|
||||||
|
if (!li?.dataset.itemId) return
|
||||||
|
const item = this.actor.items.get(li.dataset.itemId)
|
||||||
|
if (!item) return
|
||||||
|
|
||||||
|
const dragData = item.toDragData()
|
||||||
|
event.dataTransfer.setData("text/plain", JSON.stringify(dragData))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback actions which occur when a dragged element is dropped on a target.
|
||||||
|
* @param {DragEvent} event The originating DragEvent
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
async _onDrop(event) {
|
||||||
|
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event)
|
||||||
|
const actor = this.actor
|
||||||
|
|
||||||
|
// Handle different data types
|
||||||
|
switch (data.type) {
|
||||||
|
case "Item":
|
||||||
|
return this._onDropItem(event, data)
|
||||||
|
case "Actor":
|
||||||
|
return this._onDropActor(event, data)
|
||||||
|
case "ActiveEffect":
|
||||||
|
return this._onDropActiveEffect(event, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle dropping an Item on the actor sheet
|
||||||
|
* @param {DragEvent} event
|
||||||
|
* @param {object} data
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
async _onDropItem(event, data) {
|
||||||
|
if (!this.actor.isOwner) return false
|
||||||
|
|
||||||
|
let item = await fromUuid(data.uuid)
|
||||||
|
if (item.pack) {
|
||||||
|
item = await HawkmoonUtility.searchItem(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
const autoresult = HawkmoonAutomation.processAutomations("on-drop", item, this.actor)
|
||||||
|
if (autoresult.isValid) {
|
||||||
|
// In AppV2, we need to get the item data differently
|
||||||
|
const itemData = item.toObject ? item.toObject() : item
|
||||||
|
return this.actor.createEmbeddedDocuments("Item", [itemData])
|
||||||
|
} else {
|
||||||
|
ui.notifications.warn(autoresult.warningMessage)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle dropping an Actor on the sheet
|
||||||
|
* @param {DragEvent} event
|
||||||
|
* @param {object} data
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
async _onDropActor(event, data) {
|
||||||
|
// To be implemented by subclasses if needed
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle dropping an ActiveEffect on the sheet
|
||||||
|
* @param {DragEvent} event
|
||||||
|
* @param {object} data
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
async _onDropActiveEffect(event, data) {
|
||||||
|
// To be implemented by subclasses if needed
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Action Handlers
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle between edit and play mode
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static #onToggleSheet(event, target) {
|
||||||
|
console.log("Toggle sheet clicked", this)
|
||||||
|
const wasEditMode = this.isEditMode
|
||||||
|
console.log("Current mode:", this._sheetMode, "isEditMode:", wasEditMode, "isPlayMode:", this.isPlayMode)
|
||||||
|
this._sheetMode = wasEditMode ? this.constructor.SHEET_MODES.PLAY : this.constructor.SHEET_MODES.EDIT
|
||||||
|
console.log("New mode set to:", this._sheetMode, "(", wasEditMode ? "PLAY" : "EDIT", ")")
|
||||||
|
console.log("After change - isEditMode:", this.isEditMode, "isPlayMode:", this.isPlayMode)
|
||||||
|
this.render({ force: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit the actor image
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onEditImage(event, target) {
|
||||||
|
const fp = new foundry.applications.apps.FilePicker.implementation({
|
||||||
|
type: "image",
|
||||||
|
current: this.actor.img,
|
||||||
|
callback: (path) => {
|
||||||
|
this.actor.update({ img: path })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return fp.browse()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit an item
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onEditItem(event, target) {
|
||||||
|
const li = target.closest(".item")
|
||||||
|
const itemId = li?.dataset.itemId
|
||||||
|
if (!itemId) return
|
||||||
|
const item = this.actor.items.get(itemId)
|
||||||
|
if (item) item.sheet.render(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an item
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onDeleteItem(event, target) {
|
||||||
|
const li = target.closest(".item")
|
||||||
|
await HawkmoonUtility.confirmDelete(this, li)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new item
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onCreateItem(event, target) {
|
||||||
|
const itemType = target.dataset.type
|
||||||
|
await this.actor.createEmbeddedDocuments("Item", [{ name: `Nouveau ${itemType}`, type: itemType }], { renderSheet: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Equip/unequip an item
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onEquipItem(event, target) {
|
||||||
|
const li = target.closest(".item")
|
||||||
|
const itemId = li?.dataset.itemId
|
||||||
|
if (itemId) {
|
||||||
|
await this.actor.equipItem(itemId)
|
||||||
|
this.render()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify item quantity
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onModifyQuantity(event, target) {
|
||||||
|
const li = target.closest(".item")
|
||||||
|
const itemId = li?.dataset.itemId
|
||||||
|
const value = Number(target.dataset.quantiteValue)
|
||||||
|
if (itemId) {
|
||||||
|
await this.actor.incDecQuantity(itemId, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify adversité
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onModifyAdversite(event, target) {
|
||||||
|
const li = target.closest(".item")
|
||||||
|
const adv = li?.dataset.adversite
|
||||||
|
const value = Number(target.dataset.adversiteValue)
|
||||||
|
if (adv) {
|
||||||
|
await this.actor.incDecAdversite(adv, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roll initiative
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onRollInitiative(event, target) {
|
||||||
|
await this.actor.rollAttribut("adr", true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roll attribut
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onRollAttribut(event, target) {
|
||||||
|
const li = target.closest(".item")
|
||||||
|
const attrKey = li?.dataset.attrKey
|
||||||
|
if (attrKey) {
|
||||||
|
await this.actor.rollAttribut(attrKey, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roll competence
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onRollCompetence(event, target) {
|
||||||
|
const li = target.closest(".item")
|
||||||
|
const attrKey = target.dataset.attrKey
|
||||||
|
const compId = li?.dataset.itemId
|
||||||
|
if (attrKey && compId) {
|
||||||
|
await this.actor.rollCompetence(attrKey, compId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roll arme offensif
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onRollArmeOffensif(event, target) {
|
||||||
|
const li = target.closest(".item")
|
||||||
|
const armeId = li?.dataset.itemId
|
||||||
|
if (armeId) {
|
||||||
|
await this.actor.rollArmeOffensif(armeId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roll arme degats
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onRollArmeDegats(event, target) {
|
||||||
|
const li = target.closest(".item")
|
||||||
|
const armeId = li?.dataset.itemId
|
||||||
|
if (armeId) {
|
||||||
|
await this.actor.rollArmeDegats(armeId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roll assommer
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onRollAssommer(event, target) {
|
||||||
|
await this.actor.rollAssommer()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roll coup bas
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onRollCoupBas(event, target) {
|
||||||
|
await this.actor.rollCoupBas()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roll immobiliser
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onRollImmobiliser(event, target) {
|
||||||
|
await this.actor.rollImmobiliser()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roll repousser
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onRollRepousser(event, target) {
|
||||||
|
await this.actor.rollRepousser()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roll désengager
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onRollDesengager(event, target) {
|
||||||
|
await this.actor.rollDesengager()
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
}
|
||||||
@@ -0,0 +1,342 @@
|
|||||||
|
const { HandlebarsApplicationMixin } = foundry.applications.api
|
||||||
|
|
||||||
|
export default class HawkmoonItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) {
|
||||||
|
constructor(options = {}) {
|
||||||
|
super(options)
|
||||||
|
this.#dragDrop = this.#createDragDropHandlers()
|
||||||
|
}
|
||||||
|
|
||||||
|
#dragDrop
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["fvtt-hawkmoon-cyd", "item"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
height: 600,
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
submitOnChange: true,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
resizable: true,
|
||||||
|
},
|
||||||
|
tabs: [
|
||||||
|
{
|
||||||
|
navSelector: 'nav[data-group="primary"]',
|
||||||
|
contentSelector: "section.sheet-body",
|
||||||
|
initial: "description",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
dragDrop: [{ dragSelector: "[data-drag]", dropSelector: null }],
|
||||||
|
actions: {
|
||||||
|
editImage: HawkmoonItemSheet.#onEditImage,
|
||||||
|
postItem: HawkmoonItemSheet.#onPostItem,
|
||||||
|
addPredilection: HawkmoonItemSheet.#onAddPredilection,
|
||||||
|
deletePredilection: HawkmoonItemSheet.#onDeletePredilection,
|
||||||
|
addAutomation: HawkmoonItemSheet.#onAddAutomation,
|
||||||
|
deleteAutomation: HawkmoonItemSheet.#onDeleteAutomation,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tab groups state
|
||||||
|
* @type {object}
|
||||||
|
*/
|
||||||
|
tabGroups = { primary: "description" }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the sheet currently in 'Play' mode?
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = {
|
||||||
|
fields: this.document.schema.fields,
|
||||||
|
systemFields: this.document.system.schema.fields,
|
||||||
|
item: this.document,
|
||||||
|
system: this.document.system,
|
||||||
|
source: this.document.toObject(),
|
||||||
|
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }),
|
||||||
|
isEditMode: true,
|
||||||
|
isEditable: this.isEditable,
|
||||||
|
isGM: game.user.isGM,
|
||||||
|
config: CONFIG.HAWKMOON,
|
||||||
|
attributs: this.#getAttributs(),
|
||||||
|
}
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
_onRender(context, options) {
|
||||||
|
super._onRender(context, options)
|
||||||
|
this.#dragDrop.forEach((d) => d.bind(this.element))
|
||||||
|
|
||||||
|
// Activate tab navigation manually
|
||||||
|
const nav = this.element.querySelector('nav.tabs[data-group]')
|
||||||
|
if (nav) {
|
||||||
|
const group = nav.dataset.group
|
||||||
|
// Activate the current tab
|
||||||
|
const activeTab = this.tabGroups[group] || "description"
|
||||||
|
nav.querySelectorAll('[data-tab]').forEach(link => {
|
||||||
|
const tab = link.dataset.tab
|
||||||
|
link.classList.toggle('active', tab === activeTab)
|
||||||
|
link.addEventListener('click', (event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
this.tabGroups[group] = tab
|
||||||
|
this.render()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Show/hide tab content
|
||||||
|
this.element.querySelectorAll('[data-group="' + group + '"][data-tab]').forEach(content => {
|
||||||
|
content.classList.toggle('active', content.dataset.tab === activeTab)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #region Drag-and-Drop Workflow
|
||||||
|
/**
|
||||||
|
* Create drag-and-drop workflow handlers for this Application
|
||||||
|
* @returns {DragDrop[]} An array of DragDrop handlers
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
#createDragDropHandlers() {
|
||||||
|
return this.options.dragDrop.map((d) => {
|
||||||
|
d.permissions = {
|
||||||
|
dragstart: this._canDragStart.bind(this),
|
||||||
|
drop: this._canDragDrop.bind(this),
|
||||||
|
}
|
||||||
|
d.callbacks = {
|
||||||
|
dragstart: this._onDragStart.bind(this),
|
||||||
|
dragover: this._onDragOver.bind(this),
|
||||||
|
drop: this._onDrop.bind(this),
|
||||||
|
}
|
||||||
|
return new foundry.applications.ux.DragDrop.implementation(d)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can the User start a drag workflow for a given drag selector?
|
||||||
|
* @param {string} selector The candidate HTML selector for the drag event
|
||||||
|
* @returns {boolean} Can the current user drag this selector?
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
_canDragStart(selector) {
|
||||||
|
return this.isEditable
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can the User drop an entry at a given drop selector?
|
||||||
|
* @param {string} selector The candidate HTML selector for the drop event
|
||||||
|
* @returns {boolean} Can the current user drop on this selector?
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
_canDragDrop(selector) {
|
||||||
|
return this.isEditable
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for dragstart events.
|
||||||
|
* @param {DragEvent} event The drag start event
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
_onDragStart(event) {
|
||||||
|
const target = event.currentTarget
|
||||||
|
const dragData = { type: "Item", uuid: this.document.uuid }
|
||||||
|
event.dataTransfer.setData("text/plain", JSON.stringify(dragData))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for dragover events.
|
||||||
|
* @param {DragEvent} event The drag over event
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
_onDragOver(event) {
|
||||||
|
// Default behavior is fine
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for drop events.
|
||||||
|
* @param {DragEvent} event The drop event
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
async _onDrop(event) {
|
||||||
|
const data = TextEditor.getDragEventData(event)
|
||||||
|
const item = await fromUuid(data.uuid)
|
||||||
|
if (!item) return
|
||||||
|
|
||||||
|
// Handle drop logic here if needed
|
||||||
|
console.log("Item dropped:", item)
|
||||||
|
}
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Action Handlers
|
||||||
|
/**
|
||||||
|
* Edit the item image
|
||||||
|
* @param {Event} event The triggering event
|
||||||
|
* @param {HTMLElement} target The target element
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onEditImage(event, target) {
|
||||||
|
const fp = new foundry.applications.ui.FilePicker({
|
||||||
|
type: "image",
|
||||||
|
current: this.document.img,
|
||||||
|
callback: (path) => {
|
||||||
|
this.document.update({ img: path })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return fp.browse()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post item to chat
|
||||||
|
* @param {Event} event The triggering event
|
||||||
|
* @param {HTMLElement} target The target element
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onPostItem(event, target) {
|
||||||
|
let chatData = foundry.utils.duplicate(this.document)
|
||||||
|
if (this.document.actor) {
|
||||||
|
chatData.actor = { id: this.document.actor.id }
|
||||||
|
}
|
||||||
|
// Don't post any image for the item 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,
|
||||||
|
})
|
||||||
|
|
||||||
|
const html = await renderTemplate('systems/fvtt-hawkmoon-cyd/templates/post-item.hbs', chatData)
|
||||||
|
const chatOptions = {
|
||||||
|
user: game.user.id,
|
||||||
|
content: html,
|
||||||
|
}
|
||||||
|
ChatMessage.create(chatOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a predilection
|
||||||
|
* @param {Event} event The triggering event
|
||||||
|
* @param {HTMLElement} target The target element
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onAddPredilection(event, target) {
|
||||||
|
let pred = foundry.utils.duplicate(this.document.system.predilections || [])
|
||||||
|
pred.push({ name: "Nouvelle prédilection", id: foundry.utils.randomID(16), used: false, acquise: false, maitrise: false, description: "" })
|
||||||
|
await this.document.update({ 'system.predilections': pred })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a predilection
|
||||||
|
* @param {Event} event The triggering event
|
||||||
|
* @param {HTMLElement} target The target element
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onDeletePredilection(event, target) {
|
||||||
|
const index = parseInt(target.closest("[data-predilection-index]").dataset.predilectionIndex)
|
||||||
|
let pred = foundry.utils.duplicate(this.document.system.predilections)
|
||||||
|
pred.splice(index, 1)
|
||||||
|
await this.document.update({ 'system.predilections': pred })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an automation
|
||||||
|
* @param {Event} event The triggering event
|
||||||
|
* @param {HTMLElement} target The target element
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onAddAutomation(event, target) {
|
||||||
|
let autom = foundry.utils.duplicate(this.document.system.automations || [])
|
||||||
|
autom.push({
|
||||||
|
eventtype: "on-drop",
|
||||||
|
name: "Automatisation 1",
|
||||||
|
bonusname: "vigueur",
|
||||||
|
bonus: 0,
|
||||||
|
competence: "",
|
||||||
|
minLevel: 0,
|
||||||
|
baCost: 0,
|
||||||
|
id: foundry.utils.randomID(16)
|
||||||
|
})
|
||||||
|
await this.document.update({ 'system.automations': autom })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an automation
|
||||||
|
* @param {Event} event The triggering event
|
||||||
|
* @param {HTMLElement} target The target element
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onDeleteAutomation(event, target) {
|
||||||
|
const index = parseInt(target.closest("[data-automation-index]").dataset.automationIndex)
|
||||||
|
let autom = foundry.utils.duplicate(this.document.system.automations)
|
||||||
|
autom.splice(index, 1)
|
||||||
|
await this.document.update({ 'system.automations': autom })
|
||||||
|
}
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region Helper Methods
|
||||||
|
/**
|
||||||
|
* Get list of attributs
|
||||||
|
* @returns {Object}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
#getAttributs() {
|
||||||
|
return {
|
||||||
|
"adr": "Adresse",
|
||||||
|
"pui": "Puissance",
|
||||||
|
"cla": "Clairvoyance",
|
||||||
|
"pre": "Présence",
|
||||||
|
"tre": "Trempe"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
_onChangeForm(formConfig, event) {
|
||||||
|
// Handle special form changes
|
||||||
|
const target = event.target
|
||||||
|
|
||||||
|
// Handle predilection field changes
|
||||||
|
if (target.classList.contains('edit-predilection') ||
|
||||||
|
target.classList.contains('edit-predilection-description') ||
|
||||||
|
target.classList.contains('predilection-acquise') ||
|
||||||
|
target.classList.contains('predilection-maitrise') ||
|
||||||
|
target.classList.contains('predilection-used')) {
|
||||||
|
const li = target.closest('.prediction-item')
|
||||||
|
if (li) {
|
||||||
|
const index = parseInt(li.dataset.predictionIndex)
|
||||||
|
const field = target.classList.contains('edit-predilection') ? 'name' :
|
||||||
|
target.classList.contains('edit-predilection-description') ? 'description' :
|
||||||
|
target.classList.contains('predilection-acquise') ? 'acquise' :
|
||||||
|
target.classList.contains('predilection-maitrise') ? 'maitrise' : 'used'
|
||||||
|
|
||||||
|
let pred = foundry.utils.duplicate(this.document.system.predilections)
|
||||||
|
if (target.type === 'checkbox') {
|
||||||
|
pred[index][field] = target.checked
|
||||||
|
} else {
|
||||||
|
pred[index][field] = target.value
|
||||||
|
}
|
||||||
|
pred[index].id = pred[index].id || foundry.utils.randomID(16)
|
||||||
|
this.document.update({ 'system.predilections': pred })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle automation field changes
|
||||||
|
if (target.classList.contains('automation-edit-field')) {
|
||||||
|
const index = parseInt(target.dataset.automationIndex)
|
||||||
|
const field = target.dataset.automationField
|
||||||
|
let auto = foundry.utils.duplicate(this.document.system.automations)
|
||||||
|
auto[index][field] = target.value
|
||||||
|
auto[index].id = auto[index].id || foundry.utils.randomID(16)
|
||||||
|
this.document.update({ 'system.automations': auto })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
super._onChangeForm(formConfig, event)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
import HawkmoonActorSheet from "./base-actor-sheet.mjs"
|
||||||
|
|
||||||
|
const __ALLOWED_ITEM_CELLULE = { talent: 1, ressource: 1, contact: 1, equipement: 1, protection: 1, artefact: 1, arme: 1, monnaie: 1 }
|
||||||
|
|
||||||
|
export default class HawkmoonCelluleSheet extends HawkmoonActorSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
...super.DEFAULT_OPTIONS,
|
||||||
|
classes: [...super.DEFAULT_OPTIONS.classes],
|
||||||
|
window: {
|
||||||
|
...super.DEFAULT_OPTIONS.window,
|
||||||
|
title: "SHEETS.Actor.cellule",
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
...super.DEFAULT_OPTIONS.actions,
|
||||||
|
editActor: HawkmoonCelluleSheet.#onEditActor,
|
||||||
|
deleteActor: HawkmoonCelluleSheet.#onDeleteActor,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-hawkmoon-cyd/templates/cellule-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = { primary: "talents" }
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
const actor = this.document
|
||||||
|
|
||||||
|
// Add cellule-specific data
|
||||||
|
context.talents = foundry.utils.duplicate(actor.getTalents() || {})
|
||||||
|
context.ressources = foundry.utils.duplicate(actor.getRessources ? actor.getRessources() : [])
|
||||||
|
context.contacts = foundry.utils.duplicate(actor.getContacts ? actor.getContacts() : [])
|
||||||
|
context.members = this.#getMembers()
|
||||||
|
context.equipements = foundry.utils.duplicate(actor.getEquipments ? actor.getEquipments() : [])
|
||||||
|
context.artefacts = foundry.utils.duplicate(actor.getArtefacts ? actor.getArtefacts() : [])
|
||||||
|
context.armes = foundry.utils.duplicate(actor.getWeapons ? actor.getWeapons() : [])
|
||||||
|
context.monnaies = foundry.utils.duplicate(actor.getMonnaies ? actor.getMonnaies() : [])
|
||||||
|
context.protections = foundry.utils.duplicate(actor.getArmors ? actor.getArmors() : [])
|
||||||
|
context.richesse = actor.computeRichesse ? actor.computeRichesse() : 0
|
||||||
|
context.valeurEquipement = actor.computeValeurEquipement ? actor.computeValeurEquipement() : 0
|
||||||
|
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.description || "", { async: true })
|
||||||
|
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get members of the cellule with full actor data
|
||||||
|
* @returns {Array}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
#getMembers() {
|
||||||
|
let membersFull = []
|
||||||
|
for (let memberId of this.actor.system.members) {
|
||||||
|
let actor = game.actors.get(memberId)
|
||||||
|
if (actor) {
|
||||||
|
membersFull.push({ name: actor.name, id: actor.id, img: actor.img })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return membersFull
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override _onDropItem to filter allowed item types for cellule
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
async _onDropItem(event, data) {
|
||||||
|
const item = await fromUuid(data.uuid)
|
||||||
|
|
||||||
|
// Check if item type is allowed for cellule
|
||||||
|
if (!__ALLOWED_ITEM_CELLULE[item.type]) {
|
||||||
|
ui.notifications.warn(`Le type d'item ${item.type} n'est pas autorisé pour une cellule`)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return super._onDropItem(event, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override _onDropActor to handle adding members
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
async _onDropActor(event, data) {
|
||||||
|
const droppedActor = await fromUuid(data.uuid)
|
||||||
|
|
||||||
|
if (droppedActor.type !== "personnage") {
|
||||||
|
ui.notifications.warn("Seuls les personnages peuvent être ajoutés à une cellule")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if already a member
|
||||||
|
const isMember = this.actor.system.members.includes(droppedActor.id)
|
||||||
|
if (isMember) {
|
||||||
|
ui.notifications.warn("Ce personnage est déjà membre de cette cellule")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add member ID
|
||||||
|
const members = [...this.actor.system.members, droppedActor.id]
|
||||||
|
await this.actor.update({ "system.members": members })
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// #region Cellule-specific Actions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit an actor (member)
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onEditActor(event, target) {
|
||||||
|
const li = target.closest(".item")
|
||||||
|
const actorId = li?.dataset.actorId
|
||||||
|
if (!actorId) return
|
||||||
|
const actor = game.actors.get(actorId)
|
||||||
|
if (actor) actor.sheet.render(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an actor (remove member)
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onDeleteActor(event, target) {
|
||||||
|
const li = target.closest(".item")
|
||||||
|
const actorId = li?.dataset.actorId
|
||||||
|
if (actorId) {
|
||||||
|
const members = this.actor.system.members.filter(id => id !== actorId)
|
||||||
|
await this.actor.update({ "system.members": members })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import HawkmoonItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class HawkmoonCompetenceSheet extends HawkmoonItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["competence"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["competence-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-hawkmoon-cyd/templates/item-competence-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import HawkmoonItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class HawkmoonContactSheet extends HawkmoonItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["contact"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["contact-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-hawkmoon-cyd/templates/item-contact-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import HawkmoonActorSheet from "./base-actor-sheet.mjs"
|
||||||
|
import { HawkmoonUtility } from "../../hawkmoon-utility.js"
|
||||||
|
|
||||||
|
export default class HawkmoonCreatureSheet extends HawkmoonActorSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
...super.DEFAULT_OPTIONS,
|
||||||
|
classes: [...super.DEFAULT_OPTIONS.classes],
|
||||||
|
window: {
|
||||||
|
...super.DEFAULT_OPTIONS.window,
|
||||||
|
title: "SHEETS.Actor.creature",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-hawkmoon-cyd/templates/creature-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = { primary: "principal" }
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
const actor = this.document
|
||||||
|
|
||||||
|
// Add creature-specific data
|
||||||
|
context.skills = actor.getSkills ? actor.getSkills() : []
|
||||||
|
context.armes = foundry.utils.duplicate(actor.getWeapons ? actor.getWeapons() : [])
|
||||||
|
context.protections = foundry.utils.duplicate(actor.getArmors ? actor.getArmors() : [])
|
||||||
|
context.combat = actor.getCombatValues ? actor.getCombatValues() : {}
|
||||||
|
context.equipements = foundry.utils.duplicate(actor.getEquipments ? actor.getEquipments() : [])
|
||||||
|
context.talents = foundry.utils.duplicate(actor.getTalents ? actor.getTalents() : [])
|
||||||
|
context.talentsCell = this.#getCelluleTalents()
|
||||||
|
context.nbCombativite = actor.system.sante?.nbcombativite || 0
|
||||||
|
context.combativiteList = HawkmoonUtility.getCombativiteList(actor.system.sante?.nbcombativite || 0)
|
||||||
|
context.initiative = actor.getFlag("world", "last-initiative") || -1
|
||||||
|
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.description || "", { async: true })
|
||||||
|
context.enrichedHabitat = await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.habitat || "", { async: true })
|
||||||
|
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get talents from attached cellule
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
#getCelluleTalents() {
|
||||||
|
const celluleId = this.actor.system?.details?.celluleid
|
||||||
|
if (!celluleId) return []
|
||||||
|
|
||||||
|
const cellule = game.actors.get(celluleId)
|
||||||
|
if (!cellule) return []
|
||||||
|
|
||||||
|
return foundry.utils.duplicate(cellule.getTalents?.() || [])
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import HawkmoonItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class HawkmoonEquipementSheet extends HawkmoonItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["equipement"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["equipement-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-hawkmoon-cyd/templates/item-equipement-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import HawkmoonItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class HawkmoonHistoriqueSheet extends HawkmoonItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["historique"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["historique-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-hawkmoon-cyd/templates/item-historique-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import HawkmoonItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class HawkmoonMonnaieSheet extends HawkmoonItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["monnaie"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["monnaie-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-hawkmoon-cyd/templates/item-monnaie-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import HawkmoonItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class HawkmoonMutationSheet extends HawkmoonItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["mutation"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["mutation-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-hawkmoon-cyd/templates/item-mutation-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
import HawkmoonActorSheet from "./base-actor-sheet.mjs"
|
||||||
|
import { HawkmoonUtility } from "../../hawkmoon-utility.js"
|
||||||
|
|
||||||
|
export default class HawkmoonPersonnageSheet extends HawkmoonActorSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
...super.DEFAULT_OPTIONS,
|
||||||
|
classes: [...super.DEFAULT_OPTIONS.classes],
|
||||||
|
window: {
|
||||||
|
...super.DEFAULT_OPTIONS.window,
|
||||||
|
title: "SHEETS.Actor.personnage",
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
...super.DEFAULT_OPTIONS.actions,
|
||||||
|
openCellule: HawkmoonPersonnageSheet.#onOpenCellule,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-hawkmoon-cyd/templates/actor-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = { primary: "principal" }
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
const actor = this.document
|
||||||
|
|
||||||
|
// Add personnage-specific data
|
||||||
|
context.skills = actor.getSkills()
|
||||||
|
context.armes = foundry.utils.duplicate(actor.getWeapons())
|
||||||
|
context.monnaies = foundry.utils.duplicate(actor.getMonnaies())
|
||||||
|
context.protections = foundry.utils.duplicate(actor.getArmors())
|
||||||
|
context.historiques = foundry.utils.duplicate(actor.getHistoriques() || [])
|
||||||
|
context.talents = foundry.utils.duplicate(actor.getTalents() || [])
|
||||||
|
context.mutations = foundry.utils.duplicate(actor.getMutations() || [])
|
||||||
|
context.talentsCell = this.#getCelluleTalents()
|
||||||
|
context.celluleId = this.#getCelluleId()
|
||||||
|
context.profils = foundry.utils.duplicate(actor.getProfils() || [])
|
||||||
|
context.combat = actor.getCombatValues()
|
||||||
|
context.equipements = foundry.utils.duplicate(actor.getEquipments())
|
||||||
|
context.artefacts = foundry.utils.duplicate(actor.getArtefacts())
|
||||||
|
context.richesse = actor.computeRichesse()
|
||||||
|
context.coupDevastateur = actor.items.find(it => it.type == "talent" && it.name.toLowerCase() == "coup devastateur" && !it.system.used)
|
||||||
|
context.valeurEquipement = actor.computeValeurEquipement()
|
||||||
|
context.nbCombativite = actor.system.sante.nbcombativite
|
||||||
|
context.combativiteList = HawkmoonUtility.getCombativiteList(actor.system.sante.nbcombativite)
|
||||||
|
context.initiative = actor.getFlag("world", "last-initiative") || -1
|
||||||
|
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get talents from cellules this actor is a member of
|
||||||
|
* @returns {Array}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
#getCelluleTalents() {
|
||||||
|
let talents = []
|
||||||
|
for (let cellule of game.actors) {
|
||||||
|
if (cellule.type == "cellule") {
|
||||||
|
let found = cellule.system.members.includes(this.actor.id)
|
||||||
|
if (found) {
|
||||||
|
talents = talents.concat(cellule.getTalents())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return talents
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the ID of the cellule this actor is a member of
|
||||||
|
* @returns {string|null}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
#getCelluleId() {
|
||||||
|
for (let cellule of game.actors) {
|
||||||
|
if (cellule.type == "cellule") {
|
||||||
|
if (cellule.system.members.includes(this.actor.id)) {
|
||||||
|
return cellule.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open cellule sheet
|
||||||
|
* @param {Event} event
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static async #onOpenCellule(event, target) {
|
||||||
|
const celluleId = target.dataset.celluleId
|
||||||
|
if (!celluleId) return
|
||||||
|
const cellule = game.actors.get(celluleId)
|
||||||
|
if (cellule) cellule.sheet.render(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import HawkmoonItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class HawkmoonProfilSheet extends HawkmoonItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["profil"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["profil-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-hawkmoon-cyd/templates/item-profil-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import HawkmoonItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class HawkmoonProtectionSheet extends HawkmoonItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["protection"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["protection-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-hawkmoon-cyd/templates/item-protection-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import HawkmoonItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class HawkmoonRessourceSheet extends HawkmoonItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["ressource"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["ressource-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-hawkmoon-cyd/templates/item-ressource-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import HawkmoonItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class HawkmoonTalentSheet extends HawkmoonItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["talent"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["talent-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-hawkmoon-cyd/templates/item-talent-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+94
-63
@@ -1,6 +1,6 @@
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
||||||
import { HawkmoonRollDialog } from "./hawkmoon-roll-dialog.js";
|
import { HawkmoonRollDialog } from "./applications/hawkmoon-roll-dialog.mjs";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
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 __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
|
||||||
@@ -75,7 +75,7 @@ export class HawkmoonActor extends Actor {
|
|||||||
let combat = this.getCombatValues()
|
let combat = this.getCombatValues()
|
||||||
if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
|
if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
|
||||||
let bonusDefense = this.getBonusDefenseFromTalents()
|
let bonusDefense = this.getBonusDefenseFromTalents()
|
||||||
arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
|
arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée") ?? { system: { niveau: 0 } })
|
||||||
arme.system.attrKey = "pui"
|
arme.system.attrKey = "pui"
|
||||||
arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
|
arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
|
||||||
arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
|
arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + (this.system.combat.monte ? 3 : 0)
|
||||||
@@ -86,7 +86,7 @@ export class HawkmoonActor extends Actor {
|
|||||||
arme.system.isDistance = false
|
arme.system.isDistance = false
|
||||||
}
|
}
|
||||||
if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
|
if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
|
||||||
arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
|
arme.system.competence = foundry.utils.duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance") ?? { system: { niveau: 0 } })
|
||||||
arme.system.attrKey = "adr"
|
arme.system.attrKey = "adr"
|
||||||
arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
|
arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
|
||||||
arme.system.totalDegats = arme.system.degats
|
arme.system.totalDegats = arme.system.degats
|
||||||
@@ -148,26 +148,32 @@ export class HawkmoonActor extends Actor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getSkills() {
|
getSkills() {
|
||||||
let comp = []
|
// Utiliser filter et map pour éviter les duplications inutiles
|
||||||
for (let item of this.items) {
|
const comp = this.items
|
||||||
item = foundry.utils.duplicate(item)
|
.filter(item => item.type === "competence")
|
||||||
if (item.type == "competence") {
|
.map(item => {
|
||||||
item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
|
const itemCopy = foundry.utils.duplicate(item);
|
||||||
item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
|
const attrs = this.system.attributs;
|
||||||
item.system.attribut3total = item.system.niveau + (this.system.attributs[item.system.attribut3]?.value || 0)
|
|
||||||
if (item.system.niveau == 0) {
|
itemCopy.system.attribut1total = itemCopy.system.niveau + (attrs[itemCopy.system.attribut1]?.value || 0);
|
||||||
item.system.attribut1total -= 3
|
itemCopy.system.attribut2total = itemCopy.system.niveau + (attrs[itemCopy.system.attribut2]?.value || 0);
|
||||||
item.system.attribut2total -= 3
|
itemCopy.system.attribut3total = itemCopy.system.niveau + (attrs[itemCopy.system.attribut3]?.value || 0);
|
||||||
item.system.attribut3total -= 3
|
|
||||||
|
if (itemCopy.system.niveau === 0) {
|
||||||
|
itemCopy.system.attribut1total -= 3;
|
||||||
|
itemCopy.system.attribut2total -= 3;
|
||||||
|
itemCopy.system.attribut3total -= 3;
|
||||||
}
|
}
|
||||||
item.system.attribut1label = this.system.attributs[item.system.attribut1]?.label || ""
|
|
||||||
item.system.attribut2label = this.system.attributs[item.system.attribut2]?.label || ""
|
itemCopy.system.attribut1label = attrs[itemCopy.system.attribut1]?.label || "";
|
||||||
item.system.attribut3label = this.system.attributs[item.system.attribut3]?.label || ""
|
itemCopy.system.attribut2label = attrs[itemCopy.system.attribut2]?.label || "";
|
||||||
comp.push(item)
|
itemCopy.system.attribut3label = attrs[itemCopy.system.attribut3]?.label || "";
|
||||||
}
|
|
||||||
}
|
return itemCopy;
|
||||||
HawkmoonUtility.sortArrayObjectsByName(comp)
|
});
|
||||||
return comp
|
|
||||||
|
HawkmoonUtility.sortArrayObjectsByName(comp);
|
||||||
|
return comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------- --------------------- */
|
/* ----------------------- --------------------- */
|
||||||
@@ -188,7 +194,8 @@ export class HawkmoonActor extends Actor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getVitesseBase() {
|
getVitesseBase() {
|
||||||
return 5 + __vitesseBonus[this.system.attributs.adr.value]
|
const idx = Math.min(this.system.attributs.adr.value, __vitesseBonus.length - 1)
|
||||||
|
return 5 + (__vitesseBonus[idx] ?? 0)
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getProtection() {
|
getProtection() {
|
||||||
@@ -236,6 +243,9 @@ export class HawkmoonActor extends Actor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
prepareBaseData() {
|
prepareBaseData() {
|
||||||
|
if (game.release.generation >= 14) {
|
||||||
|
super.prepareBaseData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -305,7 +315,7 @@ export class HawkmoonActor extends Actor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
checkAttribut(attribut, minLevel) {
|
checkAttribut(attribut, minLevel) {
|
||||||
let attr = this.system.attributs.find(at => at.labelnorm == attribut.toLowerCase())
|
let attr = Object.values(this.system.attributs).find(at => at.labelnorm == attribut.toLowerCase())
|
||||||
if (attr && attr.value >= minLevel) {
|
if (attr && attr.value >= minLevel) {
|
||||||
return { isValid: true, attr: foundry.utils.duplicate(attr) }
|
return { isValid: true, attr: foundry.utils.duplicate(attr) }
|
||||||
}
|
}
|
||||||
@@ -403,7 +413,7 @@ export class HawkmoonActor extends Actor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getAttribute(attrKey) {
|
getAttribute(attrKey) {
|
||||||
return this.system.attributes[attrKey]
|
return this.system.attributs[attrKey]
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -424,7 +434,7 @@ export class HawkmoonActor extends Actor {
|
|||||||
if (sante.etat == this.system.sante.nbcombativite) {
|
if (sante.etat == this.system.sante.nbcombativite) {
|
||||||
ChatMessage.create({ content: `<strong>${this.name} est vaincu !</strong>` })
|
ChatMessage.create({ content: `<strong>${this.name} est vaincu !</strong>` })
|
||||||
}
|
}
|
||||||
this.processCombativite(sante)
|
// Duplicated ! this.processCombativite(sante)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -653,10 +663,17 @@ export class HawkmoonActor extends Actor {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async rollAttribut(attrKey, isInit = false) {
|
async rollAttribut(attrKey, isInit = false) {
|
||||||
let rollData = this.getCommonRollData(attrKey)
|
let rollData = this.getCommonRollData(attrKey)
|
||||||
rollData.multiplier = (isInit) ? 1 : 2
|
|
||||||
rollData.isInit = isInit
|
rollData.isInit = isInit
|
||||||
let rollDialog = await HawkmoonRollDialog.create(this, rollData)
|
if (isInit) {
|
||||||
rollDialog.render(true)
|
rollData.multiplier = 1
|
||||||
|
rollData.initbonus = this.system.combat.initbonus ?? 0
|
||||||
|
} else {
|
||||||
|
rollData.multiplier = 2 // fallback si attrKey2 vaut l'attribut principal
|
||||||
|
rollData.hasAttr2 = true
|
||||||
|
rollData.attrKey2 = attrKey // même attribut par défaut = ×2
|
||||||
|
rollData.selectableAttributes = this.system.attributs
|
||||||
|
}
|
||||||
|
await HawkmoonRollDialog.create(this, rollData)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -664,22 +681,30 @@ export class HawkmoonActor extends Actor {
|
|||||||
let rollData = this.getCommonRollData(attrKey, compId)
|
let rollData = this.getCommonRollData(attrKey, compId)
|
||||||
rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
|
rollData.multiplier = 1 // Attr multiplier, always 1 in competence mode
|
||||||
console.log("RollDatra", rollData)
|
console.log("RollDatra", rollData)
|
||||||
let rollDialog = await HawkmoonRollDialog.create(this, rollData)
|
await HawkmoonRollDialog.create(this, rollData)
|
||||||
rollDialog.render(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async rollArmeOffensif(armeId) {
|
async rollArmeOffensif(armeId) {
|
||||||
let arme = this.items.get(armeId)
|
let arme = this.items.get(armeId)
|
||||||
|
if (!arme.system.equipped) {
|
||||||
|
ui.notifications.warn("Cette arme doit être équipée pour pouvoir attaquer !")
|
||||||
|
return
|
||||||
|
}
|
||||||
if (arme.type == "arme") {
|
if (arme.type == "arme") {
|
||||||
arme = this.prepareArme(arme)
|
arme = this.prepareArme(arme)
|
||||||
}
|
}
|
||||||
|
if (!arme.system.competence) {
|
||||||
|
ui.notifications.warn("Aucune compétence trouvée pour cette arme !")
|
||||||
|
return
|
||||||
|
}
|
||||||
let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
|
let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
|
||||||
rollData.arme = arme
|
rollData.arme = arme
|
||||||
|
rollData.isCombat = true
|
||||||
|
rollData.isTir = arme.system.isDistance || false
|
||||||
HawkmoonUtility.updateWithTarget(rollData)
|
HawkmoonUtility.updateWithTarget(rollData)
|
||||||
console.log("ARME!", rollData)
|
console.log("ARME!", rollData)
|
||||||
let rollDialog = await HawkmoonRollDialog.create(this, rollData)
|
await HawkmoonRollDialog.create(this, rollData)
|
||||||
rollDialog.render(true)
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async rollAssommer() {
|
async rollAssommer() {
|
||||||
@@ -687,8 +712,7 @@ export class HawkmoonActor extends Actor {
|
|||||||
rollData.assomer = true
|
rollData.assomer = true
|
||||||
rollData.conditionsCommunes = true
|
rollData.conditionsCommunes = true
|
||||||
HawkmoonUtility.updateWithTarget(rollData)
|
HawkmoonUtility.updateWithTarget(rollData)
|
||||||
let rollDialog = await HawkmoonRollDialog.create(this, rollData)
|
await HawkmoonRollDialog.create(this, rollData)
|
||||||
rollDialog.render(true)
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async rollCoupBas() {
|
async rollCoupBas() {
|
||||||
@@ -696,8 +720,7 @@ export class HawkmoonActor extends Actor {
|
|||||||
rollData.coupBas = true
|
rollData.coupBas = true
|
||||||
rollData.conditionsCommunes = true
|
rollData.conditionsCommunes = true
|
||||||
HawkmoonUtility.updateWithTarget(rollData)
|
HawkmoonUtility.updateWithTarget(rollData)
|
||||||
let rollDialog = await HawkmoonRollDialog.create(this, rollData)
|
await HawkmoonRollDialog.create(this, rollData)
|
||||||
rollDialog.render(true)
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async rollImmobiliser() {
|
async rollImmobiliser() {
|
||||||
@@ -706,8 +729,7 @@ export class HawkmoonActor extends Actor {
|
|||||||
rollData.conditionsCommunes = true
|
rollData.conditionsCommunes = true
|
||||||
rollData.cibleconsciente = true
|
rollData.cibleconsciente = true
|
||||||
HawkmoonUtility.updateWithTarget(rollData)
|
HawkmoonUtility.updateWithTarget(rollData)
|
||||||
let rollDialog = await HawkmoonRollDialog.create(this, rollData)
|
await HawkmoonRollDialog.create(this, rollData)
|
||||||
rollDialog.render(true)
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async rollRepousser() {
|
async rollRepousser() {
|
||||||
@@ -716,8 +738,7 @@ export class HawkmoonActor extends Actor {
|
|||||||
rollData.conditionsCommunes = true
|
rollData.conditionsCommunes = true
|
||||||
rollData.cibleconsciente = true
|
rollData.cibleconsciente = true
|
||||||
HawkmoonUtility.updateWithTarget(rollData)
|
HawkmoonUtility.updateWithTarget(rollData)
|
||||||
let rollDialog = await HawkmoonRollDialog.create(this, rollData)
|
await HawkmoonRollDialog.create(this, rollData)
|
||||||
rollDialog.render(true)
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async rollDesengager() {
|
async rollDesengager() {
|
||||||
@@ -725,43 +746,53 @@ export class HawkmoonActor extends Actor {
|
|||||||
rollData.desengager = true
|
rollData.desengager = true
|
||||||
rollData.conditionsCommunes = true
|
rollData.conditionsCommunes = true
|
||||||
HawkmoonUtility.updateWithTarget(rollData)
|
HawkmoonUtility.updateWithTarget(rollData)
|
||||||
let rollDialog = await HawkmoonRollDialog.create(this, rollData)
|
await HawkmoonRollDialog.create(this, rollData)
|
||||||
rollDialog.render(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
|
async rollArmeDegats(armeId, targetVigueur = undefined, rollDataInput = undefined) {
|
||||||
let arme = this.items.get(armeId)
|
const arme = this.items.get(armeId);
|
||||||
if (arme.type == "arme") {
|
if (!arme) {
|
||||||
arme = this.prepareArme(arme)
|
ui.notifications.warn("Arme non trouvée !");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
console.log("DEGATS", arme, targetVigueur, rollDataInput)
|
|
||||||
let roll
|
if (!arme.system?.equipped) {
|
||||||
let bonus = 0
|
ui.notifications.warn("Cette arme doit être équipée pour pouvoir infliger des dégâts !");
|
||||||
let bonus2 = 0
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const preparedArme = arme.type === "arme" ? this.prepareArme(arme) : arme;
|
||||||
|
console.log("DEGATS", preparedArme, targetVigueur, rollDataInput);
|
||||||
|
|
||||||
|
let roll;
|
||||||
|
let bonus = 0;
|
||||||
|
let bonus2 = 0;
|
||||||
|
|
||||||
if (rollDataInput?.applyCoupDevastateur) {
|
if (rollDataInput?.applyCoupDevastateur) {
|
||||||
bonus2 = Math.floor(this.system.attributs.pui.value / 2)
|
bonus2 = Math.floor(this.system.attributs.pui.value / 2);
|
||||||
let talent = this.items.find(item => item.type == "talent" && item.name.toLowerCase() == "coup dévastateur")
|
const talent = this.items.find(item => item.type === "talent" && item.name.toLowerCase() === "coup dévastateur");
|
||||||
this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }])
|
if (talent) {
|
||||||
|
await this.updateEmbeddedDocuments('Item', [{ _id: talent.id, 'system.used': true }]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rollDataInput?.isHeroique) {
|
if (rollDataInput?.isHeroique) {
|
||||||
if (rollDataInput?.attaqueCharge) {
|
if (rollDataInput?.attaqueCharge) {
|
||||||
bonus = 5
|
bonus = 5;
|
||||||
}
|
}
|
||||||
if (rollDataInput?.chargeCavalerie) {
|
if (rollDataInput?.chargeCavalerie) {
|
||||||
bonus = 6
|
bonus = 6;
|
||||||
}
|
}
|
||||||
roll = await new Roll("2d10rr10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
|
roll = await new Roll("2d10rr10+" + preparedArme.system.totalDegats + "+" + bonus + "+" + bonus2).roll();
|
||||||
} else {
|
} else {
|
||||||
if (rollDataInput?.attaqueCharge) {
|
if (rollDataInput?.attaqueCharge) {
|
||||||
bonus = 3
|
bonus = 3;
|
||||||
}
|
}
|
||||||
if (rollDataInput?.chargeCavalerie) {
|
if (rollDataInput?.chargeCavalerie) {
|
||||||
bonus = 4
|
bonus = 4;
|
||||||
}
|
}
|
||||||
roll = await new Roll("1d10+" + arme.system.totalDegats + "+" + bonus + "+" + bonus2).roll()
|
roll = await new Roll("1d10+" + preparedArme.system.totalDegats + "+" + bonus + "+" + bonus2).roll();
|
||||||
}
|
}
|
||||||
await HawkmoonUtility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
|
await HawkmoonUtility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
|
||||||
let nbEtatPerdus = 0
|
let nbEtatPerdus = 0
|
||||||
@@ -770,19 +801,19 @@ export class HawkmoonActor extends Actor {
|
|||||||
}
|
}
|
||||||
//console.log(roll)
|
//console.log(roll)
|
||||||
let rollData = {
|
let rollData = {
|
||||||
arme: arme,
|
arme: preparedArme,
|
||||||
finalResult: roll.total,
|
finalResult: roll.total,
|
||||||
formula: roll.formula,
|
formula: roll.formula,
|
||||||
alias: this.name,
|
alias: this.name,
|
||||||
actorImg: this.img,
|
actorImg: this.img,
|
||||||
actorId: this.id,
|
actorId: this.id,
|
||||||
defenderTokenId: rollDataInput?.defenderTokenId,
|
defenderTokenId: rollDataInput?.defenderTokenId,
|
||||||
actionImg: arme.img,
|
actionImg: preparedArme.img,
|
||||||
targetVigueur: targetVigueur,
|
targetVigueur: targetVigueur,
|
||||||
nbEtatPerdus: nbEtatPerdus
|
nbEtatPerdus: nbEtatPerdus
|
||||||
}
|
};
|
||||||
HawkmoonUtility.createChatWithRollMode(rollData.alias, {
|
HawkmoonUtility.createChatWithRollMode(rollData.alias, {
|
||||||
content: await renderTemplate(`systems/fvtt-hawkmoon-cyd/templates/chat-degats-result.html`, rollData)
|
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-hawkmoon-cyd/templates/chat-degats-result.hbs`, rollData)
|
||||||
})
|
})
|
||||||
|
|
||||||
if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
|
if (rollDataInput?.defenderTokenId && nbEtatPerdus) {
|
||||||
|
|||||||
@@ -10,7 +10,14 @@ export class HawkmoonCombat extends Combat {
|
|||||||
const c = this.combatants.get(cId);
|
const c = this.combatants.get(cId);
|
||||||
console.log("Init for combattant", c, ids)
|
console.log("Init for combattant", c, ids)
|
||||||
let id = c._id || c.id
|
let id = c._id || c.id
|
||||||
let initValue = c.actor ? c.actor.getInitiativeScore() : 0
|
let initValue = 0
|
||||||
|
if (c.actor) {
|
||||||
|
const combat = c.actor.getCombatValues()
|
||||||
|
const roll = await new Roll(`1d10 + ${combat.initTotal}`).roll()
|
||||||
|
await HawkmoonUtility.showDiceSoNice(roll, game.settings.get("core", "rollMode"))
|
||||||
|
initValue = roll.total
|
||||||
|
await c.actor.setFlag("world", "last-initiative", initValue)
|
||||||
|
}
|
||||||
await this.updateEmbeddedDocuments("Combatant", [ { _id: id, initiative: initValue } ]);
|
await this.updateEmbeddedDocuments("Combatant", [ { _id: id, initiative: initValue } ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
||||||
import { HawkmoonRollDialog } from "./hawkmoon-roll-dialog.js";
|
import { HawkmoonRollDialog } from "./applications/hawkmoon-roll-dialog.mjs";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class HawkmoonCommands {
|
export class HawkmoonCommands {
|
||||||
@@ -89,7 +89,7 @@ export class HawkmoonCommands {
|
|||||||
if (command && command.func) {
|
if (command && command.func) {
|
||||||
const result = command.func(content, msg, params);
|
const result = command.func(content, msg, params);
|
||||||
if (result == false) {
|
if (result == false) {
|
||||||
RdDCommands._chatAnswer(msg, command.descr);
|
HawkmoonCommands._chatAnswer(msg, command.descr);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -98,8 +98,8 @@ export class HawkmoonCommands {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async createChar(msg) {
|
async createChar(msg) {
|
||||||
game.system.Hawkmoon.creator = new HawkmoonActorCreate();
|
game.system.hawkmoon.creator = new HawkmoonActorCreate();
|
||||||
game.system.Hawkmoon.creator.start();
|
game.system.hawkmoon.creator.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -116,8 +116,7 @@ export class HawkmoonCommands {
|
|||||||
rollData.mode = "generic"
|
rollData.mode = "generic"
|
||||||
rollData.title = `Dice Pool Roll`;
|
rollData.title = `Dice Pool Roll`;
|
||||||
|
|
||||||
let rollDialog = await HawkmoonRollDialog.create( this, rollData);
|
await HawkmoonRollDialog.create( this, rollData);
|
||||||
rollDialog.render( true );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ export class HawkmoonTokenHud {
|
|||||||
|
|
||||||
const controlIconActions = $(html).find('.control-icon[data-action=combat]');
|
const controlIconActions = $(html).find('.control-icon[data-action=combat]');
|
||||||
// initiative
|
// initiative
|
||||||
await HawkmoonTokenHud._configureSubMenu(controlIconActions, 'systems/fvtt-hawkmoon-cyd/templates/hud-adversites.html', hudData,
|
await HawkmoonTokenHud._configureSubMenu(controlIconActions, 'systems/fvtt-hawkmoon-cyd/templates/hud-adversites.hbs', hudData,
|
||||||
(event) => {
|
(event) => {
|
||||||
let adversite = event.currentTarget.attributes['data-action-index'].value
|
let adversite = event.currentTarget.attributes['data-action-index'].value
|
||||||
let value = Number(event.currentTarget.attributes['data-action-value'].value)
|
let value = Number(event.currentTarget.attributes['data-action-value'].value)
|
||||||
|
|||||||
+86
-19
@@ -9,10 +9,7 @@
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
// Import Modules
|
// Import Modules
|
||||||
import { HawkmoonActor } from "./hawkmoon-actor.js";
|
import { HawkmoonActor } from "./hawkmoon-actor.js";
|
||||||
import { HawkmoonItemSheet } from "./hawkmoon-item-sheet.js";
|
|
||||||
import { HawkmoonActorSheet } from "./hawkmoon-actor-sheet.js";
|
|
||||||
import { HawkmoonCreatureSheet } from "./hawkmoon-creature-sheet.js";
|
|
||||||
import { HawkmoonCelluleSheet } from "./hawkmoon-cellule-sheet.js";
|
|
||||||
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
import { HawkmoonUtility } from "./hawkmoon-utility.js";
|
||||||
import { HawkmoonCombat } from "./hawkmoon-combat.js";
|
import { HawkmoonCombat } from "./hawkmoon-combat.js";
|
||||||
import { HawkmoonItem } from "./hawkmoon-item.js";
|
import { HawkmoonItem } from "./hawkmoon-item.js";
|
||||||
@@ -20,6 +17,12 @@ import { HawkmoonAutomation } from "./hawkmoon-automation.js";
|
|||||||
import { HawkmoonTokenHud } from "./hawkmoon-hud.js";
|
import { HawkmoonTokenHud } from "./hawkmoon-hud.js";
|
||||||
import { HAWKMOON_CONFIG } from "./hawkmoon-config.js";
|
import { HAWKMOON_CONFIG } from "./hawkmoon-config.js";
|
||||||
|
|
||||||
|
// Import DataModels
|
||||||
|
import * as models from "./models/index.mjs";
|
||||||
|
|
||||||
|
// Import AppV2 Item Sheets
|
||||||
|
import * as sheets from "./applications/sheets/_module.mjs";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/* Foundry VTT Initialization */
|
/* Foundry VTT Initialization */
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -48,22 +51,59 @@ Hooks.once("init", async function () {
|
|||||||
// Define custom Entity classes
|
// Define custom Entity classes
|
||||||
CONFIG.Combat.documentClass = HawkmoonCombat
|
CONFIG.Combat.documentClass = HawkmoonCombat
|
||||||
CONFIG.Actor.documentClass = HawkmoonActor
|
CONFIG.Actor.documentClass = HawkmoonActor
|
||||||
|
CONFIG.Actor.dataModels = {
|
||||||
|
personnage: models.PersonnageDataModel,
|
||||||
|
cellule: models.CelluleDataModel,
|
||||||
|
creature: models.CreatureDataModel
|
||||||
|
}
|
||||||
|
|
||||||
CONFIG.Item.documentClass = HawkmoonItem
|
CONFIG.Item.documentClass = HawkmoonItem
|
||||||
|
CONFIG.Item.dataModels = {
|
||||||
|
talent: models.TalentDataModel,
|
||||||
|
historique: models.HistoriqueDataModel,
|
||||||
|
profil: models.ProfilDataModel,
|
||||||
|
competence: models.CompetenceDataModel,
|
||||||
|
arme: models.ArmeDataModel,
|
||||||
|
protection: models.ProtectionDataModel,
|
||||||
|
monnaie: models.MonnaieDataModel,
|
||||||
|
equipement: models.EquipementDataModel,
|
||||||
|
artefact: models.ArtefactDataModel,
|
||||||
|
ressource: models.RessourceDataModel,
|
||||||
|
contact: models.ContactDataModel,
|
||||||
|
mutation: models.MutationDataModel
|
||||||
|
}
|
||||||
|
|
||||||
|
CONFIG.HAWKMOON = HAWKMOON_CONFIG
|
||||||
|
|
||||||
game.system.hawkmoon = {
|
game.system.hawkmoon = {
|
||||||
HawkmoonUtility,
|
HawkmoonUtility,
|
||||||
HawkmoonAutomation,
|
HawkmoonAutomation,
|
||||||
config : HAWKMOON_CONFIG
|
config: HAWKMOON_CONFIG,
|
||||||
|
models,
|
||||||
|
sheets
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
// Regster sheet application classes
|
// Register sheet application classes
|
||||||
foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet);
|
foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet);
|
||||||
foundry.documents.collections.Actors.registerSheet("fvtt-hawkmoon-cyd", HawkmoonActorSheet, { types: ["personnage"], makeDefault: true })
|
foundry.documents.collections.Actors.registerSheet("fvtt-hawkmoon-cyd", sheets.HawkmoonPersonnageSheet, { types: ["personnage"], makeDefault: true })
|
||||||
foundry.documents.collections.Actors.registerSheet("fvtt-hawkmoon-cyd", HawkmoonCreatureSheet, { types: ["creature"], makeDefault: true })
|
foundry.documents.collections.Actors.registerSheet("fvtt-hawkmoon-cyd", sheets.HawkmoonCreatureSheet, { types: ["creature"], makeDefault: true })
|
||||||
foundry.documents.collections.Actors.registerSheet("fvtt-hawkmoon-cyd", HawkmoonCelluleSheet, { types: ["cellule"], makeDefault: true });
|
foundry.documents.collections.Actors.registerSheet("fvtt-hawkmoon-cyd", sheets.HawkmoonCelluleSheet, { types: ["cellule"], makeDefault: true });
|
||||||
|
|
||||||
|
// Register AppV2 Item Sheets
|
||||||
foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet);
|
foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet);
|
||||||
foundry.documents.collections.Items.registerSheet("fvtt-hawkmoon-cyd", HawkmoonItemSheet, { makeDefault: true })
|
foundry.documents.collections.Items.registerSheet("fvtt-hawkmoon-cyd", sheets.HawkmoonTalentSheet, { types: ["talent"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-hawkmoon-cyd", sheets.HawkmoonCompetenceSheet, { types: ["competence"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-hawkmoon-cyd", sheets.HawkmoonArmeSheet, { types: ["arme"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-hawkmoon-cyd", sheets.HawkmoonProtectionSheet, { types: ["protection"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-hawkmoon-cyd", sheets.HawkmoonHistoriqueSheet, { types: ["historique"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-hawkmoon-cyd", sheets.HawkmoonProfilSheet, { types: ["profil"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-hawkmoon-cyd", sheets.HawkmoonEquipementSheet, { types: ["equipement"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-hawkmoon-cyd", sheets.HawkmoonMonnaieSheet, { types: ["monnaie"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-hawkmoon-cyd", sheets.HawkmoonArtefactSheet, { types: ["artefact"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-hawkmoon-cyd", sheets.HawkmoonRessourceSheet, { types: ["ressource"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-hawkmoon-cyd", sheets.HawkmoonContactSheet, { types: ["contact"], makeDefault: true })
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-hawkmoon-cyd", sheets.HawkmoonMutationSheet, { types: ["mutation"], makeDefault: true })
|
||||||
|
|
||||||
HawkmoonUtility.init()
|
HawkmoonUtility.init()
|
||||||
HawkmoonAutomation.init()
|
HawkmoonAutomation.init()
|
||||||
@@ -76,12 +116,39 @@ function welcomeMessage() {
|
|||||||
ChatMessage.create({
|
ChatMessage.create({
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
whisper: [game.user.id],
|
whisper: [game.user.id],
|
||||||
content: `<div id="welcome-message-Hawkmoon"><span class="rdd-roll-part">
|
content: `
|
||||||
<strong>Bienvenue dans Hawkmoon et le troisième Millénaire !</strong>
|
<div class="hawkmoon-chat-result">
|
||||||
<p>Les livres de Hawkmoon sont nécessaires pour jouer : https://www.titam-france.fr</p>
|
<div class="chat-result-header">
|
||||||
<p>Hawkmoon est jeu de rôle publié par Titam France/Sombres projets, tout les droits leur appartiennent.</p>
|
<img class="actor-icon" src="systems/fvtt-hawkmoon-cyd/assets/logos/hawkmoon_logo.webp" alt="Hawkmoon" />
|
||||||
<p>Système développé par LeRatierBretonnien, support sur le <a href="https://discord.gg/pPSDNJk">Discord FR de Foundry</a>.</p>
|
<div class="header-info">
|
||||||
` });
|
<h4 class="actor-name">Bienvenue dans Hawkmoon !</h4>
|
||||||
|
<div class="action-title">
|
||||||
|
<i class="fas fa-book-open"></i>
|
||||||
|
Le Troisième Millénaire
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="result-details">
|
||||||
|
<div class="details-section">
|
||||||
|
<h5 class="section-title"><i class="fas fa-info-circle"></i> Informations importantes</h5>
|
||||||
|
<div class="description-content">
|
||||||
|
<p><strong>Les livres de Hawkmoon sont nécessaires pour jouer.</strong></p>
|
||||||
|
<p>Hawkmoon est un jeu de rôle publié par <strong>Titam France / Sombres projets</strong>, tous les droits leur appartiennent.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="details-section">
|
||||||
|
<h5 class="section-title"><i class="fas fa-users"></i> Support & Communauté</h5>
|
||||||
|
<div class="description-content">
|
||||||
|
<p>Système développé par <strong>LeRatierBretonnien</strong></p>
|
||||||
|
<p>Support disponible sur le <a href="https://discord.gg/pPSDNJk" target="_blank" style="color: #d4af37; text-decoration: underline;">Discord FR de Foundry VTT</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -113,10 +180,10 @@ Hooks.once("ready", function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
import("https://www.uberwald.me/fvtt_appcount/count-class-ready.js").then(moduleCounter=>{
|
import("https://www.uberwald.me/fvtt_appcount/count-class-ready.js").then(moduleCounter => {
|
||||||
console.log("ClassCounter loaded", moduleCounter)
|
console.log("ClassCounter loaded", moduleCounter)
|
||||||
moduleCounter.ClassCounter.registerUsageCount()
|
moduleCounter.ClassCounter.registerUsageCount()
|
||||||
}).catch(err=>
|
}).catch(err =>
|
||||||
console.log("No stats available, giving up.")
|
console.log("No stats available, giving up.")
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -132,7 +199,7 @@ Hooks.on("chatMessage", (html, content, msg) => {
|
|||||||
if (content[0] == '/') {
|
if (content[0] == '/') {
|
||||||
let regExp = /(\S+)/g;
|
let regExp = /(\S+)/g;
|
||||||
let commands = content.match(regExp);
|
let commands = content.match(regExp);
|
||||||
if (game.system.mournblade.commands.processChatCommand(commands, content, msg)) {
|
if (game.system.hawkmoon.commands.processChatCommand(commands, content, msg)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+104
-40
@@ -104,15 +104,42 @@ export class HawkmoonUtility {
|
|||||||
return this.skills
|
return this.skills
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static updatePauseLogo(html) {
|
||||||
|
const validLogos = ["hawkmoon_logo", "logo_pause_resistance", "logo_pause_hawkmoon_stone", "logo_pause_hawkmoon_violet", "logo_pause_hawkmoon_beige", "logo_pause_hawkmoon_rouge"];
|
||||||
|
let logoName = game.settings.get("fvtt-hawkmoon-cyd", "hawkmoon-pause-logo");
|
||||||
|
|
||||||
|
// Validation du nom du logo
|
||||||
|
if (!validLogos.includes(logoName)) {
|
||||||
|
console.error("Hawkmoon | Invalid logo name:", logoName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let logoPause = "systems/fvtt-hawkmoon-cyd/assets/logos/" + logoName + ".webp";
|
||||||
|
console.log("Hawkmoon | Updating pause logo to:", logoPause);
|
||||||
|
|
||||||
|
// Supprimer l'ancien style s'il existe
|
||||||
|
let oldStyle = document.getElementById('hawkmoon-pause-logo-override')
|
||||||
|
if (oldStyle) {
|
||||||
|
oldStyle.remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Injecter une règle CSS pour override le logo
|
||||||
|
let styleSheet = document.createElement('style')
|
||||||
|
styleSheet.id = 'hawkmoon-pause-logo-override'
|
||||||
|
styleSheet.textContent = `#pause>img { content: url(${logoPause}) !important; }`
|
||||||
|
document.head.appendChild(styleSheet)
|
||||||
|
|
||||||
|
console.log("Hawkmoon | Logo CSS rule injected")
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async ready() {
|
static async ready() {
|
||||||
const skills = await HawkmoonUtility.loadCompendium("fvtt-hawkmoon-cyd.skills")
|
const skills = await HawkmoonUtility.loadCompendium("fvtt-hawkmoon-cyd.skills")
|
||||||
this.skills = skills.map(i => i.toObject())
|
this.skills = skills.map(i => i.toObject())
|
||||||
|
|
||||||
// Setup pause logo
|
// Setup pause logo
|
||||||
let logoPause = "systems/fvtt-hawkmoon-cyd/assets/logos/" + game.settings.get("fvtt-hawkmoon-cyd", "hawkmoon-pause-logo") + ".webp"
|
this.updatePauseLogo()
|
||||||
let logoImg = document.querySelector('#pause').children[0]
|
|
||||||
logoImg.setAttribute('style', `content: url(${logoPause})`)
|
|
||||||
|
|
||||||
game.system.hawkmoon.config.listeNiveauSkill = this.createDirectOptionList(0, 10)
|
game.system.hawkmoon.config.listeNiveauSkill = this.createDirectOptionList(0, 10)
|
||||||
game.system.hawkmoon.config.listeNiveauCreature = this.createDirectOptionList(0, 35)
|
game.system.hawkmoon.config.listeNiveauCreature = this.createDirectOptionList(0, 35)
|
||||||
@@ -120,13 +147,6 @@ export class HawkmoonUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static createDirectOptionList(min, max) {
|
|
||||||
let options = {};
|
|
||||||
for (let i = min; i <= max; i++) {
|
|
||||||
options[`${i}`] = `${i}`;
|
|
||||||
}
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
static createArrayOptionList(min, max) {
|
static createArrayOptionList(min, max) {
|
||||||
let options = [];
|
let options = [];
|
||||||
for (let i = min; i <= max; i++) {
|
for (let i = min; i <= max; i++) {
|
||||||
@@ -143,8 +163,19 @@ export class HawkmoonUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async loadCompendium(compendium, filter = item => true) {
|
static async loadCompendium(compendium, filter = item => true) {
|
||||||
let compendiumData = await HawkmoonUtility.loadCompendiumData(compendium);
|
const pack = game.packs.get(compendium);
|
||||||
return compendiumData.filter(filter);
|
if (!pack) {
|
||||||
|
console.warn(`Hawkmoon | Compendium not found: ${compendium}`);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const compendiumData = await pack.getDocuments();
|
||||||
|
return compendiumData.filter(filter);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Hawkmoon | Error loading compendium ${compendium}:`, error);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -187,13 +218,13 @@ export class HawkmoonUtility {
|
|||||||
static async preloadHandlebarsTemplates() {
|
static async preloadHandlebarsTemplates() {
|
||||||
|
|
||||||
const templatePaths = [
|
const templatePaths = [
|
||||||
'systems/fvtt-hawkmoon-cyd/templates/editor-notes-gm.html',
|
'systems/fvtt-hawkmoon-cyd/templates/editor-notes-gm.hbs',
|
||||||
'systems/fvtt-hawkmoon-cyd/templates/partial-item-header.html',
|
'systems/fvtt-hawkmoon-cyd/templates/partial-item-header.hbs',
|
||||||
'systems/fvtt-hawkmoon-cyd/templates/partial-item-description.html',
|
'systems/fvtt-hawkmoon-cyd/templates/partial-item-description.hbs',
|
||||||
'systems/fvtt-hawkmoon-cyd/templates/partial-item-nav.html',
|
'systems/fvtt-hawkmoon-cyd/templates/partial-item-nav.hbs',
|
||||||
'systems/fvtt-hawkmoon-cyd/templates/partial-item-prix.html',
|
'systems/fvtt-hawkmoon-cyd/templates/partial-item-prix.hbs',
|
||||||
'systems/fvtt-hawkmoon-cyd/templates/partial-automation.html',
|
'systems/fvtt-hawkmoon-cyd/templates/partial-automation.hbs',
|
||||||
'systems/fvtt-hawkmoon-cyd/templates/hud-adversites.html',
|
'systems/fvtt-hawkmoon-cyd/templates/hud-adversites.hbs',
|
||||||
]
|
]
|
||||||
return foundry.applications.handlebars.loadTemplates(templatePaths);
|
return foundry.applications.handlebars.loadTemplates(templatePaths);
|
||||||
}
|
}
|
||||||
@@ -247,11 +278,14 @@ export class HawkmoonUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getTarget() {
|
static getTarget() {
|
||||||
if (game.user.targets && game.user.targets.size == 1) {
|
console.log("getTarget - targets size:", game.user.targets?.size)
|
||||||
|
if (game.user.targets && game.user.targets.size >= 1) {
|
||||||
for (let target of game.user.targets) {
|
for (let target of game.user.targets) {
|
||||||
return target;
|
console.log("getTarget - Returning target:", target.id)
|
||||||
|
return target; // Prendre la première cible si plusieurs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
console.log("getTarget - No target found")
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,11 +379,17 @@ export class HawkmoonUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static computeResult(rollData) {
|
static computeResult(rollData) {
|
||||||
|
// Validation des données de roll
|
||||||
|
if (!rollData.roll?.terms?.[0]?.results?.[0]?.result) {
|
||||||
|
console.error("Hawkmoon | Invalid roll data:", rollData);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rollData.diceResult = rollData.roll.terms[0].results[0].result
|
rollData.diceResult = rollData.roll.terms[0].results[0].result
|
||||||
if (rollData.mainDice.includes("d20")) {
|
if (rollData.mainDice.includes("d20")) {
|
||||||
let diceValue = rollData.roll.terms[0].results[0].result
|
let diceValue = rollData.roll.terms[0].results[0].result
|
||||||
if (diceValue % 2 == 1) {
|
if (diceValue % 2 == 1) {
|
||||||
//console.log("PAIR/IMP2", diceValue)
|
rollData.isD20Impair = true
|
||||||
rollData.finalResult -= rollData.roll.terms[0].results[0].result // Substract value
|
rollData.finalResult -= rollData.roll.terms[0].results[0].result // Substract value
|
||||||
if (diceValue == 1 || diceValue == 11) {
|
if (diceValue == 1 || diceValue == 11) {
|
||||||
rollData.isDramatique = true
|
rollData.isDramatique = true
|
||||||
@@ -358,7 +398,6 @@ export class HawkmoonUtility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.log("Result : ", rollData
|
|
||||||
this.computeResultQuality(rollData)
|
this.computeResultQuality(rollData)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,8 +413,8 @@ export class HawkmoonUtility {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static applyCombativite(rollData, value) {
|
static applyCombativite(rollData, value) {
|
||||||
if (game.user.isGM) {
|
if (game.user.isGM) {
|
||||||
let defender = game.canvas.tokens.get(rollData.defenderTokenId).actor
|
let defender = game.canvas.tokens.get(rollData.defenderTokenId)?.actor
|
||||||
defender.changeEtatCombativite(value)
|
defender?.changeEtatCombativite(value)
|
||||||
} else {
|
} else {
|
||||||
game.socket.emit("system.fvtt-hawkmoon-cyd", { msg: "msg_apply_combativite", data: { defenderTokenId: rollData.defenderTokenId, value } });
|
game.socket.emit("system.fvtt-hawkmoon-cyd", { msg: "msg_apply_combativite", data: { defenderTokenId: rollData.defenderTokenId, value } });
|
||||||
}
|
}
|
||||||
@@ -425,11 +464,13 @@ export class HawkmoonUtility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rollData.diceFormula += `+${rollData.bonusMalusContext}`
|
|
||||||
} else if (rollData.attr2) {
|
} else if (rollData.attr2) {
|
||||||
rollData.diceFormula += `+${rollData.attr.value}+${rollData.attr2.value}+${rollData.modificateur}+${rollData.bonusMalusContext}`
|
rollData.diceFormula += `+${rollData.attr.value}+${rollData.attr2.value}+${rollData.modificateur}`
|
||||||
} else {
|
} else {
|
||||||
rollData.diceFormula += `+${rollData.attr.value}*${rollData.multiplier}+${rollData.modificateur}+${rollData.bonusMalusContext}`
|
rollData.diceFormula += `+${rollData.attr.value}*${rollData.multiplier}+${rollData.modificateur}`
|
||||||
|
if (rollData.isInit && rollData.initbonus) {
|
||||||
|
rollData.diceFormula += `+${rollData.initbonus}`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bonus arme naturelle en défense
|
// Bonus arme naturelle en défense
|
||||||
@@ -508,15 +549,15 @@ export class HawkmoonUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.createChatWithRollMode(rollData.alias, {
|
this.createChatWithRollMode(rollData.alias, {
|
||||||
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-hawkmoon-cyd/templates/chat-generic-result.html`, rollData)
|
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-hawkmoon-cyd/templates/chat-generic-result.hbs`, rollData)
|
||||||
}, rollData)
|
}, rollData)
|
||||||
|
|
||||||
if ((rollData.coupBas || rollData.arme) && rollData.isSuccess && rollData.defenderTokenId) {
|
if ((rollData.coupBas || rollData.arme) && rollData.isSuccess && rollData.defenderTokenId) {
|
||||||
this.applyCombativite(rollData, rollData.nbCombativitePerdu)
|
this.applyCombativite(rollData, rollData.nbCombativitePerdu)
|
||||||
}
|
}
|
||||||
if (rollData.coupBas && rollData.isSuccess && rollData.defenderTokenId) {
|
if (rollData.coupBas && rollData.isSuccess && rollData.defenderTokenId) {
|
||||||
let defender = game.canvas.tokens.get(rollData.defenderTokenId).actor
|
let defender = game.canvas.tokens.get(rollData.defenderTokenId)?.actor
|
||||||
defender.incDecAdversite("bleue", -2)
|
defender?.incDecAdversite("bleue", -2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,7 +591,7 @@ export class HawkmoonUtility {
|
|||||||
this.computeResultQuality(rollData)
|
this.computeResultQuality(rollData)
|
||||||
|
|
||||||
this.createChatWithRollMode(rollData.alias, {
|
this.createChatWithRollMode(rollData.alias, {
|
||||||
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-hawkmoon-cyd/templates/chat-generic-result.html`, rollData)
|
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-hawkmoon-cyd/templates/chat-generic-result.hbs`, rollData)
|
||||||
}, rollData)
|
}, rollData)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -633,9 +674,13 @@ export class HawkmoonUtility {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
chatOptions.alias = chatOptions.alias || name
|
chatOptions.alias = chatOptions.alias || name
|
||||||
|
|
||||||
|
// Ajouter le flag directement dans les options pour éviter les problèmes de timing
|
||||||
|
if (rollData) {
|
||||||
|
chatOptions.flags = { world: { "hawkmoon-roll": rollData } }
|
||||||
|
}
|
||||||
|
|
||||||
let msg = await ChatMessage.create(chatOptions)
|
let msg = await ChatMessage.create(chatOptions)
|
||||||
console.log("=======>", rollData)
|
|
||||||
msg.setFlag("world", "hawkmoon-roll", rollData)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -646,8 +691,7 @@ export class HawkmoonUtility {
|
|||||||
modificateursOptions: this.getModificateurOptions(),
|
modificateursOptions: this.getModificateurOptions(),
|
||||||
pointAmeOptions: this.getPointAmeOptions(),
|
pointAmeOptions: this.getPointAmeOptions(),
|
||||||
difficulte: 0,
|
difficulte: 0,
|
||||||
modificateur: 0,
|
modificateur: "0",
|
||||||
bonusMalusContext: 0,
|
|
||||||
bonusArmeNaturelle: 0,
|
bonusArmeNaturelle: 0,
|
||||||
defenseurAveugle: false,
|
defenseurAveugle: false,
|
||||||
defenseurDeDos: false,
|
defenseurDeDos: false,
|
||||||
@@ -658,6 +702,8 @@ export class HawkmoonUtility {
|
|||||||
tireurDeplacement: "immobile",
|
tireurDeplacement: "immobile",
|
||||||
cibleCouvert: "aucun",
|
cibleCouvert: "aucun",
|
||||||
distanceTir: "porteemoyenne",
|
distanceTir: "porteemoyenne",
|
||||||
|
cibleDeplace: false,
|
||||||
|
cibleCaC: false,
|
||||||
attaqueCharge: false,
|
attaqueCharge: false,
|
||||||
attaqueDesarme: false,
|
attaqueDesarme: false,
|
||||||
attaqueAmbidextre1: false,
|
attaqueAmbidextre1: false,
|
||||||
@@ -672,10 +718,19 @@ export class HawkmoonUtility {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static updateWithTarget(rollData) {
|
static updateWithTarget(rollData) {
|
||||||
let target = HawkmoonUtility.getTarget()
|
let target = HawkmoonUtility.getTarget()
|
||||||
|
console.log("updateWithTarget - Current target:", target)
|
||||||
|
console.log("updateWithTarget - Existing defenderTokenId:", rollData.defenderTokenId)
|
||||||
if (target) {
|
if (target) {
|
||||||
rollData.defenderTokenId = target.id
|
rollData.defenderTokenId = target.id
|
||||||
let defender = game.canvas.tokens.get(rollData.defenderTokenId).actor
|
console.log("updateWithTarget - Set defenderTokenId to:", rollData.defenderTokenId)
|
||||||
|
}
|
||||||
|
// Utiliser la cible déjà enregistrée si aucune cible n'est actuellement sélectionnée
|
||||||
|
if (rollData.defenderTokenId) {
|
||||||
|
let defender = game.canvas.tokens.get(rollData.defenderTokenId)?.actor
|
||||||
|
if (!defender) return
|
||||||
|
console.log("updateWithTarget - Defender actor:", defender.name)
|
||||||
rollData.armeDefense = defender.getBestDefenseValue()
|
rollData.armeDefense = defender.getBestDefenseValue()
|
||||||
|
console.log("updateWithTarget - armeDefense:", rollData.armeDefense)
|
||||||
rollData.armeAttaqueDefenseur = defender.getBestAttackValue()
|
rollData.armeAttaqueDefenseur = defender.getBestAttackValue()
|
||||||
rollData.targetVigueur = defender.getVigueur()
|
rollData.targetVigueur = defender.getVigueur()
|
||||||
rollData.protectionDefenseur = defender.getProtection()
|
rollData.protectionDefenseur = defender.getProtection()
|
||||||
@@ -691,14 +746,23 @@ export class HawkmoonUtility {
|
|||||||
rollData.difficulte = rollData.armeAttaqueDefenseur?.system?.totalOffensif || 0;
|
rollData.difficulte = rollData.armeAttaqueDefenseur?.system?.totalOffensif || 0;
|
||||||
} else if (rollData.armeDefense) {
|
} else if (rollData.armeDefense) {
|
||||||
rollData.difficulte = rollData.armeDefense.system.totalDefensif
|
rollData.difficulte = rollData.armeDefense.system.totalDefensif
|
||||||
if (!rollData.desengager && !rollData.arme.system.armenaturelle && !rollData.arme.system.armefortune) {
|
console.log("updateWithTarget - Calculated difficulte from armeDefense:", rollData.difficulte)
|
||||||
|
if (rollData.arme && !rollData.desengager && !rollData.arme.system.armenaturelle && !rollData.arme.system.armefortune) {
|
||||||
if (rollData.armeDefense.system.armenaturelle || rollData.armeDefense.system.armefortune) {
|
if (rollData.armeDefense.system.armenaturelle || rollData.armeDefense.system.armefortune) {
|
||||||
rollData.bonusArmeNaturelle = 3
|
rollData.bonusArmeNaturelle = 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (rollData.arme?.system.isDistance) {
|
||||||
|
// Pour les armes à distance, calculer la difficulté de base (protection + distance par défaut)
|
||||||
|
const distanceValues = { "porteecourte": 5, "porteemoyenne": 9, "porteelongue": 14 }
|
||||||
|
rollData.difficulte = rollData.protectionDefenseur + distanceValues[rollData.distanceTir || "porteemoyenne"]
|
||||||
|
console.log("updateWithTarget - Calculated difficulte for ranged:", rollData.difficulte, "= protection", rollData.protectionDefenseur, "+ distance", distanceValues[rollData.distanceTir || "porteemoyenne"])
|
||||||
} else {
|
} else {
|
||||||
|
console.log("updateWithTarget - No armeDefense found!")
|
||||||
ui.notifications.warn("Aucune arme de défense équipée, difficulté manuelle à positionner.")
|
ui.notifications.warn("Aucune arme de défense équipée, difficulté manuelle à positionner.")
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
console.log("updateWithTarget - No defenderTokenId, skipping target calculations")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -789,7 +853,7 @@ export class HawkmoonUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async confirmDelete(actorSheet, li) {
|
static async confirmDelete(actorSheet, li) {
|
||||||
let itemId = li.data("item-id");
|
let itemId = li.dataset.itemId;
|
||||||
let msgTxt = "<p>Etes vous certain de vouloir supprimer cet item ?";
|
let msgTxt = "<p>Etes vous certain de vouloir supprimer cet item ?";
|
||||||
let buttons = {
|
let buttons = {
|
||||||
delete: {
|
delete: {
|
||||||
@@ -797,7 +861,7 @@ export class HawkmoonUtility {
|
|||||||
label: "Oui !",
|
label: "Oui !",
|
||||||
callback: () => {
|
callback: () => {
|
||||||
actorSheet.actor.deleteEmbeddedDocuments("Item", [itemId]);
|
actorSheet.actor.deleteEmbeddedDocuments("Item", [itemId]);
|
||||||
li.slideUp(200, () => actorSheet.render(false));
|
actorSheet.render(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
cancel: {
|
cancel: {
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les armes
|
||||||
|
*/
|
||||||
|
export default class ArmeDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
prixpo: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prixca: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prixsc: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
rarete: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
quantite: new fields.NumberField({ initial: 1, integer: true }),
|
||||||
|
equipped: new fields.BooleanField({ initial: false }),
|
||||||
|
typearme: new fields.StringField({ initial: "" }),
|
||||||
|
armenaturelle: new fields.BooleanField({ initial: false }),
|
||||||
|
armefortune: new fields.BooleanField({ initial: false }),
|
||||||
|
bonusmaniementoff: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
seuildefense: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
onlevelonly: new fields.BooleanField({ initial: false }),
|
||||||
|
degats: new fields.StringField({ initial: "" }),
|
||||||
|
deuxmains: new fields.BooleanField({ initial: false }),
|
||||||
|
percearmure: new fields.BooleanField({ initial: false }),
|
||||||
|
percearmurevalue: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
courte: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
moyenne: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
longue: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
tr: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les artefacts
|
||||||
|
*/
|
||||||
|
export default class ArtefactDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
prixpo: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prixca: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prixsc: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
rarete: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
quantite: new fields.NumberField({ initial: 1, integer: true }),
|
||||||
|
equipped: new fields.BooleanField({ initial: false }),
|
||||||
|
complexite: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
branche: new fields.StringField({ initial: "" }),
|
||||||
|
branche2: new fields.StringField({ initial: "none" }),
|
||||||
|
dureerealisation: new fields.StringField({ initial: "" }),
|
||||||
|
tempsroute: new fields.StringField({ initial: "" }),
|
||||||
|
effetdejeu: new fields.StringField({ initial: "" }),
|
||||||
|
defautcourant: new fields.StringField({ initial: "" }),
|
||||||
|
autrescarac: new fields.StringField({ initial: "" }),
|
||||||
|
avantagespossibles: new fields.StringField({ initial: "" }),
|
||||||
|
avantages: new fields.StringField({ initial: "" }),
|
||||||
|
competences: new fields.StringField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* Template de base pour tous les items
|
||||||
|
*/
|
||||||
|
export class BaseItemModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template pour les équipements de base
|
||||||
|
*/
|
||||||
|
export class BaseEquipItemModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
prixpo: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prixca: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prixsc: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
rarete: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
quantite: new fields.NumberField({ initial: 1, integer: true }),
|
||||||
|
equipped: new fields.BooleanField({ initial: false })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template pour l'automatisation
|
||||||
|
*/
|
||||||
|
export class AutomationItemModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
isautomated: new fields.BooleanField({ initial: false }),
|
||||||
|
automations: new fields.ArrayField(
|
||||||
|
new fields.SchemaField({
|
||||||
|
id: new fields.StringField({ initial: "" }),
|
||||||
|
eventtype: new fields.StringField({ initial: "on-drop" }),
|
||||||
|
name: new fields.StringField({ initial: "" }),
|
||||||
|
bonusname: new fields.StringField({ initial: "vigueur" }),
|
||||||
|
bonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
competence: new fields.StringField({ initial: "" }),
|
||||||
|
minLevel: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
baCost: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
{ initial: [] }
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les cellules
|
||||||
|
*/
|
||||||
|
export default class CelluleDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
notoriete: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
resistance: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
developpement: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
members: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
description: new fields.HTMLField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les compétences
|
||||||
|
*/
|
||||||
|
export default class CompetenceDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
niveau: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
attribut1: new fields.StringField({ initial: "" }),
|
||||||
|
attribut2: new fields.StringField({ initial: "" }),
|
||||||
|
attribut3: new fields.StringField({ initial: "" }),
|
||||||
|
doublebonus: new fields.BooleanField({ initial: false }),
|
||||||
|
predilections: new fields.ArrayField(
|
||||||
|
new fields.SchemaField({
|
||||||
|
id: new fields.StringField({ initial: "" }),
|
||||||
|
name: new fields.StringField({ initial: "" }),
|
||||||
|
description: new fields.StringField({ initial: "" }),
|
||||||
|
acquise: new fields.BooleanField({ initial: false }),
|
||||||
|
maitrise: new fields.BooleanField({ initial: false }),
|
||||||
|
used: new fields.BooleanField({ initial: false })
|
||||||
|
}),
|
||||||
|
{ initial: [] }
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les contacts
|
||||||
|
*/
|
||||||
|
export default class ContactDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
contacttype: new fields.StringField({ initial: "" }),
|
||||||
|
niveau: new fields.StringField({ initial: "" }),
|
||||||
|
pointdev: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
description: new fields.HTMLField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les créatures
|
||||||
|
*/
|
||||||
|
export default class CreatureDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
// Template biodata
|
||||||
|
biodata: new fields.SchemaField({
|
||||||
|
name: new fields.StringField({ initial: "" }),
|
||||||
|
age: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
poids: new fields.StringField({ initial: "" }),
|
||||||
|
taille: new fields.StringField({ initial: "" }),
|
||||||
|
cheveux: new fields.StringField({ initial: "" }),
|
||||||
|
sexe: new fields.StringField({ initial: "" }),
|
||||||
|
yeux: new fields.StringField({ initial: "" }),
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
habitat: new fields.HTMLField({ initial: "" }),
|
||||||
|
notes: new fields.HTMLField({ initial: "" }),
|
||||||
|
statut: new fields.StringField({ initial: "" }),
|
||||||
|
gmnotes: new fields.HTMLField({ initial: "" }),
|
||||||
|
statutresistant: new fields.StringField({ initial: "commun" })
|
||||||
|
}),
|
||||||
|
// Template core
|
||||||
|
subactors: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
attributs: new fields.SchemaField({
|
||||||
|
adr: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Adresse" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "adresse" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "adr" }),
|
||||||
|
value: new fields.NumberField({ initial: 1, integer: true })
|
||||||
|
}),
|
||||||
|
pui: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Puissance" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "puissance" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "pui" }),
|
||||||
|
value: new fields.NumberField({ initial: 1, integer: true })
|
||||||
|
}),
|
||||||
|
cla: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Clairvoyance" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "clairvoyance" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "cla" }),
|
||||||
|
value: new fields.NumberField({ initial: 1, integer: true })
|
||||||
|
}),
|
||||||
|
pre: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Présence" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "presence" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "pre" }),
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
tre: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Trempe" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "trempe" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "tre" }),
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
bonneaventure: new fields.SchemaField({
|
||||||
|
base: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
actuelle: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
experience: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
eclat: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
sante: new fields.SchemaField({
|
||||||
|
vigueur: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
etat: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
vigueurmodifier: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
nbcombativite: new fields.NumberField({ initial: 5, integer: true })
|
||||||
|
}),
|
||||||
|
adversite: new fields.SchemaField({
|
||||||
|
bleue: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
rouge: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
noire: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
vitesse: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
combat: new fields.SchemaField({
|
||||||
|
initbonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
vitessebonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
bonusdegats: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
attaquebonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
defensebonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
defensetotale: new fields.BooleanField({ initial: false }),
|
||||||
|
monte: new fields.BooleanField({ initial: false })
|
||||||
|
}),
|
||||||
|
// Propriétés spécifiques aux créatures
|
||||||
|
ressources: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour l'équipement
|
||||||
|
*/
|
||||||
|
export default class EquipementDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
prixpo: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prixca: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prixsc: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
rarete: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
quantite: new fields.NumberField({ initial: 1, integer: true }),
|
||||||
|
equipped: new fields.BooleanField({ initial: false })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les historiques
|
||||||
|
*/
|
||||||
|
export default class HistoriqueDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
bonusmalus: new fields.StringField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Index des DataModels pour Hawkmoon CYD
|
||||||
|
* Ce fichier centralise tous les exports des modèles de données
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Modèles d'items
|
||||||
|
export { default as TalentDataModel } from './talent.mjs';
|
||||||
|
export { default as HistoriqueDataModel } from './historique.mjs';
|
||||||
|
export { default as ProfilDataModel } from './profil.mjs';
|
||||||
|
export { default as CompetenceDataModel } from './competence.mjs';
|
||||||
|
export { default as ArmeDataModel } from './arme.mjs';
|
||||||
|
export { default as ProtectionDataModel } from './protection.mjs';
|
||||||
|
export { default as MonnaieDataModel } from './monnaie.mjs';
|
||||||
|
export { default as EquipementDataModel } from './equipement.mjs';
|
||||||
|
export { default as ArtefactDataModel } from './artefact.mjs';
|
||||||
|
export { default as RessourceDataModel } from './ressource.mjs';
|
||||||
|
export { default as ContactDataModel } from './contact.mjs';
|
||||||
|
export { default as MutationDataModel } from './mutation.mjs';
|
||||||
|
|
||||||
|
// Modèles d'acteurs
|
||||||
|
export { default as PersonnageDataModel } from './personnage.mjs';
|
||||||
|
export { default as CelluleDataModel } from './cellule.mjs';
|
||||||
|
export { default as CreatureDataModel } from './creature.mjs';
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les monnaies
|
||||||
|
*/
|
||||||
|
export default class MonnaieDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
prixpo: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prixca: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prixsc: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
rarete: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
quantite: new fields.NumberField({ initial: 1, integer: true }),
|
||||||
|
equipped: new fields.BooleanField({ initial: false })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les mutations
|
||||||
|
*/
|
||||||
|
export default class MutationDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
mutationcategorie: new fields.StringField({ initial: "tares_communes" }),
|
||||||
|
hascomplexite: new fields.BooleanField({ initial: false }),
|
||||||
|
complexite: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les personnages
|
||||||
|
*/
|
||||||
|
export default class PersonnageDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
// Template biodata
|
||||||
|
biodata: new fields.SchemaField({
|
||||||
|
name: new fields.StringField({ initial: "" }),
|
||||||
|
age: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
poids: new fields.StringField({ initial: "70" }),
|
||||||
|
taille: new fields.StringField({ initial: "1,80m" }),
|
||||||
|
cheveux: new fields.StringField({ initial: "Brun" }),
|
||||||
|
sexe: new fields.StringField({ initial: "" }),
|
||||||
|
yeux: new fields.StringField({ initial: "Verts" }),
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
habitat: new fields.HTMLField({ initial: "" }),
|
||||||
|
notes: new fields.HTMLField({ initial: "" }),
|
||||||
|
statut: new fields.StringField({ initial: "" }),
|
||||||
|
gmnotes: new fields.HTMLField({ initial: "" }),
|
||||||
|
mainpreferee: new fields.StringField({ initial: "Droite" }),
|
||||||
|
statutresistant: new fields.StringField({ initial: "commun" })
|
||||||
|
}),
|
||||||
|
// Template core
|
||||||
|
subactors: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
attributs: new fields.SchemaField({
|
||||||
|
adr: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Adresse" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "adresse" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "adr" }),
|
||||||
|
value: new fields.NumberField({ initial: 1, integer: true })
|
||||||
|
}),
|
||||||
|
pui: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Puissance" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "puissance" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "pui" }),
|
||||||
|
value: new fields.NumberField({ initial: 1, integer: true })
|
||||||
|
}),
|
||||||
|
cla: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Clairvoyance" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "clairvoyance" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "cla" }),
|
||||||
|
value: new fields.NumberField({ initial: 1, integer: true })
|
||||||
|
}),
|
||||||
|
pre: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Présence" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "presence" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "pre" }),
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
tre: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Trempe" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "trempe" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "tre" }),
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
bonneaventure: new fields.SchemaField({
|
||||||
|
base: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
actuelle: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
experience: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
eclat: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
sante: new fields.SchemaField({
|
||||||
|
vigueur: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
etat: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
vigueurmodifier: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
nbcombativite: new fields.NumberField({ initial: 5, integer: true })
|
||||||
|
}),
|
||||||
|
adversite: new fields.SchemaField({
|
||||||
|
bleue: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
rouge: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
noire: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
vitesse: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
combat: new fields.SchemaField({
|
||||||
|
initbonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
vitessebonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
bonusdegats: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
attaquebonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
defensebonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
defensetotale: new fields.BooleanField({ initial: false }),
|
||||||
|
monte: new fields.BooleanField({ initial: false })
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les profils
|
||||||
|
*/
|
||||||
|
export default class ProfilDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
exemples: new fields.StringField({ initial: "" }),
|
||||||
|
attribut1: new fields.StringField({ initial: "" }),
|
||||||
|
attribut2: new fields.StringField({ initial: "" }),
|
||||||
|
attribut3: new fields.StringField({ initial: "" }),
|
||||||
|
competences: new fields.StringField({ initial: "" }),
|
||||||
|
talentsinitie: new fields.StringField({ initial: "" }),
|
||||||
|
prerequisaguerri: new fields.StringField({ initial: "" }),
|
||||||
|
talentsaguerri: new fields.StringField({ initial: "" }),
|
||||||
|
prerequismaitre: new fields.StringField({ initial: "" }),
|
||||||
|
talentsmaitre: new fields.StringField({ initial: "" }),
|
||||||
|
celluleinfo: new fields.StringField({ initial: "" }),
|
||||||
|
equipement: new fields.StringField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les protections
|
||||||
|
*/
|
||||||
|
export default class ProtectionDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
prixpo: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prixca: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prixsc: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
rarete: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
quantite: new fields.NumberField({ initial: 1, integer: true }),
|
||||||
|
equipped: new fields.BooleanField({ initial: false }),
|
||||||
|
protection: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
adversitepoids: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les ressources
|
||||||
|
*/
|
||||||
|
export default class RessourceDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
pointdev: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
description: new fields.HTMLField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les talents
|
||||||
|
*/
|
||||||
|
export default class TalentDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
isautomated: new fields.BooleanField({ initial: false }),
|
||||||
|
automations: new fields.ArrayField(
|
||||||
|
new fields.SchemaField({
|
||||||
|
id: new fields.StringField({ initial: "" }),
|
||||||
|
eventtype: new fields.StringField({ initial: "on-drop" }),
|
||||||
|
name: new fields.StringField({ initial: "" }),
|
||||||
|
bonusname: new fields.StringField({ initial: "vigueur" }),
|
||||||
|
bonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
competence: new fields.StringField({ initial: "" }),
|
||||||
|
minLevel: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
baCost: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
{ initial: [] }
|
||||||
|
),
|
||||||
|
talenttype: new fields.StringField({ initial: "" }),
|
||||||
|
utilisation: new fields.StringField({ initial: "" }),
|
||||||
|
prerequis: new fields.StringField({ initial: "" }),
|
||||||
|
resumebonus: new fields.StringField({ initial: "" }),
|
||||||
|
used: new fields.BooleanField({ initial: false })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1 +1 @@
|
|||||||
MANIFEST-000301
|
MANIFEST-000439
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
2025/06/24-20:47:28.504597 7f151effd6c0 Recovering log #299
|
2026/05/06-18:00:14.573290 7fd32a7ed6c0 Recovering log #438
|
||||||
2025/06/24-20:47:28.514673 7f151effd6c0 Delete type=3 #297
|
2026/05/06-18:00:14.583030 7fd32a7ed6c0 Delete type=0 #438
|
||||||
2025/06/24-20:47:28.514784 7f151effd6c0 Delete type=0 #299
|
2026/05/06-18:00:14.583082 7fd32a7ed6c0 Delete type=3 #437
|
||||||
2025/06/24-21:03:58.298797 7f151d7fa6c0 Level-0 table #304: started
|
|
||||||
2025/06/24-21:03:58.298835 7f151d7fa6c0 Level-0 table #304: 0 bytes OK
|
|
||||||
2025/06/24-21:03:58.305605 7f151d7fa6c0 Delete type=0 #302
|
|
||||||
2025/06/24-21:03:58.316223 7f151d7fa6c0 Manual compaction at level-0 from '!journal!MUbViCE2PkVxlzqe' @ 72057594037927935 : 1 .. '!journal.pages!gVybbv17TFY8o3Y4.fQidyqfF1TbsZKHM' @ 0 : 0; will stop at (end)
|
|
||||||
2025/06/24-21:03:58.316257 7f151d7fa6c0 Manual compaction at level-1 from '!journal!MUbViCE2PkVxlzqe' @ 72057594037927935 : 1 .. '!journal.pages!gVybbv17TFY8o3Y4.fQidyqfF1TbsZKHM' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
2025/06/03-13:26:59.527706 7f53dffff6c0 Recovering log #295
|
2026/05/06-17:43:45.593194 7f13097ed6c0 Recovering log #436
|
||||||
2025/06/03-13:26:59.538330 7f53dffff6c0 Delete type=3 #293
|
2026/05/06-17:43:45.603829 7f13097ed6c0 Delete type=0 #436
|
||||||
2025/06/03-13:26:59.538407 7f53dffff6c0 Delete type=0 #295
|
2026/05/06-17:43:45.603909 7f13097ed6c0 Delete type=3 #435
|
||||||
2025/06/03-13:30:56.587918 7f53df3ff6c0 Level-0 table #300: started
|
|
||||||
2025/06/03-13:30:56.587964 7f53df3ff6c0 Level-0 table #300: 0 bytes OK
|
|
||||||
2025/06/03-13:30:56.617514 7f53df3ff6c0 Delete type=0 #298
|
|
||||||
2025/06/03-13:30:56.714892 7f53df3ff6c0 Manual compaction at level-0 from '!journal!MUbViCE2PkVxlzqe' @ 72057594037927935 : 1 .. '!journal.pages!gVybbv17TFY8o3Y4.fQidyqfF1TbsZKHM' @ 0 : 0; will stop at (end)
|
|
||||||
2025/06/03-13:30:56.715021 7f53df3ff6c0 Manual compaction at level-1 from '!journal!MUbViCE2PkVxlzqe' @ 72057594037927935 : 1 .. '!journal.pages!gVybbv17TFY8o3Y4.fQidyqfF1TbsZKHM' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
+1
-1
@@ -1 +1 @@
|
|||||||
MANIFEST-000300
|
MANIFEST-000434
|
||||||
|
|||||||
+3
-8
@@ -1,8 +1,3 @@
|
|||||||
2025/06/24-20:47:28.375708 7f151effd6c0 Recovering log #298
|
2026/05/02-22:53:14.438750 7f09889fd6c0 Recovering log #433
|
||||||
2025/06/24-20:47:28.385573 7f151effd6c0 Delete type=3 #296
|
2026/05/02-22:53:14.491497 7f09889fd6c0 Delete type=0 #433
|
||||||
2025/06/24-20:47:28.385688 7f151effd6c0 Delete type=0 #298
|
2026/05/02-22:53:14.491560 7f09889fd6c0 Delete type=3 #432
|
||||||
2025/06/24-21:03:58.229253 7f151d7fa6c0 Level-0 table #303: started
|
|
||||||
2025/06/24-21:03:58.229277 7f151d7fa6c0 Level-0 table #303: 0 bytes OK
|
|
||||||
2025/06/24-21:03:58.235239 7f151d7fa6c0 Delete type=0 #301
|
|
||||||
2025/06/24-21:03:58.255927 7f151d7fa6c0 Manual compaction at level-0 from '!items!0fit7HelSjaFtXcW' @ 72057594037927935 : 1 .. '!items!wxrzP3NyiHiYnAMJ' @ 0 : 0; will stop at (end)
|
|
||||||
2025/06/24-21:03:58.255971 7f151d7fa6c0 Manual compaction at level-1 from '!items!0fit7HelSjaFtXcW' @ 72057594037927935 : 1 .. '!items!wxrzP3NyiHiYnAMJ' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
+3
-8
@@ -1,8 +1,3 @@
|
|||||||
2025/06/03-13:26:59.405001 7f53e5dfa6c0 Recovering log #294
|
2026/05/02-22:52:57.748488 7fe282bfe6c0 Recovering log #431
|
||||||
2025/06/03-13:26:59.415733 7f53e5dfa6c0 Delete type=3 #292
|
2026/05/02-22:52:57.803792 7fe282bfe6c0 Delete type=0 #431
|
||||||
2025/06/03-13:26:59.415800 7f53e5dfa6c0 Delete type=0 #294
|
2026/05/02-22:52:57.803902 7fe282bfe6c0 Delete type=3 #430
|
||||||
2025/06/03-13:30:56.309035 7f53df3ff6c0 Level-0 table #299: started
|
|
||||||
2025/06/03-13:30:56.309066 7f53df3ff6c0 Level-0 table #299: 0 bytes OK
|
|
||||||
2025/06/03-13:30:56.343046 7f53df3ff6c0 Delete type=0 #297
|
|
||||||
2025/06/03-13:30:56.395832 7f53df3ff6c0 Manual compaction at level-0 from '!items!0fit7HelSjaFtXcW' @ 72057594037927935 : 1 .. '!items!wxrzP3NyiHiYnAMJ' @ 0 : 0; will stop at (end)
|
|
||||||
2025/06/03-13:30:56.395893 7f53df3ff6c0 Manual compaction at level-1 from '!items!0fit7HelSjaFtXcW' @ 72057594037927935 : 1 .. '!items!wxrzP3NyiHiYnAMJ' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000300
|
MANIFEST-000426
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
2025/06/24-20:47:28.349172 7f151dffb6c0 Recovering log #298
|
2026/04/01-23:48:22.821542 7fe6ad3fe6c0 Recovering log #424
|
||||||
2025/06/24-20:47:28.359761 7f151dffb6c0 Delete type=3 #296
|
2026/04/01-23:48:22.831720 7fe6ad3fe6c0 Delete type=3 #422
|
||||||
2025/06/24-20:47:28.359875 7f151dffb6c0 Delete type=0 #298
|
2026/04/01-23:48:22.831773 7fe6ad3fe6c0 Delete type=0 #424
|
||||||
2025/06/24-21:03:58.203272 7f151d7fa6c0 Level-0 table #303: started
|
2026/04/01-23:48:49.933594 7fe6977fe6c0 Level-0 table #429: started
|
||||||
2025/06/24-21:03:58.203347 7f151d7fa6c0 Level-0 table #303: 0 bytes OK
|
2026/04/01-23:48:49.933618 7fe6977fe6c0 Level-0 table #429: 0 bytes OK
|
||||||
2025/06/24-21:03:58.209369 7f151d7fa6c0 Delete type=0 #301
|
2026/04/01-23:48:49.941087 7fe6977fe6c0 Delete type=0 #427
|
||||||
2025/06/24-21:03:58.229076 7f151d7fa6c0 Manual compaction at level-0 from '!items!0nhTxujlIUB63Aqt' @ 72057594037927935 : 1 .. '!items!tFU5yISK6spdNWco' @ 0 : 0; will stop at (end)
|
2026/04/01-23:48:49.941234 7fe6977fe6c0 Manual compaction at level-0 from '!items!0nhTxujlIUB63Aqt' @ 72057594037927935 : 1 .. '!items!tFU5yISK6spdNWco' @ 0 : 0; will stop at (end)
|
||||||
2025/06/24-21:03:58.229112 7f151d7fa6c0 Manual compaction at level-1 from '!items!0nhTxujlIUB63Aqt' @ 72057594037927935 : 1 .. '!items!tFU5yISK6spdNWco' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
2025/06/03-13:26:59.375226 7f53e55f96c0 Recovering log #294
|
2026/04/01-23:46:40.104749 7fe697fff6c0 Recovering log #419
|
||||||
2025/06/03-13:26:59.385670 7f53e55f96c0 Delete type=3 #292
|
2026/04/01-23:46:40.156075 7fe697fff6c0 Delete type=3 #417
|
||||||
2025/06/03-13:26:59.385742 7f53e55f96c0 Delete type=0 #294
|
2026/04/01-23:46:40.156217 7fe697fff6c0 Delete type=0 #419
|
||||||
2025/06/03-13:30:56.443109 7f53df3ff6c0 Level-0 table #299: started
|
2026/04/01-23:48:06.506267 7fe6977fe6c0 Level-0 table #425: started
|
||||||
2025/06/03-13:30:56.443148 7f53df3ff6c0 Level-0 table #299: 0 bytes OK
|
2026/04/01-23:48:06.506290 7fe6977fe6c0 Level-0 table #425: 0 bytes OK
|
||||||
2025/06/03-13:30:56.473604 7f53df3ff6c0 Delete type=0 #297
|
2026/04/01-23:48:06.512158 7fe6977fe6c0 Delete type=0 #423
|
||||||
2025/06/03-13:30:56.493334 7f53df3ff6c0 Manual compaction at level-0 from '!items!0nhTxujlIUB63Aqt' @ 72057594037927935 : 1 .. '!items!tFU5yISK6spdNWco' @ 0 : 0; will stop at (end)
|
2026/04/01-23:48:06.518617 7fe6977fe6c0 Manual compaction at level-0 from '!items!0nhTxujlIUB63Aqt' @ 72057594037927935 : 1 .. '!items!tFU5yISK6spdNWco' @ 0 : 0; will stop at (end)
|
||||||
2025/06/03-13:30:56.493550 7f53df3ff6c0 Manual compaction at level-1 from '!items!0nhTxujlIUB63Aqt' @ 72057594037927935 : 1 .. '!items!tFU5yISK6spdNWco' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000300
|
MANIFEST-000426
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
2025/06/24-20:47:28.321545 7f151e7fc6c0 Recovering log #298
|
2026/04/01-23:48:22.797623 7fe6ad3fe6c0 Recovering log #424
|
||||||
2025/06/24-20:47:28.331748 7f151e7fc6c0 Delete type=3 #296
|
2026/04/01-23:48:22.806917 7fe6ad3fe6c0 Delete type=3 #422
|
||||||
2025/06/24-20:47:28.331800 7f151e7fc6c0 Delete type=0 #298
|
2026/04/01-23:48:22.806976 7fe6ad3fe6c0 Delete type=0 #424
|
||||||
2025/06/24-21:03:58.209532 7f151d7fa6c0 Level-0 table #303: started
|
2026/04/01-23:48:49.920356 7fe6977fe6c0 Level-0 table #429: started
|
||||||
2025/06/24-21:03:58.209573 7f151d7fa6c0 Level-0 table #303: 0 bytes OK
|
2026/04/01-23:48:49.920405 7fe6977fe6c0 Level-0 table #429: 0 bytes OK
|
||||||
2025/06/24-21:03:58.215589 7f151d7fa6c0 Delete type=0 #301
|
2026/04/01-23:48:49.927156 7fe6977fe6c0 Delete type=0 #427
|
||||||
2025/06/24-21:03:58.229089 7f151d7fa6c0 Manual compaction at level-0 from '!items!15IDGG6JoZnRCQtY' @ 72057594037927935 : 1 .. '!items!yI1zY5k8mAdx9wHK' @ 0 : 0; will stop at (end)
|
2026/04/01-23:48:49.941217 7fe6977fe6c0 Manual compaction at level-0 from '!items!15IDGG6JoZnRCQtY' @ 72057594037927935 : 1 .. '!items!yI1zY5k8mAdx9wHK' @ 0 : 0; will stop at (end)
|
||||||
2025/06/24-21:03:58.229117 7f151d7fa6c0 Manual compaction at level-1 from '!items!15IDGG6JoZnRCQtY' @ 72057594037927935 : 1 .. '!items!yI1zY5k8mAdx9wHK' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
2025/06/03-13:26:59.341579 7f53dffff6c0 Recovering log #294
|
2026/04/01-23:46:39.985628 7fe6acbfd6c0 Recovering log #419
|
||||||
2025/06/03-13:26:59.353145 7f53dffff6c0 Delete type=3 #292
|
2026/04/01-23:46:40.048051 7fe6acbfd6c0 Delete type=3 #417
|
||||||
2025/06/03-13:26:59.353222 7f53dffff6c0 Delete type=0 #294
|
2026/04/01-23:46:40.048122 7fe6acbfd6c0 Delete type=0 #419
|
||||||
2025/06/03-13:30:56.343217 7f53df3ff6c0 Level-0 table #299: started
|
2026/04/01-23:48:06.492888 7fe6977fe6c0 Level-0 table #425: started
|
||||||
2025/06/03-13:30:56.343264 7f53df3ff6c0 Level-0 table #299: 0 bytes OK
|
2026/04/01-23:48:06.492949 7fe6977fe6c0 Level-0 table #425: 0 bytes OK
|
||||||
2025/06/03-13:30:56.370130 7f53df3ff6c0 Delete type=0 #297
|
2026/04/01-23:48:06.499711 7fe6977fe6c0 Delete type=0 #423
|
||||||
2025/06/03-13:30:56.395847 7f53df3ff6c0 Manual compaction at level-0 from '!items!15IDGG6JoZnRCQtY' @ 72057594037927935 : 1 .. '!items!yI1zY5k8mAdx9wHK' @ 0 : 0; will stop at (end)
|
2026/04/01-23:48:06.518591 7fe6977fe6c0 Manual compaction at level-0 from '!items!15IDGG6JoZnRCQtY' @ 72057594037927935 : 1 .. '!items!yI1zY5k8mAdx9wHK' @ 0 : 0; will stop at (end)
|
||||||
2025/06/03-13:30:56.395903 7f53df3ff6c0 Manual compaction at level-1 from '!items!15IDGG6JoZnRCQtY' @ 72057594037927935 : 1 .. '!items!yI1zY5k8mAdx9wHK' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user