sotc-battle-show-ability : affichage des capacités en combat
This commit is contained in:
parent
84aa6b3437
commit
e35a3996ee
11 changed files with 1363 additions and 0 deletions
160
sotc-clash-arrow/sotc-clash-arrow-spec.md
Normal file
160
sotc-clash-arrow/sotc-clash-arrow-spec.md
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
# sotc-clash-arrow — Spécification Technique v1.0
|
||||
|
||||
## Vue d'ensemble
|
||||
|
||||
Module FoundryVTT v11 permettant de tracer des flèches courbées entre les **Dés de Vitesse** du module *Stars Initiative Overlay* (SIO) de Vani, pour visualiser les clashes dans *Star of the City* (SotC).
|
||||
|
||||
S'appuie sur le module **SBSA (clash-resolver)** pour lire les compétences assignées aux dés.
|
||||
|
||||
---
|
||||
|
||||
## Dépendances
|
||||
|
||||
| Module | Rôle |
|
||||
|---|---|
|
||||
| `stars-initiative-overlay` | Fournit les marqueurs PIXI des Dés de Vitesse |
|
||||
| `clash-resolver` (SBSA) | Fournit les compétences stockées par dé via flags |
|
||||
|
||||
---
|
||||
|
||||
## Logique des couleurs
|
||||
|
||||
| Couleur | Condition |
|
||||
|---|---|
|
||||
| **Bleu** `#4a9eff` | A cible B, mais B n'a **pas** de compétence active sur son dé |
|
||||
| **Jaune** `#ffd84a` | A→B **ET** B→A existent simultanément (clash mutuel automatique) |
|
||||
| **Gris** `#888899` | Flèche de preview pendant le drag (avant relâchement) |
|
||||
|
||||
La détection du clash mutuel est **automatique** : dès que la flèche A→B est créée alors que B→A existe déjà, les **deux** flèches passent en jaune.
|
||||
|
||||
---
|
||||
|
||||
## Interactions utilisateur
|
||||
|
||||
### Tracer une flèche
|
||||
1. Maintenir **clic gauche** sur un Dé de Vitesse SIO
|
||||
2. Déplacer la souris vers un autre dé — la flèche preview change de couleur en temps réel selon la cible survolée
|
||||
3. Relâcher sur le dé cible → la flèche devient persistante
|
||||
|
||||
**Qui peut tracer ?** Tous les utilisateurs (GM et joueurs), depuis n'importe quel token.
|
||||
|
||||
### Supprimer une flèche
|
||||
- **Clic droit** sur un Dé de Vitesse → supprime toutes les flèches depuis/vers ce dé
|
||||
|
||||
### Reset global
|
||||
- Automatique au début d'un nouveau round (hook `updateCombat` + hook SIO `sioRoundReset`)
|
||||
- Automatique à la fin du combat (`deleteCombat`)
|
||||
- Manuel via le bouton **GM** dans la barre de contrôles de scène (icône `×`)
|
||||
|
||||
---
|
||||
|
||||
## Architecture des fichiers
|
||||
|
||||
```
|
||||
sotc-clash-arrow/
|
||||
├── module.json
|
||||
├── styles/
|
||||
│ └── sotc-clash-arrow.css
|
||||
├── lang/
|
||||
│ ├── fr.json
|
||||
│ └── en.json
|
||||
└── scripts/
|
||||
├── main.js ← point d'entrée
|
||||
├── Hooks.js ← enregistrement des hooks FoundryVTT
|
||||
├── ArrowStore.js ← store centralisé + sync socket
|
||||
├── ClashArrowLayer.js ← couche PIXI (dessin des flèches)
|
||||
├── DieInteraction.js ← gestion du drag souris
|
||||
└── SIOBridge.js ← intégration SIO + détection compétences SBSA
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Description des modules JS
|
||||
|
||||
### `main.js`
|
||||
- Point d'entrée unique chargé par `module.json`
|
||||
- Expose `globalThis.sotcClashArrow` pour débogage console
|
||||
- Vérifie la présence du module SIO au `ready`
|
||||
|
||||
### `ArrowStore.js`
|
||||
- Store en mémoire (`Map<id, Arrow>`)
|
||||
- Détecte automatiquement le clash mutuel à chaque `addArrow()`
|
||||
- Synchronise via `game.socket` (événement `module.sotc-clash-arrow`) pour que tous les clients voient les mêmes flèches
|
||||
- Émet un événement `change` → `ClashArrowLayer` se redessine
|
||||
|
||||
**Structure d'une flèche :**
|
||||
```js
|
||||
{
|
||||
id : "tokenA:0→tokenB:1",
|
||||
fromToken : "tokenA_id",
|
||||
fromDie : 0,
|
||||
toToken : "tokenB_id",
|
||||
toDie : 1,
|
||||
x1, y1 : number, // coords canvas du centre du dé source
|
||||
x2, y2 : number, // coords canvas du centre du dé cible
|
||||
mutual : boolean, // true = flèche jaune
|
||||
}
|
||||
```
|
||||
|
||||
### `ClashArrowLayer.js`
|
||||
- Hérite de `CanvasLayer` (FoundryVTT v11)
|
||||
- `zIndex: 180` → au-dessus des tokens (100), sous l'UI (900+)
|
||||
- Deux `PIXI.Graphics` séparés : flèches persistantes + preview
|
||||
- Courbe de Bézier cubique avec pointe de flèche trigonométrique
|
||||
- `BEZIER_CURVE = 0.35` : facteur de courbure ajustable
|
||||
|
||||
### `DieInteraction.js`
|
||||
- Écoute `pointerdown` (via hook interne `sotcca:diePointerDown`) → démarre le drag
|
||||
- `pointermove` → met à jour la preview avec la couleur calculée en temps réel
|
||||
- `pointerup` → crée la flèche dans `ArrowStore` si une cible valide est sous le curseur
|
||||
|
||||
### `SIOBridge.js`
|
||||
- `getSIODieCenter()` : lit `token._initiativeMarkers[i].getBounds()` pour les coords canvas
|
||||
- `findDieUnderPoint()` : parcourt tous les tokens/marqueurs, hit-test à ±24px
|
||||
- `tokenHasActiveSkillOnDie()` : combine état SIO (`diceStates[i] !== 0`) ET présence d'une compétence SBSA (`flag "clash-resolver" → "dieSkills"[i]`)
|
||||
- `hookSIOMarkers()` : attache les listeners sur les marqueurs PIXI existants + futurs (via hook `refreshToken`)
|
||||
|
||||
### `Hooks.js`
|
||||
- `init` : enregistrement du layer dans `CONFIG.Canvas.layers`
|
||||
- `canvasReady` : init socket + interactions + hook SIO markers
|
||||
- `canvasTearDown` : `ArrowStore.clear()`
|
||||
- `updateCombat` (nouveau round) + `sioRoundReset` + `deleteCombat` → reset
|
||||
- `getSceneControlButtons` : bouton reset GM
|
||||
- `sotcca:mutualClash` : message chat signalant un clash mutuel
|
||||
|
||||
---
|
||||
|
||||
## Chemins de données supposés (à vérifier)
|
||||
|
||||
> ⚠️ Ces chemins sont des hypothèses basées sur l'analyse du module SIO et SBSA.
|
||||
> À valider lors des tests avec les modules installés.
|
||||
|
||||
| Donnée | Chemin supposé |
|
||||
|---|---|
|
||||
| Marqueurs PIXI SIO | `token._initiativeMarkers[]` |
|
||||
| États des dés SIO | `tokenDoc.getFlag("stars-initiative-overlay", "diceStates")` → `int[]` |
|
||||
| Nombre de dés | `actor.system.speed_dice.num_dice` |
|
||||
| Compétences par dé (SBSA) | `tokenDoc.getFlag("clash-resolver", "dieSkills")` → `string[]` |
|
||||
| Hook reset SIO | `"sioRoundReset"` (à confirmer dans la source SIO) |
|
||||
|
||||
---
|
||||
|
||||
## Synchronisation multi-clients
|
||||
|
||||
Toutes les modifications du store sont broadcastées via `game.socket.emit("module.sotc-clash-arrow", payload)`.
|
||||
|
||||
Les autres clients reçoivent le payload et appliquent la même modification localement sans re-broadcaster, pour éviter les boucles.
|
||||
|
||||
**Actions socket :**
|
||||
- `add` : nouvelle flèche (+ mise à jour éventuelle de la flèche inverse)
|
||||
- `remove` : suppression d'une flèche (+ dés-mutualisation de l'inverse)
|
||||
- `clear` : reset total
|
||||
|
||||
---
|
||||
|
||||
## Notes d'implémentation
|
||||
|
||||
- Le layer PIXI est enregistré dans `CONFIG.Canvas.layers` au hook `init`, avant la construction du canvas
|
||||
- Les listeners sur les marqueurs SIO sont attachés avec un délai de 50ms après `refreshToken` pour laisser SIO finir de recréer ses containers PIXI
|
||||
- Un marqueur déjà hookié est marqué `marker._sotcca_hooked = true` pour éviter les doublons
|
||||
- La flèche de preview utilise `alpha = 0.55` pour la distinguer des flèches persistantes (`alpha = 0.92`)
|
||||
Loading…
Add table
Add a link
Reference in a new issue