Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| adf9b0b2e6 | |||
| 5c2a364832 | |||
| ec0e522145 | |||
| 8123b53f75 | |||
| 58478d56ea | |||
| a99eeaccba | |||
| 2ab380786f | |||
| c3ce628e24 | |||
| 8e5fb9aca1 | |||
| 1b2a74969d | |||
| 98a6a41078 | |||
| c73136b3c9 | |||
| 49996104ce | |||
| b3cf0b0aa1 | |||
| 63c0153860 | |||
| 8bfbdedf43 | |||
| 6d2fca9fc2 | |||
| b26ce2f114 |
@@ -68,4 +68,4 @@ jobs:
|
|||||||
manifest: 'https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/latest/system.json'
|
manifest: 'https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/latest/system.json'
|
||||||
notes: 'https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/fvtt-celestopol-${{github.event.release.tag_name}}.zip'
|
notes: 'https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/fvtt-celestopol-${{github.event.release.tag_name}}.zip'
|
||||||
compatibility-minimum: '13'
|
compatibility-minimum: '13'
|
||||||
compatibility-verified: '13'
|
compatibility-verified: '14'
|
||||||
|
|||||||
@@ -13,3 +13,4 @@ css/*.css
|
|||||||
# Règles (PDFs privés)
|
# Règles (PDFs privés)
|
||||||
__regles/
|
__regles/
|
||||||
*.pdf
|
*.pdf
|
||||||
|
.github/
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
# Célestopol 1922 — Système FoundryVTT
|
||||||
|
|
||||||
|
Système [Foundry VTT](https://foundryvtt.com) pour **Célestopol 1922**, le jeu de rôle d'[Antre Monde Éditions](https://antremonde.fr).
|
||||||
|
|
||||||
|
Copyright 2025-2026 Antre Monde Editions All rights reserved
|
||||||
|
|
||||||
|
Celestopol 1922 is a game written by Emmanuel Chastellière and Julien Arnaud. The authors retain their moral rights to this work in both print and digital formats.
|
||||||
|
|
||||||
|
This system for FoundryVTT has been approved and authorized by Antre-Monde Edition
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✨ Fonctionnalités
|
||||||
|
|
||||||
|
### Personnages joueurs (PJ)
|
||||||
|
- **4 attributs** (Âme, Corps, Cœur, Esprit) × **4 compétences** chacun (16 compétences au total)
|
||||||
|
- Gestion des **Blessures** (8 niveaux avec malus automatique aux jets)
|
||||||
|
- Suivi du **Destin** et du **Spleen** (jauges à 8 crans)
|
||||||
|
- **Anomalies** : 9 types, déclenchées sur certains résultats de dé
|
||||||
|
- **Factions** : 8 factions standard + 2 personnalisées, avec aspects liés
|
||||||
|
- **Équipement** : armes, armures, équipements génériques
|
||||||
|
- Onglets dédiés : Principal · Compétences · Factions · Équipement · Combat · Biographie
|
||||||
|
|
||||||
|
### Personnages non-joueurs (PNJ)
|
||||||
|
- Fiche simplifiée : compétences, blessures, équipement, biographie
|
||||||
|
|
||||||
|
### Items
|
||||||
|
- **Arme** : mêlée ou à distance, modificateurs de portée
|
||||||
|
- **Armure** : protection et malus éventuels
|
||||||
|
- **Aspect de faction** : lié à une faction, bonus / usage limité
|
||||||
|
- **Anomalie** : type, usages, description
|
||||||
|
- **Équipement** générique
|
||||||
|
|
||||||
|
### Mécanique de jet de désde démonstration
|
||||||
|
- **Pool de d6** : `max(1, compétence + malus_blessures)` dés
|
||||||
|
- **Bonus Phase de Lune** : automatique selon la phase en cours (0 à +3)
|
||||||
|
- **Modificateurs** : difficulté et bonus libres via DialogV2
|
||||||
|
- Seuil de succès standard : **7**
|
||||||
|
- Résultats spéciaux : **Brio** (+destin), **Contrecoup** (−destin), **Triomphe** (+anomalie/−spleen), **Catastrophe** (−anomalie/+spleen)
|
||||||
|
|
||||||
|
### Dé de la Lune
|
||||||
|
- Jet de dé de lune indépendant (menu contextuel du token)
|
||||||
|
- 8 faces : Nouvelle Lune, Premiers Croissants, Dernier Croissant, Gibbeuses ×2, Pleine Lune, Lune de Feu, Lune Noire
|
||||||
|
- Sur certains résultats : **choix de contrepartie** via pop-up (perte d'anomalie, spleen, ou échec catastrophique)
|
||||||
|
- Carte de résultat avec boutons d'application directe
|
||||||
|
|
||||||
|
### Combat
|
||||||
|
- **Initiative Célestopol** : jet d'initiative avec dé spécial, insertion dans le tracker
|
||||||
|
- Attaque avec calcul automatique dommages / protection
|
||||||
|
- Chat de combat avec récapitulatif des dégâts et blessures appliqués
|
||||||
|
|
||||||
|
### Compendiums inclus
|
||||||
|
| Pack | Contenu |
|
||||||
|
| ------------ | ------------------------------ |
|
||||||
|
| Anomalies | Les 8 anomalies du jeu de base |
|
||||||
|
| Prétirés | 8 personnages prêts à jouer |
|
||||||
|
| Aides de jeu | Aide du système |
|
||||||
|
| Scènes | Scènes utiles |
|
||||||
|
|
||||||
|
## 🎨 Charte graphique
|
||||||
|
|
||||||
|
- Police de titre : **CopaseticNF** (Regular + Bold)
|
||||||
|
- Vert sombre en-tête : `#0c4c0c`
|
||||||
|
- Orange texte : `#e07b00`
|
||||||
|
- Fond parchemin : `#f0e8d4`
|
||||||
|
- Texture en-tête : `assets/ui/fond_cadrille.jpg`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 👤 Auteur
|
||||||
|
|
||||||
|
**LeRatierBretonnien / Uberwald**
|
||||||
|
- Discord : `LeRatierBretonnien`
|
||||||
|
- Site : [uberwald.me](https://www.uberwald.me)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📜 Licence
|
||||||
|
|
||||||
|
Copyright 2025 Antre Monde Editions All rights reserved
|
||||||
|
|
||||||
|
Celestopol 1922 is a game written by Emmanuel Chastellière and Julien Arnaud. The authors retain their moral rights to this work in both print and digital formats.
|
||||||
|
|
||||||
|
This system for FoundryVTT has been approved and authorized by Antre-Monde Edition.
|
||||||
@@ -0,0 +1,368 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
convert-old-system.py
|
||||||
|
Convertit les fichiers JSON d'acteurs exportés de l'ancien système Célestopol 1922
|
||||||
|
(system id: celestopol1922) vers le format du nouveau système (fvtt-celestopol).
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python3 convert-old-system.py <fichier.json> [fichier2.json ...]
|
||||||
|
|
||||||
|
Le fichier converti est écrit à côté du fichier source sous le nom :
|
||||||
|
<nom>-converted.json
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
# ─── Mapping des types d'anomalies (préfixe "CEL1922.opt." → clé nouveau système) ─────
|
||||||
|
ANOMALY_TYPE_MAP = {
|
||||||
|
"none": "none",
|
||||||
|
"entropie": "entropie",
|
||||||
|
"communicationaveclesmorts": "communicationaveclesmorts",
|
||||||
|
"illusion": "illusion",
|
||||||
|
"suggestion": "suggestion",
|
||||||
|
"tarotdivinatoire": "tarotdivinatoire",
|
||||||
|
"telekinesie": "telekinesie",
|
||||||
|
"telepathie": "telepathie",
|
||||||
|
"voyageastral": "voyageastral",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clé anomaly vide → "none"
|
||||||
|
VALID_ANOMALY_TYPES = set(ANOMALY_TYPE_MAP.values())
|
||||||
|
|
||||||
|
# ─── Domaines (stats) ──────────────────────────────────────────────────────────────────
|
||||||
|
STATS = ["ame", "corps", "coeur", "esprit"]
|
||||||
|
|
||||||
|
# Compétences par domaine (dans l'ordre du nouveau système)
|
||||||
|
SKILLS = {
|
||||||
|
"ame": ["artifice", "attraction", "coercition", "faveur"],
|
||||||
|
"corps": ["echauffouree", "effacement", "mobilite", "prouesse"],
|
||||||
|
"coeur": ["appreciation", "arts", "inspiration", "traque"],
|
||||||
|
"esprit": ["instruction", "mtechnologique", "raisonnement", "traitement"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def make_id():
|
||||||
|
"""Génère un identifiant Foundry-compatible (16 chars hex)."""
|
||||||
|
return uuid.uuid4().hex[:16]
|
||||||
|
|
||||||
|
|
||||||
|
def strip_prefix(label: str) -> str:
|
||||||
|
"""Extrait la clé depuis 'CEL1922.opt.<clé>'."""
|
||||||
|
return label.split(".")[-1]
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_anomaly_type(old_system: dict) -> str:
|
||||||
|
"""
|
||||||
|
Résout le type d'anomalie depuis l'ancien système.
|
||||||
|
old_system.anomaly est un int (index dans anomalytypes[]).
|
||||||
|
"""
|
||||||
|
anomalytypes = old_system.get("skill", {}).get("anomalytypes", [])
|
||||||
|
idx = old_system.get("anomaly", 0)
|
||||||
|
try:
|
||||||
|
idx = int(idx)
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
idx = 0
|
||||||
|
|
||||||
|
if idx == 0 or not anomalytypes:
|
||||||
|
return "none"
|
||||||
|
|
||||||
|
if idx < len(anomalytypes):
|
||||||
|
raw = strip_prefix(anomalytypes[idx])
|
||||||
|
return ANOMALY_TYPE_MAP.get(raw, "none")
|
||||||
|
|
||||||
|
return "none"
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_anomaly_type_from_name(item_name: str) -> str:
|
||||||
|
"""
|
||||||
|
Infère le type d'anomalie depuis le nom de l'item (ex: 'Entropie 1' → 'entropie').
|
||||||
|
Fallback si le mapping par index est insuffisant.
|
||||||
|
"""
|
||||||
|
# Normalise : minuscules, retire accents, retire espaces et chiffres
|
||||||
|
name_clean = item_name.lower().strip()
|
||||||
|
name_clean = re.sub(r"\s*\d+\s*$", "", name_clean).strip() # retire le niveau en fin
|
||||||
|
name_clean = re.sub(r"\s+", "", name_clean) # retire tous les espaces
|
||||||
|
|
||||||
|
# Normalisation des accents courants
|
||||||
|
replacements = [
|
||||||
|
("é", "e"), ("è", "e"), ("ê", "e"), ("ë", "e"),
|
||||||
|
("à", "a"), ("â", "a"), ("ä", "a"),
|
||||||
|
("î", "i"), ("ï", "i"),
|
||||||
|
("ô", "o"), ("ö", "o"),
|
||||||
|
("û", "u"), ("ù", "u"), ("ü", "u"),
|
||||||
|
("ç", "c"),
|
||||||
|
]
|
||||||
|
for src, dst in replacements:
|
||||||
|
name_clean = name_clean.replace(src, dst)
|
||||||
|
|
||||||
|
for key in ANOMALY_TYPE_MAP:
|
||||||
|
if key == "none":
|
||||||
|
continue
|
||||||
|
if key in name_clean or name_clean in key:
|
||||||
|
return key
|
||||||
|
|
||||||
|
return "none"
|
||||||
|
|
||||||
|
|
||||||
|
def convert_stats_character(old_skill: dict, warnings: list) -> dict:
|
||||||
|
"""Convertit system.skill (ancien) → system.stats (nouveau) pour un PJ."""
|
||||||
|
stats = {}
|
||||||
|
for stat in STATS:
|
||||||
|
old_stat = old_skill.get(stat, {})
|
||||||
|
new_stat = {
|
||||||
|
"label": stat,
|
||||||
|
"res": int(old_stat.get("res", 0) or 0),
|
||||||
|
}
|
||||||
|
for skill in SKILLS[stat]:
|
||||||
|
old_sk = old_stat.get(skill, {})
|
||||||
|
val = old_sk.get("value", 0)
|
||||||
|
try:
|
||||||
|
val = int(val) if val is not None else 0
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
warnings.append(f"Valeur de compétence invalide pour {stat}.{skill}: {val!r} → 0")
|
||||||
|
val = 0
|
||||||
|
new_stat[skill] = {"label": skill, "value": val}
|
||||||
|
stats[stat] = new_stat
|
||||||
|
return stats
|
||||||
|
|
||||||
|
|
||||||
|
def convert_stats_npc(old_skill: dict, warnings: list) -> dict:
|
||||||
|
"""Convertit system.skill (ancien) → system.stats (nouveau) pour un PNJ."""
|
||||||
|
stats = {}
|
||||||
|
for stat in STATS:
|
||||||
|
old_stat = old_skill.get(stat, {})
|
||||||
|
res = int(old_stat.get("res", 0) or 0)
|
||||||
|
stats[stat] = {
|
||||||
|
"label": stat,
|
||||||
|
"res": res,
|
||||||
|
"actuel": res, # actuel = res par défaut
|
||||||
|
}
|
||||||
|
return stats
|
||||||
|
|
||||||
|
|
||||||
|
def convert_attributs(old_attributs: dict) -> dict:
|
||||||
|
"""Convertit les attributs du vieux format plat vers SchemaField {value, max}."""
|
||||||
|
return {
|
||||||
|
"entregent": {
|
||||||
|
"value": int(old_attributs.get("entregent", 0) or 0),
|
||||||
|
"max": int(old_attributs.get("entregentmax", 0) or 0),
|
||||||
|
},
|
||||||
|
"fortune": {
|
||||||
|
"value": int(old_attributs.get("fortune", 0) or 0),
|
||||||
|
"max": int(old_attributs.get("fortunemax", 0) or 0),
|
||||||
|
},
|
||||||
|
"reve": {
|
||||||
|
"value": int(old_attributs.get("reve", 0) or 0),
|
||||||
|
"max": int(old_attributs.get("revemax", 0) or 0),
|
||||||
|
},
|
||||||
|
"vision": {
|
||||||
|
"value": int(old_attributs.get("vision", 0) or 0),
|
||||||
|
"max": int(old_attributs.get("visionmax", 0) or 0),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def convert_item(item: dict, warnings: list) -> dict | None:
|
||||||
|
"""
|
||||||
|
Convertit un item de l'ancien format vers le nouveau.
|
||||||
|
Retourne None si l'item doit être ignoré (type inconnu sans données utiles).
|
||||||
|
"""
|
||||||
|
old_type = item.get("type", "")
|
||||||
|
old_sys = item.get("system", {})
|
||||||
|
name = item.get("name", "Sans nom")
|
||||||
|
new_item = {
|
||||||
|
"_id": make_id(),
|
||||||
|
"name": name,
|
||||||
|
"img": item.get("img", "icons/svg/item-bag.svg"),
|
||||||
|
"effects": [],
|
||||||
|
"flags": {},
|
||||||
|
"sort": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
if old_type == "anomaly":
|
||||||
|
level = 0
|
||||||
|
try:
|
||||||
|
level = int(old_sys.get("value", 1) or 1)
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
level = 1
|
||||||
|
level = max(1, min(4, level))
|
||||||
|
|
||||||
|
# Résolution du subtype : l'ancien système le stocke mal ("weapon"), on l'infère du nom
|
||||||
|
subtype = resolve_anomaly_type_from_name(name)
|
||||||
|
if subtype == "none":
|
||||||
|
warnings.append(f"Impossible de déterminer le type d'anomalie depuis '{name}', 'none' utilisé")
|
||||||
|
|
||||||
|
new_item["type"] = "anomaly"
|
||||||
|
new_item["system"] = {
|
||||||
|
"subtype": subtype,
|
||||||
|
"level": level,
|
||||||
|
"usesRemaining": level,
|
||||||
|
"technique": old_sys.get("technique", "") or "",
|
||||||
|
"narratif": old_sys.get("narratif", "") or "",
|
||||||
|
}
|
||||||
|
|
||||||
|
elif old_type == "aspect":
|
||||||
|
valeur = 0
|
||||||
|
try:
|
||||||
|
valeur = int(old_sys.get("value", 0) or 0)
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
valeur = 0
|
||||||
|
|
||||||
|
new_item["type"] = "aspect"
|
||||||
|
new_item["system"] = {
|
||||||
|
"valeur": valeur,
|
||||||
|
"description": old_sys.get("narratif", "") or old_sys.get("technique", "") or "",
|
||||||
|
}
|
||||||
|
|
||||||
|
elif old_type == "item":
|
||||||
|
old_subtype = (old_sys.get("subtype") or "").lower().strip()
|
||||||
|
damage = old_sys.get("damage", "") or ""
|
||||||
|
protect = old_sys.get("protection", "") or ""
|
||||||
|
|
||||||
|
if old_subtype == "weapon" or (damage and not protect):
|
||||||
|
new_item["type"] = "weapon"
|
||||||
|
new_item["system"] = {
|
||||||
|
"type": "melee",
|
||||||
|
"degats": "0",
|
||||||
|
"portee": "contact",
|
||||||
|
"equipped": False,
|
||||||
|
"description": old_sys.get("technique", "") or old_sys.get("narratif", "") or "",
|
||||||
|
}
|
||||||
|
if damage:
|
||||||
|
warnings.append(f"Item '{name}' : valeur damage='{damage}' non convertie automatiquement, à saisir manuellement")
|
||||||
|
elif old_subtype == "armor" or (protect and not damage):
|
||||||
|
new_item["type"] = "armure"
|
||||||
|
new_item["system"] = {
|
||||||
|
"protection": 1,
|
||||||
|
"malus": 1,
|
||||||
|
"equipped": False,
|
||||||
|
"description": old_sys.get("technique", "") or old_sys.get("narratif", "") or "",
|
||||||
|
}
|
||||||
|
if protect:
|
||||||
|
warnings.append(f"Item '{name}' : valeur protection='{protect}' non convertie automatiquement, à saisir manuellement")
|
||||||
|
else:
|
||||||
|
# Équipement générique
|
||||||
|
new_item["type"] = "equipment"
|
||||||
|
new_item["system"] = {
|
||||||
|
"description": old_sys.get("technique", "") or old_sys.get("narratif", "") or "",
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
warnings.append(f"Type d'item inconnu '{old_type}' pour '{name}', ignoré")
|
||||||
|
return None
|
||||||
|
|
||||||
|
return new_item
|
||||||
|
|
||||||
|
|
||||||
|
def convert_actor(old: dict) -> tuple[dict, list[str]]:
|
||||||
|
"""Convertit un acteur complet. Retourne (new_actor, warnings)."""
|
||||||
|
warnings = []
|
||||||
|
actor_type = old.get("type", "character")
|
||||||
|
old_sys = old.get("system", {})
|
||||||
|
old_skill = old_sys.get("skill", {})
|
||||||
|
|
||||||
|
new_sys = {}
|
||||||
|
|
||||||
|
# ── Champs communs ──────────────────────────────────────────────────────────────
|
||||||
|
new_sys["concept"] = old_sys.get("concept", "") or ""
|
||||||
|
new_sys["description"] = old_sys.get("description", "") or "" # gardé dans metier/concept
|
||||||
|
new_sys["metier"] = old_sys.get("metier", "") or old_sys.get("concept", "") or ""
|
||||||
|
new_sys["faction"] = old_sys.get("faction", "") or ""
|
||||||
|
|
||||||
|
# ── Blessures / Destin / Spleen ─────────────────────────────────────────────────
|
||||||
|
new_sys["blessures"] = {"lvl": int(old_sys.get("blessures", {}).get("lvl", 0) or 0)}
|
||||||
|
new_sys["destin"] = {"lvl": int(old_sys.get("destin", {}).get("lvl", 0) or 0)}
|
||||||
|
new_sys["spleen"] = {"lvl": int(old_sys.get("spleen", {}).get("lvl", 0) or 0)}
|
||||||
|
|
||||||
|
# ── Stats ───────────────────────────────────────────────────────────────────────
|
||||||
|
if actor_type == "character":
|
||||||
|
new_sys["stats"] = convert_stats_character(old_skill, warnings)
|
||||||
|
|
||||||
|
# Anomalie : type depuis l'index, niveau depuis anomalyval
|
||||||
|
anomaly_type = resolve_anomaly_type(old_sys)
|
||||||
|
anomaly_val = int(old_sys.get("anomalyval", 0) or 0)
|
||||||
|
new_sys["anomaly"] = {"type": anomaly_type, "value": anomaly_val}
|
||||||
|
|
||||||
|
# Attributs
|
||||||
|
new_sys["attributs"] = convert_attributs(old_sys.get("attributs", {}))
|
||||||
|
|
||||||
|
# Biographie → historique
|
||||||
|
new_sys["historique"] = old_sys.get("description", "") or ""
|
||||||
|
new_sys["descriptionPhysique"] = ""
|
||||||
|
new_sys["descriptionPsychologique"] = ""
|
||||||
|
new_sys["initiative"] = 0
|
||||||
|
|
||||||
|
# Factions (vide)
|
||||||
|
new_sys["factions"] = old_sys.get("factions", {})
|
||||||
|
|
||||||
|
elif actor_type == "npc":
|
||||||
|
new_sys["stats"] = convert_stats_npc(old_skill, warnings)
|
||||||
|
new_sys["npcType"] = old_sys.get("npcType", "standard") or "standard"
|
||||||
|
new_sys["historique"] = old_sys.get("description", "") or ""
|
||||||
|
|
||||||
|
# ── Items ───────────────────────────────────────────────────────────────────────
|
||||||
|
new_items = []
|
||||||
|
for item in old.get("items", []):
|
||||||
|
converted = convert_item(item, warnings)
|
||||||
|
if converted:
|
||||||
|
new_items.append(converted)
|
||||||
|
|
||||||
|
new_actor = {
|
||||||
|
"_id": make_id(),
|
||||||
|
"name": old.get("name", "Personnage sans nom"),
|
||||||
|
"type": actor_type,
|
||||||
|
"img": old.get("img", "icons/svg/mystery-man.svg"),
|
||||||
|
"system": new_sys,
|
||||||
|
"items": new_items,
|
||||||
|
"effects": [],
|
||||||
|
"folder": None,
|
||||||
|
"flags": {},
|
||||||
|
"prototypeToken": old.get("prototypeToken", {}),
|
||||||
|
}
|
||||||
|
|
||||||
|
return new_actor, warnings
|
||||||
|
|
||||||
|
|
||||||
|
def convert_file(path: str) -> None:
|
||||||
|
"""Lit path, convertit, écrit <base>-converted.json."""
|
||||||
|
print(f"\n{'─' * 60}")
|
||||||
|
print(f"Traitement : {path}")
|
||||||
|
|
||||||
|
with open(path, "r", encoding="utf-8") as f:
|
||||||
|
old = json.load(f)
|
||||||
|
|
||||||
|
new_actor, warnings = convert_actor(old)
|
||||||
|
|
||||||
|
for w in warnings:
|
||||||
|
print(f" ⚠ {w}")
|
||||||
|
|
||||||
|
base, _ = os.path.splitext(path)
|
||||||
|
out_path = f"{base}-converted.json"
|
||||||
|
|
||||||
|
with open(out_path, "w", encoding="utf-8") as f:
|
||||||
|
json.dump(new_actor, f, ensure_ascii=False, indent=2)
|
||||||
|
|
||||||
|
print(f" ✓ Écrit : {out_path}")
|
||||||
|
print(f" type={new_actor['type']} items={len(new_actor['items'])} avertissements={len(warnings)}")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Usage: python3 convert-old-system.py <fichier.json> [fichier2.json ...]")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
for path in sys.argv[1:]:
|
||||||
|
if not os.path.isfile(path):
|
||||||
|
print(f"Fichier introuvable : {path}", file=sys.stderr)
|
||||||
|
continue
|
||||||
|
convert_file(path)
|
||||||
|
|
||||||
|
print(f"\n{'─' * 60}")
|
||||||
|
print("Conversion terminée.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
{
|
||||||
|
"_id": "e9e583fc41454c90",
|
||||||
|
"name": "Ajax",
|
||||||
|
"type": "npc",
|
||||||
|
"img": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/ajax.Avatar.webp?1719437847752",
|
||||||
|
"system": {
|
||||||
|
"concept": "",
|
||||||
|
"description": "",
|
||||||
|
"metier": "",
|
||||||
|
"faction": "",
|
||||||
|
"blessures": {
|
||||||
|
"lvl": 0
|
||||||
|
},
|
||||||
|
"destin": {
|
||||||
|
"lvl": 0
|
||||||
|
},
|
||||||
|
"spleen": {
|
||||||
|
"lvl": 0
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"ame": {
|
||||||
|
"label": "ame",
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0
|
||||||
|
},
|
||||||
|
"corps": {
|
||||||
|
"label": "corps",
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0
|
||||||
|
},
|
||||||
|
"coeur": {
|
||||||
|
"label": "coeur",
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0
|
||||||
|
},
|
||||||
|
"esprit": {
|
||||||
|
"label": "esprit",
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"npcType": "standard",
|
||||||
|
"historique": ""
|
||||||
|
},
|
||||||
|
"items": [],
|
||||||
|
"effects": [],
|
||||||
|
"folder": null,
|
||||||
|
"flags": {},
|
||||||
|
"prototypeToken": {
|
||||||
|
"name": "Ajax",
|
||||||
|
"displayName": 0,
|
||||||
|
"actorLink": false,
|
||||||
|
"appendNumber": false,
|
||||||
|
"prependAdjective": false,
|
||||||
|
"texture": {
|
||||||
|
"src": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/ajax.Token.webp?1719437847752",
|
||||||
|
"scaleX": 1,
|
||||||
|
"scaleY": 1,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"rotation": 0,
|
||||||
|
"anchorX": 0.5,
|
||||||
|
"anchorY": 0.5,
|
||||||
|
"fit": "contain",
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"alphaThreshold": 0.75
|
||||||
|
},
|
||||||
|
"width": 1,
|
||||||
|
"height": 1,
|
||||||
|
"lockRotation": false,
|
||||||
|
"rotation": 0,
|
||||||
|
"alpha": 1,
|
||||||
|
"disposition": -1,
|
||||||
|
"displayBars": 0,
|
||||||
|
"bar1": {
|
||||||
|
"attribute": null
|
||||||
|
},
|
||||||
|
"bar2": {
|
||||||
|
"attribute": null
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"alpha": 0.5,
|
||||||
|
"angle": 360,
|
||||||
|
"bright": 0,
|
||||||
|
"coloration": 1,
|
||||||
|
"dim": 0,
|
||||||
|
"attenuation": 0.5,
|
||||||
|
"luminosity": 0.5,
|
||||||
|
"saturation": 0,
|
||||||
|
"contrast": 0,
|
||||||
|
"shadows": 0,
|
||||||
|
"animation": {
|
||||||
|
"type": null,
|
||||||
|
"speed": 5,
|
||||||
|
"intensity": 5,
|
||||||
|
"reverse": false
|
||||||
|
},
|
||||||
|
"darkness": {
|
||||||
|
"min": 0,
|
||||||
|
"max": 1
|
||||||
|
},
|
||||||
|
"negative": false,
|
||||||
|
"priority": 0,
|
||||||
|
"color": null
|
||||||
|
},
|
||||||
|
"sight": {
|
||||||
|
"enabled": true,
|
||||||
|
"range": 30,
|
||||||
|
"angle": 360,
|
||||||
|
"visionMode": "basic",
|
||||||
|
"color": null,
|
||||||
|
"attenuation": 0.1,
|
||||||
|
"brightness": 0,
|
||||||
|
"saturation": 0,
|
||||||
|
"contrast": 0
|
||||||
|
},
|
||||||
|
"detectionModes": [],
|
||||||
|
"flags": {},
|
||||||
|
"randomImg": false,
|
||||||
|
"occludable": {
|
||||||
|
"radius": 0
|
||||||
|
},
|
||||||
|
"ring": {
|
||||||
|
"enabled": false,
|
||||||
|
"colors": {
|
||||||
|
"ring": null,
|
||||||
|
"background": null
|
||||||
|
},
|
||||||
|
"effects": 1,
|
||||||
|
"subject": {
|
||||||
|
"scale": 1,
|
||||||
|
"texture": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"turnMarker": {
|
||||||
|
"mode": 1,
|
||||||
|
"animation": null,
|
||||||
|
"src": null,
|
||||||
|
"disposition": false
|
||||||
|
},
|
||||||
|
"movementAction": null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,459 @@
|
|||||||
|
{
|
||||||
|
"folder": "fbRXVyFLLyOpuiTd",
|
||||||
|
"name": "Ajax",
|
||||||
|
"type": "npc",
|
||||||
|
"img": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/ajax.Avatar.webp?1719437847752",
|
||||||
|
"system": {
|
||||||
|
"concept": "",
|
||||||
|
"anomaly": "0",
|
||||||
|
"anomalyval": 0,
|
||||||
|
"anomalymax": "0",
|
||||||
|
"initiative": 0,
|
||||||
|
"description": "",
|
||||||
|
"prefs": {
|
||||||
|
"typeofthrow": {
|
||||||
|
"check": true,
|
||||||
|
"choice": "0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"typeofthrow": {
|
||||||
|
"check": true,
|
||||||
|
"choice": "0"
|
||||||
|
},
|
||||||
|
"configure": {
|
||||||
|
"numberofdice": 0,
|
||||||
|
"aspect": 0,
|
||||||
|
"bonus": 0,
|
||||||
|
"bonusauspiciousdice": 0,
|
||||||
|
"typeofthrow": 0,
|
||||||
|
"aspectskill": 0,
|
||||||
|
"bonusmalusskill": 0,
|
||||||
|
"aspectspeciality": 0,
|
||||||
|
"rolldifficulty": 0,
|
||||||
|
"bonusmalusspeciality": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"skill": {
|
||||||
|
"skilltypes": [
|
||||||
|
"CEL1922.opt.ame",
|
||||||
|
"CEL1922.opt.attraction",
|
||||||
|
"CEL1922.opt.artifice",
|
||||||
|
"CEL1922.opt.coercition",
|
||||||
|
"CEL1922.opt.faveur",
|
||||||
|
"CEL1922.opt.corps",
|
||||||
|
"CEL1922.opt.echauffouree",
|
||||||
|
"CEL1922.opt.effacement",
|
||||||
|
"CEL1922.opt.prouesse",
|
||||||
|
"CEL1922.opt.mobilite",
|
||||||
|
"CEL1922.opt.coeur",
|
||||||
|
"CEL1922.opt.appreciation",
|
||||||
|
"CEL1922.opt.arts",
|
||||||
|
"CEL1922.opt.inspiration",
|
||||||
|
"CEL1922.opt.traque",
|
||||||
|
"CEL1922.opt.esprit",
|
||||||
|
"CEL1922.opt.instruction",
|
||||||
|
"CEL1922.opt.mtechnologique",
|
||||||
|
"CEL1922.opt.raisonnement",
|
||||||
|
"CEL1922.opt.traitement"
|
||||||
|
],
|
||||||
|
"moondicetypes": [
|
||||||
|
"CEL1922.opt.nouvellelune",
|
||||||
|
"CEL1922.opt.premiercroissant",
|
||||||
|
"CEL1922.opt.premierquartier",
|
||||||
|
"CEL1922.opt.lunegibbeuse",
|
||||||
|
"CEL1922.opt.lunevoutee",
|
||||||
|
"CEL1922.opt.derniercroissant",
|
||||||
|
"CEL1922.opt.dernierquartier",
|
||||||
|
"CEL1922.opt.pleinelune"
|
||||||
|
],
|
||||||
|
"woundstypes": [
|
||||||
|
"CEL1922.opt.none",
|
||||||
|
"CEL1922.opt.anodin",
|
||||||
|
"CEL1922.opt.derisoire",
|
||||||
|
"CEL1922.opt.negligeable",
|
||||||
|
"CEL1922.opt.superficiel",
|
||||||
|
"CEL1922.opt.leger",
|
||||||
|
"CEL1922.opt.modere",
|
||||||
|
"CEL1922.opt.grave",
|
||||||
|
"CEL1922.opt.dramatique"
|
||||||
|
],
|
||||||
|
"woundsmalus": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-2,
|
||||||
|
-2,
|
||||||
|
-3,
|
||||||
|
-999
|
||||||
|
],
|
||||||
|
"woundsrecup": [
|
||||||
|
"CEL1922.opt.none",
|
||||||
|
"CEL1922.1 minute",
|
||||||
|
"CEL1922.1 minute",
|
||||||
|
"CEL1922.10 minutes",
|
||||||
|
"CEL1922.10 minutes",
|
||||||
|
"CEL1922.30 minutes",
|
||||||
|
"CEL1922.30 minutes",
|
||||||
|
"CEL1922.1 day",
|
||||||
|
"CEL1922.Out of Fiction"
|
||||||
|
],
|
||||||
|
"destinytypes": [
|
||||||
|
"CEL1922.opt.none",
|
||||||
|
"CEL1922.opt.libel1",
|
||||||
|
"CEL1922.opt.libel2",
|
||||||
|
"CEL1922.opt.libel3",
|
||||||
|
"CEL1922.opt.libel4",
|
||||||
|
"CEL1922.opt.libel5",
|
||||||
|
"CEL1922.opt.libel6",
|
||||||
|
"CEL1922.opt.libel7",
|
||||||
|
"CEL1922.opt.libel8"
|
||||||
|
],
|
||||||
|
"spleentypes": [
|
||||||
|
"CEL1922.opt.none",
|
||||||
|
"CEL1922.opt.libel1",
|
||||||
|
"CEL1922.opt.libel2",
|
||||||
|
"CEL1922.opt.libel3",
|
||||||
|
"CEL1922.opt.libel4",
|
||||||
|
"CEL1922.opt.libel5",
|
||||||
|
"CEL1922.opt.libel6",
|
||||||
|
"CEL1922.opt.libel7",
|
||||||
|
"CEL1922.opt.libel8"
|
||||||
|
],
|
||||||
|
"anomalytypes": [
|
||||||
|
"CEL1922.opt.none",
|
||||||
|
"CEL1922.opt.entropie",
|
||||||
|
"CEL1922.opt.communicationaveclesmorts",
|
||||||
|
"CEL1922.opt.illusion",
|
||||||
|
"CEL1922.opt.suggestion",
|
||||||
|
"CEL1922.opt.tarotdivinatoire",
|
||||||
|
"CEL1922.opt.telekinesie",
|
||||||
|
"CEL1922.opt.telepathie",
|
||||||
|
"CEL1922.opt.voyageastral"
|
||||||
|
],
|
||||||
|
"ame": {
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0,
|
||||||
|
"artifice": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"attraction": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"coercition": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"faveur": {
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"corps": {
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0,
|
||||||
|
"echauffouree": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"effacement": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"prouesse": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"mobilite": {
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"coeur": {
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0,
|
||||||
|
"appreciation": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"arts": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"inspiration": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"traque": {
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"esprit": {
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0,
|
||||||
|
"instruction": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"mtechnologique": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"raisonnement": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"traitement": {
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"aspecttypes": [
|
||||||
|
"CEL1922.opt.none",
|
||||||
|
"CEL1922.opt.aspect1",
|
||||||
|
"CEL1922.opt.aspect2",
|
||||||
|
"CEL1922.opt.aspect3",
|
||||||
|
"CEL1922.opt.aspect4",
|
||||||
|
"CEL1922.opt.aspect5",
|
||||||
|
"CEL1922.opt.aspect6",
|
||||||
|
"CEL1922.opt.aspect7",
|
||||||
|
"CEL1922.opt.aspect8"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blessures": {
|
||||||
|
"lvl": 0,
|
||||||
|
"blessure_1": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"blessure_2": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"blessure_3": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": -1
|
||||||
|
},
|
||||||
|
"blessure_4": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": -1
|
||||||
|
},
|
||||||
|
"blessure_5": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": -2
|
||||||
|
},
|
||||||
|
"blessure_6": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": -2
|
||||||
|
},
|
||||||
|
"blessure_7": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": -3
|
||||||
|
},
|
||||||
|
"blessure_8": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": -999
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"destin": {
|
||||||
|
"lvl": 0,
|
||||||
|
"destin_1": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"destin_2": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"destin_3": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"destin_4": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"destin_5": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"destin_6": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"destin_7": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"destin_8": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"spleen": {
|
||||||
|
"lvl": 0,
|
||||||
|
"spleen_1": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"spleen_2": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"spleen_3": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"spleen_4": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"spleen_5": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"spleen_6": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"spleen_7": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"spleen_8": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"prototypeToken": {
|
||||||
|
"name": "Ajax",
|
||||||
|
"displayName": 0,
|
||||||
|
"actorLink": false,
|
||||||
|
"appendNumber": false,
|
||||||
|
"prependAdjective": false,
|
||||||
|
"texture": {
|
||||||
|
"src": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/ajax.Token.webp?1719437847752",
|
||||||
|
"scaleX": 1,
|
||||||
|
"scaleY": 1,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"rotation": 0,
|
||||||
|
"anchorX": 0.5,
|
||||||
|
"anchorY": 0.5,
|
||||||
|
"fit": "contain",
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"alphaThreshold": 0.75
|
||||||
|
},
|
||||||
|
"width": 1,
|
||||||
|
"height": 1,
|
||||||
|
"lockRotation": false,
|
||||||
|
"rotation": 0,
|
||||||
|
"alpha": 1,
|
||||||
|
"disposition": -1,
|
||||||
|
"displayBars": 0,
|
||||||
|
"bar1": {
|
||||||
|
"attribute": null
|
||||||
|
},
|
||||||
|
"bar2": {
|
||||||
|
"attribute": null
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"alpha": 0.5,
|
||||||
|
"angle": 360,
|
||||||
|
"bright": 0,
|
||||||
|
"coloration": 1,
|
||||||
|
"dim": 0,
|
||||||
|
"attenuation": 0.5,
|
||||||
|
"luminosity": 0.5,
|
||||||
|
"saturation": 0,
|
||||||
|
"contrast": 0,
|
||||||
|
"shadows": 0,
|
||||||
|
"animation": {
|
||||||
|
"type": null,
|
||||||
|
"speed": 5,
|
||||||
|
"intensity": 5,
|
||||||
|
"reverse": false
|
||||||
|
},
|
||||||
|
"darkness": {
|
||||||
|
"min": 0,
|
||||||
|
"max": 1
|
||||||
|
},
|
||||||
|
"negative": false,
|
||||||
|
"priority": 0,
|
||||||
|
"color": null
|
||||||
|
},
|
||||||
|
"sight": {
|
||||||
|
"enabled": true,
|
||||||
|
"range": 30,
|
||||||
|
"angle": 360,
|
||||||
|
"visionMode": "basic",
|
||||||
|
"color": null,
|
||||||
|
"attenuation": 0.1,
|
||||||
|
"brightness": 0,
|
||||||
|
"saturation": 0,
|
||||||
|
"contrast": 0
|
||||||
|
},
|
||||||
|
"detectionModes": [],
|
||||||
|
"flags": {},
|
||||||
|
"randomImg": false,
|
||||||
|
"occludable": {
|
||||||
|
"radius": 0
|
||||||
|
},
|
||||||
|
"ring": {
|
||||||
|
"enabled": false,
|
||||||
|
"colors": {
|
||||||
|
"ring": null,
|
||||||
|
"background": null
|
||||||
|
},
|
||||||
|
"effects": 1,
|
||||||
|
"subject": {
|
||||||
|
"scale": 1,
|
||||||
|
"texture": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"turnMarker": {
|
||||||
|
"mode": 1,
|
||||||
|
"animation": null,
|
||||||
|
"src": null,
|
||||||
|
"disposition": false
|
||||||
|
},
|
||||||
|
"movementAction": null
|
||||||
|
},
|
||||||
|
"items": [],
|
||||||
|
"effects": [],
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "celestopol1922",
|
||||||
|
"systemVersion": "0.0.7bêta",
|
||||||
|
"coreVersion": "13.348",
|
||||||
|
"createdTime": 1719437808862,
|
||||||
|
"modifiedTime": 1719437944369,
|
||||||
|
"lastModifiedBy": "6VFjkRpqiseDFIh9",
|
||||||
|
"compendiumSource": null,
|
||||||
|
"duplicateSource": null,
|
||||||
|
"exportSource": {
|
||||||
|
"worldId": "celestopol-1922",
|
||||||
|
"uuid": "Actor.QcGcXhb9FvHCb3uf",
|
||||||
|
"coreVersion": "13.351",
|
||||||
|
"systemId": "celestopol1922",
|
||||||
|
"systemVersion": "1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ownership": {
|
||||||
|
"default": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,296 @@
|
|||||||
|
{
|
||||||
|
"_id": "04f6df7b17f747c6",
|
||||||
|
"name": "BAO WANG",
|
||||||
|
"type": "character",
|
||||||
|
"img": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/systems/celestopol1922/images/pj/bao_wang.png?1719410935795",
|
||||||
|
"system": {
|
||||||
|
"concept": "L′ESCROC",
|
||||||
|
"description": "<h1>BAO WANG : L′ESCROC </h1><p></p><p><span class=\"fontstyle0\">Ancien employé du casino flottant la Libellule, Bao Wang officiait comme videur.</span></p><p></p><p><span class=\"fontstyle0\">Après une adolescence de petite frappe dans les faubourgs de Shanghai, il parvint à s’introduire dans un obus-traversier pour rejoindre Célestopol, autant attiré par les perspectives offertes par la cité lunaire que par le besoin de se faire oublier des services de police de sa ville natale.</span></p><p></p><p><span class=\"fontstyle0\">Problème : Bao répugne à se battre et préfère largement la finesse à la violence. De son ancienne vie, il conserve un goût prononcé pour le jeu et la gente féminine. Par ailleurs, Bao a également un certain penchant pour les cabarets clandestins dans lesquels il aime à se travestir à l’occasion. C’est dans l’un de ces lieux interlopes de la cité que le jeune Chinois a rencontré Ernest. Ils ont sympathisé et le vétéran a su voir un certain potentiel chez Bao. Ce dernier, passablement désœuvré et fauché, accepta sans trop y croire d’intégrer l’agence du Lys blanc.</span></p><p></p><p><span class=\"fontstyle0\">Son sens de la débrouillardise et son passé houleux parfois bien utile lui octroient des compétences uniques et font désormais de lui un agent indispensable. Le jeune homme s’investit d’ailleurs sincèrement dans son travail. Toujours tiré à quatre épingles, Bao est reconnu parmi ses coéquipiers comme le plus nonchalant du groupe.</span> <br style=\"font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;orphans:2;text-align:-webkit-auto;text-indent:0px;text-transform:none;white-space:normal;widows:2;word-spacing:0px;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px\" /></p>",
|
||||||
|
"metier": "L′ESCROC",
|
||||||
|
"faction": "",
|
||||||
|
"blessures": {
|
||||||
|
"lvl": 0
|
||||||
|
},
|
||||||
|
"destin": {
|
||||||
|
"lvl": 0
|
||||||
|
},
|
||||||
|
"spleen": {
|
||||||
|
"lvl": 0
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"ame": {
|
||||||
|
"label": "ame",
|
||||||
|
"res": 2,
|
||||||
|
"artifice": {
|
||||||
|
"label": "artifice",
|
||||||
|
"value": 4
|
||||||
|
},
|
||||||
|
"attraction": {
|
||||||
|
"label": "attraction",
|
||||||
|
"value": 2
|
||||||
|
},
|
||||||
|
"coercition": {
|
||||||
|
"label": "coercition",
|
||||||
|
"value": 2
|
||||||
|
},
|
||||||
|
"faveur": {
|
||||||
|
"label": "faveur",
|
||||||
|
"value": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"corps": {
|
||||||
|
"label": "corps",
|
||||||
|
"res": 4,
|
||||||
|
"echauffouree": {
|
||||||
|
"label": "echauffouree",
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"effacement": {
|
||||||
|
"label": "effacement",
|
||||||
|
"value": 4
|
||||||
|
},
|
||||||
|
"mobilite": {
|
||||||
|
"label": "mobilite",
|
||||||
|
"value": 2
|
||||||
|
},
|
||||||
|
"prouesse": {
|
||||||
|
"label": "prouesse",
|
||||||
|
"value": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"coeur": {
|
||||||
|
"label": "coeur",
|
||||||
|
"res": 0,
|
||||||
|
"appreciation": {
|
||||||
|
"label": "appreciation",
|
||||||
|
"value": 2
|
||||||
|
},
|
||||||
|
"arts": {
|
||||||
|
"label": "arts",
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"inspiration": {
|
||||||
|
"label": "inspiration",
|
||||||
|
"value": 1
|
||||||
|
},
|
||||||
|
"traque": {
|
||||||
|
"label": "traque",
|
||||||
|
"value": 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"esprit": {
|
||||||
|
"label": "esprit",
|
||||||
|
"res": 0,
|
||||||
|
"instruction": {
|
||||||
|
"label": "instruction",
|
||||||
|
"value": 1
|
||||||
|
},
|
||||||
|
"mtechnologique": {
|
||||||
|
"label": "mtechnologique",
|
||||||
|
"value": 2
|
||||||
|
},
|
||||||
|
"raisonnement": {
|
||||||
|
"label": "raisonnement",
|
||||||
|
"value": 1
|
||||||
|
},
|
||||||
|
"traitement": {
|
||||||
|
"label": "traitement",
|
||||||
|
"value": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"anomaly": {
|
||||||
|
"type": "entropie",
|
||||||
|
"value": 1
|
||||||
|
},
|
||||||
|
"attributs": {
|
||||||
|
"entregent": {
|
||||||
|
"value": 0,
|
||||||
|
"max": 0
|
||||||
|
},
|
||||||
|
"fortune": {
|
||||||
|
"value": 0,
|
||||||
|
"max": 0
|
||||||
|
},
|
||||||
|
"reve": {
|
||||||
|
"value": 0,
|
||||||
|
"max": 0
|
||||||
|
},
|
||||||
|
"vision": {
|
||||||
|
"value": 0,
|
||||||
|
"max": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"historique": "<h1>BAO WANG : L′ESCROC </h1><p></p><p><span class=\"fontstyle0\">Ancien employé du casino flottant la Libellule, Bao Wang officiait comme videur.</span></p><p></p><p><span class=\"fontstyle0\">Après une adolescence de petite frappe dans les faubourgs de Shanghai, il parvint à s’introduire dans un obus-traversier pour rejoindre Célestopol, autant attiré par les perspectives offertes par la cité lunaire que par le besoin de se faire oublier des services de police de sa ville natale.</span></p><p></p><p><span class=\"fontstyle0\">Problème : Bao répugne à se battre et préfère largement la finesse à la violence. De son ancienne vie, il conserve un goût prononcé pour le jeu et la gente féminine. Par ailleurs, Bao a également un certain penchant pour les cabarets clandestins dans lesquels il aime à se travestir à l’occasion. C’est dans l’un de ces lieux interlopes de la cité que le jeune Chinois a rencontré Ernest. Ils ont sympathisé et le vétéran a su voir un certain potentiel chez Bao. Ce dernier, passablement désœuvré et fauché, accepta sans trop y croire d’intégrer l’agence du Lys blanc.</span></p><p></p><p><span class=\"fontstyle0\">Son sens de la débrouillardise et son passé houleux parfois bien utile lui octroient des compétences uniques et font désormais de lui un agent indispensable. Le jeune homme s’investit d’ailleurs sincèrement dans son travail. Toujours tiré à quatre épingles, Bao est reconnu parmi ses coéquipiers comme le plus nonchalant du groupe.</span> <br style=\"font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;orphans:2;text-align:-webkit-auto;text-indent:0px;text-transform:none;white-space:normal;widows:2;word-spacing:0px;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px\" /></p>",
|
||||||
|
"descriptionPhysique": "",
|
||||||
|
"descriptionPsychologique": "",
|
||||||
|
"initiative": 0,
|
||||||
|
"factions": {
|
||||||
|
"pinkerton": 0,
|
||||||
|
"police": 0,
|
||||||
|
"okhrana": 0,
|
||||||
|
"lunanovatek": 0,
|
||||||
|
"oto": 0,
|
||||||
|
"syndicats": 0,
|
||||||
|
"vorovskoymir": 0,
|
||||||
|
"cour": 0,
|
||||||
|
"perso": 0,
|
||||||
|
"libel": "",
|
||||||
|
"perso2": 0,
|
||||||
|
"libel2": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"_id": "23315ed101e248c8",
|
||||||
|
"name": "Entropie 1",
|
||||||
|
"img": "https://assets.forge-vtt.com/bazaar/core/icons/svg/item-bag.svg",
|
||||||
|
"effects": [],
|
||||||
|
"flags": {},
|
||||||
|
"sort": 0,
|
||||||
|
"type": "anomaly",
|
||||||
|
"system": {
|
||||||
|
"subtype": "entropie",
|
||||||
|
"level": 1,
|
||||||
|
"usesRemaining": 1,
|
||||||
|
"technique": "<p><span class=\"fontstyle0\">Bao peut relancer le dé de la Lune une fois lors d’un même scénario et choisit de conserver le résultat qu’il préfère (cette faculté ne fonctionne pas sur les tests de chance).</span></p>",
|
||||||
|
"narratif": "<p><span class=\"fontstyle0\">Bao peut influer sur le hasard de manière mineure. </span><span class=\"fontstyle2\">Exemple : <em>avoir une bonne main en jouant au poker à la distribution, que le feu soit au vert en tournant au coin de la rue, etc.</em></span></p>"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_id": "4edb4b80b9514a7b",
|
||||||
|
"name": "Belle gueule 2",
|
||||||
|
"img": "https://assets.forge-vtt.com/bazaar/core/icons/svg/item-bag.svg",
|
||||||
|
"effects": [],
|
||||||
|
"flags": {},
|
||||||
|
"sort": 0,
|
||||||
|
"type": "aspect",
|
||||||
|
"system": {
|
||||||
|
"valeur": 2,
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_id": "153b0a094ca4462e",
|
||||||
|
"name": "Aime le jeu 1",
|
||||||
|
"img": "https://assets.forge-vtt.com/bazaar/core/icons/svg/item-bag.svg",
|
||||||
|
"effects": [],
|
||||||
|
"flags": {},
|
||||||
|
"sort": 0,
|
||||||
|
"type": "aspect",
|
||||||
|
"system": {
|
||||||
|
"valeur": 1,
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_id": "cbdc76f66bd041a0",
|
||||||
|
"name": "Nouvel Équipement",
|
||||||
|
"img": "https://assets.forge-vtt.com/bazaar/core/icons/svg/item-bag.svg",
|
||||||
|
"effects": [],
|
||||||
|
"flags": {},
|
||||||
|
"sort": 0,
|
||||||
|
"type": "equipment",
|
||||||
|
"system": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"effects": [],
|
||||||
|
"folder": null,
|
||||||
|
"flags": {},
|
||||||
|
"prototypeToken": {
|
||||||
|
"name": "BAO WANG",
|
||||||
|
"displayName": 0,
|
||||||
|
"actorLink": false,
|
||||||
|
"appendNumber": false,
|
||||||
|
"prependAdjective": false,
|
||||||
|
"texture": {
|
||||||
|
"src": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/bao_wang.Token.webp?1719410935795",
|
||||||
|
"scaleX": 1,
|
||||||
|
"scaleY": 1,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"rotation": 0,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"anchorX": 0.5,
|
||||||
|
"anchorY": 0.5,
|
||||||
|
"fit": "contain",
|
||||||
|
"alphaThreshold": 0.75
|
||||||
|
},
|
||||||
|
"width": 1,
|
||||||
|
"height": 1,
|
||||||
|
"lockRotation": false,
|
||||||
|
"rotation": 0,
|
||||||
|
"alpha": 1,
|
||||||
|
"disposition": -1,
|
||||||
|
"displayBars": 0,
|
||||||
|
"bar1": {
|
||||||
|
"attribute": null
|
||||||
|
},
|
||||||
|
"bar2": {
|
||||||
|
"attribute": null
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"alpha": 0.5,
|
||||||
|
"angle": 360,
|
||||||
|
"bright": 0,
|
||||||
|
"coloration": 1,
|
||||||
|
"dim": 0,
|
||||||
|
"attenuation": 0.5,
|
||||||
|
"luminosity": 0.5,
|
||||||
|
"saturation": 0,
|
||||||
|
"contrast": 0,
|
||||||
|
"shadows": 0,
|
||||||
|
"animation": {
|
||||||
|
"type": null,
|
||||||
|
"speed": 5,
|
||||||
|
"intensity": 5,
|
||||||
|
"reverse": false
|
||||||
|
},
|
||||||
|
"darkness": {
|
||||||
|
"min": 0,
|
||||||
|
"max": 1
|
||||||
|
},
|
||||||
|
"color": null,
|
||||||
|
"negative": false,
|
||||||
|
"priority": 0
|
||||||
|
},
|
||||||
|
"sight": {
|
||||||
|
"enabled": false,
|
||||||
|
"range": 0,
|
||||||
|
"angle": 360,
|
||||||
|
"visionMode": "basic",
|
||||||
|
"attenuation": 0.1,
|
||||||
|
"brightness": 0,
|
||||||
|
"saturation": 0,
|
||||||
|
"contrast": 0,
|
||||||
|
"color": null
|
||||||
|
},
|
||||||
|
"detectionModes": [],
|
||||||
|
"flags": {},
|
||||||
|
"randomImg": false,
|
||||||
|
"occludable": {
|
||||||
|
"radius": 0
|
||||||
|
},
|
||||||
|
"ring": {
|
||||||
|
"enabled": false,
|
||||||
|
"colors": {
|
||||||
|
"ring": null,
|
||||||
|
"background": null
|
||||||
|
},
|
||||||
|
"effects": 1,
|
||||||
|
"subject": {
|
||||||
|
"scale": 1,
|
||||||
|
"texture": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"turnMarker": {
|
||||||
|
"mode": 1,
|
||||||
|
"animation": null,
|
||||||
|
"src": null,
|
||||||
|
"disposition": false
|
||||||
|
},
|
||||||
|
"movementAction": null
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,143 @@
|
|||||||
|
{
|
||||||
|
"_id": "fabe178df844475b",
|
||||||
|
"name": "Citoyen",
|
||||||
|
"type": "npc",
|
||||||
|
"img": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/citoyen.Avatar.webp?1719438184882",
|
||||||
|
"system": {
|
||||||
|
"concept": "",
|
||||||
|
"description": "",
|
||||||
|
"metier": "",
|
||||||
|
"faction": "",
|
||||||
|
"blessures": {
|
||||||
|
"lvl": 0
|
||||||
|
},
|
||||||
|
"destin": {
|
||||||
|
"lvl": 0
|
||||||
|
},
|
||||||
|
"spleen": {
|
||||||
|
"lvl": 0
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"ame": {
|
||||||
|
"label": "ame",
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0
|
||||||
|
},
|
||||||
|
"corps": {
|
||||||
|
"label": "corps",
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0
|
||||||
|
},
|
||||||
|
"coeur": {
|
||||||
|
"label": "coeur",
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0
|
||||||
|
},
|
||||||
|
"esprit": {
|
||||||
|
"label": "esprit",
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"npcType": "standard",
|
||||||
|
"historique": ""
|
||||||
|
},
|
||||||
|
"items": [],
|
||||||
|
"effects": [],
|
||||||
|
"folder": null,
|
||||||
|
"flags": {},
|
||||||
|
"prototypeToken": {
|
||||||
|
"name": "Citoyen",
|
||||||
|
"displayName": 0,
|
||||||
|
"actorLink": false,
|
||||||
|
"appendNumber": false,
|
||||||
|
"prependAdjective": false,
|
||||||
|
"texture": {
|
||||||
|
"src": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/citoyen.Token.webp?1719438184882",
|
||||||
|
"scaleX": 1,
|
||||||
|
"scaleY": 1,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"rotation": 0,
|
||||||
|
"anchorX": 0.5,
|
||||||
|
"anchorY": 0.5,
|
||||||
|
"fit": "contain",
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"alphaThreshold": 0.75
|
||||||
|
},
|
||||||
|
"width": 1,
|
||||||
|
"height": 1,
|
||||||
|
"lockRotation": false,
|
||||||
|
"rotation": 0,
|
||||||
|
"alpha": 1,
|
||||||
|
"disposition": -1,
|
||||||
|
"displayBars": 0,
|
||||||
|
"bar1": {
|
||||||
|
"attribute": null
|
||||||
|
},
|
||||||
|
"bar2": {
|
||||||
|
"attribute": null
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"alpha": 0.5,
|
||||||
|
"angle": 360,
|
||||||
|
"bright": 0,
|
||||||
|
"coloration": 1,
|
||||||
|
"dim": 0,
|
||||||
|
"attenuation": 0.5,
|
||||||
|
"luminosity": 0.5,
|
||||||
|
"saturation": 0,
|
||||||
|
"contrast": 0,
|
||||||
|
"shadows": 0,
|
||||||
|
"animation": {
|
||||||
|
"type": null,
|
||||||
|
"speed": 5,
|
||||||
|
"intensity": 5,
|
||||||
|
"reverse": false
|
||||||
|
},
|
||||||
|
"darkness": {
|
||||||
|
"min": 0,
|
||||||
|
"max": 1
|
||||||
|
},
|
||||||
|
"negative": false,
|
||||||
|
"priority": 0,
|
||||||
|
"color": null
|
||||||
|
},
|
||||||
|
"sight": {
|
||||||
|
"enabled": true,
|
||||||
|
"range": 30,
|
||||||
|
"angle": 360,
|
||||||
|
"visionMode": "basic",
|
||||||
|
"color": null,
|
||||||
|
"attenuation": 0.1,
|
||||||
|
"brightness": 0,
|
||||||
|
"saturation": 0,
|
||||||
|
"contrast": 0
|
||||||
|
},
|
||||||
|
"detectionModes": [],
|
||||||
|
"flags": {},
|
||||||
|
"randomImg": false,
|
||||||
|
"occludable": {
|
||||||
|
"radius": 0
|
||||||
|
},
|
||||||
|
"ring": {
|
||||||
|
"enabled": false,
|
||||||
|
"colors": {
|
||||||
|
"ring": null,
|
||||||
|
"background": null
|
||||||
|
},
|
||||||
|
"effects": 1,
|
||||||
|
"subject": {
|
||||||
|
"scale": 1,
|
||||||
|
"texture": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"turnMarker": {
|
||||||
|
"mode": 1,
|
||||||
|
"animation": null,
|
||||||
|
"src": null,
|
||||||
|
"disposition": false
|
||||||
|
},
|
||||||
|
"movementAction": null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,459 @@
|
|||||||
|
{
|
||||||
|
"folder": "5aDs3Gbi2cHy35X9",
|
||||||
|
"name": "Citoyen",
|
||||||
|
"type": "npc",
|
||||||
|
"img": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/citoyen.Avatar.webp?1719438184882",
|
||||||
|
"system": {
|
||||||
|
"concept": "",
|
||||||
|
"anomaly": "0",
|
||||||
|
"anomalyval": 0,
|
||||||
|
"anomalymax": "0",
|
||||||
|
"initiative": 0,
|
||||||
|
"description": "",
|
||||||
|
"prefs": {
|
||||||
|
"typeofthrow": {
|
||||||
|
"check": true,
|
||||||
|
"choice": "0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"typeofthrow": {
|
||||||
|
"check": true,
|
||||||
|
"choice": "0"
|
||||||
|
},
|
||||||
|
"configure": {
|
||||||
|
"numberofdice": 0,
|
||||||
|
"aspect": 0,
|
||||||
|
"bonus": 0,
|
||||||
|
"bonusauspiciousdice": 0,
|
||||||
|
"typeofthrow": 0,
|
||||||
|
"aspectskill": 0,
|
||||||
|
"bonusmalusskill": 0,
|
||||||
|
"aspectspeciality": 0,
|
||||||
|
"rolldifficulty": 0,
|
||||||
|
"bonusmalusspeciality": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"skill": {
|
||||||
|
"skilltypes": [
|
||||||
|
"CEL1922.opt.ame",
|
||||||
|
"CEL1922.opt.attraction",
|
||||||
|
"CEL1922.opt.artifice",
|
||||||
|
"CEL1922.opt.coercition",
|
||||||
|
"CEL1922.opt.faveur",
|
||||||
|
"CEL1922.opt.corps",
|
||||||
|
"CEL1922.opt.echauffouree",
|
||||||
|
"CEL1922.opt.effacement",
|
||||||
|
"CEL1922.opt.prouesse",
|
||||||
|
"CEL1922.opt.mobilite",
|
||||||
|
"CEL1922.opt.coeur",
|
||||||
|
"CEL1922.opt.appreciation",
|
||||||
|
"CEL1922.opt.arts",
|
||||||
|
"CEL1922.opt.inspiration",
|
||||||
|
"CEL1922.opt.traque",
|
||||||
|
"CEL1922.opt.esprit",
|
||||||
|
"CEL1922.opt.instruction",
|
||||||
|
"CEL1922.opt.mtechnologique",
|
||||||
|
"CEL1922.opt.raisonnement",
|
||||||
|
"CEL1922.opt.traitement"
|
||||||
|
],
|
||||||
|
"moondicetypes": [
|
||||||
|
"CEL1922.opt.nouvellelune",
|
||||||
|
"CEL1922.opt.premiercroissant",
|
||||||
|
"CEL1922.opt.premierquartier",
|
||||||
|
"CEL1922.opt.lunegibbeuse",
|
||||||
|
"CEL1922.opt.lunevoutee",
|
||||||
|
"CEL1922.opt.derniercroissant",
|
||||||
|
"CEL1922.opt.dernierquartier",
|
||||||
|
"CEL1922.opt.pleinelune"
|
||||||
|
],
|
||||||
|
"woundstypes": [
|
||||||
|
"CEL1922.opt.none",
|
||||||
|
"CEL1922.opt.anodin",
|
||||||
|
"CEL1922.opt.derisoire",
|
||||||
|
"CEL1922.opt.negligeable",
|
||||||
|
"CEL1922.opt.superficiel",
|
||||||
|
"CEL1922.opt.leger",
|
||||||
|
"CEL1922.opt.modere",
|
||||||
|
"CEL1922.opt.grave",
|
||||||
|
"CEL1922.opt.dramatique"
|
||||||
|
],
|
||||||
|
"woundsmalus": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-2,
|
||||||
|
-2,
|
||||||
|
-3,
|
||||||
|
-999
|
||||||
|
],
|
||||||
|
"woundsrecup": [
|
||||||
|
"CEL1922.opt.none",
|
||||||
|
"CEL1922.1 minute",
|
||||||
|
"CEL1922.1 minute",
|
||||||
|
"CEL1922.10 minutes",
|
||||||
|
"CEL1922.10 minutes",
|
||||||
|
"CEL1922.30 minutes",
|
||||||
|
"CEL1922.30 minutes",
|
||||||
|
"CEL1922.1 day",
|
||||||
|
"CEL1922.Out of Fiction"
|
||||||
|
],
|
||||||
|
"destinytypes": [
|
||||||
|
"CEL1922.opt.none",
|
||||||
|
"CEL1922.opt.libel1",
|
||||||
|
"CEL1922.opt.libel2",
|
||||||
|
"CEL1922.opt.libel3",
|
||||||
|
"CEL1922.opt.libel4",
|
||||||
|
"CEL1922.opt.libel5",
|
||||||
|
"CEL1922.opt.libel6",
|
||||||
|
"CEL1922.opt.libel7",
|
||||||
|
"CEL1922.opt.libel8"
|
||||||
|
],
|
||||||
|
"spleentypes": [
|
||||||
|
"CEL1922.opt.none",
|
||||||
|
"CEL1922.opt.libel1",
|
||||||
|
"CEL1922.opt.libel2",
|
||||||
|
"CEL1922.opt.libel3",
|
||||||
|
"CEL1922.opt.libel4",
|
||||||
|
"CEL1922.opt.libel5",
|
||||||
|
"CEL1922.opt.libel6",
|
||||||
|
"CEL1922.opt.libel7",
|
||||||
|
"CEL1922.opt.libel8"
|
||||||
|
],
|
||||||
|
"anomalytypes": [
|
||||||
|
"CEL1922.opt.none",
|
||||||
|
"CEL1922.opt.entropie",
|
||||||
|
"CEL1922.opt.communicationaveclesmorts",
|
||||||
|
"CEL1922.opt.illusion",
|
||||||
|
"CEL1922.opt.suggestion",
|
||||||
|
"CEL1922.opt.tarotdivinatoire",
|
||||||
|
"CEL1922.opt.telekinesie",
|
||||||
|
"CEL1922.opt.telepathie",
|
||||||
|
"CEL1922.opt.voyageastral"
|
||||||
|
],
|
||||||
|
"ame": {
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0,
|
||||||
|
"artifice": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"attraction": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"coercition": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"faveur": {
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"corps": {
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0,
|
||||||
|
"echauffouree": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"effacement": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"prouesse": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"mobilite": {
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"coeur": {
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0,
|
||||||
|
"appreciation": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"arts": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"inspiration": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"traque": {
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"esprit": {
|
||||||
|
"res": 0,
|
||||||
|
"actuel": 0,
|
||||||
|
"instruction": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"mtechnologique": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"raisonnement": {
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
"traitement": {
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"aspecttypes": [
|
||||||
|
"CEL1922.opt.none",
|
||||||
|
"CEL1922.opt.aspect1",
|
||||||
|
"CEL1922.opt.aspect2",
|
||||||
|
"CEL1922.opt.aspect3",
|
||||||
|
"CEL1922.opt.aspect4",
|
||||||
|
"CEL1922.opt.aspect5",
|
||||||
|
"CEL1922.opt.aspect6",
|
||||||
|
"CEL1922.opt.aspect7",
|
||||||
|
"CEL1922.opt.aspect8"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blessures": {
|
||||||
|
"lvl": 0,
|
||||||
|
"blessure_1": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"blessure_2": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"blessure_3": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": -1
|
||||||
|
},
|
||||||
|
"blessure_4": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": -1
|
||||||
|
},
|
||||||
|
"blessure_5": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": -2
|
||||||
|
},
|
||||||
|
"blessure_6": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": -2
|
||||||
|
},
|
||||||
|
"blessure_7": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": -3
|
||||||
|
},
|
||||||
|
"blessure_8": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": -999
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"destin": {
|
||||||
|
"lvl": 0,
|
||||||
|
"destin_1": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"destin_2": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"destin_3": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"destin_4": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"destin_5": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"destin_6": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"destin_7": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"destin_8": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"spleen": {
|
||||||
|
"lvl": 0,
|
||||||
|
"spleen_1": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"spleen_2": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"spleen_3": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"spleen_4": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"spleen_5": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"spleen_6": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"spleen_7": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
},
|
||||||
|
"spleen_8": {
|
||||||
|
"check": false,
|
||||||
|
"bonus": 0,
|
||||||
|
"malus": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"prototypeToken": {
|
||||||
|
"name": "Citoyen",
|
||||||
|
"displayName": 0,
|
||||||
|
"actorLink": false,
|
||||||
|
"appendNumber": false,
|
||||||
|
"prependAdjective": false,
|
||||||
|
"texture": {
|
||||||
|
"src": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/citoyen.Token.webp?1719438184882",
|
||||||
|
"scaleX": 1,
|
||||||
|
"scaleY": 1,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"rotation": 0,
|
||||||
|
"anchorX": 0.5,
|
||||||
|
"anchorY": 0.5,
|
||||||
|
"fit": "contain",
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"alphaThreshold": 0.75
|
||||||
|
},
|
||||||
|
"width": 1,
|
||||||
|
"height": 1,
|
||||||
|
"lockRotation": false,
|
||||||
|
"rotation": 0,
|
||||||
|
"alpha": 1,
|
||||||
|
"disposition": -1,
|
||||||
|
"displayBars": 0,
|
||||||
|
"bar1": {
|
||||||
|
"attribute": null
|
||||||
|
},
|
||||||
|
"bar2": {
|
||||||
|
"attribute": null
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"alpha": 0.5,
|
||||||
|
"angle": 360,
|
||||||
|
"bright": 0,
|
||||||
|
"coloration": 1,
|
||||||
|
"dim": 0,
|
||||||
|
"attenuation": 0.5,
|
||||||
|
"luminosity": 0.5,
|
||||||
|
"saturation": 0,
|
||||||
|
"contrast": 0,
|
||||||
|
"shadows": 0,
|
||||||
|
"animation": {
|
||||||
|
"type": null,
|
||||||
|
"speed": 5,
|
||||||
|
"intensity": 5,
|
||||||
|
"reverse": false
|
||||||
|
},
|
||||||
|
"darkness": {
|
||||||
|
"min": 0,
|
||||||
|
"max": 1
|
||||||
|
},
|
||||||
|
"negative": false,
|
||||||
|
"priority": 0,
|
||||||
|
"color": null
|
||||||
|
},
|
||||||
|
"sight": {
|
||||||
|
"enabled": true,
|
||||||
|
"range": 30,
|
||||||
|
"angle": 360,
|
||||||
|
"visionMode": "basic",
|
||||||
|
"color": null,
|
||||||
|
"attenuation": 0.1,
|
||||||
|
"brightness": 0,
|
||||||
|
"saturation": 0,
|
||||||
|
"contrast": 0
|
||||||
|
},
|
||||||
|
"detectionModes": [],
|
||||||
|
"flags": {},
|
||||||
|
"randomImg": false,
|
||||||
|
"occludable": {
|
||||||
|
"radius": 0
|
||||||
|
},
|
||||||
|
"ring": {
|
||||||
|
"enabled": false,
|
||||||
|
"colors": {
|
||||||
|
"ring": null,
|
||||||
|
"background": null
|
||||||
|
},
|
||||||
|
"effects": 1,
|
||||||
|
"subject": {
|
||||||
|
"scale": 1,
|
||||||
|
"texture": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"turnMarker": {
|
||||||
|
"mode": 1,
|
||||||
|
"animation": null,
|
||||||
|
"src": null,
|
||||||
|
"disposition": false
|
||||||
|
},
|
||||||
|
"movementAction": null
|
||||||
|
},
|
||||||
|
"items": [],
|
||||||
|
"effects": [],
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"systemId": "celestopol1922",
|
||||||
|
"systemVersion": "0.0.7bêta",
|
||||||
|
"coreVersion": "13.348",
|
||||||
|
"createdTime": 1719438039685,
|
||||||
|
"modifiedTime": 1719438184895,
|
||||||
|
"lastModifiedBy": "6VFjkRpqiseDFIh9",
|
||||||
|
"compendiumSource": null,
|
||||||
|
"duplicateSource": null,
|
||||||
|
"exportSource": {
|
||||||
|
"worldId": "celestopol-1922",
|
||||||
|
"uuid": "Actor.H4qPWYC8kbacuBfm",
|
||||||
|
"coreVersion": "13.351",
|
||||||
|
"systemId": "celestopol1922",
|
||||||
|
"systemVersion": "1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ownership": {
|
||||||
|
"default": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
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.
|
After Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 131 KiB |
+439
-2
@@ -39,9 +39,11 @@ import {
|
|||||||
} from "./module/applications/_module.mjs"
|
} from "./module/applications/_module.mjs"
|
||||||
|
|
||||||
const DAMAGE_APPLICATION_FLAG = "damageApplication"
|
const DAMAGE_APPLICATION_FLAG = "damageApplication"
|
||||||
|
const MOON_EFFECT_FLAG = "moonEffectApplied"
|
||||||
const FACTION_ASPECT_STATE_SETTING = "factionAspectState"
|
const FACTION_ASPECT_STATE_SETTING = "factionAspectState"
|
||||||
const PREGENS_IMPORTED_SETTING = "pregensImported"
|
const PREGENS_IMPORTED_SETTING = "pregensImported"
|
||||||
const WELCOME_SCENE_IMPORTED_SETTING = "welcomeSceneImported"
|
const WELCOME_SCENE_IMPORTED_SETTING = "welcomeSceneImported"
|
||||||
|
const DEFAULT_ROLL_THRESHOLD_SETTING = "defaultRollThreshold"
|
||||||
|
|
||||||
/* ─── Init hook ──────────────────────────────────────────────────────────── */
|
/* ─── Init hook ──────────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
@@ -64,8 +66,10 @@ Hooks.once("init", () => {
|
|||||||
// Expose SYSTEM constants + utilities globales
|
// Expose SYSTEM constants + utilities globales
|
||||||
game.celestopol = {
|
game.celestopol = {
|
||||||
SYSTEM,
|
SYSTEM,
|
||||||
|
DEFAULT_ROLL_THRESHOLD_SETTING,
|
||||||
rollMoonStandalone: (actor = null) => CelestopolRoll.rollMoonStandalone(actor),
|
rollMoonStandalone: (actor = null) => CelestopolRoll.rollMoonStandalone(actor),
|
||||||
manageFactionAspects: (actor = null) => _manageFactionAspects(actor),
|
manageFactionAspects: (actor = null) => _manageFactionAspects(actor),
|
||||||
|
resetFactionAspects: () => _resetFactionAspects(),
|
||||||
getFactionAspectState: () => _getFactionAspectState(),
|
getFactionAspectState: () => _getFactionAspectState(),
|
||||||
getFactionAspectSummary: (actor = null) => _getFactionAspectSummary(actor),
|
getFactionAspectSummary: (actor = null) => _getFactionAspectSummary(actor),
|
||||||
getFactionDisplayLabel: (value) => _getFactionDisplayLabel(value),
|
getFactionDisplayLabel: (value) => _getFactionDisplayLabel(value),
|
||||||
@@ -173,6 +177,9 @@ Hooks.once("ready", async () => {
|
|||||||
if (foundry.utils.hasProperty(changed, `flags.${SYSTEM_ID}.${DAMAGE_APPLICATION_FLAG}`)) {
|
if (foundry.utils.hasProperty(changed, `flags.${SYSTEM_ID}.${DAMAGE_APPLICATION_FLAG}`)) {
|
||||||
_updateRenderedChatMessageState(message)
|
_updateRenderedChatMessageState(message)
|
||||||
}
|
}
|
||||||
|
if (foundry.utils.hasProperty(changed, `flags.${SYSTEM_ID}.${MOON_EFFECT_FLAG}`)) {
|
||||||
|
_updateRenderedMoonEffectState(message)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
_activateExistingChatCards()
|
_activateExistingChatCards()
|
||||||
|
|
||||||
@@ -352,11 +359,269 @@ function _registerHandlebarsHelpers() {
|
|||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Helper : récupérer un setting système par son nom
|
||||||
|
Handlebars.registerHelper("getSetting", (settingName) => {
|
||||||
|
return game.settings.get(SYSTEM_ID, settingName)
|
||||||
|
})
|
||||||
|
|
||||||
Handlebars.registerHelper("let", function(value, options) {
|
Handlebars.registerHelper("let", function(value, options) {
|
||||||
return options.fn({ value })
|
return options.fn({ value })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ─── Migration depuis l'ancien système ─────────────────────────────────── */
|
||||||
|
|
||||||
|
/** Mapping des types d'anomalies ancien→nouveau */
|
||||||
|
const _OLD_ANOMALY_TYPES = [
|
||||||
|
"none", "entropie", "communicationaveclesmorts", "illusion",
|
||||||
|
"suggestion", "tarotdivinatoire", "telekinesie", "telepathie", "voyageastral",
|
||||||
|
]
|
||||||
|
|
||||||
|
const _OLD_SKILLS = {
|
||||||
|
ame: ["artifice", "attraction", "coercition", "faveur"],
|
||||||
|
corps: ["echauffouree", "effacement", "mobilite", "prouesse"],
|
||||||
|
coeur: ["appreciation", "arts", "inspiration", "traque"],
|
||||||
|
esprit: ["instruction", "mtechnologique", "raisonnement", "traitement"],
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Infère le type d'anomalie depuis le nom de l'item (ex: "Entropie 1" → "entropie"). */
|
||||||
|
function _anomalyTypeFromName(name) {
|
||||||
|
let n = name.toLowerCase().replace(/\s*\d+\s*$/, "").replace(/\s+/g, "")
|
||||||
|
const accents = [["é","e"],["è","e"],["ê","e"],["ë","e"],["à","a"],["â","a"],
|
||||||
|
["î","i"],["ï","i"],["ô","o"],["û","u"],["ù","u"],["ü","u"],["ç","c"]]
|
||||||
|
for (const [s,d] of accents) n = n.replaceAll(s, d)
|
||||||
|
return _OLD_ANOMALY_TYPES.find(k => k !== "none" && (k.includes(n) || n.includes(k))) ?? "none"
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convertit les stats d'un PJ (skill → stats). */
|
||||||
|
function _convertStatsCharacter(oldSkill) {
|
||||||
|
const stats = {}
|
||||||
|
for (const stat of ["ame","corps","coeur","esprit"]) {
|
||||||
|
const os = oldSkill[stat] ?? {}
|
||||||
|
const ns = { label: stat, res: Number(os.res ?? 0) }
|
||||||
|
for (const sk of _OLD_SKILLS[stat]) {
|
||||||
|
const val = Number(os[sk]?.value ?? 0) || 0
|
||||||
|
ns[sk] = { label: sk, value: val }
|
||||||
|
}
|
||||||
|
stats[stat] = ns
|
||||||
|
}
|
||||||
|
return stats
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convertit les stats d'un PNJ (skill → stats avec actuel). */
|
||||||
|
function _convertStatsNPC(oldSkill) {
|
||||||
|
const stats = {}
|
||||||
|
for (const stat of ["ame","corps","coeur","esprit"]) {
|
||||||
|
const res = Number(oldSkill[stat]?.res ?? 0)
|
||||||
|
stats[stat] = { label: stat, res, actuel: res }
|
||||||
|
}
|
||||||
|
return stats
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convertit les attributs du format plat vers {value, max}. */
|
||||||
|
function _convertAttributs(a = {}) {
|
||||||
|
return {
|
||||||
|
entregent: { value: Number(a.entregent ?? 0), max: Number(a.entregentmax ?? 0) },
|
||||||
|
fortune: { value: Number(a.fortune ?? 0), max: Number(a.fortunemax ?? 0) },
|
||||||
|
reve: { value: Number(a.reve ?? 0), max: Number(a.revemax ?? 0) },
|
||||||
|
vision: { value: Number(a.vision ?? 0), max: Number(a.visionmax ?? 0) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convertit un item de l'ancien format. Retourne null si ignoré. */
|
||||||
|
function _convertItem(item, warnings) {
|
||||||
|
const os = item.system ?? {}
|
||||||
|
const name = item.name ?? "Sans nom"
|
||||||
|
const base = {
|
||||||
|
name,
|
||||||
|
img: item.img ?? "icons/svg/item-bag.svg",
|
||||||
|
effects: [],
|
||||||
|
flags: {},
|
||||||
|
sort: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.type === "anomaly") {
|
||||||
|
const level = Math.max(1, Math.min(4, Number(os.value ?? 1) || 1))
|
||||||
|
const subtype = _anomalyTypeFromName(name)
|
||||||
|
if (subtype === "none")
|
||||||
|
warnings.push(`Impossible de déterminer le type d'anomalie depuis "${name}"`)
|
||||||
|
return { ...base, type: "anomaly", system: {
|
||||||
|
subtype, level, usesRemaining: level,
|
||||||
|
technique: os.technique ?? "", narratif: os.narratif ?? "",
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.type === "aspect") {
|
||||||
|
return { ...base, type: "aspect", system: {
|
||||||
|
valeur: Number(os.value ?? 0) || 0,
|
||||||
|
description: os.narratif ?? os.technique ?? "",
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.type === "item") {
|
||||||
|
const sub = (os.subtype ?? "").toLowerCase()
|
||||||
|
if (sub === "weapon") {
|
||||||
|
if (os.damage) warnings.push(`"${name}" : dégâts "${os.damage}" à saisir manuellement`)
|
||||||
|
return { ...base, type: "weapon", system: {
|
||||||
|
type: "melee", degats: "0", portee: "contact", equipped: false,
|
||||||
|
description: os.technique ?? os.narratif ?? "",
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
if (sub === "armor") {
|
||||||
|
if (os.protection) warnings.push(`"${name}" : protection "${os.protection}" à saisir manuellement`)
|
||||||
|
return { ...base, type: "armure", system: {
|
||||||
|
protection: 1, malus: 1, equipped: false,
|
||||||
|
description: os.technique ?? os.narratif ?? "",
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
return { ...base, type: "equipment", system: {
|
||||||
|
description: os.technique ?? os.narratif ?? "",
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
warnings.push(`Type d'item inconnu "${item.type}" pour "${name}", ignoré`)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convertit un acteur complet de l'ancien format vers le nouveau. */
|
||||||
|
function _convertOldActor(old) {
|
||||||
|
const warnings = []
|
||||||
|
const os = old.system ?? {}
|
||||||
|
const osk = os.skill ?? {}
|
||||||
|
const type = old.type ?? "character"
|
||||||
|
|
||||||
|
// Anomalie : résolution depuis l'index stocké dans os.anomaly
|
||||||
|
const anomalyIdx = Number(os.anomaly ?? 0)
|
||||||
|
const anomalyTypes = osk.anomalytypes ?? _OLD_ANOMALY_TYPES.map(k => `CEL1922.opt.${k}`)
|
||||||
|
const rawAnomalyKey = (anomalyTypes[anomalyIdx] ?? "").split(".").pop() ?? "none"
|
||||||
|
const anomalyType = _OLD_ANOMALY_TYPES.includes(rawAnomalyKey) ? rawAnomalyKey : "none"
|
||||||
|
|
||||||
|
const sys = {
|
||||||
|
concept: os.concept ?? "",
|
||||||
|
metier: os.metier ?? os.concept ?? "",
|
||||||
|
faction: os.faction ?? "",
|
||||||
|
blessures: { lvl: Number(os.blessures?.lvl ?? 0) },
|
||||||
|
destin: { lvl: Number(os.destin?.lvl ?? 0) },
|
||||||
|
spleen: { lvl: Number(os.spleen?.lvl ?? 0) },
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === "character") {
|
||||||
|
sys.stats = _convertStatsCharacter(osk)
|
||||||
|
sys.anomaly = { type: anomalyType, value: Number(os.anomalyval ?? 0) }
|
||||||
|
sys.attributs = _convertAttributs(os.attributs)
|
||||||
|
sys.historique = os.description ?? ""
|
||||||
|
sys.descriptionPhysique = ""
|
||||||
|
sys.descriptionPsychologique = ""
|
||||||
|
sys.initiative = 0
|
||||||
|
sys.factions = os.factions ?? {}
|
||||||
|
} else {
|
||||||
|
sys.stats = _convertStatsNPC(osk)
|
||||||
|
sys.npcType = os.npcType ?? "standard"
|
||||||
|
sys.historique = os.description ?? ""
|
||||||
|
}
|
||||||
|
|
||||||
|
const items = (old.items ?? []).map(it => _convertItem(it, warnings)).filter(Boolean)
|
||||||
|
|
||||||
|
const actor = {
|
||||||
|
name: old.name ?? "Personnage sans nom",
|
||||||
|
type,
|
||||||
|
img: old.img ?? "icons/svg/mystery-man.svg",
|
||||||
|
system: sys,
|
||||||
|
items,
|
||||||
|
effects: [],
|
||||||
|
folder: null,
|
||||||
|
flags: {},
|
||||||
|
prototypeToken: old.prototypeToken ?? {},
|
||||||
|
}
|
||||||
|
|
||||||
|
return { actor, warnings }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Ouvre la dialog DialogV2 de migration et gère l'import de l'acteur. */
|
||||||
|
async function _openMigrationDialog() {
|
||||||
|
const content = `
|
||||||
|
<div class="cel-migration-dialog" style="padding:0.5em 0">
|
||||||
|
<p style="margin-bottom:0.8em">${game.i18n.localize("CELESTOPOL.Migration.instructions")}</p>
|
||||||
|
<div style="display:flex;gap:0.5em;align-items:center">
|
||||||
|
<label style="font-weight:bold;white-space:nowrap">
|
||||||
|
${game.i18n.localize("CELESTOPOL.Migration.fileLabel")}
|
||||||
|
</label>
|
||||||
|
<input type="file" id="cel-migration-file" accept=".json" style="flex:1">
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
await foundry.applications.api.DialogV2.wait({
|
||||||
|
window: { title: game.i18n.localize("CELESTOPOL.Migration.title") },
|
||||||
|
classes: ["fvtt-celestopol"],
|
||||||
|
content,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
label: game.i18n.localize("CELESTOPOL.Migration.importBtn"),
|
||||||
|
icon: "fas fa-file-import",
|
||||||
|
action: "import",
|
||||||
|
default: true,
|
||||||
|
callback: (_event, _btn, dialog) => {
|
||||||
|
const fileInput = dialog.element.querySelector("#cel-migration-file")
|
||||||
|
return fileInput?.files?.[0] ?? null
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: game.i18n.localize("Cancel"),
|
||||||
|
icon: "fas fa-times",
|
||||||
|
action: "cancel",
|
||||||
|
callback: () => null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
submit: async (result) => {
|
||||||
|
if (!result) return
|
||||||
|
const text = await result.text()
|
||||||
|
let old
|
||||||
|
try { old = JSON.parse(text) }
|
||||||
|
catch {
|
||||||
|
ui.notifications.error(game.i18n.localize("CELESTOPOL.Migration.errorParse"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const { actor, warnings } = _convertOldActor(old)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const created = await Actor.create(actor)
|
||||||
|
ui.notifications.info(game.i18n.format("CELESTOPOL.Migration.success", {
|
||||||
|
name: created.name, count: actor.items.length,
|
||||||
|
}))
|
||||||
|
if (warnings.length) {
|
||||||
|
console.warn(`Célestopol Migration | ${created.name} — avertissements :`)
|
||||||
|
warnings.forEach(w => console.warn(" ⚠", w))
|
||||||
|
ui.notifications.warn(game.i18n.format("CELESTOPOL.Migration.warnings", { count: warnings.length }))
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.error("Célestopol Migration | Échec de création de l'acteur :", err)
|
||||||
|
ui.notifications.error(game.i18n.localize("CELESTOPOL.Migration.errorCreate"))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classe de menu de paramètre pour la migration.
|
||||||
|
* Étend ApplicationV2 (requis par registerMenu) mais surcharge render()
|
||||||
|
* pour déclencher directement la dialog de migration.
|
||||||
|
*/
|
||||||
|
class CelestopolMigrationMenu extends foundry.applications.api.ApplicationV2 {
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
id: "celestopol-migration",
|
||||||
|
window: { title: "CELESTOPOL.Migration.title" },
|
||||||
|
classes: ["fvtt-celestopol"],
|
||||||
|
position: { width: 480 },
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Surcharge : ignore le rendu AppV2 et ouvre directement la dialog. */
|
||||||
|
async render(...args) {
|
||||||
|
await _openMigrationDialog()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ─── Settings ───────────────────────────────────────────────────────────── */
|
/* ─── Settings ───────────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
function _registerSettings() {
|
function _registerSettings() {
|
||||||
@@ -368,6 +633,22 @@ function _registerSettings() {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Seuil de difficulté par défaut pour les jets normaux (hors combat)
|
||||||
|
game.settings.register(SYSTEM_ID, DEFAULT_ROLL_THRESHOLD_SETTING, {
|
||||||
|
name: "CELESTOPOL.Setting.defaultRollThreshold.name",
|
||||||
|
hint: "CELESTOPOL.Setting.defaultRollThreshold.hint",
|
||||||
|
scope: "world",
|
||||||
|
config: true,
|
||||||
|
type: Number,
|
||||||
|
default: 11,
|
||||||
|
range: {
|
||||||
|
min: 1,
|
||||||
|
max: 30,
|
||||||
|
step: 1,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
// Suivi de l'import des anomalies (caché)
|
// Suivi de l'import des anomalies (caché)
|
||||||
game.settings.register(SYSTEM_ID, "anomaliesImported", {
|
game.settings.register(SYSTEM_ID, "anomaliesImported", {
|
||||||
scope: "world",
|
scope: "world",
|
||||||
@@ -393,6 +674,16 @@ function _registerSettings() {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Entrée de menu : migration depuis l'ancien système
|
||||||
|
game.settings.registerMenu(SYSTEM_ID, "migrateOldSystem", {
|
||||||
|
name: "CELESTOPOL.Setting.migrateOldSystem.name",
|
||||||
|
hint: "CELESTOPOL.Setting.migrateOldSystem.hint",
|
||||||
|
label: "CELESTOPOL.Setting.migrateOldSystem.label",
|
||||||
|
icon: "fas fa-file-import",
|
||||||
|
type: CelestopolMigrationMenu,
|
||||||
|
restricted: true,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _createWelcomeChatMessage() {
|
async function _createWelcomeChatMessage() {
|
||||||
@@ -548,8 +839,9 @@ function _activateExistingChatCards() {
|
|||||||
document.querySelectorAll(".message[data-message-id]").forEach(messageEl => {
|
document.querySelectorAll(".message[data-message-id]").forEach(messageEl => {
|
||||||
const messageId = messageEl.dataset.messageId
|
const messageId = messageEl.dataset.messageId
|
||||||
const message = game.messages.get(messageId)
|
const message = game.messages.get(messageId)
|
||||||
const root = messageEl.querySelector(".celestopol.chat-roll")
|
if (!message) return
|
||||||
if (!message || !root) return
|
const root = messageEl.querySelector(".celestopol.chat-roll, .celestopol-roll.moon-standalone-card")
|
||||||
|
if (!root) return
|
||||||
_activateChatCardListeners(message, root)
|
_activateChatCardListeners(message, root)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -559,12 +851,19 @@ function _activateChatCardListeners(message, html) {
|
|||||||
if (!root) return
|
if (!root) return
|
||||||
|
|
||||||
_renderWeaponDamageState(message, root)
|
_renderWeaponDamageState(message, root)
|
||||||
|
_renderMoonEffectState(message, root)
|
||||||
|
|
||||||
root.querySelectorAll('[data-action="apply-weapon-damage"]').forEach(button => {
|
root.querySelectorAll('[data-action="apply-weapon-damage"]').forEach(button => {
|
||||||
if (button.dataset.bound === "true") return
|
if (button.dataset.bound === "true") return
|
||||||
button.dataset.bound = "true"
|
button.dataset.bound = "true"
|
||||||
button.addEventListener("click", event => _onApplyWeaponDamageClick(event, message))
|
button.addEventListener("click", event => _onApplyWeaponDamageClick(event, message))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
root.querySelectorAll('[data-action="apply-moon-effect"]').forEach(button => {
|
||||||
|
if (button.dataset.bound === "true") return
|
||||||
|
button.dataset.bound = "true"
|
||||||
|
button.addEventListener("click", event => _onApplyMoonEffectClick(event, message))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _onApplyWeaponDamageClick(event, message) {
|
async function _onApplyWeaponDamageClick(event, message) {
|
||||||
@@ -746,6 +1045,126 @@ async function _applyWeaponDamage({ actorId, actorUuid = null, incomingWounds, c
|
|||||||
return { actorName: actor.name, appliedWounds, armorProtection }
|
return { actorName: actor.name, appliedWounds, armorProtection }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ─── Dé de la Lune — contreparties ─────────────────────────────────────── */
|
||||||
|
|
||||||
|
function _getMoonEffectState(message) {
|
||||||
|
return message?.getFlag(SYSTEM_ID, MOON_EFFECT_FLAG) ?? null
|
||||||
|
}
|
||||||
|
|
||||||
|
function _renderMoonEffectState(message, root) {
|
||||||
|
const state = _getMoonEffectState(message)
|
||||||
|
const actionsDiv = root.querySelector(".moon-effect-actions")
|
||||||
|
if (!actionsDiv) return
|
||||||
|
|
||||||
|
if (!state?.applied) return
|
||||||
|
|
||||||
|
const NEGATIVE_EFFECTS = new Set(["lose-anomaly", "gain-spleen", "lose-destin"])
|
||||||
|
|
||||||
|
// Désactiver tous les boutons et afficher le statut
|
||||||
|
actionsDiv.querySelectorAll(".moon-effect-btn").forEach(btn => { btn.disabled = true })
|
||||||
|
|
||||||
|
let statusEl = actionsDiv.querySelector(".moon-effect-applied-status")
|
||||||
|
if (!statusEl) {
|
||||||
|
statusEl = document.createElement("span")
|
||||||
|
actionsDiv.append(statusEl)
|
||||||
|
}
|
||||||
|
statusEl.className = "moon-effect-applied-status" + (NEGATIVE_EFFECTS.has(state.effect) ? " is-negative" : "")
|
||||||
|
statusEl.textContent = state.effectLabel
|
||||||
|
? game.i18n.format("CELESTOPOL.Moon.effectApplied", { label: state.effectLabel })
|
||||||
|
: game.i18n.localize("CELESTOPOL.Moon.effectApplied")
|
||||||
|
}
|
||||||
|
|
||||||
|
function _updateRenderedMoonEffectState(message) {
|
||||||
|
const msgEl = document.querySelector(`.message[data-message-id="${message.id}"]`)
|
||||||
|
if (!msgEl) return
|
||||||
|
const root = msgEl.querySelector(".celestopol.chat-roll, .celestopol-roll.moon-standalone-card")
|
||||||
|
if (!root) return
|
||||||
|
_renderMoonEffectState(message, root)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function _onApplyMoonEffectClick(event, message) {
|
||||||
|
event.preventDefault()
|
||||||
|
const state = _getMoonEffectState(message)
|
||||||
|
if (state?.applied) return
|
||||||
|
|
||||||
|
const button = event.currentTarget
|
||||||
|
const effect = button.dataset.effect
|
||||||
|
const actionsDiv = button.closest(".moon-effect-actions")
|
||||||
|
const actorId = actionsDiv?.dataset.moonActorId ?? ""
|
||||||
|
const actorUuid = actionsDiv?.dataset.moonActorUuid ?? ""
|
||||||
|
|
||||||
|
// Désactiver immédiatement pour éviter les double-clics
|
||||||
|
actionsDiv?.querySelectorAll(".moon-effect-btn").forEach(btn => { btn.disabled = true })
|
||||||
|
|
||||||
|
const actor = await CelestopolRoll.resolveActor({ actorId, actorUuid })
|
||||||
|
if (!actor) {
|
||||||
|
ui.notifications.warn(game.i18n.localize("CELESTOPOL.Moon.actorNotFound"))
|
||||||
|
actionsDiv?.querySelectorAll(".moon-effect-btn").forEach(btn => { btn.disabled = false })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const effectLabel = await _applyMoonEffect(actor, effect)
|
||||||
|
if (effectLabel === null) {
|
||||||
|
actionsDiv?.querySelectorAll(".moon-effect-btn").forEach(btn => { btn.disabled = false })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await message.setFlag(SYSTEM_ID, MOON_EFFECT_FLAG, { applied: true, effect, effectLabel })
|
||||||
|
}
|
||||||
|
|
||||||
|
async function _applyMoonEffect(actor, effect) {
|
||||||
|
const i18n = key => game.i18n.localize(`CELESTOPOL.Moon.${key}`)
|
||||||
|
const anomaly = actor.items.find(i => i.type === "anomaly")
|
||||||
|
|
||||||
|
switch (effect) {
|
||||||
|
case "regain-anomaly": {
|
||||||
|
if (!anomaly) { ui.notifications.warn(i18n("noAnomaly")); return null }
|
||||||
|
const max = anomaly.system?.level ?? 0
|
||||||
|
const cur = anomaly.system?.usesRemaining ?? 0
|
||||||
|
if (cur >= max) { ui.notifications.warn(i18n("anomalyFull")); return null }
|
||||||
|
await anomaly.update({ "system.usesRemaining": Math.min(max, cur + 1) })
|
||||||
|
ui.notifications.info(game.i18n.format("CELESTOPOL.Moon.effectApplied", { label: i18n("effectRegainAnomaly") }))
|
||||||
|
return i18n("effectRegainAnomaly")
|
||||||
|
}
|
||||||
|
case "lose-spleen": {
|
||||||
|
const cur = actor.system?.spleen?.lvl ?? 0
|
||||||
|
if (cur <= 0) { ui.notifications.warn(i18n("spleenEmpty")); return null }
|
||||||
|
await actor.update({ "system.spleen.lvl": Math.max(0, cur - 1) })
|
||||||
|
ui.notifications.info(game.i18n.format("CELESTOPOL.Moon.effectApplied", { label: i18n("effectLoseSpleen") }))
|
||||||
|
return i18n("effectLoseSpleen")
|
||||||
|
}
|
||||||
|
case "gain-destin": {
|
||||||
|
const cur = actor.system?.destin?.lvl ?? 0
|
||||||
|
await actor.update({ "system.destin.lvl": Math.min(8, cur + 2) })
|
||||||
|
ui.notifications.info(game.i18n.format("CELESTOPOL.Moon.effectApplied", { label: i18n("effectGainDestin") }))
|
||||||
|
return i18n("effectGainDestin")
|
||||||
|
}
|
||||||
|
case "lose-destin": {
|
||||||
|
const cur = actor.system?.destin?.lvl ?? 0
|
||||||
|
await actor.update({ "system.destin.lvl": Math.max(0, cur - 2) })
|
||||||
|
ui.notifications.info(game.i18n.format("CELESTOPOL.Moon.effectApplied", { label: i18n("effectLoseDestin") }))
|
||||||
|
return i18n("effectLoseDestin")
|
||||||
|
}
|
||||||
|
case "lose-anomaly": {
|
||||||
|
if (!anomaly) { ui.notifications.warn(i18n("noAnomaly")); return null }
|
||||||
|
const cur = anomaly.system?.usesRemaining ?? 0
|
||||||
|
if (cur <= 0) { ui.notifications.warn(i18n("anomalyEmpty")); return null }
|
||||||
|
await anomaly.update({ "system.usesRemaining": Math.max(0, cur - 1) })
|
||||||
|
ui.notifications.info(game.i18n.format("CELESTOPOL.Moon.effectApplied", { label: i18n("effectLoseAnomaly") }))
|
||||||
|
return i18n("effectLoseAnomaly")
|
||||||
|
}
|
||||||
|
case "gain-spleen": {
|
||||||
|
const cur = actor.system?.spleen?.lvl ?? 0
|
||||||
|
if (cur >= 8) { ui.notifications.warn(i18n("spleenFull")); return null }
|
||||||
|
await actor.update({ "system.spleen.lvl": Math.min(8, cur + 1) })
|
||||||
|
ui.notifications.info(game.i18n.format("CELESTOPOL.Moon.effectApplied", { label: i18n("effectGainSpleen") }))
|
||||||
|
return i18n("effectGainSpleen")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function _getDefaultFactionAspectState() {
|
function _getDefaultFactionAspectState() {
|
||||||
return {
|
return {
|
||||||
pointsMax: 8,
|
pointsMax: 8,
|
||||||
@@ -823,6 +1242,24 @@ async function _setFactionAspectState(state) {
|
|||||||
return cleanState
|
return cleanState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function _resetFactionAspects() {
|
||||||
|
if (!game.user.isGM) {
|
||||||
|
ui.notifications.warn(game.i18n.localize("CELESTOPOL.FactionAspect.gmOnly"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||||
|
window: { title: game.i18n.localize("CELESTOPOL.FactionAspect.resetTitle") },
|
||||||
|
content: `<p>${game.i18n.localize("CELESTOPOL.FactionAspect.resetConfirm")}</p>`,
|
||||||
|
yes: { label: game.i18n.localize("CELESTOPOL.FactionAspect.resetConfirmYes"), icon: "fas fa-redo" },
|
||||||
|
no: { label: game.i18n.localize("Cancel"), icon: "fas fa-times" },
|
||||||
|
rejectClose: false,
|
||||||
|
})
|
||||||
|
if (!confirmed) return
|
||||||
|
const state = _getFactionAspectState()
|
||||||
|
await _setFactionAspectState({ ...state, activatedAspects: [] })
|
||||||
|
ui.notifications.info(game.i18n.localize("CELESTOPOL.FactionAspect.resetSuccess"))
|
||||||
|
}
|
||||||
|
|
||||||
function _refreshFactionAspectSheets() {
|
function _refreshFactionAspectSheets() {
|
||||||
for (const actor of game.actors.contents) {
|
for (const actor of game.actors.contents) {
|
||||||
if (actor.type !== "character") continue
|
if (actor.type !== "character") continue
|
||||||
|
|||||||
+63
-4
@@ -58,7 +58,25 @@
|
|||||||
"instruction": "Instruction",
|
"instruction": "Instruction",
|
||||||
"mtechnologique": "Merveilleux technologique",
|
"mtechnologique": "Merveilleux technologique",
|
||||||
"raisonnement": "Raisonnement",
|
"raisonnement": "Raisonnement",
|
||||||
"traitement": "Traitement"
|
"traitement": "Traitement",
|
||||||
|
"tooltip": {
|
||||||
|
"artifice": "Art du badinage et de la conversation subtile. Permet de se glisser dans une discussion pour glaner des renseignements ou noyer des informations mensongères. Favorise la manipulation et l'incitation plutôt que la contrainte.",
|
||||||
|
"attraction": "Capacité à orienter les émotions d'un interlocuteur. Sert à plaire, séduire, mais aussi à passer inaperçu lors d'une soirée mondaine.",
|
||||||
|
"coercition": "Art d'intimider par le regard ou les mots. Couvre également la capacité à donner des ordres dans un contexte militaire ou hiérarchique.",
|
||||||
|
"faveur": "Rapport de force oral : convaincre, persuader, négocier. S'appuie sur un discours argumentatif pour imposer son point de vue ou emporter l'adhésion.",
|
||||||
|
"echauffouree": "Techniques de combat à mains nues, avec une arme improvisée, une arme blanche ou des armes à feu et à distance.",
|
||||||
|
"effacement": "Capacité à être discret et à ne pas se faire repérer. Couvre le camouflage et l'escamotage. Requiert souvent de demeurer immobile.",
|
||||||
|
"mobilite": "Réflexes et vivacité. Sert pour la conduite, le pilotage, l'équitation, et représente l'initiative d'un protagoniste.",
|
||||||
|
"prouesse": "Efforts sportifs et physiques : escalade, natation, sprint, force brute et endurance.",
|
||||||
|
"appreciation": "Observer son environnement de façon exhaustive. Permet de repérer des intrus, des pièges, des guets-apens et des indices.",
|
||||||
|
"arts": "Domaines artistiques au sens large : musique, littérature, théâtre, prestidigitation. Permet de captiver un auditoire ou de créer des œuvres.",
|
||||||
|
"inspiration": "Intuition et inconscient : écouter sa petite voix intérieure sans démarche logique préalable. Permet aussi de lire le comportement d'une personne.",
|
||||||
|
"traque": "Filer un individu ou un groupe, pister et s'orienter. Ouvre également vers les techniques de survie.",
|
||||||
|
"instruction": "Savoirs encyclopédiques : sciences humaines, sciences dures, sciences sociales et linguistique. Chaque tranche de 2 points permet de maîtriser une langue supplémentaire.",
|
||||||
|
"mtechnologique": "Technologies extraordinaires de Célestopol : mécanique, automates, ingénierie au sélénium, horlogerie, serrurerie et artisanat.",
|
||||||
|
"raisonnement": "Capacités cognitives : déduction froide, logique pragmatique, analyse des faits. Utile pour percevoir des liens dans une enquête.",
|
||||||
|
"traitement": "Techniques médicales et thérapeutiques : premiers secours, chirurgie, pharmacopée, psychanalyse et psychothérapie."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Anomaly": {
|
"Anomaly": {
|
||||||
"type": "Type d'anomalie",
|
"type": "Type d'anomalie",
|
||||||
@@ -171,7 +189,12 @@
|
|||||||
"renforts": "Renforts",
|
"renforts": "Renforts",
|
||||||
"renseignements": "Renseignements",
|
"renseignements": "Renseignements",
|
||||||
"ressources": "Ressources",
|
"ressources": "Ressources",
|
||||||
"surveillance": "Surveillance"
|
"surveillance": "Surveillance",
|
||||||
|
"resetButton": "Réinitialiser",
|
||||||
|
"resetTitle": "Réinitialiser les Aspects de faction",
|
||||||
|
"resetConfirm": "Voulez-vous réinitialiser tous les Aspects de faction mobilisés ? Cette action efface la réserve de scénario en cours.",
|
||||||
|
"resetConfirmYes": "Réinitialiser",
|
||||||
|
"resetSuccess": "Aspects de faction réinitialisés pour le nouveau scénario."
|
||||||
},
|
},
|
||||||
"Track": {
|
"Track": {
|
||||||
"blessures": "Blessures",
|
"blessures": "Blessures",
|
||||||
@@ -350,7 +373,22 @@
|
|||||||
"mauvaiseFortune": "🔴 Mauvaise Fortune",
|
"mauvaiseFortune": "🔴 Mauvaise Fortune",
|
||||||
"chanceInterpret": "Chance",
|
"chanceInterpret": "Chance",
|
||||||
"narrativeInterpret": "Narratif",
|
"narrativeInterpret": "Narratif",
|
||||||
"quantiteHint": "Valeur"
|
"quantiteHint": "Valeur",
|
||||||
|
"applyChoose": "Choisissez la contrepartie :",
|
||||||
|
"effectNarrativeOnly": "(Narratif — sans effet mécanique)",
|
||||||
|
"effectRegainAnomaly": "🌟 Regain d'1 Anomalie",
|
||||||
|
"effectLoseSpleen": "💚 Perte d'1 Spleen",
|
||||||
|
"effectGainDestin": "⭐ Gain de 2 Destin",
|
||||||
|
"effectLoseDestin": "⭐ Perte de 2 Destin",
|
||||||
|
"effectLoseAnomaly": "❌ Perte d'1 Anomalie",
|
||||||
|
"effectGainSpleen": "💔 Gain d'1 Spleen",
|
||||||
|
"effectApplied": "Contrepartie appliquée : {label}",
|
||||||
|
"noAnomaly": "Ce personnage n'a pas d'anomalie",
|
||||||
|
"anomalyFull": "L'anomalie est déjà au maximum d'utilisations",
|
||||||
|
"anomalyEmpty": "L'anomalie n'a plus d'utilisation disponible",
|
||||||
|
"spleenEmpty": "Le Spleen est déjà à 0",
|
||||||
|
"spleenFull": "Le Spleen est déjà au maximum",
|
||||||
|
"actorNotFound": "Personnage introuvable"
|
||||||
},
|
},
|
||||||
"Difficulty": {
|
"Difficulty": {
|
||||||
"unknown": "Aucun seuil",
|
"unknown": "Aucun seuil",
|
||||||
@@ -415,8 +453,27 @@
|
|||||||
"rollMoonDieByDefault": {
|
"rollMoonDieByDefault": {
|
||||||
"name": "Lancer le dé de la lune par défaut",
|
"name": "Lancer le dé de la lune par défaut",
|
||||||
"hint": "Cocher automatiquement 'Lancer le dé de la lune' dans les fenêtres de jet"
|
"hint": "Cocher automatiquement 'Lancer le dé de la lune' dans les fenêtres de jet"
|
||||||
|
},
|
||||||
|
"defaultRollThreshold": {
|
||||||
|
"name": "Seuil de difficulté par défaut",
|
||||||
|
"hint": "Valeur du seuil utilisée par défaut pour les jets de compétence hors combat"
|
||||||
|
},
|
||||||
|
"migrateOldSystem": {
|
||||||
|
"name": "Migration depuis l'ancien système",
|
||||||
|
"hint": "Importer un personnage exporté depuis l'ancien système Célestopol 1922 (celestopol1922).",
|
||||||
|
"label": "Migrer un personnage…"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Migration": {
|
||||||
|
"title": "Migration ancien système Célestopol",
|
||||||
|
"instructions": "Sélectionnez un fichier JSON exporté depuis l'ancien système Célestopol 1922. Le personnage sera converti et créé automatiquement dans la liste des acteurs.",
|
||||||
|
"fileLabel": "Fichier JSON :",
|
||||||
|
"importBtn": "Convertir et importer",
|
||||||
|
"success": "'{name}' importé avec succès ({count} item(s)).",
|
||||||
|
"warnings": "{count} avertissement(s) — consultez la console (F12) pour le détail.",
|
||||||
|
"errorParse": "Impossible de lire le fichier JSON. Vérifiez qu'il s'agit bien d'un export Célestopol valide.",
|
||||||
|
"errorCreate": "Échec de la création de l'acteur. Consultez la console (F12) pour le détail."
|
||||||
|
},
|
||||||
"Welcome": {
|
"Welcome": {
|
||||||
"title": "Bienvenue dans Célestopol 1922",
|
"title": "Bienvenue dans Célestopol 1922",
|
||||||
"intro": "Bienvenue dans le système FoundryVTT de Célestopol 1922.",
|
"intro": "Bienvenue dans le système FoundryVTT de Célestopol 1922.",
|
||||||
@@ -449,7 +506,9 @@
|
|||||||
"rangeLongue": "Longue portée",
|
"rangeLongue": "Longue portée",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
"typeMelee": "Mêlée",
|
"typeMelee": "Mêlée",
|
||||||
"typeDistance": "Distance"
|
"typeDistance": "Distance",
|
||||||
|
"equip": "Équiper",
|
||||||
|
"unequip": "Retirer"
|
||||||
},
|
},
|
||||||
"Armure": {
|
"Armure": {
|
||||||
"protection": "Protection",
|
"protection": "Protection",
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ export default class CelestopolActorSheet extends HandlebarsApplicationMixin(fou
|
|||||||
skillLevel: CelestopolActorSheet.#onSkillLevel,
|
skillLevel: CelestopolActorSheet.#onSkillLevel,
|
||||||
factionLevel: CelestopolActorSheet.#onFactionLevel,
|
factionLevel: CelestopolActorSheet.#onFactionLevel,
|
||||||
toggleArmure: CelestopolActorSheet.#onToggleArmure,
|
toggleArmure: CelestopolActorSheet.#onToggleArmure,
|
||||||
|
toggleWeapon: CelestopolActorSheet.#onToggleWeapon,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,6 +238,13 @@ export default class CelestopolActorSheet extends HandlebarsApplicationMixin(fou
|
|||||||
if (item?.type === "armure") await item.update({ "system.equipped": !item.system.equipped })
|
if (item?.type === "armure") await item.update({ "system.equipped": !item.system.equipped })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async #onToggleWeapon(_event, target) {
|
||||||
|
const uuid = target.closest('[data-item-uuid]')?.dataset.itemUuid
|
||||||
|
if (!uuid) return
|
||||||
|
const item = await fromUuid(uuid)
|
||||||
|
if (item?.type === "weapon") await item.update({ "system.equipped": !item.system.equipped })
|
||||||
|
}
|
||||||
|
|
||||||
static #onFactionLevel(_event, target) {
|
static #onFactionLevel(_event, target) {
|
||||||
if (!this.isEditable) return
|
if (!this.isEditable) return
|
||||||
const factionId = target.dataset.faction
|
const factionId = target.dataset.faction
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ export default class CelestopolCharacterSheet extends CelestopolActorSheet {
|
|||||||
supprimerXpLog: CelestopolCharacterSheet.#onSupprimerXpLog,
|
supprimerXpLog: CelestopolCharacterSheet.#onSupprimerXpLog,
|
||||||
rollMoonDie: CelestopolCharacterSheet.#onRollMoonDie,
|
rollMoonDie: CelestopolCharacterSheet.#onRollMoonDie,
|
||||||
manageFactionAspects: CelestopolCharacterSheet.#onManageFactionAspects,
|
manageFactionAspects: CelestopolCharacterSheet.#onManageFactionAspects,
|
||||||
|
resetFactionAspects: CelestopolCharacterSheet.#onResetFactionAspects,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,6 +246,10 @@ export default class CelestopolCharacterSheet extends CelestopolActorSheet {
|
|||||||
await game.celestopol?.manageFactionAspects(this.document)
|
await game.celestopol?.manageFactionAspects(this.document)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async #onResetFactionAspects() {
|
||||||
|
await game.celestopol?.resetFactionAspects()
|
||||||
|
}
|
||||||
|
|
||||||
/** Ouvre un dialogue pour dépenser de l'XP. */
|
/** Ouvre un dialogue pour dépenser de l'XP. */
|
||||||
static async #onDepenseXp() {
|
static async #onDepenseXp() {
|
||||||
const actor = this.document
|
const actor = this.document
|
||||||
|
|||||||
+16
-16
@@ -31,28 +31,28 @@ export const STATS = {
|
|||||||
/** Domaines groupées par attribut. */
|
/** Domaines groupées par attribut. */
|
||||||
export const SKILLS = {
|
export const SKILLS = {
|
||||||
ame: {
|
ame: {
|
||||||
artifice: { id: "artifice", label: "CELESTOPOL.Skill.artifice", stat: "ame", resThreshold: 5 },
|
artifice: { id: "artifice", label: "CELESTOPOL.Skill.artifice", tooltip: "CELESTOPOL.Skill.tooltip.artifice", stat: "ame", resThreshold: 5 },
|
||||||
attraction: { id: "attraction", label: "CELESTOPOL.Skill.attraction", stat: "ame", resThreshold: 2 },
|
attraction: { id: "attraction", label: "CELESTOPOL.Skill.attraction", tooltip: "CELESTOPOL.Skill.tooltip.attraction", stat: "ame", resThreshold: 2 },
|
||||||
coercition: { id: "coercition", label: "CELESTOPOL.Skill.coercition", stat: "ame", resThreshold: 3 },
|
coercition: { id: "coercition", label: "CELESTOPOL.Skill.coercition", tooltip: "CELESTOPOL.Skill.tooltip.coercition", stat: "ame", resThreshold: 3 },
|
||||||
faveur: { id: "faveur", label: "CELESTOPOL.Skill.faveur", stat: "ame", resThreshold: 6 },
|
faveur: { id: "faveur", label: "CELESTOPOL.Skill.faveur", tooltip: "CELESTOPOL.Skill.tooltip.faveur", stat: "ame", resThreshold: 6 },
|
||||||
},
|
},
|
||||||
corps: {
|
corps: {
|
||||||
echauffouree: { id: "echauffouree", label: "CELESTOPOL.Skill.echauffouree", stat: "corps", resThreshold: 6 },
|
echauffouree: { id: "echauffouree", label: "CELESTOPOL.Skill.echauffouree", tooltip: "CELESTOPOL.Skill.tooltip.echauffouree", stat: "corps", resThreshold: 6 },
|
||||||
effacement: { id: "effacement", label: "CELESTOPOL.Skill.effacement", stat: "corps", resThreshold: 3 },
|
effacement: { id: "effacement", label: "CELESTOPOL.Skill.effacement", tooltip: "CELESTOPOL.Skill.tooltip.effacement", stat: "corps", resThreshold: 3 },
|
||||||
mobilite: { id: "mobilite", label: "CELESTOPOL.Skill.mobilite", stat: "corps", resThreshold: 2 },
|
mobilite: { id: "mobilite", label: "CELESTOPOL.Skill.mobilite", tooltip: "CELESTOPOL.Skill.tooltip.mobilite", stat: "corps", resThreshold: 2 },
|
||||||
prouesse: { id: "prouesse", label: "CELESTOPOL.Skill.prouesse", stat: "corps", resThreshold: 5 },
|
prouesse: { id: "prouesse", label: "CELESTOPOL.Skill.prouesse", tooltip: "CELESTOPOL.Skill.tooltip.prouesse", stat: "corps", resThreshold: 5 },
|
||||||
},
|
},
|
||||||
coeur: {
|
coeur: {
|
||||||
appreciation: { id: "appreciation", label: "CELESTOPOL.Skill.appreciation", stat: "coeur", resThreshold: 6 },
|
appreciation: { id: "appreciation", label: "CELESTOPOL.Skill.appreciation", tooltip: "CELESTOPOL.Skill.tooltip.appreciation", stat: "coeur", resThreshold: 6 },
|
||||||
arts: { id: "arts", label: "CELESTOPOL.Skill.arts", stat: "coeur", resThreshold: 2 },
|
arts: { id: "arts", label: "CELESTOPOL.Skill.arts", tooltip: "CELESTOPOL.Skill.tooltip.arts", stat: "coeur", resThreshold: 2 },
|
||||||
inspiration: { id: "inspiration", label: "CELESTOPOL.Skill.inspiration", stat: "coeur", resThreshold: 3 },
|
inspiration: { id: "inspiration", label: "CELESTOPOL.Skill.inspiration", tooltip: "CELESTOPOL.Skill.tooltip.inspiration", stat: "coeur", resThreshold: 3 },
|
||||||
traque: { id: "traque", label: "CELESTOPOL.Skill.traque", stat: "coeur", resThreshold: 5 },
|
traque: { id: "traque", label: "CELESTOPOL.Skill.traque", tooltip: "CELESTOPOL.Skill.tooltip.traque", stat: "coeur", resThreshold: 5 },
|
||||||
},
|
},
|
||||||
esprit: {
|
esprit: {
|
||||||
instruction: { id: "instruction", label: "CELESTOPOL.Skill.instruction", stat: "esprit", resThreshold: 2 },
|
instruction: { id: "instruction", label: "CELESTOPOL.Skill.instruction", tooltip: "CELESTOPOL.Skill.tooltip.instruction", stat: "esprit", resThreshold: 2 },
|
||||||
mtechnologique: { id: "mtechnologique", label: "CELESTOPOL.Skill.mtechnologique", stat: "esprit", resThreshold: 6 },
|
mtechnologique: { id: "mtechnologique", label: "CELESTOPOL.Skill.mtechnologique", tooltip: "CELESTOPOL.Skill.tooltip.mtechnologique", stat: "esprit", resThreshold: 6 },
|
||||||
raisonnement: { id: "raisonnement", label: "CELESTOPOL.Skill.raisonnement", stat: "esprit", resThreshold: 5 },
|
raisonnement: { id: "raisonnement", label: "CELESTOPOL.Skill.raisonnement", tooltip: "CELESTOPOL.Skill.tooltip.raisonnement", stat: "esprit", resThreshold: 5 },
|
||||||
traitement: { id: "traitement", label: "CELESTOPOL.Skill.traitement", stat: "esprit", resThreshold: 3 },
|
traitement: { id: "traitement", label: "CELESTOPOL.Skill.traitement", tooltip: "CELESTOPOL.Skill.tooltip.traitement", stat: "esprit", resThreshold: 3 },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+64
-36
@@ -294,12 +294,13 @@ export class CelestopolRoll extends Roll {
|
|||||||
|
|
||||||
if (!rollContext) return null
|
if (!rollContext) return null
|
||||||
|
|
||||||
// En combat : Corps PNJ = seuil direct ; sinon seuil fixe = 11
|
// En combat : Corps PNJ = seuil direct ; sinon seuil configurable via setting
|
||||||
const corpsPnj = isCombat ? (parseInt(rollContext.corpsPnj ?? 7) || 7) : null
|
const corpsPnj = isCombat ? (parseInt(rollContext.corpsPnj ?? 7) || 7) : null
|
||||||
const difficulty = isCombat ? "combat" : "standard"
|
const difficulty = isCombat ? "combat" : "standard"
|
||||||
|
const defaultThreshold = game.settings.get(game.celestopol.SYSTEM.id, game.celestopol.DEFAULT_ROLL_THRESHOLD_SETTING)
|
||||||
const diffConfig = isCombat
|
const diffConfig = isCombat
|
||||||
? { value: corpsPnj, label: "CELESTOPOL.Combat.corpsPnj" }
|
? { value: corpsPnj, label: "CELESTOPOL.Combat.corpsPnj" }
|
||||||
: { value: 11, label: "CELESTOPOL.Roll.threshold" }
|
: { value: defaultThreshold, label: "CELESTOPOL.Roll.threshold" }
|
||||||
const autoSuccess = rollContext.modifier === "auto"
|
const autoSuccess = rollContext.modifier === "auto"
|
||||||
const modifier = autoSuccess ? 0 : (parseInt(rollContext.modifier ?? 0) || 0)
|
const modifier = autoSuccess ? 0 : (parseInt(rollContext.modifier ?? 0) || 0)
|
||||||
const aspectMod = parseInt(rollContext.aspectModifier ?? 0) || 0
|
const aspectMod = parseInt(rollContext.aspectModifier ?? 0) || 0
|
||||||
@@ -320,6 +321,8 @@ export class CelestopolRoll extends Roll {
|
|||||||
: null
|
: null
|
||||||
const resolvedWeaponName = (isRangedDefense && selectedCombatTarget?.weaponName) ? selectedCombatTarget.weaponName : weaponName
|
const resolvedWeaponName = (isRangedDefense && selectedCombatTarget?.weaponName) ? selectedCombatTarget.weaponName : weaponName
|
||||||
const resolvedWeaponDegats = (isRangedDefense && selectedCombatTarget?.weaponDegats) ? selectedCombatTarget.weaponDegats : weaponDegats
|
const resolvedWeaponDegats = (isRangedDefense && selectedCombatTarget?.weaponDegats) ? selectedCombatTarget.weaponDegats : weaponDegats
|
||||||
|
// Dégâts de l'arme adverse en cas d'échec (arme équipée du PNJ ciblé en mêlée, arme distance en esquive)
|
||||||
|
const incomingWeaponDegats = selectedCombatTarget?.weaponDegats ?? resolvedWeaponDegats
|
||||||
const targetActorId = selectedCombatTarget?.id || ""
|
const targetActorId = selectedCombatTarget?.id || ""
|
||||||
const targetActorUuid = selectedCombatTarget?.uuid || ""
|
const targetActorUuid = selectedCombatTarget?.uuid || ""
|
||||||
const targetActorName = selectedCombatTarget?.name || ""
|
const targetActorName = selectedCombatTarget?.name || ""
|
||||||
@@ -373,6 +376,7 @@ export class CelestopolRoll extends Roll {
|
|||||||
weaponType,
|
weaponType,
|
||||||
weaponName: resolvedWeaponName,
|
weaponName: resolvedWeaponName,
|
||||||
weaponDegats: resolvedWeaponDegats,
|
weaponDegats: resolvedWeaponDegats,
|
||||||
|
incomingWeaponDegats,
|
||||||
targetActorId,
|
targetActorId,
|
||||||
targetActorUuid,
|
targetActorUuid,
|
||||||
targetActorName,
|
targetActorName,
|
||||||
@@ -383,7 +387,7 @@ export class CelestopolRoll extends Roll {
|
|||||||
puiserRessources: effectivePuiser,
|
puiserRessources: effectivePuiser,
|
||||||
nbDice: (!isResistance && useFortune) ? 1 : nbDice,
|
nbDice: (!isResistance && useFortune) ? 1 : nbDice,
|
||||||
formula,
|
formula,
|
||||||
rollMode: rollContext.visibility ?? "publicroll",
|
rollMode: rollContext.visibility ?? "public",
|
||||||
rollMoonDie: effectiveMoon,
|
rollMoonDie: effectiveMoon,
|
||||||
moonDieResult,
|
moonDieResult,
|
||||||
moonFace,
|
moonFace,
|
||||||
@@ -407,9 +411,9 @@ export class CelestopolRoll extends Roll {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mêlée échouée OU défense à distance échouée → le protagoniste subit les dégâts de l'arme PNJ
|
// Mêlée échouée OU défense à distance échouée → le protagoniste (PJ uniquement) subit les dégâts de l'arme PNJ
|
||||||
if (isCombat && (weaponType === "melee" || isRangedDefense) && actor && roll.options.resultType === "failure") {
|
if (isCombat && (weaponType === "melee" || isRangedDefense) && actor?.type === "character" && roll.options.resultType === "failure") {
|
||||||
const incomingWounds = this.getIncomingWounds(resolvedWeaponDegats)
|
const incomingWounds = this.getIncomingWounds(roll.options.incomingWeaponDegats ?? resolvedWeaponDegats)
|
||||||
const protection = this.getActorArmorProtection(actor)
|
const protection = this.getActorArmorProtection(actor)
|
||||||
const appliedWounds = incomingWounds === null
|
const appliedWounds = incomingWounds === null
|
||||||
? 1
|
? 1
|
||||||
@@ -461,7 +465,7 @@ export class CelestopolRoll extends Roll {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Détermine succès/échec selon la marge (total − seuil).
|
* Détermine succès/échec selon la marge (total − seuil).
|
||||||
* Seuil : 11 pour les tests normaux, Corps PNJ pour le combat.
|
* Seuil : configurable via setting pour les tests normaux, Corps PNJ pour le combat.
|
||||||
* Pas de succès/échec critique — seul le Dé de la Lune produit des résultats exceptionnels.
|
* Pas de succès/échec critique — seul le Dé de la Lune produit des résultats exceptionnels.
|
||||||
*/
|
*/
|
||||||
computeResult() {
|
computeResult() {
|
||||||
@@ -476,9 +480,10 @@ export class CelestopolRoll extends Roll {
|
|||||||
this.options.margin = null
|
this.options.margin = null
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const defaultThreshold = game.settings.get(game.celestopol.SYSTEM.id, game.celestopol.DEFAULT_ROLL_THRESHOLD_SETTING)
|
||||||
const threshold = this.options.isCombat
|
const threshold = this.options.isCombat
|
||||||
? (this.options.difficultyValue ?? 0)
|
? (this.options.difficultyValue ?? 0)
|
||||||
: 11
|
: defaultThreshold
|
||||||
if (threshold === 0) {
|
if (threshold === 0) {
|
||||||
this.options.resultType = "unknown"
|
this.options.resultType = "unknown"
|
||||||
this.options.margin = null
|
this.options.margin = null
|
||||||
@@ -507,9 +512,10 @@ export class CelestopolRoll extends Roll {
|
|||||||
const resultType = this.resultType
|
const resultType = this.resultType
|
||||||
const diceResults = this.dice[0]?.results?.map(r => r.result) ?? []
|
const diceResults = this.dice[0]?.results?.map(r => r.result) ?? []
|
||||||
const diceSum = diceResults.reduce((a, b) => a + b, 0)
|
const diceSum = diceResults.reduce((a, b) => a + b, 0)
|
||||||
|
const defaultThreshold = game.settings.get(game.celestopol.SYSTEM.id, game.celestopol.DEFAULT_ROLL_THRESHOLD_SETTING)
|
||||||
const threshold = this.options.isCombat
|
const threshold = this.options.isCombat
|
||||||
? (this.options.difficultyValue ?? 0)
|
? (this.options.difficultyValue ?? 0)
|
||||||
: 11
|
: defaultThreshold
|
||||||
const margin = this.options.margin
|
const margin = this.options.margin
|
||||||
const woundMalus = this.options.woundMalus ?? 0
|
const woundMalus = this.options.woundMalus ?? 0
|
||||||
const armorMalus = this.options.armorMalus ?? 0
|
const armorMalus = this.options.armorMalus ?? 0
|
||||||
@@ -555,12 +561,19 @@ export class CelestopolRoll extends Roll {
|
|||||||
? Math.max(0, incomingWounds - selectedTargetProtection)
|
? Math.max(0, incomingWounds - selectedTargetProtection)
|
||||||
: null
|
: null
|
||||||
|
|
||||||
// Libellé de difficulté : en combat "Corps PNJ : N", en opposition "vs ?", sinon "Seuil : 11"
|
// Type de l'acteur qui lance le jet (character | npc)
|
||||||
|
const rollingActor = await this.constructor.resolveActor({
|
||||||
|
actorUuid: this.options.actorUuid ?? null,
|
||||||
|
actorId: this.options.actorId ?? null,
|
||||||
|
})
|
||||||
|
const actorType = rollingActor?.type ?? this.options.actorType ?? null
|
||||||
|
|
||||||
|
// Libellé de difficulté : en combat "Corps PNJ : N", en opposition "vs ?", sinon "Seuil : N"
|
||||||
const difficultyLabel = this.options.isCombat
|
const difficultyLabel = this.options.isCombat
|
||||||
? `${game.i18n.localize("CELESTOPOL.Combat.corpsPnj")} : ${threshold}`
|
? `${game.i18n.localize("CELESTOPOL.Combat.corpsPnj")} : ${threshold}`
|
||||||
: isOpposition
|
: isOpposition
|
||||||
? `${game.i18n.localize("CELESTOPOL.Roll.oppositionVs")}`
|
? `${game.i18n.localize("CELESTOPOL.Roll.oppositionVs")}`
|
||||||
: `${game.i18n.localize("CELESTOPOL.Roll.threshold")} : 11`
|
: `${game.i18n.localize("CELESTOPOL.Roll.threshold")} : ${threshold}`
|
||||||
|
|
||||||
return {
|
return {
|
||||||
cssClass: [SYSTEM.id, "dice-roll"].join(" "),
|
cssClass: [SYSTEM.id, "dice-roll"].join(" "),
|
||||||
@@ -600,6 +613,8 @@ export class CelestopolRoll extends Roll {
|
|||||||
woundLabel,
|
woundLabel,
|
||||||
isResistance: this.options.isResistance ?? false,
|
isResistance: this.options.isResistance ?? false,
|
||||||
isCombat: this.options.isCombat ?? false,
|
isCombat: this.options.isCombat ?? false,
|
||||||
|
actorType,
|
||||||
|
isNpcAttack: actorType === "npc",
|
||||||
weaponName: this.options.weaponName ?? null,
|
weaponName: this.options.weaponName ?? null,
|
||||||
weaponDegats,
|
weaponDegats,
|
||||||
weaponType: this.options.weaponType ?? null,
|
weaponType: this.options.weaponType ?? null,
|
||||||
@@ -620,13 +635,17 @@ export class CelestopolRoll extends Roll {
|
|||||||
selectedTargetAppliedWounds,
|
selectedTargetAppliedWounds,
|
||||||
availableTargets,
|
availableTargets,
|
||||||
// Dé de lune
|
// Dé de lune
|
||||||
hasMoonDie: moonDieResult !== null,
|
hasMoonDie: moonDieResult !== null,
|
||||||
moonDieResult,
|
moonDieResult,
|
||||||
moonFaceSymbol: moonFace?.symbol ?? "",
|
moonFaceSymbol: moonFace?.symbol ?? "",
|
||||||
moonFaceLabel: moonFace ? game.i18n.localize(moonFace.label) : "",
|
moonFaceLabel: moonFace ? game.i18n.localize(moonFace.label) : "",
|
||||||
moonResultClass: moonResultType?.cssClass ?? "",
|
moonResultClass: moonResultType?.cssClass ?? "",
|
||||||
moonResultLabel: moonResultType ? game.i18n.localize(moonResultType.label) : "",
|
moonResultLabel: moonResultType ? game.i18n.localize(moonResultType.label) : "",
|
||||||
moonResultDesc: moonResultType ? game.i18n.localize(moonResultType.desc) : "",
|
moonResultDesc: moonResultType ? game.i18n.localize(moonResultType.desc) : "",
|
||||||
|
moonResultTypeId: moonResultType?.id ?? null,
|
||||||
|
moonActorId: (actorType === "character") ? (this.options.actorId ?? null) : null,
|
||||||
|
moonActorUuid: (actorType === "character") ? (this.options.actorUuid ?? null) : null,
|
||||||
|
moonActorIsCharacter: actorType === "character",
|
||||||
isPrivate,
|
isPrivate,
|
||||||
tooltip: isPrivate ? "" : await this.getTooltip(),
|
tooltip: isPrivate ? "" : await this.getTooltip(),
|
||||||
}
|
}
|
||||||
@@ -634,11 +653,20 @@ export class CelestopolRoll extends Roll {
|
|||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
async toMessage(messageData = {}, { messageMode, rollMode, create = true } = {}) {
|
async toMessage(messageData = {}, { messageMode, rollMode, create = true } = {}) {
|
||||||
if (rollMode) {
|
const modernToLegacyRollMode = {
|
||||||
messageMode = Roll._mapLegacyRollMode(rollMode)
|
public: CONST.DICE_ROLL_MODES.PUBLIC,
|
||||||
|
gm: CONST.DICE_ROLL_MODES.PRIVATE,
|
||||||
|
blind: CONST.DICE_ROLL_MODES.BLIND,
|
||||||
|
self: CONST.DICE_ROLL_MODES.SELF,
|
||||||
|
ic: CONST.DICE_ROLL_MODES.PUBLIC,
|
||||||
}
|
}
|
||||||
messageMode ||= game.settings.get("core", "messageMode")
|
let effectiveRollMode = rollMode ?? messageMode ?? game.settings.get("core", "rollMode") ?? CONST.DICE_ROLL_MODES.PUBLIC
|
||||||
if (!this._evaluated) await this.evaluate({ allowInteractive: messageMode !== "blind" })
|
effectiveRollMode = modernToLegacyRollMode[effectiveRollMode] ?? effectiveRollMode
|
||||||
|
if (!Object.values(CONST.DICE_ROLL_MODES).includes(effectiveRollMode)) {
|
||||||
|
effectiveRollMode = game.settings.get("core", "rollMode") ?? CONST.DICE_ROLL_MODES.PUBLIC
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._evaluated) await this.evaluate({ allowInteractive: effectiveRollMode !== CONST.DICE_ROLL_MODES.BLIND })
|
||||||
|
|
||||||
const skillLocalized = this.skillLabel ? game.i18n.localize(this.skillLabel) : ""
|
const skillLocalized = this.skillLabel ? game.i18n.localize(this.skillLabel) : ""
|
||||||
const statLocalized = this.options.statLabel
|
const statLocalized = this.options.statLabel
|
||||||
@@ -650,7 +678,7 @@ export class CelestopolRoll extends Roll {
|
|||||||
actorUuid: this.options.actorUuid ?? null,
|
actorUuid: this.options.actorUuid ?? null,
|
||||||
actorId: this.options.actorId ?? null,
|
actorId: this.options.actorId ?? null,
|
||||||
})
|
})
|
||||||
const content = await this.render({ isPrivate: messageMode !== "public" })
|
const content = await this.render({ isPrivate: effectiveRollMode !== CONST.DICE_ROLL_MODES.PUBLIC })
|
||||||
const chatData = foundry.utils.mergeObject({
|
const chatData = foundry.utils.mergeObject({
|
||||||
author: game.user.id,
|
author: game.user.id,
|
||||||
content,
|
content,
|
||||||
@@ -660,13 +688,9 @@ export class CelestopolRoll extends Roll {
|
|||||||
speaker: speakerActor ? ChatMessage.getSpeaker({ actor: speakerActor }) : undefined,
|
speaker: speakerActor ? ChatMessage.getSpeaker({ actor: speakerActor }) : undefined,
|
||||||
style: CONST.CHAT_MESSAGE_STYLES.OTHER,
|
style: CONST.CHAT_MESSAGE_STYLES.OTHER,
|
||||||
}, messageData)
|
}, messageData)
|
||||||
|
ChatMessage.applyRollMode(chatData, effectiveRollMode)
|
||||||
const cls = foundry.utils.getDocumentClass("ChatMessage")
|
if (create) return ChatMessage.create(chatData)
|
||||||
const msg = new cls(chatData)
|
return chatData
|
||||||
msg.applyMode(messageMode)
|
|
||||||
|
|
||||||
if (create) return cls.create(msg)
|
|
||||||
return msg.toObject()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -681,15 +705,20 @@ export class CelestopolRoll extends Roll {
|
|||||||
const resultType = face ? SYSTEM.MOON_RESULT_TYPES[face.result] ?? null : null
|
const resultType = face ? SYSTEM.MOON_RESULT_TYPES[face.result] ?? null : null
|
||||||
const isGoodFortune = result <= 4
|
const isGoodFortune = result <= 4
|
||||||
|
|
||||||
|
const actorIsCharacter = actor?.type === "character"
|
||||||
const templateData = {
|
const templateData = {
|
||||||
result,
|
result,
|
||||||
moonFaceSymbol: face?.symbol ?? "",
|
moonFaceSymbol: face?.symbol ?? "",
|
||||||
moonFaceLabel: face ? game.i18n.localize(face.label) : "",
|
moonFaceLabel: face ? game.i18n.localize(face.label) : "",
|
||||||
moonResultLabel: resultType ? game.i18n.localize(resultType.label) : "",
|
moonResultLabel: resultType ? game.i18n.localize(resultType.label) : "",
|
||||||
moonResultDesc: resultType ? game.i18n.localize(resultType.desc) : "",
|
moonResultDesc: resultType ? game.i18n.localize(resultType.desc) : "",
|
||||||
moonResultClass: resultType?.cssClass ?? "",
|
moonResultClass: resultType?.cssClass ?? "",
|
||||||
|
moonResultTypeId: resultType?.id ?? null,
|
||||||
isGoodFortune,
|
isGoodFortune,
|
||||||
actorName: actor?.name ?? null,
|
actorName: actor?.name ?? null,
|
||||||
|
moonActorIsCharacter: actorIsCharacter,
|
||||||
|
moonActorId: actorIsCharacter ? (actor.id ?? null) : null,
|
||||||
|
moonActorUuid: actorIsCharacter ? (actor.uuid ?? null) : null,
|
||||||
}
|
}
|
||||||
|
|
||||||
const content = await foundry.applications.handlebars.renderTemplate(
|
const content = await foundry.applications.handlebars.renderTemplate(
|
||||||
@@ -704,7 +733,6 @@ export class CelestopolRoll extends Roll {
|
|||||||
await ChatMessage.create({
|
await ChatMessage.create({
|
||||||
content,
|
content,
|
||||||
speaker,
|
speaker,
|
||||||
rolls: [roll],
|
|
||||||
style: CONST.CHAT_MESSAGE_STYLES.OTHER,
|
style: CONST.CHAT_MESSAGE_STYLES.OTHER,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-39
@@ -13,8 +13,6 @@
|
|||||||
|
|
||||||
import { SYSTEM } from "../config/system.mjs"
|
import { SYSTEM } from "../config/system.mjs"
|
||||||
|
|
||||||
const WEAPON_DAMAGE_PRIORITY = { "0": 0, "1": 1, "2": 2, X: 3 }
|
|
||||||
|
|
||||||
export default class CelestopolCharacter extends foundry.abstract.TypeDataModel {
|
export default class CelestopolCharacter extends foundry.abstract.TypeDataModel {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields
|
const fields = foundry.data.fields
|
||||||
@@ -233,7 +231,7 @@ export default class CelestopolCharacter extends foundry.abstract.TypeDataModel
|
|||||||
woundLevel: this.blessures.lvl,
|
woundLevel: this.blessures.lvl,
|
||||||
difficulty: this.prefs.difficulty,
|
difficulty: this.prefs.difficulty,
|
||||||
rollMoonDie: this.prefs.rollMoonDie ?? false,
|
rollMoonDie: this.prefs.rollMoonDie ?? false,
|
||||||
destGaugeFull: this.destin.lvl > 0,
|
destGaugeFull: this.destin.lvl >= 8,
|
||||||
fortuneValue: this.attributs.fortune.value,
|
fortuneValue: this.attributs.fortune.value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -275,40 +273,39 @@ export default class CelestopolCharacter extends foundry.abstract.TypeDataModel
|
|||||||
* Collecte les cibles de combat sur la scène active.
|
* Collecte les cibles de combat sur la scène active.
|
||||||
* Pour un PJ attaquant, seules les cibles PNJ présentes sur la scène sont proposées.
|
* Pour un PJ attaquant, seules les cibles PNJ présentes sur la scène sont proposées.
|
||||||
* @param {object} options
|
* @param {object} options
|
||||||
* @param {boolean} [options.onlyRanged=false]
|
* @param {boolean} [options.onlyRanged=false] - Filtrer sur les PNJ ayant une arme à distance équipée
|
||||||
* @param {boolean} [options.fallbackToAll=false]
|
* @param {boolean} [options.fallbackToAll=false] - Revenir à tous les PNJ si aucune cible trouvée
|
||||||
|
* @param {boolean} [options.includeMeleeWeapon=false] - Inclure l'arme de mêlée équipée du PNJ (dégâts adverses)
|
||||||
* @returns {Array<{id:string, uuid:string, name:string, corps:number, weaponName?:string, weaponDegats?:string}>}
|
* @returns {Array<{id:string, uuid:string, name:string, corps:number, weaponName?:string, weaponDegats?:string}>}
|
||||||
*/
|
*/
|
||||||
_getCombatTargets({ onlyRanged = false, fallbackToAll = false } = {}) {
|
_getCombatTargets({ onlyRanged = false, fallbackToAll = false, includeMeleeWeapon = false } = {}) {
|
||||||
const getBestRangedWeapon = actor => {
|
const getEquippedWeapon = (actor, type) =>
|
||||||
const rangedWeapons = actor.itemTypes?.weapon?.filter(item => item.system.type === "distance") ?? []
|
actor.itemTypes?.weapon?.find(item => item.system.type === type && item.system.equipped) ?? null
|
||||||
if (!rangedWeapons.length) return null
|
|
||||||
return rangedWeapons.reduce((best, item) => {
|
const toEntry = actor => {
|
||||||
if (!best) return item
|
const entry = {
|
||||||
const bestPriority = WEAPON_DAMAGE_PRIORITY[best.system.degats] ?? -1
|
id: actor.id,
|
||||||
const itemPriority = WEAPON_DAMAGE_PRIORITY[item.system.degats] ?? -1
|
uuid: actor.uuid,
|
||||||
if (itemPriority !== bestPriority) return itemPriority > bestPriority ? item : best
|
name: actor.name,
|
||||||
return item.name.localeCompare(best.name) < 0 ? item : best
|
corps: actor.system.stats?.corps?.res ?? 0,
|
||||||
}, null)
|
}
|
||||||
|
if (onlyRanged) {
|
||||||
|
const weapon = getEquippedWeapon(actor, "distance")
|
||||||
|
if (weapon) {
|
||||||
|
entry.weaponName = weapon.name
|
||||||
|
entry.weaponDegats = weapon.system.degats
|
||||||
|
}
|
||||||
|
} else if (includeMeleeWeapon) {
|
||||||
|
const weapon = getEquippedWeapon(actor, "melee")
|
||||||
|
entry.weaponDegats = weapon ? weapon.system.degats : "0"
|
||||||
|
}
|
||||||
|
return entry
|
||||||
}
|
}
|
||||||
|
|
||||||
const toEntry = actor => ({
|
|
||||||
id: actor.id,
|
|
||||||
uuid: actor.uuid,
|
|
||||||
name: actor.name,
|
|
||||||
corps: actor.system.stats?.corps?.res ?? 0,
|
|
||||||
...(onlyRanged ? (() => {
|
|
||||||
const weapon = getBestRangedWeapon(actor)
|
|
||||||
return weapon ? {
|
|
||||||
weaponName: weapon.name,
|
|
||||||
weaponDegats: weapon.system.degats,
|
|
||||||
} : {}
|
|
||||||
})() : {}),
|
|
||||||
})
|
|
||||||
const sceneTokens = canvas?.scene?.isView ? (canvas.tokens?.placeables ?? []) : []
|
const sceneTokens = canvas?.scene?.isView ? (canvas.tokens?.placeables ?? []) : []
|
||||||
const targets = [...new Map(sceneTokens
|
const targets = [...new Map(sceneTokens
|
||||||
.filter(t => t.actor?.type === "npc" && t.actor.id !== this.parent.id)
|
.filter(t => t.actor?.type === "npc" && t.actor.id !== this.parent.id)
|
||||||
.filter(t => !onlyRanged || getBestRangedWeapon(t.actor))
|
.filter(t => !onlyRanged || getEquippedWeapon(t.actor, "distance"))
|
||||||
.map(t => {
|
.map(t => {
|
||||||
const actor = t.actor
|
const actor = t.actor
|
||||||
return [actor.uuid, toEntry(actor)]
|
return [actor.uuid, toEntry(actor)]
|
||||||
@@ -346,20 +343,19 @@ export default class CelestopolCharacter extends foundry.abstract.TypeDataModel
|
|||||||
armorMalus: this.getArmorMalusForRoll("corps", "echauffouree"),
|
armorMalus: this.getArmorMalusForRoll("corps", "echauffouree"),
|
||||||
woundLevel: this.blessures.lvl,
|
woundLevel: this.blessures.lvl,
|
||||||
rollMoonDie: this.prefs.rollMoonDie ?? false,
|
rollMoonDie: this.prefs.rollMoonDie ?? false,
|
||||||
destGaugeFull: this.destin.lvl > 0,
|
destGaugeFull: this.destin.lvl >= 8,
|
||||||
fortuneValue: this.attributs.fortune.value,
|
fortuneValue: this.attributs.fortune.value,
|
||||||
isCombat: true,
|
isCombat: true,
|
||||||
isRangedDefense: false,
|
isRangedDefense: false,
|
||||||
weaponType: item.system.type,
|
weaponType: item.system.type,
|
||||||
weaponName: item.name,
|
weaponName: item.name,
|
||||||
weaponDegats: item.system.degats,
|
weaponDegats: item.system.degats,
|
||||||
availableTargets: this._getCombatTargets(),
|
availableTargets: this._getCombatTargets({ includeMeleeWeapon: item.system.type === "melee" }),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lance une attaque de mêlée à mains nues.
|
* Lance une attaque à mains nues (Échauffourée sans arme).
|
||||||
* @returns {Promise<import("../documents/roll.mjs").CelestopolRoll|null>}
|
|
||||||
*/
|
*/
|
||||||
async rollUnarmedAttack() {
|
async rollUnarmedAttack() {
|
||||||
const { CelestopolRoll } = await import("../documents/roll.mjs")
|
const { CelestopolRoll } = await import("../documents/roll.mjs")
|
||||||
@@ -380,14 +376,14 @@ export default class CelestopolCharacter extends foundry.abstract.TypeDataModel
|
|||||||
armorMalus: this.getArmorMalusForRoll("corps", "echauffouree"),
|
armorMalus: this.getArmorMalusForRoll("corps", "echauffouree"),
|
||||||
woundLevel: this.blessures.lvl,
|
woundLevel: this.blessures.lvl,
|
||||||
rollMoonDie: this.prefs.rollMoonDie ?? false,
|
rollMoonDie: this.prefs.rollMoonDie ?? false,
|
||||||
destGaugeFull: this.destin.lvl > 0,
|
destGaugeFull: this.destin.lvl >= 8,
|
||||||
fortuneValue: this.attributs.fortune.value,
|
fortuneValue: this.attributs.fortune.value,
|
||||||
isCombat: true,
|
isCombat: true,
|
||||||
isRangedDefense: false,
|
isRangedDefense: false,
|
||||||
weaponType: "melee",
|
weaponType: "melee",
|
||||||
weaponName: game.i18n.localize("CELESTOPOL.Combat.unarmedAttack"),
|
weaponName: game.i18n.localize("CELESTOPOL.Combat.unarmedAttack"),
|
||||||
weaponDegats: "0",
|
weaponDegats: "0",
|
||||||
availableTargets: this._getCombatTargets(),
|
availableTargets: this._getCombatTargets({ includeMeleeWeapon: true }),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,14 +415,14 @@ export default class CelestopolCharacter extends foundry.abstract.TypeDataModel
|
|||||||
armorMalus: this.getArmorMalusForRoll("corps", "mobilite"),
|
armorMalus: this.getArmorMalusForRoll("corps", "mobilite"),
|
||||||
woundLevel: this.blessures.lvl,
|
woundLevel: this.blessures.lvl,
|
||||||
rollMoonDie: this.prefs.rollMoonDie ?? false,
|
rollMoonDie: this.prefs.rollMoonDie ?? false,
|
||||||
destGaugeFull: this.destin.lvl > 0,
|
destGaugeFull: this.destin.lvl >= 8,
|
||||||
fortuneValue: this.attributs.fortune.value,
|
fortuneValue: this.attributs.fortune.value,
|
||||||
isCombat: true,
|
isCombat: true,
|
||||||
isRangedDefense: true,
|
isRangedDefense: true,
|
||||||
weaponType: "distance",
|
weaponType: "distance",
|
||||||
weaponName: item.name,
|
weaponName: item.name,
|
||||||
weaponDegats: "0",
|
weaponDegats: "0",
|
||||||
availableTargets: this._getCombatTargets(),
|
availableTargets: this._getCombatTargets({ onlyRanged: true, fallbackToAll: true }),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,7 +449,7 @@ export default class CelestopolCharacter extends foundry.abstract.TypeDataModel
|
|||||||
armorMalus: this.getArmorMalusForRoll("corps", "mobilite"),
|
armorMalus: this.getArmorMalusForRoll("corps", "mobilite"),
|
||||||
woundLevel: this.blessures.lvl,
|
woundLevel: this.blessures.lvl,
|
||||||
rollMoonDie: this.prefs.rollMoonDie ?? false,
|
rollMoonDie: this.prefs.rollMoonDie ?? false,
|
||||||
destGaugeFull: this.destin.lvl > 0,
|
destGaugeFull: this.destin.lvl >= 8,
|
||||||
fortuneValue: this.attributs.fortune.value,
|
fortuneValue: this.attributs.fortune.value,
|
||||||
isCombat: true,
|
isCombat: true,
|
||||||
isRangedDefense: true,
|
isRangedDefense: true,
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ export class CelestopolWeapon extends foundry.abstract.TypeDataModel {
|
|||||||
choices: Object.keys(SYSTEM.WEAPON_DAMAGE_TYPES) }),
|
choices: Object.keys(SYSTEM.WEAPON_DAMAGE_TYPES) }),
|
||||||
portee: new fields.StringField({ required: true, nullable: false, initial: "contact",
|
portee: new fields.StringField({ required: true, nullable: false, initial: "contact",
|
||||||
choices: Object.keys(SYSTEM.WEAPON_RANGE_TYPES) }),
|
choices: Object.keys(SYSTEM.WEAPON_RANGE_TYPES) }),
|
||||||
|
equipped: new fields.BooleanField({ initial: false }),
|
||||||
description: new fields.HTMLField({ required: true, textSearch: true }),
|
description: new fields.HTMLField({ required: true, textSearch: true }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
MANIFEST-000062
|
MANIFEST-000110
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
2026/04/13-13:11:31.249954 7f2a6b7fe6c0 Recovering log #60
|
2026/05/29-19:25:48.566717 7f386cbff6c0 Recovering log #107
|
||||||
2026/04/13-13:11:31.302525 7f2a6b7fe6c0 Delete type=3 #58
|
2026/05/29-19:25:48.575874 7f386cbff6c0 Delete type=3 #105
|
||||||
2026/04/13-13:11:31.302579 7f2a6b7fe6c0 Delete type=0 #60
|
2026/05/29-19:25:48.575904 7f386cbff6c0 Delete type=0 #107
|
||||||
2026/04/13-14:20:41.118813 7f2a69ffb6c0 Level-0 table #65: started
|
2026/05/29-19:26:15.982905 7f381e7fc6c0 Level-0 table #113: started
|
||||||
2026/04/13-14:20:41.118847 7f2a69ffb6c0 Level-0 table #65: 0 bytes OK
|
2026/05/29-19:26:15.982917 7f381e7fc6c0 Level-0 table #113: 0 bytes OK
|
||||||
2026/04/13-14:20:41.156390 7f2a69ffb6c0 Delete type=0 #63
|
2026/05/29-19:26:15.988613 7f381e7fc6c0 Delete type=0 #111
|
||||||
2026/04/13-14:20:41.210923 7f2a69ffb6c0 Manual compaction at level-0 from '!journal!eNYstmPK0mMmVJYC' @ 72057594037927935 : 1 .. '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 0 : 0; will stop at (end)
|
2026/05/29-19:26:15.998513 7f381e7fc6c0 Manual compaction at level-0 from '!journal!eNYstmPK0mMmVJYC' @ 72057594037927935 : 1 .. '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 0 : 0; will stop at (end)
|
||||||
2026/04/13-14:20:41.272745 7f2a69ffb6c0 Manual compaction at level-1 from '!journal!eNYstmPK0mMmVJYC' @ 72057594037927935 : 1 .. '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
2026/04/13-13:10:44.862648 7ff582bff6c0 Recovering log #56
|
2026/05/29-18:25:23.135570 7f381f7fe6c0 Delete type=3 #1
|
||||||
2026/04/13-13:10:44.908015 7ff582bff6c0 Delete type=3 #54
|
2026/05/29-18:27:57.110280 7f381e7fc6c0 Level-0 table #108: started
|
||||||
2026/04/13-13:10:44.908061 7ff582bff6c0 Delete type=0 #56
|
2026/05/29-18:27:57.110317 7f381e7fc6c0 Level-0 table #108: 0 bytes OK
|
||||||
2026/04/13-13:10:47.939764 7ff580bfb6c0 Level-0 table #61: started
|
2026/05/29-18:27:57.146936 7f381e7fc6c0 Delete type=0 #106
|
||||||
2026/04/13-13:10:47.939788 7ff580bfb6c0 Level-0 table #61: 0 bytes OK
|
2026/05/29-18:27:57.291474 7f381e7fc6c0 Manual compaction at level-0 from '!journal!eNYstmPK0mMmVJYC' @ 72057594037927935 : 1 .. '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 0 : 0; will stop at '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 1 : 1
|
||||||
2026/04/13-13:10:47.972855 7ff580bfb6c0 Delete type=0 #59
|
2026/05/29-18:27:57.291484 7f381e7fc6c0 Compacting 1@0 + 0@1 files
|
||||||
2026/04/13-13:10:47.973045 7ff580bfb6c0 Manual compaction at level-0 from '!journal!eNYstmPK0mMmVJYC' @ 72057594037927935 : 1 .. '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 0 : 0; will stop at (end)
|
2026/05/29-18:27:57.308314 7f381e7fc6c0 Generated table #109@0: 6 keys, 5441 bytes
|
||||||
2026/04/13-13:10:48.030502 7ff580bfb6c0 Manual compaction at level-1 from '!journal!eNYstmPK0mMmVJYC' @ 72057594037927935 : 1 .. '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 0 : 0; will stop at (end)
|
2026/05/29-18:27:57.308348 7f381e7fc6c0 Compacted 1@0 + 0@1 files => 5441 bytes
|
||||||
|
2026/05/29-18:27:57.339343 7f381e7fc6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
|
||||||
|
2026/05/29-18:27:57.339668 7f381e7fc6c0 Delete type=2 #88
|
||||||
|
2026/05/29-18:27:57.450192 7f381e7fc6c0 Manual compaction at level-0 from '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 1 : 1 .. '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000112
|
MANIFEST-000173
|
||||||
|
|||||||
+14
-15
@@ -1,15 +1,14 @@
|
|||||||
2026/04/13-13:11:31.130509 7f2a6bfff6c0 Recovering log #109
|
2026/05/29-19:25:48.540511 7f381ffff6c0 Recovering log #170
|
||||||
2026/04/13-13:11:31.189864 7f2a6bfff6c0 Delete type=3 #107
|
2026/05/29-19:25:48.551076 7f381ffff6c0 Delete type=3 #168
|
||||||
2026/04/13-13:11:31.189928 7f2a6bfff6c0 Delete type=0 #109
|
2026/05/29-19:25:48.551131 7f381ffff6c0 Delete type=0 #170
|
||||||
2026/04/13-14:20:41.156517 7f2a69ffb6c0 Level-0 table #115: started
|
2026/05/29-19:26:15.960995 7f381e7fc6c0 Level-0 table #176: started
|
||||||
2026/04/13-14:20:41.173655 7f2a69ffb6c0 Level-0 table #115: 3524 bytes OK
|
2026/05/29-19:26:15.964212 7f381e7fc6c0 Level-0 table #176: 3524 bytes OK
|
||||||
2026/04/13-14:20:41.210761 7f2a69ffb6c0 Delete type=0 #113
|
2026/05/29-19:26:15.970133 7f381e7fc6c0 Delete type=0 #174
|
||||||
2026/04/13-14:20:41.210932 7f2a69ffb6c0 Manual compaction at level-0 from '!items!anomCommMorts001' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at (end)
|
2026/05/29-19:26:15.988655 7f381e7fc6c0 Manual compaction at level-0 from '!items!anomCommMorts001' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 145 : 1
|
||||||
2026/04/13-14:20:41.210963 7f2a69ffb6c0 Manual compaction at level-1 from '!items!anomCommMorts001' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 97 : 1
|
2026/05/29-19:26:15.988659 7f381e7fc6c0 Compacting 1@0 + 1@1 files
|
||||||
2026/04/13-14:20:41.210970 7f2a69ffb6c0 Compacting 1@1 + 1@2 files
|
2026/05/29-19:26:15.991895 7f381e7fc6c0 Generated table #177@0: 9 keys, 6617 bytes
|
||||||
2026/04/13-14:20:41.229806 7f2a69ffb6c0 Generated table #116@1: 9 keys, 6617 bytes
|
2026/05/29-19:26:15.991901 7f381e7fc6c0 Compacted 1@0 + 1@1 files => 6617 bytes
|
||||||
2026/04/13-14:20:41.229844 7f2a69ffb6c0 Compacted 1@1 + 1@2 files => 6617 bytes
|
2026/05/29-19:26:15.998180 7f381e7fc6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
|
||||||
2026/04/13-14:20:41.272334 7f2a69ffb6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
2026/05/29-19:26:15.998402 7f381e7fc6c0 Delete type=2 #172
|
||||||
2026/04/13-14:20:41.272481 7f2a69ffb6c0 Delete type=2 #111
|
2026/05/29-19:26:15.998461 7f381e7fc6c0 Delete type=2 #176
|
||||||
2026/04/13-14:20:41.272658 7f2a69ffb6c0 Delete type=2 #115
|
2026/05/29-19:26:16.010680 7f381e7fc6c0 Manual compaction at level-0 from '!items!null' @ 145 : 1 .. '!items!null' @ 0 : 0; will stop at (end)
|
||||||
2026/04/13-14:20:41.365704 7f2a69ffb6c0 Manual compaction at level-1 from '!items!null' @ 97 : 1 .. '!items!null' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
2026/04/13-13:10:44.750651 7ff581bfd6c0 Recovering log #104
|
2026/05/29-18:25:23.097516 7f381effd6c0 Delete type=3 #1
|
||||||
2026/04/13-13:10:44.797855 7ff581bfd6c0 Delete type=3 #102
|
2026/05/29-18:27:57.232279 7f381e7fc6c0 Level-0 table #171: started
|
||||||
2026/04/13-13:10:44.797919 7ff581bfd6c0 Delete type=0 #104
|
2026/05/29-18:27:57.253183 7f381e7fc6c0 Level-0 table #171: 3524 bytes OK
|
||||||
2026/04/13-13:10:47.796281 7ff580bfb6c0 Level-0 table #110: started
|
2026/05/29-18:27:57.291326 7f381e7fc6c0 Delete type=0 #169
|
||||||
2026/04/13-13:10:47.824966 7ff580bfb6c0 Level-0 table #110: 3524 bytes OK
|
2026/05/29-18:27:57.404912 7f381e7fc6c0 Manual compaction at level-0 from '!items!anomCommMorts001' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 141 : 1
|
||||||
2026/04/13-13:10:47.857042 7ff580bfb6c0 Delete type=0 #108
|
2026/05/29-18:27:57.404922 7f381e7fc6c0 Compacting 2@0 + 0@1 files
|
||||||
2026/04/13-13:10:47.973011 7ff580bfb6c0 Manual compaction at level-0 from '!items!anomCommMorts001' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at (end)
|
2026/05/29-18:27:57.421172 7f381e7fc6c0 Generated table #172@0: 9 keys, 6617 bytes
|
||||||
2026/04/13-13:10:47.973057 7ff580bfb6c0 Manual compaction at level-1 from '!items!anomCommMorts001' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 93 : 1
|
2026/05/29-18:27:57.421194 7f381e7fc6c0 Compacted 2@0 + 0@1 files => 6617 bytes
|
||||||
2026/04/13-13:10:47.973063 7ff580bfb6c0 Compacting 1@1 + 1@2 files
|
2026/05/29-18:27:57.449840 7f381e7fc6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
|
||||||
2026/04/13-13:10:47.995133 7ff580bfb6c0 Generated table #111@1: 9 keys, 6617 bytes
|
2026/05/29-18:27:57.449959 7f381e7fc6c0 Delete type=2 #166
|
||||||
2026/04/13-13:10:47.995159 7ff580bfb6c0 Compacted 1@1 + 1@2 files => 6617 bytes
|
2026/05/29-18:27:57.450112 7f381e7fc6c0 Delete type=2 #171
|
||||||
2026/04/13-13:10:48.030149 7ff580bfb6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
2026/05/29-18:27:57.505063 7f381e7fc6c0 Manual compaction at level-0 from '!items!null' @ 141 : 1 .. '!items!null' @ 0 : 0; will stop at (end)
|
||||||
2026/04/13-13:10:48.030263 7ff580bfb6c0 Delete type=2 #106
|
|
||||||
2026/04/13-13:10:48.030388 7ff580bfb6c0 Delete type=2 #110
|
|
||||||
2026/04/13-13:10:48.030511 7ff580bfb6c0 Manual compaction at level-1 from '!items!null' @ 93 : 1 .. '!items!null' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000023
|
MANIFEST-000071
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
2026/04/13-13:11:31.193586 7f2a6b7fe6c0 Recovering log #21
|
2026/05/29-19:25:48.553559 7f386cbff6c0 Recovering log #68
|
||||||
2026/04/13-13:11:31.247393 7f2a6b7fe6c0 Delete type=3 #19
|
2026/05/29-19:25:48.563799 7f386cbff6c0 Delete type=3 #66
|
||||||
2026/04/13-13:11:31.247448 7f2a6b7fe6c0 Delete type=0 #21
|
2026/05/29-19:25:48.563837 7f386cbff6c0 Delete type=0 #68
|
||||||
2026/04/13-14:20:41.081350 7f2a69ffb6c0 Level-0 table #26: started
|
2026/05/29-19:26:15.976984 7f381e7fc6c0 Level-0 table #74: started
|
||||||
2026/04/13-14:20:41.081377 7f2a69ffb6c0 Level-0 table #26: 0 bytes OK
|
2026/05/29-19:26:15.976996 7f381e7fc6c0 Level-0 table #74: 0 bytes OK
|
||||||
2026/04/13-14:20:41.118613 7f2a69ffb6c0 Delete type=0 #24
|
2026/05/29-19:26:15.982862 7f381e7fc6c0 Delete type=0 #72
|
||||||
2026/04/13-14:20:41.210913 7f2a69ffb6c0 Manual compaction at level-0 from '!actors!6RZ6IzJUHm4dB5Ut' @ 72057594037927935 : 1 .. '!folders!MbFQgPdF6Gtbj5AU' @ 0 : 0; will stop at (end)
|
2026/05/29-19:26:15.998506 7f381e7fc6c0 Manual compaction at level-0 from '!actors!6RZ6IzJUHm4dB5Ut' @ 72057594037927935 : 1 .. '!folders!MbFQgPdF6Gtbj5AU' @ 0 : 0; will stop at (end)
|
||||||
2026/04/13-14:20:41.210940 7f2a69ffb6c0 Manual compaction at level-1 from '!actors!6RZ6IzJUHm4dB5Ut' @ 72057594037927935 : 1 .. '!folders!MbFQgPdF6Gtbj5AU' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
2026/04/13-13:10:44.800502 7ff582bff6c0 Recovering log #16
|
2026/05/29-18:25:23.116810 7f381ffff6c0 Delete type=3 #1
|
||||||
2026/04/13-13:10:44.846821 7ff582bff6c0 Delete type=3 #14
|
2026/05/29-18:27:57.533567 7f381e7fc6c0 Level-0 table #69: started
|
||||||
2026/04/13-13:10:44.846886 7ff582bff6c0 Delete type=0 #16
|
2026/05/29-18:27:57.533614 7f381e7fc6c0 Level-0 table #69: 0 bytes OK
|
||||||
2026/04/13-13:10:47.902261 7ff580bfb6c0 Level-0 table #22: started
|
2026/05/29-18:27:57.568380 7f381e7fc6c0 Delete type=0 #67
|
||||||
2026/04/13-13:10:47.902285 7ff580bfb6c0 Level-0 table #22: 0 bytes OK
|
2026/05/29-18:27:57.662122 7f381e7fc6c0 Manual compaction at level-0 from '!actors!6RZ6IzJUHm4dB5Ut' @ 72057594037927935 : 1 .. '!folders!MbFQgPdF6Gtbj5AU' @ 0 : 0; will stop at '!folders!MbFQgPdF6Gtbj5AU' @ 37 : 1
|
||||||
2026/04/13-13:10:47.939594 7ff580bfb6c0 Delete type=0 #20
|
2026/05/29-18:27:57.662130 7f381e7fc6c0 Compacting 1@0 + 0@1 files
|
||||||
2026/04/13-13:10:47.973036 7ff580bfb6c0 Manual compaction at level-0 from '!actors!6RZ6IzJUHm4dB5Ut' @ 72057594037927935 : 1 .. '!folders!MbFQgPdF6Gtbj5AU' @ 0 : 0; will stop at (end)
|
2026/05/29-18:27:57.681906 7f381e7fc6c0 Generated table #70@0: 36 keys, 35733 bytes
|
||||||
2026/04/13-13:10:48.030491 7ff580bfb6c0 Manual compaction at level-1 from '!actors!6RZ6IzJUHm4dB5Ut' @ 72057594037927935 : 1 .. '!folders!MbFQgPdF6Gtbj5AU' @ 0 : 0; will stop at (end)
|
2026/05/29-18:27:57.681939 7f381e7fc6c0 Compacted 1@0 + 0@1 files => 35733 bytes
|
||||||
|
2026/05/29-18:27:57.724776 7f381e7fc6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
|
||||||
|
2026/05/29-18:27:57.724885 7f381e7fc6c0 Delete type=2 #49
|
||||||
|
2026/05/29-18:27:57.817815 7f381e7fc6c0 Manual compaction at level-0 from '!folders!MbFQgPdF6Gtbj5AU' @ 37 : 1 .. '!folders!MbFQgPdF6Gtbj5AU' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000062
|
MANIFEST-000113
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
2026/04/13-13:11:31.305113 7f2a6a7fc6c0 Recovering log #60
|
2026/05/29-19:25:48.578477 7f381f7fe6c0 Recovering log #110
|
||||||
2026/04/13-13:11:31.358709 7f2a6a7fc6c0 Delete type=3 #58
|
2026/05/29-19:25:48.589121 7f381f7fe6c0 Delete type=3 #108
|
||||||
2026/04/13-13:11:31.358775 7f2a6a7fc6c0 Delete type=0 #60
|
2026/05/29-19:25:48.589160 7f381f7fe6c0 Delete type=0 #110
|
||||||
2026/04/13-14:20:41.045418 7f2a69ffb6c0 Level-0 table #65: started
|
2026/05/29-19:26:15.970220 7f381e7fc6c0 Level-0 table #116: started
|
||||||
2026/04/13-14:20:41.045487 7f2a69ffb6c0 Level-0 table #65: 0 bytes OK
|
2026/05/29-19:26:15.970241 7f381e7fc6c0 Level-0 table #116: 0 bytes OK
|
||||||
2026/04/13-14:20:41.081154 7f2a69ffb6c0 Delete type=0 #63
|
2026/05/29-19:26:15.976948 7f381e7fc6c0 Delete type=0 #114
|
||||||
2026/04/13-14:20:41.210899 7f2a69ffb6c0 Manual compaction at level-0 from '!scenes!Jr7lGxYk2RETlXRv' @ 72057594037927935 : 1 .. '!scenes.tokens.delta.items!Jr7lGxYk2RETlXRv.6urwC5SVcou6UOAG.CTg4yBE12iMee1RU.BYT1CrA37R3Og0nu' @ 0 : 0; will stop at (end)
|
2026/05/29-19:26:15.998499 7f381e7fc6c0 Manual compaction at level-0 from '!scenes!0iGCRqkdJKjmmbl4' @ 72057594037927935 : 1 .. '!scenes.levels!X3XJg7raEXtOFOtj.defaultLevel0000' @ 0 : 0; will stop at (end)
|
||||||
2026/04/13-14:20:41.210948 7f2a69ffb6c0 Manual compaction at level-1 from '!scenes!Jr7lGxYk2RETlXRv' @ 72057594037927935 : 1 .. '!scenes.tokens.delta.items!Jr7lGxYk2RETlXRv.6urwC5SVcou6UOAG.CTg4yBE12iMee1RU.BYT1CrA37R3Og0nu' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
2026/04/13-13:10:44.916572 7ff5813fc6c0 Recovering log #55
|
2026/05/29-18:25:23.154144 7f381ffff6c0 Delete type=3 #1
|
||||||
2026/04/13-13:10:44.960340 7ff5813fc6c0 Delete type=3 #53
|
2026/05/29-18:27:57.197941 7f381e7fc6c0 Level-0 table #111: started
|
||||||
2026/04/13-13:10:44.960396 7ff5813fc6c0 Delete type=0 #55
|
2026/05/29-18:27:57.197975 7f381e7fc6c0 Level-0 table #111: 0 bytes OK
|
||||||
2026/04/13-13:10:47.857212 7ff580bfb6c0 Level-0 table #61: started
|
2026/05/29-18:27:57.232075 7f381e7fc6c0 Delete type=0 #109
|
||||||
2026/04/13-13:10:47.857237 7ff580bfb6c0 Level-0 table #61: 0 bytes OK
|
2026/05/29-18:27:57.339840 7f381e7fc6c0 Manual compaction at level-0 from '!scenes!0iGCRqkdJKjmmbl4' @ 72057594037927935 : 1 .. '!scenes.levels!X3XJg7raEXtOFOtj.defaultLevel0000' @ 0 : 0; will stop at '!scenes.levels!X3XJg7raEXtOFOtj.defaultLevel0000' @ 61 : 1
|
||||||
2026/04/13-13:10:47.902098 7ff580bfb6c0 Delete type=0 #59
|
2026/05/29-18:27:57.339849 7f381e7fc6c0 Compacting 1@0 + 0@1 files
|
||||||
2026/04/13-13:10:47.973025 7ff580bfb6c0 Manual compaction at level-0 from '!scenes!Jr7lGxYk2RETlXRv' @ 72057594037927935 : 1 .. '!scenes.tokens.delta.items!Jr7lGxYk2RETlXRv.6urwC5SVcou6UOAG.CTg4yBE12iMee1RU.BYT1CrA37R3Og0nu' @ 0 : 0; will stop at (end)
|
2026/05/29-18:27:57.358860 7f381e7fc6c0 Generated table #112@0: 4 keys, 1746 bytes
|
||||||
2026/04/13-13:10:48.030475 7ff580bfb6c0 Manual compaction at level-1 from '!scenes!Jr7lGxYk2RETlXRv' @ 72057594037927935 : 1 .. '!scenes.tokens.delta.items!Jr7lGxYk2RETlXRv.6urwC5SVcou6UOAG.CTg4yBE12iMee1RU.BYT1CrA37R3Og0nu' @ 0 : 0; will stop at (end)
|
2026/05/29-18:27:57.358888 7f381e7fc6c0 Compacted 1@0 + 0@1 files => 1746 bytes
|
||||||
|
2026/05/29-18:27:57.404742 7f381e7fc6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
|
||||||
|
2026/05/29-18:27:57.404821 7f381e7fc6c0 Delete type=2 #91
|
||||||
|
2026/05/29-18:27:57.505039 7f381e7fc6c0 Manual compaction at level-0 from '!scenes.levels!X3XJg7raEXtOFOtj.defaultLevel0000' @ 61 : 1 .. '!scenes.levels!X3XJg7raEXtOFOtj.defaultLevel0000' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
+44
-44
@@ -24,7 +24,7 @@
|
|||||||
min-width: 54px;
|
min-width: 54px;
|
||||||
|
|
||||||
label {
|
label {
|
||||||
font-size: 0.58em;
|
font-size: 0.6em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
color: var(--cel-orange-light);
|
color: var(--cel-orange-light);
|
||||||
@@ -34,12 +34,12 @@
|
|||||||
.stat-value, .attr-display {
|
.stat-value, .attr-display {
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 1.05em;
|
font-size: 1.2em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.attr-sep { color: rgba(196,154,26,0.5); margin: 0 1px; font-size: 0.85em; }
|
.attr-sep { color: rgba(196,154,26,0.5); margin: 0 1px; font-size: 0.8em; }
|
||||||
|
|
||||||
input.attr-val, input.attr-max {
|
input.attr-val, input.attr-max {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
border-bottom: 1px solid var(--cel-orange-light);
|
border-bottom: 1px solid var(--cel-orange-light);
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 1em;
|
font-size: 1.1em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
.armor-malus-value {
|
.armor-malus-value {
|
||||||
color: #e06040;
|
color: #e06040;
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 1.05em;
|
font-size: 1.2em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
label { color: #e06040; opacity: 0.8; }
|
label { color: #e06040; opacity: 0.8; }
|
||||||
@@ -92,7 +92,7 @@
|
|||||||
.stat-name {
|
.stat-name {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 1em;
|
font-size: 1.1em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,7 @@
|
|||||||
border: 1px solid var(--cel-orange);
|
border: 1px solid var(--cel-orange);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: rgba(224, 123, 0, 0.08);
|
background: rgba(224, 123, 0, 0.08);
|
||||||
font-size: 0.78em;
|
font-size: 0.8em;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
|
||||||
.res-die-icon {
|
.res-die-icon {
|
||||||
@@ -164,7 +164,7 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 3px 8px;
|
padding: 3px 8px;
|
||||||
border-bottom: 1px solid rgba(122,92,32,0.18);
|
border-bottom: 1px solid rgba(122,92,32,0.18);
|
||||||
font-size: 0.85em;
|
font-size: 0.8em;
|
||||||
|
|
||||||
// Alternating cream-dark rows for legibility
|
// Alternating cream-dark rows for legibility
|
||||||
&:nth-child(even) { background: var(--cel-cream-dark); }
|
&:nth-child(even) { background: var(--cel-cream-dark); }
|
||||||
@@ -279,7 +279,7 @@
|
|||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-size: 1.1em;
|
font-size: 1.2em;
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -293,7 +293,7 @@
|
|||||||
height: 14px;
|
height: 14px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: 1px solid currentColor;
|
border: 1px solid currentColor;
|
||||||
font-size: 0.65em;
|
font-size: 0.7em;
|
||||||
font-family: var(--cel-font-body);
|
font-family: var(--cel-font-body);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
@@ -349,7 +349,7 @@
|
|||||||
gap: 6px;
|
gap: 6px;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
background: rgba(139,115,85,0.1);
|
background: rgba(139,115,85,0.1);
|
||||||
font-size: 0.85em;
|
font-size: 0.8em;
|
||||||
label { color: var(--cel-border); }
|
label { color: var(--cel-border); }
|
||||||
input[type="number"] { width: 40px; .cel-input-std(); }
|
input[type="number"] { width: 40px; .cel-input-std(); }
|
||||||
}
|
}
|
||||||
@@ -380,7 +380,7 @@
|
|||||||
.faction-aspect-summary-title {
|
.faction-aspect-summary-title {
|
||||||
color: var(--cel-green);
|
color: var(--cel-green);
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 1em;
|
font-size: 1.1em;
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
line-height: 1.05;
|
line-height: 1.05;
|
||||||
@@ -393,7 +393,7 @@
|
|||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 0.84em;
|
font-size: 0.8em;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,7 +413,7 @@
|
|||||||
|
|
||||||
.label {
|
.label {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 0.66em;
|
font-size: 0.7em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.03em;
|
letter-spacing: 0.03em;
|
||||||
color: var(--cel-border);
|
color: var(--cel-border);
|
||||||
@@ -423,7 +423,7 @@
|
|||||||
.value {
|
.value {
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 1.02em;
|
font-size: 1.1em;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -448,7 +448,7 @@
|
|||||||
.faction-aspect-active-title {
|
.faction-aspect-active-title {
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
color: var(--cel-border);
|
color: var(--cel-border);
|
||||||
font-size: 0.68em;
|
font-size: 0.7em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
line-height: 1.1;
|
line-height: 1.1;
|
||||||
@@ -477,20 +477,20 @@
|
|||||||
|
|
||||||
.name {
|
.name {
|
||||||
color: var(--cel-green);
|
color: var(--cel-green);
|
||||||
font-size: 0.88em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.value {
|
.value {
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 0.9em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.faction-aspect-empty {
|
.faction-aspect-empty {
|
||||||
color: #666;
|
color: #666;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-size: 0.84em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,7 +505,7 @@
|
|||||||
background-image: url("../assets/ui/fond_cadrille.jpg");
|
background-image: url("../assets/ui/fond_cadrille.jpg");
|
||||||
background-blend-mode: soft-light;
|
background-blend-mode: soft-light;
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
th { padding: 5px 8px; font-family: var(--cel-font-title); font-size: 1.05em; letter-spacing: 0.06em; text-transform: uppercase; }
|
th { padding: 5px 8px; font-family: var(--cel-font-title); font-size: 1.2em; letter-spacing: 0.06em; text-transform: uppercase; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.faction-row {
|
.faction-row {
|
||||||
@@ -542,7 +542,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.faction-count {
|
.faction-count {
|
||||||
font-size: 0.85em;
|
font-size: 0.8em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
min-width: 16px;
|
min-width: 16px;
|
||||||
@@ -569,7 +569,7 @@
|
|||||||
border-bottom: 1px solid rgba(122,92,32,0.25);
|
border-bottom: 1px solid rgba(122,92,32,0.25);
|
||||||
color: var(--cel-green);
|
color: var(--cel-green);
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 1.05em;
|
font-size: 1.2em;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
@@ -578,7 +578,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
font-size: 0.88em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.factions-legend-row {
|
.factions-legend-row {
|
||||||
@@ -634,7 +634,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.item-tag {
|
.item-tag {
|
||||||
font-size: 0.75em;
|
font-size: 0.8em;
|
||||||
padding: 1px 7px;
|
padding: 1px 7px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: rgba(12,76,12,0.15);
|
background: rgba(12,76,12,0.15);
|
||||||
@@ -661,7 +661,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
min-width: 20px;
|
min-width: 20px;
|
||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
font-size: 1.08rem;
|
font-size: 1.1rem;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -684,7 +684,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.equip-empty {
|
.equip-empty {
|
||||||
font-size: 0.85em;
|
font-size: 0.8em;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
color: var(--cel-border);
|
color: var(--cel-border);
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
@@ -736,7 +736,7 @@
|
|||||||
.biography-portrait-empty {
|
.biography-portrait-empty {
|
||||||
padding: 14px;
|
padding: 14px;
|
||||||
color: var(--cel-border);
|
color: var(--cel-border);
|
||||||
font-size: 0.82em;
|
font-size: 0.8em;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
@@ -769,7 +769,7 @@
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: linear-gradient(180deg, rgba(255,255,255,0.82), rgba(233,223,201,0.95));
|
background: linear-gradient(180deg, rgba(255,255,255,0.82), rgba(233,223,201,0.95));
|
||||||
color: var(--cel-green);
|
color: var(--cel-green);
|
||||||
font-size: 0.82em;
|
font-size: 0.8em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
@@ -790,7 +790,7 @@
|
|||||||
|
|
||||||
.biography-portrait-hint {
|
.biography-portrait-hint {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 0.78em;
|
font-size: 0.8em;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
color: var(--cel-border);
|
color: var(--cel-border);
|
||||||
}
|
}
|
||||||
@@ -838,7 +838,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
.cel-input-std();
|
.cel-input-std();
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 1.1em;
|
font-size: 1.2em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--cel-green);
|
color: var(--cel-green);
|
||||||
}
|
}
|
||||||
@@ -848,7 +848,7 @@
|
|||||||
border-color: rgba(122,92,32,0.4);
|
border-color: rgba(122,92,32,0.4);
|
||||||
.xp-depense-value {
|
.xp-depense-value {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 1.1em;
|
font-size: 1.2em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--cel-border);
|
color: var(--cel-border);
|
||||||
}
|
}
|
||||||
@@ -858,7 +858,7 @@
|
|||||||
background: var(--cel-green);
|
background: var(--cel-green);
|
||||||
border: 1px solid var(--cel-orange);
|
border: 1px solid var(--cel-orange);
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
font-size: 0.78em;
|
font-size: 0.9em;
|
||||||
padding: 5px 12px;
|
padding: 5px 12px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
@@ -875,14 +875,14 @@
|
|||||||
.xp-log-table {
|
.xp-log-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
font-size: 0.82em;
|
font-size: 0.8em;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
|
|
||||||
thead tr {
|
thead tr {
|
||||||
background: rgba(12,76,12,0.35);
|
background: rgba(12,76,12,0.35);
|
||||||
th {
|
th {
|
||||||
color: var(--cel-orange-light);
|
color: var(--cel-orange-light);
|
||||||
font-size: 0.75em;
|
font-size: 0.8em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
padding: 3px 6px;
|
padding: 3px 6px;
|
||||||
@@ -918,7 +918,7 @@
|
|||||||
.xp-ref {
|
.xp-ref {
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
summary {
|
summary {
|
||||||
font-size: 0.78em;
|
font-size: 0.8em;
|
||||||
color: var(--cel-orange-light);
|
color: var(--cel-orange-light);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
letter-spacing: 0.03em;
|
letter-spacing: 0.03em;
|
||||||
@@ -930,7 +930,7 @@
|
|||||||
.xp-ref-table {
|
.xp-ref-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
font-size: 0.82em;
|
font-size: 0.8em;
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
|
|
||||||
thead tr {
|
thead tr {
|
||||||
@@ -941,7 +941,7 @@
|
|||||||
}
|
}
|
||||||
th {
|
th {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 0.9em;
|
font-size: 1em;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
@@ -987,7 +987,7 @@
|
|||||||
|
|
||||||
.anomaly-block-title {
|
.anomaly-block-title {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 0.85em;
|
font-size: 0.9em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.07em;
|
letter-spacing: 0.07em;
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
@@ -1000,7 +1000,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
color: var(--cel-border);
|
color: var(--cel-border);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-size: 0.85em;
|
font-size: 0.8em;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -1030,12 +1030,12 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
.anomaly-name {
|
.anomaly-name {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 1em;
|
font-size: 1.1em;
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.anomaly-subtype {
|
.anomaly-subtype {
|
||||||
font-size: 0.75em;
|
font-size: 0.8em;
|
||||||
color: var(--cel-cream, #f0e8d4);
|
color: var(--cel-cream, #f0e8d4);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
@@ -1057,7 +1057,7 @@
|
|||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
|
|
||||||
.anomaly-level-label {
|
.anomaly-level-label {
|
||||||
font-size: 0.72em;
|
font-size: 0.7em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: var(--cel-cream, #f0e8d4);
|
color: var(--cel-cream, #f0e8d4);
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
@@ -1085,7 +1085,7 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
.anomaly-uses-label {
|
.anomaly-uses-label {
|
||||||
font-size: 0.72em;
|
font-size: 0.7em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: var(--cel-cream, #f0e8d4);
|
color: var(--cel-cream, #f0e8d4);
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
@@ -1110,7 +1110,7 @@
|
|||||||
background: var(--cel-green);
|
background: var(--cel-green);
|
||||||
border: 1px solid var(--cel-orange);
|
border: 1px solid var(--cel-orange);
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
font-size: 0.72em;
|
font-size: 0.8em;
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
|
|||||||
+2
-2
@@ -1,13 +1,13 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "CopaseticNF";
|
font-family: "CopaseticNF";
|
||||||
src: url("../assets/fonts/CopaseticNF.otf") format("opentype");
|
src: url("../assets/fonts/CopaseticNF.woff");
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "CopaseticNF";
|
font-family: "CopaseticNF";
|
||||||
src: url("../assets/fonts/CopaseticNF-Bold.otf") format("opentype");
|
src: url("../assets/fonts/CopaseticNF-Bold.woff");
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-8
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
--cel-border: #7a5c20; // bordure dorée
|
--cel-border: #7a5c20; // bordure dorée
|
||||||
--cel-accent: #6b1e28; // bordeaux profond (échecs, accents)
|
--cel-accent: #6b1e28; // bordeaux profond (échecs, accents)
|
||||||
|
--cel-text: #2f2413; // texte de corps sur fond clair (parchemin)
|
||||||
|
|
||||||
--cel-shadow: rgba(10,15,10,0.5);
|
--cel-shadow: rgba(10,15,10,0.5);
|
||||||
|
|
||||||
@@ -84,7 +85,7 @@
|
|||||||
border-bottom: 1px solid rgba(196,154,26,0.5);
|
border-bottom: 1px solid rgba(196,154,26,0.5);
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 1.4em;
|
font-size: 1.5em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
letter-spacing: 0.06em;
|
letter-spacing: 0.06em;
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
@@ -93,7 +94,7 @@
|
|||||||
|
|
||||||
.actor-name {
|
.actor-name {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 1.4em;
|
font-size: 1.5em;
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
letter-spacing: 0.06em;
|
letter-spacing: 0.06em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -119,7 +120,7 @@
|
|||||||
gap: 4px;
|
gap: 4px;
|
||||||
|
|
||||||
label {
|
label {
|
||||||
font-size: 0.65em;
|
font-size: 0.7em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.06em;
|
letter-spacing: 0.06em;
|
||||||
color: var(--cel-orange-light);
|
color: var(--cel-orange-light);
|
||||||
@@ -130,7 +131,7 @@
|
|||||||
// Styles identiques play mode et edit mode
|
// Styles identiques play mode et edit mode
|
||||||
span,
|
span,
|
||||||
input[type="text"] {
|
input[type="text"] {
|
||||||
font-size: 0.95em;
|
font-size: 0.9em;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
color: var(--cel-cream);
|
color: var(--cel-cream);
|
||||||
@@ -172,14 +173,14 @@
|
|||||||
min-width: 52px;
|
min-width: 52px;
|
||||||
|
|
||||||
label {
|
label {
|
||||||
font-size: 0.62em;
|
font-size: 0.6em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.08em;
|
letter-spacing: 0.08em;
|
||||||
color: var(--cel-orange-light);
|
color: var(--cel-orange-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-value {
|
.stat-value {
|
||||||
font-size: 1.4em;
|
font-size: 1.5em;
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@@ -241,7 +242,7 @@
|
|||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
color: rgba(240,232,212,0.8);
|
color: rgba(240,232,212,0.8);
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 0.85em;
|
font-size: 0.9em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.07em;
|
letter-spacing: 0.07em;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -330,7 +331,7 @@
|
|||||||
|
|
||||||
.wound-value {
|
.wound-value {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 0.95em;
|
font-size: 1.1em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
|
|||||||
+20
-20
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
.anomaly-section-title {
|
.anomaly-section-title {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 0.78em;
|
font-size: 0.9em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.07em;
|
letter-spacing: 0.07em;
|
||||||
color: var(--cel-green-dark, #0c4c0c);
|
color: var(--cel-green-dark, #0c4c0c);
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
min-height: 60px;
|
min-height: 60px;
|
||||||
padding: 4px 6px;
|
padding: 4px 6px;
|
||||||
color: #1a1209;
|
color: #1a1209;
|
||||||
font-size: 0.88em;
|
font-size: 0.9em;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
.editor-content, .prosemirror { color: #1a1209; background: transparent; }
|
.editor-content, .prosemirror { color: #1a1209; background: transparent; }
|
||||||
p { margin: 0 0 4px 0; color: #1a1209; }
|
p { margin: 0 0 4px 0; color: #1a1209; }
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
border-bottom: 1px solid var(--cel-orange-light);
|
border-bottom: 1px solid var(--cel-orange-light);
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 1.2em;
|
font-size: 1.3em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
border: 1px solid var(--cel-orange-light);
|
border: 1px solid var(--cel-orange-light);
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
font-size: 0.85em;
|
font-size: 0.8em;
|
||||||
option { background: var(--cel-green-dark); color: var(--cel-cream); }
|
option { background: var(--cel-green-dark); color: var(--cel-cream); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
label { color: var(--cel-orange-light); font-size: 0.75em; text-transform: uppercase; }
|
label { color: var(--cel-orange-light); font-size: 0.8em; text-transform: uppercase; }
|
||||||
input[type="number"] {
|
input[type="number"] {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
@@ -147,7 +147,7 @@
|
|||||||
padding: 5px 12px;
|
padding: 5px 12px;
|
||||||
color: rgba(240,232,212,0.7);
|
color: rgba(240,232,212,0.7);
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 0.78em;
|
font-size: 0.9em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.07em;
|
letter-spacing: 0.07em;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -186,7 +186,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
label { color: var(--cel-orange-light); font-size: 0.72em; text-transform: uppercase; }
|
label { color: var(--cel-orange-light); font-size: 0.7em; text-transform: uppercase; }
|
||||||
input[type="number"] {
|
input[type="number"] {
|
||||||
width: 44px;
|
width: 44px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
@@ -207,7 +207,7 @@
|
|||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
label {
|
label {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 0.75em;
|
font-size: 0.8em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
color: var(--cel-border); // #7a5c20 — contraste WCAG AA sur fond crème
|
color: var(--cel-border); // #7a5c20 — contraste WCAG AA sur fond crème
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
.scores-stat-col {
|
.scores-stat-col {
|
||||||
.scores-stat-name {
|
.scores-stat-name {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 0.75em;
|
font-size: 0.8em;
|
||||||
color: var(--cel-orange); // gold
|
color: var(--cel-orange); // gold
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
border-bottom: 1px solid var(--cel-border);
|
border-bottom: 1px solid var(--cel-border);
|
||||||
@@ -266,7 +266,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
label { color: var(--cel-orange-light); font-size: 0.75em; text-transform: uppercase; }
|
label { color: var(--cel-orange-light); font-size: 0.8em; text-transform: uppercase; }
|
||||||
.level-input, .anomaly-level-value {
|
.level-input, .anomaly-level-value {
|
||||||
width: 38px;
|
width: 38px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
@@ -301,7 +301,7 @@
|
|||||||
border: 1px solid rgba(196,154,26,0.4);
|
border: 1px solid rgba(196,154,26,0.4);
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 0.85em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,7 +327,7 @@
|
|||||||
|
|
||||||
.anomaly-skills-label {
|
.anomaly-skills-label {
|
||||||
color: var(--cel-orange-light, #c49a1a);
|
color: var(--cel-orange-light, #c49a1a);
|
||||||
font-size: 0.72em;
|
font-size: 0.7em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
@@ -339,7 +339,7 @@
|
|||||||
border: 1px solid rgba(196,154,26,0.55);
|
border: 1px solid rgba(196,154,26,0.55);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 1px 7px;
|
padding: 1px 7px;
|
||||||
font-size: 0.72em;
|
font-size: 0.7em;
|
||||||
color: var(--cel-cream, #f0e8d4);
|
color: var(--cel-cream, #f0e8d4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -368,8 +368,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
label { font-size: 0.75em; color: var(--cel-orange-light); white-space: nowrap; }
|
label { font-size: 0.8em; color: var(--cel-orange-light); white-space: nowrap; }
|
||||||
select { background: rgba(0,0,0,0.3); border: 1px solid var(--cel-orange); color: var(--cel-orange); font-family: var(--cel-font-title); border-radius: 3px; padding: 2px 4px; font-size: 0.85em; }
|
select { background: rgba(0,0,0,0.3); border: 1px solid var(--cel-orange); color: var(--cel-orange); font-family: var(--cel-font-title); border-radius: 3px; padding: 2px 4px; font-size: 0.9em; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.weapon-damage-badge {
|
.weapon-damage-badge {
|
||||||
@@ -380,9 +380,9 @@
|
|||||||
border: 1px solid var(--cel-orange);
|
border: 1px solid var(--cel-orange);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
.damage-label { font-size: 0.72em; text-transform: uppercase; color: var(--cel-orange-light); letter-spacing: 0.05em; }
|
.damage-label { font-size: 0.7em; text-transform: uppercase; color: var(--cel-orange-light); letter-spacing: 0.05em; }
|
||||||
.damage-value { font-family: var(--cel-font-title); font-size: 1.6em; font-weight: bold; color: var(--cel-orange); min-width: 28px; text-align: center; }
|
.damage-value { font-family: var(--cel-font-title); font-size: 1.8em; font-weight: bold; color: var(--cel-orange); min-width: 28px; text-align: center; }
|
||||||
.damage-hint { font-size: 0.78em; color: var(--cel-cream); font-style: italic; }
|
.damage-hint { font-size: 0.8em; color: var(--cel-cream); font-style: italic; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,10 +404,10 @@
|
|||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
padding: 8px 20px;
|
padding: 8px 20px;
|
||||||
min-width: 110px;
|
min-width: 110px;
|
||||||
label { font-size: 0.72em; text-transform: uppercase; color: var(--cel-orange-light); letter-spacing: 0.05em; }
|
label { font-size: 0.7em; text-transform: uppercase; color: var(--cel-orange-light); letter-spacing: 0.05em; }
|
||||||
.armure-stat-value {
|
.armure-stat-value {
|
||||||
input[type="number"], span {
|
input[type="number"], span {
|
||||||
font-family: var(--cel-font-title); font-size: 1.8em; font-weight: bold; color: var(--cel-orange);
|
font-family: var(--cel-font-title); font-size: 2em; font-weight: bold; color: var(--cel-orange);
|
||||||
text-align: center; background: transparent; border: none; width: 40px;
|
text-align: center; background: transparent; border: none; width: 40px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
.cel-section-header() {
|
.cel-section-header() {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 0.78em;
|
font-size: 0.9em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.1em;
|
letter-spacing: 0.1em;
|
||||||
// Gold instead of vivid green — Art Déco elegance
|
// Gold instead of vivid green — Art Déco elegance
|
||||||
|
|||||||
+21
-21
@@ -14,12 +14,12 @@
|
|||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
font-size: 0.85em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.npc-type-badge {
|
.npc-type-badge {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 0.8em;
|
font-size: 0.9em;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
@@ -65,14 +65,14 @@
|
|||||||
.domain-label-primary {
|
.domain-label-primary {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 1.1em;
|
font-size: 1.2em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.06em;
|
letter-spacing: 0.06em;
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
}
|
}
|
||||||
|
|
||||||
.domain-label-secondary {
|
.domain-label-secondary {
|
||||||
font-size: 0.75em;
|
font-size: 0.8em;
|
||||||
color: rgba(220,170,80,0.7);
|
color: rgba(220,170,80,0.7);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
input.domain-value-input {
|
input.domain-value-input {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
.cel-input-std();
|
.cel-input-std();
|
||||||
font-size: 1.2em;
|
font-size: 1.3em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
|
|
||||||
.domain-value {
|
.domain-value {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 1.4em;
|
font-size: 1.5em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
min-width: 20px;
|
min-width: 20px;
|
||||||
@@ -124,7 +124,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.domain-value-base {
|
.domain-value-base {
|
||||||
font-size: 0.75em;
|
font-size: 0.8em;
|
||||||
color: rgba(220,170,80,0.6);
|
color: rgba(220,170,80,0.6);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 0.9em;
|
font-size: 1em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.06em;
|
letter-spacing: 0.06em;
|
||||||
border-bottom: 1px solid rgba(196,154,26,0.4);
|
border-bottom: 1px solid rgba(196,154,26,0.4);
|
||||||
@@ -197,7 +197,7 @@
|
|||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 0.9em;
|
font-size: 1em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.06em;
|
letter-spacing: 0.06em;
|
||||||
border-radius: 4px 4px 0 0;
|
border-radius: 4px 4px 0 0;
|
||||||
@@ -222,13 +222,13 @@
|
|||||||
.faction-name {
|
.faction-name {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
color: var(--cel-orange);
|
color: var(--cel-orange);
|
||||||
font-size: 0.95em;
|
font-size: 1.1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.faction-none {
|
.faction-none {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
color: rgba(122,92,32,0.5);
|
color: rgba(122,92,32,0.5);
|
||||||
font-size: 0.85em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,7 +242,7 @@
|
|||||||
border-top: none;
|
border-top: none;
|
||||||
border-radius: 0 0 4px 4px;
|
border-radius: 0 0 4px 4px;
|
||||||
|
|
||||||
label { font-size: 0.85em; color: var(--cel-brown); }
|
label { font-size: 0.8em; color: var(--cel-brown); }
|
||||||
select { flex: 1; .cel-input-std(); }
|
select { flex: 1; .cel-input-std(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -269,7 +269,7 @@
|
|||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-size: 1.1em;
|
font-size: 1.2em;
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -284,7 +284,7 @@
|
|||||||
height: 14px;
|
height: 14px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: 1px solid currentColor;
|
border: 1px solid currentColor;
|
||||||
font-size: 0.65em;
|
font-size: 0.7em;
|
||||||
font-family: var(--cel-font-body);
|
font-family: var(--cel-font-body);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
@@ -340,7 +340,7 @@
|
|||||||
gap: 6px;
|
gap: 6px;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
background: rgba(139,115,85,0.1);
|
background: rgba(139,115,85,0.1);
|
||||||
font-size: 0.85em;
|
font-size: 0.8em;
|
||||||
label { color: var(--cel-border); }
|
label { color: var(--cel-border); }
|
||||||
input[type="number"] { width: 40px; .cel-input-std(); }
|
input[type="number"] { width: 40px; .cel-input-std(); }
|
||||||
}
|
}
|
||||||
@@ -372,7 +372,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.item-tag {
|
.item-tag {
|
||||||
font-size: 0.75em;
|
font-size: 0.8em;
|
||||||
padding: 1px 7px;
|
padding: 1px 7px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: rgba(12,76,12,0.15);
|
background: rgba(12,76,12,0.15);
|
||||||
@@ -399,14 +399,14 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
min-width: 20px;
|
min-width: 20px;
|
||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
font-size: 1.08rem;
|
font-size: 1.1rem;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.equip-empty {
|
.equip-empty {
|
||||||
font-size: 0.85em;
|
font-size: 0.8em;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
color: var(--cel-border);
|
color: var(--cel-border);
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
@@ -465,7 +465,7 @@
|
|||||||
.biography-portrait-empty {
|
.biography-portrait-empty {
|
||||||
padding: 14px;
|
padding: 14px;
|
||||||
color: var(--cel-border);
|
color: var(--cel-border);
|
||||||
font-size: 0.82em;
|
font-size: 0.8em;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
@@ -498,7 +498,7 @@
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: linear-gradient(180deg, rgba(255,255,255,0.82), rgba(233,223,201,0.95));
|
background: linear-gradient(180deg, rgba(255,255,255,0.82), rgba(233,223,201,0.95));
|
||||||
color: var(--cel-green);
|
color: var(--cel-green);
|
||||||
font-size: 0.82em;
|
font-size: 0.8em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
@@ -519,7 +519,7 @@
|
|||||||
|
|
||||||
.biography-portrait-hint {
|
.biography-portrait-hint {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 0.78em;
|
font-size: 0.8em;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
color: var(--cel-border);
|
color: var(--cel-border);
|
||||||
}
|
}
|
||||||
|
|||||||
+206
-116
@@ -30,7 +30,7 @@
|
|||||||
.roll-actor {
|
.roll-actor {
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
color: var(--cel-orange-light, #ddb84a);
|
color: var(--cel-orange-light, #ddb84a);
|
||||||
font-size: 0.78em;
|
font-size: 0.9em;
|
||||||
letter-spacing: 0.07em;
|
letter-spacing: 0.07em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
.roll-skill-line {
|
.roll-skill-line {
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
font-size: 1.25em;
|
font-size: 1.4em;
|
||||||
color: var(--cel-cream, #f0e8d4);
|
color: var(--cel-cream, #f0e8d4);
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
|
|
||||||
@@ -58,24 +58,24 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
font-size: 0.82em;
|
font-size: 0.9em;
|
||||||
color: var(--cel-cream, #f0e8d4);
|
color: var(--cel-cream, #f0e8d4);
|
||||||
|
|
||||||
.dval, .nb-dice {
|
.dval, .nb-dice {
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
font-size: 1.7em;
|
font-size: 2em;
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
.dlabel { font-size: 0.78em; text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.75; }
|
.dlabel { font-size: 0.8em; text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.75; }
|
||||||
.dminus { color: #f0a0a0; font-weight: bold; }
|
.dminus { color: #f0a0a0; font-weight: bold; }
|
||||||
.deq { opacity: 0.55; }
|
.deq { opacity: 0.55; }
|
||||||
.ddice { color: var(--cel-orange, #e07b00); }
|
.ddice { color: var(--cel-orange, #e07b00); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.wound-info {
|
.wound-info {
|
||||||
font-size: 0.73em;
|
font-size: 0.8em;
|
||||||
color: #f0a0a0;
|
color: #f0a0a0;
|
||||||
margin-top: 3px;
|
margin-top: 3px;
|
||||||
}
|
}
|
||||||
@@ -117,17 +117,17 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 0.65em;
|
font-size: 0.7em;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.moon-icon { font-size: 1.2em; flex-shrink: 0; }
|
.moon-icon { font-size: 1.3em; flex-shrink: 0; }
|
||||||
|
|
||||||
.moon-text {
|
.moon-text {
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
font-size: 0.88em;
|
font-size: 1em;
|
||||||
color: var(--cel-green, #0c4c0c);
|
color: var(--cel-green, #0c4c0c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
|
|
||||||
label {
|
label {
|
||||||
flex: 0 0 110px;
|
flex: 0 0 110px;
|
||||||
font-size: 0.78em;
|
font-size: 0.8em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
color: var(--cel-border, #7a5c20);
|
color: var(--cel-border, #7a5c20);
|
||||||
@@ -165,8 +165,8 @@
|
|||||||
padding: 3px 7px;
|
padding: 3px 7px;
|
||||||
background: rgba(255,255,255,0.85);
|
background: rgba(255,255,255,0.85);
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-size: 0.85em;
|
font-size: 0.9em;
|
||||||
color: #333;
|
color: var(--cel-text, #2f2413);
|
||||||
|
|
||||||
&:focus { outline: 1px solid var(--cel-orange, #e07b00); }
|
&:focus { outline: 1px solid var(--cel-orange, #e07b00); }
|
||||||
}
|
}
|
||||||
@@ -233,7 +233,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 0.65em;
|
font-size: 0.7em;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,7 +242,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.destin-icon {
|
.destin-icon {
|
||||||
font-size: 1.1em;
|
font-size: 1.2em;
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
@@ -252,20 +252,20 @@
|
|||||||
|
|
||||||
.destin-main {
|
.destin-main {
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
font-size: 0.9em;
|
font-size: 1.1em;
|
||||||
color: var(--cel-green, #0c4c0c);
|
color: var(--cel-green, #0c4c0c);
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.destin-bonus {
|
.destin-bonus {
|
||||||
font-size: 0.72em;
|
font-size: 0.8em;
|
||||||
color: var(--cel-border, #7a5c20);
|
color: var(--cel-border, #7a5c20);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.destin-count {
|
.destin-count {
|
||||||
font-size: 0.75em;
|
font-size: 0.8em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--cel-green, #0c4c0c);
|
color: var(--cel-green, #0c4c0c);
|
||||||
background: rgba(196,154,26,0.2);
|
background: rgba(196,154,26,0.2);
|
||||||
@@ -275,7 +275,7 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
&.no-destin {
|
&.no-destin {
|
||||||
color: #888;
|
color: rgba(0,0,0,0.45);
|
||||||
background: rgba(0,0,0,0.05);
|
background: rgba(0,0,0,0.05);
|
||||||
border-color: rgba(0,0,0,0.1);
|
border-color: rgba(0,0,0,0.1);
|
||||||
}
|
}
|
||||||
@@ -283,7 +283,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-visibility label { color: #888; }
|
.form-visibility label { color: rgba(0,0,0,0.45); }
|
||||||
|
|
||||||
.form-faction-aspect select {
|
.form-faction-aspect select {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@@ -326,7 +326,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 0.75em;
|
font-size: 0.8em;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -338,13 +338,13 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
.puiser-main {
|
.puiser-main {
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
font-size: 0.9em;
|
font-size: 1.1em;
|
||||||
color: var(--cel-accent, #6b1e28);
|
color: var(--cel-accent, #6b1e28);
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
.puiser-sub {
|
.puiser-sub {
|
||||||
font-size: 0.7em;
|
font-size: 0.7em;
|
||||||
color: #888;
|
color: rgba(0,0,0,0.45);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -405,7 +405,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.fortune-icon {
|
.fortune-icon {
|
||||||
font-size: 1.1em;
|
font-size: 1.2em;
|
||||||
color: var(--cel-green, #0c4c0c);
|
color: var(--cel-green, #0c4c0c);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
@@ -414,12 +414,12 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
.fortune-main {
|
.fortune-main {
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
font-size: 0.9em;
|
font-size: 1.1em;
|
||||||
color: var(--cel-green, #0c4c0c);
|
color: var(--cel-green, #0c4c0c);
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
.fortune-bonus {
|
.fortune-bonus {
|
||||||
font-size: 0.72em;
|
font-size: 0.8em;
|
||||||
color: var(--cel-border, #7a5c20);
|
color: var(--cel-border, #7a5c20);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
@@ -459,7 +459,7 @@
|
|||||||
|
|
||||||
.preview-formula {
|
.preview-formula {
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
font-size: 1.6em;
|
font-size: 1.9em;
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
@@ -469,6 +469,90 @@
|
|||||||
|
|
||||||
// ─── Chat message ─────────────────────────────────────────────────────────────
|
// ─── Chat message ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
// ── Contreparties dé de lune (partagé : chat-roll + moon-standalone-card) ──
|
||||||
|
.celestopol.chat-roll,
|
||||||
|
.celestopol-roll.moon-standalone-card {
|
||||||
|
.moon-effect-actions {
|
||||||
|
padding: 6px 10px 8px;
|
||||||
|
border-top: 2px solid rgba(122,92,32,0.18);
|
||||||
|
background: rgba(12,76,12,0.04);
|
||||||
|
border-radius: 0 0 3px 3px;
|
||||||
|
|
||||||
|
.moon-effect-label {
|
||||||
|
display: block;
|
||||||
|
font-family: var(--cel-font-title);
|
||||||
|
font-size: 0.8em;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--cel-border, #7a5c20);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.07em;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.moon-effect-buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 5px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.moon-effect-btn {
|
||||||
|
font-family: var(--cel-font-title);
|
||||||
|
font-size: 0.9em;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 4px 11px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: filter 0.12s, opacity 0.12s;
|
||||||
|
line-height: 1.4;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
// Positif par défaut : vert jade / or
|
||||||
|
background: var(--cel-green, #1b3828);
|
||||||
|
color: var(--cel-orange-light, #ddb84a);
|
||||||
|
border: 1px solid rgba(196,154,26,0.35);
|
||||||
|
|
||||||
|
&:hover:not(:disabled) { filter: brightness(1.18); }
|
||||||
|
&:disabled { opacity: 0.55; cursor: not-allowed; }
|
||||||
|
|
||||||
|
&.moon-effect-negative {
|
||||||
|
background: var(--cel-accent, #6b1e28);
|
||||||
|
color: var(--cel-cream, #f0e8d4);
|
||||||
|
border-color: rgba(139,30,46,0.4);
|
||||||
|
&:hover:not(:disabled) { filter: brightness(1.12); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.moon-effect-narrative {
|
||||||
|
font-size: 0.8em;
|
||||||
|
color: var(--cel-border, #7a5c20);
|
||||||
|
font-style: italic;
|
||||||
|
align-self: center;
|
||||||
|
padding-left: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.moon-effect-applied-status {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
margin-top: 6px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
font-family: var(--cel-font-title);
|
||||||
|
font-style: italic;
|
||||||
|
padding: 3px 9px;
|
||||||
|
border-radius: 3px;
|
||||||
|
color: var(--cel-green, #1b3828);
|
||||||
|
background: rgba(12,76,12,0.09);
|
||||||
|
border: 1px solid rgba(12,76,12,0.22);
|
||||||
|
|
||||||
|
&.is-negative {
|
||||||
|
color: var(--cel-accent, #6b1e28);
|
||||||
|
background: rgba(107,30,40,0.09);
|
||||||
|
border-color: rgba(107,30,40,0.25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.celestopol.chat-roll {
|
.celestopol.chat-roll {
|
||||||
border: 1px solid var(--cel-border, #7a5c20);
|
border: 1px solid var(--cel-border, #7a5c20);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
@@ -506,11 +590,11 @@
|
|||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
font-size: 0.92em;
|
font-size: 1.1em;
|
||||||
}
|
}
|
||||||
.skill-info {
|
.skill-info {
|
||||||
color: var(--cel-cream, #f0e8d4);
|
color: var(--cel-cream, #f0e8d4);
|
||||||
font-size: 0.77em;
|
font-size: 0.8em;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
.stat-lbl { color: var(--cel-orange-light, #ddb84a); }
|
.stat-lbl { color: var(--cel-orange-light, #ddb84a); }
|
||||||
.sep { margin: 0 2px; opacity: 0.5; }
|
.sep { margin: 0 2px; opacity: 0.5; }
|
||||||
@@ -540,10 +624,10 @@
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: white;
|
background: white;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 1.05em;
|
font-size: 1.2em;
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
box-shadow: 1px 1px 2px rgba(0,0,0,0.12);
|
box-shadow: 1px 1px 2px rgba(0,0,0,0.12);
|
||||||
color: #222;
|
color: var(--cel-text, #2f2413);
|
||||||
|
|
||||||
&.max {
|
&.max {
|
||||||
background: var(--cel-green, #0c4c0c);
|
background: var(--cel-green, #0c4c0c);
|
||||||
@@ -569,15 +653,15 @@
|
|||||||
padding: 5px 10px 4px;
|
padding: 5px 10px 4px;
|
||||||
background: var(--cel-cream, #f0e8d4);
|
background: var(--cel-cream, #f0e8d4);
|
||||||
border-top: 1px solid rgba(122,92,32,0.2);
|
border-top: 1px solid rgba(122,92,32,0.2);
|
||||||
font-size: 0.83em;
|
font-size: 0.9em;
|
||||||
color: #555;
|
color: #555;
|
||||||
|
|
||||||
.fl-label { color: #999; font-size: 0.88em; text-transform: uppercase; letter-spacing: 0.04em; margin-right: 2px; }
|
.fl-label { color: rgba(0,0,0,0.4); font-size: 0.9em; text-transform: uppercase; letter-spacing: 0.04em; margin-right: 2px; }
|
||||||
.fl-ndice { color: var(--cel-green, #0c4c0c); font-weight: bold; }
|
.fl-ndice { color: var(--cel-green, #0c4c0c); font-weight: bold; }
|
||||||
.fl-sum { font-weight: bold; color: #333; }
|
.fl-sum { font-weight: bold; color: var(--cel-text, #2f2413); }
|
||||||
.fl-total {
|
.fl-total {
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
font-size: 1.5em;
|
font-size: 1.7em;
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
@@ -588,8 +672,8 @@
|
|||||||
.fl-asp { color: var(--cel-orange, #e07b00); font-weight: bold; }
|
.fl-asp { color: var(--cel-orange, #e07b00); font-weight: bold; }
|
||||||
.fl-faction { color: var(--cel-green, #0c4c0c); font-weight: bold; }
|
.fl-faction { color: var(--cel-green, #0c4c0c); font-weight: bold; }
|
||||||
.fl-sep { font-weight: bold; color: var(--cel-border, #7a5c20); margin: 0 2px; }
|
.fl-sep { font-weight: bold; color: var(--cel-border, #7a5c20); margin: 0 2px; }
|
||||||
.fl-eq { color: #aaa; }
|
.fl-eq { color: rgba(0,0,0,0.35); }
|
||||||
.fl-op { color: #aaa; }
|
.fl-op { color: rgba(0,0,0,0.35); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Seuil et marge ──
|
// ── Seuil et marge ──
|
||||||
@@ -600,22 +684,22 @@
|
|||||||
padding: 5px 12px 6px;
|
padding: 5px 12px 6px;
|
||||||
background: var(--cel-cream, #f0e8d4);
|
background: var(--cel-cream, #f0e8d4);
|
||||||
border-top: 1px solid rgba(122,92,32,0.2);
|
border-top: 1px solid rgba(122,92,32,0.2);
|
||||||
font-size: 0.82em;
|
font-size: 0.9em;
|
||||||
|
|
||||||
.vs-wrap {
|
.vs-wrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
}
|
}
|
||||||
.vs-label { color: #aaa; text-transform: uppercase; font-size: 0.8em; }
|
.vs-label { color: rgba(0,0,0,0.35); text-transform: uppercase; font-size: 0.8em; }
|
||||||
.diff-label{ font-style: italic; color: var(--cel-green, #0c4c0c); }
|
.diff-label{ font-style: italic; color: var(--cel-green, #0c4c0c); }
|
||||||
.diff-val { color: #888; }
|
.diff-val { color: rgba(0,0,0,0.45); }
|
||||||
|
|
||||||
.margin-badge {
|
.margin-badge {
|
||||||
padding: 2px 10px;
|
padding: 2px 10px;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 1.05em;
|
font-size: 1.2em;
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
|
|
||||||
@@ -635,7 +719,7 @@
|
|||||||
// ── Destin utilisé ──
|
// ── Destin utilisé ──
|
||||||
.used-info {
|
.used-info {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 0.77em;
|
font-size: 0.8em;
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
padding: 3px 8px;
|
padding: 3px 8px;
|
||||||
background: rgba(196,154,26,0.1);
|
background: rgba(196,154,26,0.1);
|
||||||
@@ -673,7 +757,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.damage-header {
|
.damage-header {
|
||||||
font-size: 0.72em;
|
font-size: 0.8em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.08em;
|
letter-spacing: 0.08em;
|
||||||
color: var(--cel-border, #7a5c20);
|
color: var(--cel-border, #7a5c20);
|
||||||
@@ -690,13 +774,13 @@
|
|||||||
|
|
||||||
.damage-value {
|
.damage-value {
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
font-size: 1.9em;
|
font-size: 2.2em;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
}
|
}
|
||||||
|
|
||||||
.damage-unit {
|
.damage-unit {
|
||||||
font-size: 0.82em;
|
font-size: 0.9em;
|
||||||
color: var(--cel-green, #0c4c0c);
|
color: var(--cel-green, #0c4c0c);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
@@ -704,7 +788,7 @@
|
|||||||
.damage-breakdown,
|
.damage-breakdown,
|
||||||
.damage-note {
|
.damage-note {
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
font-size: 0.76em;
|
font-size: 0.8em;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
color: #5c4630;
|
color: #5c4630;
|
||||||
}
|
}
|
||||||
@@ -730,7 +814,7 @@
|
|||||||
background: var(--cel-green, #0c4c0c);
|
background: var(--cel-green, #0c4c0c);
|
||||||
color: var(--cel-orange-light, #ddb84a);
|
color: var(--cel-orange-light, #ddb84a);
|
||||||
padding: 4px 10px;
|
padding: 4px 10px;
|
||||||
font-size: 0.78em;
|
font-size: 0.8em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
@@ -745,7 +829,7 @@
|
|||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
padding: 6px 8px;
|
padding: 6px 8px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size: 0.76em;
|
font-size: 0.8em;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
|
|
||||||
&.is-applied {
|
&.is-applied {
|
||||||
@@ -787,7 +871,7 @@
|
|||||||
font-family: var(--cel-font-body, serif);
|
font-family: var(--cel-font-body, serif);
|
||||||
|
|
||||||
.moon-die-face {
|
.moon-die-face {
|
||||||
font-size: 1.8em;
|
font-size: 1.9em;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
@@ -800,7 +884,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.moon-die-phase {
|
.moon-die-phase {
|
||||||
font-size: 0.72em;
|
font-size: 0.8em;
|
||||||
opacity: 0.75;
|
opacity: 0.75;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
@@ -808,14 +892,14 @@
|
|||||||
|
|
||||||
.moon-die-type {
|
.moon-die-type {
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
font-size: 1em;
|
font-size: 1.1em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
letter-spacing: 0.06em;
|
letter-spacing: 0.06em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.moon-die-desc {
|
.moon-die-desc {
|
||||||
font-size: 0.72em;
|
font-size: 0.8em;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
opacity: 0.85;
|
opacity: 0.85;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
@@ -852,13 +936,13 @@
|
|||||||
border-top: 2px solid rgba(0,0,0,0.1);
|
border-top: 2px solid rgba(0,0,0,0.1);
|
||||||
|
|
||||||
.result-icon {
|
.result-icon {
|
||||||
font-size: 0.85em;
|
font-size: 0.9em;
|
||||||
opacity: 0.85;
|
opacity: 0.85;
|
||||||
letter-spacing: 0.15em;
|
letter-spacing: 0.15em;
|
||||||
}
|
}
|
||||||
.result-label { font-size: 1.2em; line-height: 1.2; }
|
.result-label { font-size: 1.3em; line-height: 1.2; }
|
||||||
.result-desc {
|
.result-desc {
|
||||||
font-size: 0.65em;
|
font-size: 0.7em;
|
||||||
letter-spacing: 0.08em;
|
letter-spacing: 0.08em;
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
@@ -919,22 +1003,22 @@
|
|||||||
|
|
||||||
.welcome-mark {
|
.welcome-mark {
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
font-size: 1.05em;
|
font-size: 1.1em;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.welcome-title {
|
.welcome-title {
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
font-size: 0.98em;
|
font-size: 1.1em;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.welcome-body {
|
.welcome-body {
|
||||||
padding: 9px 11px 10px;
|
padding: 9px 11px 10px;
|
||||||
color: #3f3623;
|
color: var(--cel-text, #2f2413);
|
||||||
font-size: 0.84em;
|
font-size: 0.9em;
|
||||||
line-height: 1.45;
|
line-height: 1.45;
|
||||||
|
|
||||||
p {
|
p {
|
||||||
@@ -954,7 +1038,7 @@
|
|||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
color: var(--cel-border, #7a5c20);
|
color: var(--cel-border, #7a5c20);
|
||||||
font-size: 0.72em;
|
font-size: 0.8em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
@@ -997,27 +1081,27 @@
|
|||||||
|
|
||||||
.portrait-message-mark {
|
.portrait-message-mark {
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
font-size: 1.05em;
|
font-size: 1.1em;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.portrait-message-title {
|
.portrait-message-title {
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
font-size: 0.98em;
|
font-size: 1.1em;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.portrait-message-body {
|
.portrait-message-body {
|
||||||
padding: 9px 11px 10px;
|
padding: 9px 11px 10px;
|
||||||
color: #3f3623;
|
color: var(--cel-text, #2f2413);
|
||||||
}
|
}
|
||||||
|
|
||||||
.portrait-message-name {
|
.portrait-message-name {
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
color: var(--cel-green, #0c4c0c);
|
color: var(--cel-green, #0c4c0c);
|
||||||
font-size: 0.84em;
|
font-size: 0.9em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
@@ -1100,7 +1184,7 @@
|
|||||||
&:hover {
|
&:hover {
|
||||||
border-color: var(--cel-orange, #e07b00);
|
border-color: var(--cel-orange, #e07b00);
|
||||||
background: linear-gradient(180deg, rgba(224,123,0,0.18), rgba(224,123,0,0.06));
|
background: linear-gradient(180deg, rgba(224,123,0,0.18), rgba(224,123,0,0.06));
|
||||||
color: #7a3e00;
|
color: var(--cel-border, #7a5c20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1124,7 +1208,7 @@
|
|||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
font-size: 0.88em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.faction-aspect-points {
|
.faction-aspect-points {
|
||||||
@@ -1146,7 +1230,7 @@
|
|||||||
border: 1px solid rgba(122,92,32,0.18);
|
border: 1px solid rgba(122,92,32,0.18);
|
||||||
|
|
||||||
strong {
|
strong {
|
||||||
font-size: 0.72em;
|
font-size: 0.8em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
color: var(--cel-border, #7a5c20);
|
color: var(--cel-border, #7a5c20);
|
||||||
@@ -1155,14 +1239,14 @@
|
|||||||
em {
|
em {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
font-size: 1.05em;
|
font-size: 1.2em;
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.faction-aspect-source-line {
|
.faction-aspect-source-line {
|
||||||
font-size: 0.78em;
|
font-size: 0.8em;
|
||||||
color: var(--cel-border, #7a5c20);
|
color: var(--cel-border, #7a5c20);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1171,7 +1255,7 @@
|
|||||||
border-left: 3px solid #b84a2e;
|
border-left: 3px solid #b84a2e;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: rgba(184, 74, 46, 0.08);
|
background: rgba(184, 74, 46, 0.08);
|
||||||
color: #8b3e2b;
|
color: var(--cel-accent, #6b1e28);
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1190,7 +1274,7 @@
|
|||||||
background: rgba(12, 76, 12, 0.08);
|
background: rgba(12, 76, 12, 0.08);
|
||||||
border: 1px solid rgba(12, 76, 12, 0.18);
|
border: 1px solid rgba(12, 76, 12, 0.18);
|
||||||
color: var(--cel-green, #0c4c0c);
|
color: var(--cel-green, #0c4c0c);
|
||||||
font-size: 0.72em;
|
font-size: 0.8em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1204,7 +1288,7 @@
|
|||||||
label {
|
label {
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
font-size: 0.68em;
|
font-size: 0.7em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.04em;
|
letter-spacing: 0.04em;
|
||||||
color: var(--cel-border, #7a5c20);
|
color: var(--cel-border, #7a5c20);
|
||||||
@@ -1219,13 +1303,13 @@
|
|||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
background: rgba(255,255,255,0.9);
|
background: rgba(255,255,255,0.9);
|
||||||
font-size: 0.78em;
|
font-size: 0.8em;
|
||||||
color: #2f2413;
|
color: var(--cel-text, #2f2413);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
select option {
|
select option {
|
||||||
color: #2f2413;
|
color: var(--cel-text, #2f2413);
|
||||||
background: #fffaf0;
|
background: #fffaf0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1251,7 +1335,7 @@
|
|||||||
background: rgba(224,123,0,0.12);
|
background: rgba(224,123,0,0.12);
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
font-size: 0.72em;
|
font-size: 0.8em;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
cursor: help;
|
cursor: help;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
@@ -1273,7 +1357,11 @@
|
|||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
font-size: 0.82em;
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
color: var(--cel-border, #7a5c20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1281,7 +1369,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
font-size: 0.74em;
|
font-size: 0.8em;
|
||||||
|
color: var(--cel-border, #7a5c20);
|
||||||
}
|
}
|
||||||
|
|
||||||
.faction-aspect-active-list {
|
.faction-aspect-active-list {
|
||||||
@@ -1298,8 +1387,8 @@
|
|||||||
padding: 3px 6px;
|
padding: 3px 6px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: rgba(255,255,255,0.7);
|
background: rgba(255,255,255,0.7);
|
||||||
color: #2f2413;
|
color: var(--cel-text, #2f2413);
|
||||||
font-size: 0.76em;
|
font-size: 0.8em;
|
||||||
|
|
||||||
&.is-relevant {
|
&.is-relevant {
|
||||||
border-left: 3px solid var(--cel-green, #0c4c0c);
|
border-left: 3px solid var(--cel-green, #0c4c0c);
|
||||||
@@ -1307,20 +1396,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.faction-aspect-active-name {
|
.faction-aspect-active-name {
|
||||||
color: #2f2413;
|
color: var(--cel-text, #2f2413);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.faction-aspect-active-value {
|
.faction-aspect-active-value {
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
font-size: 0.92em;
|
font-size: 1.1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.faction-aspect-empty {
|
.faction-aspect-empty {
|
||||||
color: #666;
|
color: rgba(0,0,0,0.5);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-size: 0.74em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.faction-aspect-remove-block {
|
.faction-aspect-remove-block {
|
||||||
@@ -1349,7 +1438,7 @@
|
|||||||
border-left: 3px solid #c0392b;
|
border-left: 3px solid #c0392b;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
color: #f0c0c0;
|
color: #f0c0c0;
|
||||||
font-size: 0.85em;
|
font-size: 0.9em;
|
||||||
.wound-icon { font-size: 1em; }
|
.wound-icon { font-size: 1em; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1358,7 +1447,7 @@
|
|||||||
.celestopol.chat-roll {
|
.celestopol.chat-roll {
|
||||||
.roll-result-banner.tie {
|
.roll-result-banner.tie {
|
||||||
background: #3a2e1a;
|
background: #3a2e1a;
|
||||||
color: #d4b870;
|
color: var(--cel-orange-light, #ddb84a);
|
||||||
border-top: 2px solid #7a6230;
|
border-top: 2px solid #7a6230;
|
||||||
border-bottom: 2px solid #7a6230;
|
border-bottom: 2px solid #7a6230;
|
||||||
text-shadow: 0 1px 2px rgba(0,0,0,0.6);
|
text-shadow: 0 1px 2px rgba(0,0,0,0.6);
|
||||||
@@ -1369,12 +1458,12 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.3em;
|
gap: 0.3em;
|
||||||
margin-bottom: 1px;
|
margin-bottom: 1px;
|
||||||
font-size: 0.85em;
|
font-size: 0.9em;
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
.weapon-icon-small { font-size: 0.9em; }
|
.weapon-icon-small { font-size: 0.9em; }
|
||||||
.weapon-degats-small {
|
.weapon-degats-small {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #f0c060;
|
color: var(--cel-border, #7a5c20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1391,15 +1480,15 @@
|
|||||||
.weapon-icon { font-size: 1em; }
|
.weapon-icon { font-size: 1em; }
|
||||||
.weapon-degats {
|
.weapon-degats {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #f0c060;
|
color: var(--cel-border, #7a5c20);
|
||||||
font-size: 0.85em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-corps-pnj {
|
.form-corps-pnj {
|
||||||
.corps-pnj-input {
|
.corps-pnj-input {
|
||||||
width: 70px;
|
width: 70px;
|
||||||
font-size: 1.1em;
|
font-size: 1.3em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
@@ -1420,7 +1509,7 @@
|
|||||||
label {
|
label {
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 0.85em;
|
font-size: 0.9em;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
@@ -1435,7 +1524,7 @@
|
|||||||
border: 1px solid rgba(196, 154, 26, 0.5);
|
border: 1px solid rgba(196, 154, 26, 0.5);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
font-size: 0.85em;
|
font-size: 0.9em;
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1451,7 +1540,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
font-size: 0.88em;
|
font-size: 0.9em;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
|
||||||
i { opacity: 0.8; }
|
i { opacity: 0.8; }
|
||||||
@@ -1465,14 +1554,14 @@
|
|||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
|
|
||||||
label {
|
label {
|
||||||
color: #e08060;
|
color: var(--cel-accent, #6b1e28);
|
||||||
font-size: 0.85em;
|
font-size: 0.9em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
|
|
||||||
i { color: #e08060; }
|
i { color: var(--cel-accent, #6b1e28); }
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
@@ -1482,13 +1571,13 @@
|
|||||||
border: 1px solid rgba(200, 100, 60, 0.4);
|
border: 1px solid rgba(200, 100, 60, 0.4);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
font-size: 0.85em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-threshold-fixed {
|
.form-threshold-fixed {
|
||||||
.threshold-value {
|
.threshold-value {
|
||||||
font-size: 1.2em;
|
font-size: 1.4em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
@@ -1514,7 +1603,7 @@
|
|||||||
input[type="checkbox"] { flex-shrink: 0; }
|
input[type="checkbox"] { flex-shrink: 0; }
|
||||||
|
|
||||||
.opposition-icon {
|
.opposition-icon {
|
||||||
font-size: 1.2em;
|
font-size: 1.3em;
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1525,14 +1614,14 @@
|
|||||||
|
|
||||||
.opposition-main {
|
.opposition-main {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 0.9em;
|
font-size: 1.1em;
|
||||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
}
|
}
|
||||||
|
|
||||||
.opposition-sub {
|
.opposition-sub {
|
||||||
font-size: 0.75em;
|
font-size: 0.8em;
|
||||||
opacity: 0.7;
|
color: #8a7060;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1567,7 +1656,7 @@
|
|||||||
|
|
||||||
.moon-standalone-title {
|
.moon-standalone-title {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 1em;
|
font-size: 1.1em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--cel-green-dark, #0c4c0c);
|
color: var(--cel-green-dark, #0c4c0c);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
@@ -1575,7 +1664,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.moon-standalone-actor {
|
.moon-standalone-actor {
|
||||||
font-size: 0.85em;
|
font-size: 0.9em;
|
||||||
color: var(--cel-text, #333);
|
color: var(--cel-text, #333);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
@@ -1604,7 +1693,7 @@
|
|||||||
|
|
||||||
.moon-standalone-phase {
|
.moon-standalone-phase {
|
||||||
font-family: var(--cel-font-title);
|
font-family: var(--cel-font-title);
|
||||||
font-size: 0.95em;
|
font-size: 1.1em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--cel-text, #333);
|
color: var(--cel-text, #333);
|
||||||
}
|
}
|
||||||
@@ -1617,8 +1706,8 @@
|
|||||||
|
|
||||||
&.moon-triomphe { border-left-color: var(--cel-green, #0c4c0c); }
|
&.moon-triomphe { border-left-color: var(--cel-green, #0c4c0c); }
|
||||||
&.moon-brio { border-left-color: var(--cel-border, #7a5c20); }
|
&.moon-brio { border-left-color: var(--cel-border, #7a5c20); }
|
||||||
&.moon-contrecoup { border-left-color: #c07800; }
|
&.moon-contrecoup { border-left-color: var(--cel-orange, #c49a1a); }
|
||||||
&.moon-catastrophe{ border-left-color: #8b1e2e; }
|
&.moon-catastrophe{ border-left-color: var(--cel-accent, #6b1e28); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.moon-interpret-row {
|
.moon-interpret-row {
|
||||||
@@ -1627,15 +1716,15 @@
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
|
||||||
.moon-interpret-label {
|
.moon-interpret-label {
|
||||||
font-size: 0.72em;
|
font-size: 0.8em;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.07em;
|
letter-spacing: 0.07em;
|
||||||
color: #888;
|
color: rgba(0,0,0,0.45);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.moon-fortune {
|
.moon-fortune {
|
||||||
font-size: 0.85em;
|
font-size: 0.9em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 1px 8px;
|
padding: 1px 8px;
|
||||||
@@ -1648,7 +1737,7 @@
|
|||||||
|
|
||||||
&.mauvaise-fortune {
|
&.mauvaise-fortune {
|
||||||
background: rgba(139, 30, 46, 0.1);
|
background: rgba(139, 30, 46, 0.1);
|
||||||
color: #8b1e2e;
|
color: var(--cel-accent, #6b1e28);
|
||||||
border: 1px solid rgba(139,30,46,0.3);
|
border: 1px solid rgba(139,30,46,0.3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1659,6 +1748,7 @@
|
|||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
padding: 6px 8px;
|
padding: 6px 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Message d'initiative ──────────────────────────────────────────────────────
|
// ── Message d'initiative ──────────────────────────────────────────────────────
|
||||||
@@ -1698,11 +1788,11 @@
|
|||||||
color: var(--cel-orange, #e07b00);
|
color: var(--cel-orange, #e07b00);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
font-size: 0.92em;
|
font-size: 1.1em;
|
||||||
}
|
}
|
||||||
.skill-info {
|
.skill-info {
|
||||||
color: var(--cel-cream, #f0e8d4);
|
color: var(--cel-cream, #f0e8d4);
|
||||||
font-size: 0.77em;
|
font-size: 0.8em;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1730,19 +1820,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.initiative-icon {
|
.initiative-icon {
|
||||||
font-size: 1.1em;
|
font-size: 1.2em;
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.initiative-score {
|
.initiative-score {
|
||||||
font-size: 2.4em;
|
font-size: 2.5em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.initiative-detail {
|
.initiative-detail {
|
||||||
font-size: 0.65em;
|
font-size: 0.7em;
|
||||||
opacity: 0.75;
|
opacity: 0.75;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-family: var(--cel-font-body, serif);
|
font-family: var(--cel-font-body, serif);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
{{#each (lookup ../skills statId) as |skill skillId|}}
|
{{#each (lookup ../skills statId) as |skill skillId|}}
|
||||||
{{#if @root.isEditMode}}
|
{{#if @root.isEditMode}}
|
||||||
<div class="skill-row edit-mode" data-stat-id="{{statId}}" data-skill-id="{{skillId}}">
|
<div class="skill-row edit-mode" data-stat-id="{{statId}}" data-skill-id="{{skillId}}">
|
||||||
<span class="skill-name">{{localize skill.label}}</span>
|
<span class="skill-name" data-tooltip="{{localize skill.tooltip}}">{{localize skill.label}}</span>
|
||||||
<div class="skill-checkboxes-container">
|
<div class="skill-checkboxes-container">
|
||||||
<div class="skill-checkboxes">
|
<div class="skill-checkboxes">
|
||||||
{{#each (range 8) as |lvl|}}
|
{{#each (range 8) as |lvl|}}
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
{{else}}
|
{{else}}
|
||||||
<div class="skill-row rollable" data-stat-id="{{statId}}" data-skill-id="{{skillId}}"
|
<div class="skill-row rollable" data-stat-id="{{statId}}" data-skill-id="{{skillId}}"
|
||||||
title="{{localize 'CELESTOPOL.Roll.clickToRoll'}}">
|
title="{{localize 'CELESTOPOL.Roll.clickToRoll'}}">
|
||||||
<span class="skill-name">{{localize skill.label}}</span>
|
<span class="skill-name" data-tooltip="{{localize skill.tooltip}}">{{localize skill.label}}</span>
|
||||||
<div class="skill-checkboxes-container">
|
<div class="skill-checkboxes-container">
|
||||||
<div class="skill-checkboxes">
|
<div class="skill-checkboxes">
|
||||||
{{#each (range 8) as |lvl|}}
|
{{#each (range 8) as |lvl|}}
|
||||||
@@ -49,8 +49,29 @@
|
|||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{!-- Items : Anomalie (unique), Aspects, Attributs --}}
|
{{!-- Items : Aspects, Anomalie --}}
|
||||||
<div class="items-section">
|
<div class="items-section">
|
||||||
|
{{!-- Aspects --}}
|
||||||
|
<div class="items-group">
|
||||||
|
<div class="items-header">
|
||||||
|
<span>{{localize "CELESTOPOL.Item.aspects"}}</span>
|
||||||
|
{{#if isEditMode}}
|
||||||
|
<a data-action="createAspect" title="{{localize 'CELESTOPOL.Item.newAspect'}}"><i class="fas fa-plus"></i></a>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{#each aspects as |item|}}
|
||||||
|
<div class="item-row" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true">
|
||||||
|
<img src="{{item.img}}" class="item-icon" alt="{{item.name}}">
|
||||||
|
<span class="item-name">{{item.name}}</span>
|
||||||
|
<span class="item-value">{{item.system.valeur}}</span>
|
||||||
|
<div class="item-controls">
|
||||||
|
<a data-action="edit" data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
|
||||||
|
{{#if ../isEditMode}}<a data-action="delete" data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
|
||||||
{{!-- Anomalie : bloc proéminent unique --}}
|
{{!-- Anomalie : bloc proéminent unique --}}
|
||||||
<div class="anomaly-block">
|
<div class="anomaly-block">
|
||||||
<div class="anomaly-block-header">
|
<div class="anomaly-block-header">
|
||||||
@@ -124,26 +145,5 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{!-- Aspects --}}
|
|
||||||
<div class="items-group">
|
|
||||||
<div class="items-header">
|
|
||||||
<span>{{localize "CELESTOPOL.Item.aspects"}}</span>
|
|
||||||
{{#if isEditMode}}
|
|
||||||
<a data-action="createAspect" title="{{localize 'CELESTOPOL.Item.newAspect'}}"><i class="fas fa-plus"></i></a>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
{{#each aspects as |item|}}
|
|
||||||
<div class="item-row" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true">
|
|
||||||
<img src="{{item.img}}" class="item-icon" alt="{{item.name}}">
|
|
||||||
<span class="item-name">{{item.name}}</span>
|
|
||||||
<span class="item-value">{{item.system.valeur}}</span>
|
|
||||||
<div class="item-controls">
|
|
||||||
<a data-action="edit" data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
|
|
||||||
{{#if ../isEditMode}}<a data-action="delete" data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>{{/if}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
<a class="faction-aspect-manage" data-action="manageFactionAspects">
|
<a class="faction-aspect-manage" data-action="manageFactionAspects">
|
||||||
<i class="fa-solid fa-sliders"></i> {{localize "CELESTOPOL.FactionAspect.manage"}}
|
<i class="fa-solid fa-sliders"></i> {{localize "CELESTOPOL.FactionAspect.manage"}}
|
||||||
</a>
|
</a>
|
||||||
|
<a class="faction-aspect-reset" data-action="resetFactionAspects">
|
||||||
|
<i class="fa-solid fa-rotate-left"></i> {{localize "CELESTOPOL.FactionAspect.resetButton"}}
|
||||||
|
</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
</span>
|
</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<span class="skill-info">
|
<span class="skill-info">
|
||||||
{{#if statLabel}}<span class="stat-lbl">{{statLabel}}</span><span class="sep"> › </span>{{/if}}
|
{{#if statLabel}}<span class="stat-lbl">{{localize statLabel}}</span><span class="sep"> › </span>{{/if}}
|
||||||
<span class="skill-lbl">{{skillLabel}}</span>
|
<span class="skill-lbl">{{localize skillLabel}}</span>
|
||||||
</span>
|
</span>
|
||||||
{{#if woundLabel}}<span class="wound-info">⚠ {{woundLabel}}</span>{{/if}}
|
{{#if woundLabel}}<span class="wound-info">⚠ {{woundLabel}}</span>{{/if}}
|
||||||
</div>
|
</div>
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{!-- Résultat du Dé de la Lune (narratif) --}}
|
{{!-- Résultat du Dé de la Lune (narratif + choix de contrepartie) --}}
|
||||||
{{#if hasMoonDie}}
|
{{#if hasMoonDie}}
|
||||||
<div class="moon-die-result {{moonResultClass}}">
|
<div class="moon-die-result {{moonResultClass}}">
|
||||||
<span class="moon-die-face">{{moonFaceSymbol}}</span>
|
<span class="moon-die-face">{{moonFaceSymbol}}</span>
|
||||||
@@ -132,6 +132,27 @@
|
|||||||
<span class="moon-die-desc">{{moonResultDesc}}</span>
|
<span class="moon-die-desc">{{moonResultDesc}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{#if moonActorIsCharacter}}
|
||||||
|
<div class="moon-effect-actions" data-moon-actor-id="{{moonActorId}}" data-moon-actor-uuid="{{moonActorUuid}}">
|
||||||
|
<span class="moon-effect-label">{{localize "CELESTOPOL.Moon.applyChoose"}}</span>
|
||||||
|
<div class="moon-effect-buttons">
|
||||||
|
{{#if (eq moonResultTypeId "triomphe")}}
|
||||||
|
<button type="button" class="moon-effect-btn" data-action="apply-moon-effect" data-effect="regain-anomaly">{{localize "CELESTOPOL.Moon.effectRegainAnomaly"}}</button>
|
||||||
|
<button type="button" class="moon-effect-btn" data-action="apply-moon-effect" data-effect="lose-spleen">{{localize "CELESTOPOL.Moon.effectLoseSpleen"}}</button>
|
||||||
|
{{else if (eq moonResultTypeId "brio")}}
|
||||||
|
<button type="button" class="moon-effect-btn" data-action="apply-moon-effect" data-effect="gain-destin">{{localize "CELESTOPOL.Moon.effectGainDestin"}}</button>
|
||||||
|
<span class="moon-effect-narrative">{{localize "CELESTOPOL.Moon.effectNarrativeOnly"}}</span>
|
||||||
|
{{else if (eq moonResultTypeId "contrecoup")}}
|
||||||
|
<button type="button" class="moon-effect-btn moon-effect-negative" data-action="apply-moon-effect" data-effect="lose-destin">{{localize "CELESTOPOL.Moon.effectLoseDestin"}}</button>
|
||||||
|
<span class="moon-effect-narrative">{{localize "CELESTOPOL.Moon.effectNarrativeOnly"}}</span>
|
||||||
|
{{else if (eq moonResultTypeId "catastrophe")}}
|
||||||
|
<button type="button" class="moon-effect-btn moon-effect-negative" data-action="apply-moon-effect" data-effect="lose-anomaly">{{localize "CELESTOPOL.Moon.effectLoseAnomaly"}}</button>
|
||||||
|
<button type="button" class="moon-effect-btn moon-effect-negative" data-action="apply-moon-effect" data-effect="gain-spleen">{{localize "CELESTOPOL.Moon.effectGainSpleen"}}</button>
|
||||||
|
<span class="moon-effect-narrative">{{localize "CELESTOPOL.Moon.effectNarrativeOnly"}}</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{!-- Bandeau résultat --}}
|
{{!-- Bandeau résultat --}}
|
||||||
@@ -162,7 +183,7 @@
|
|||||||
<span class="result-label">{{localize "CELESTOPOL.Roll.failure"}}</span>
|
<span class="result-label">{{localize "CELESTOPOL.Roll.failure"}}</span>
|
||||||
{{#if isCombat}}
|
{{#if isCombat}}
|
||||||
{{#if (eq weaponType "melee")}}
|
{{#if (eq weaponType "melee")}}
|
||||||
<span class="result-desc">{{localize "CELESTOPOL.Combat.failureHit"}}</span>
|
{{#unless isNpcAttack}}<span class="result-desc">{{localize "CELESTOPOL.Combat.failureHit"}}</span>{{/unless}}
|
||||||
{{else if isRangedDefense}}
|
{{else if isRangedDefense}}
|
||||||
<span class="result-desc">{{localize "CELESTOPOL.Combat.rangedDefenseFailure"}}</span>
|
<span class="result-desc">{{localize "CELESTOPOL.Combat.rangedDefenseFailure"}}</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|||||||
@@ -36,4 +36,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{!-- Choix de la contrepartie --}}
|
||||||
|
{{#if moonActorIsCharacter}}
|
||||||
|
<div class="moon-effect-actions" data-moon-actor-id="{{moonActorId}}" data-moon-actor-uuid="{{moonActorUuid}}">
|
||||||
|
<span class="moon-effect-label">{{localize "CELESTOPOL.Moon.applyChoose"}}</span>
|
||||||
|
<div class="moon-effect-buttons">
|
||||||
|
{{#if (eq moonResultTypeId "triomphe")}}
|
||||||
|
<button type="button" class="moon-effect-btn" data-action="apply-moon-effect" data-effect="regain-anomaly">{{localize "CELESTOPOL.Moon.effectRegainAnomaly"}}</button>
|
||||||
|
<button type="button" class="moon-effect-btn" data-action="apply-moon-effect" data-effect="lose-spleen">{{localize "CELESTOPOL.Moon.effectLoseSpleen"}}</button>
|
||||||
|
{{else if (eq moonResultTypeId "brio")}}
|
||||||
|
<button type="button" class="moon-effect-btn" data-action="apply-moon-effect" data-effect="gain-destin">{{localize "CELESTOPOL.Moon.effectGainDestin"}}</button>
|
||||||
|
<span class="moon-effect-narrative">{{localize "CELESTOPOL.Moon.effectNarrativeOnly"}}</span>
|
||||||
|
{{else if (eq moonResultTypeId "contrecoup")}}
|
||||||
|
<button type="button" class="moon-effect-btn moon-effect-negative" data-action="apply-moon-effect" data-effect="lose-destin">{{localize "CELESTOPOL.Moon.effectLoseDestin"}}</button>
|
||||||
|
<span class="moon-effect-narrative">{{localize "CELESTOPOL.Moon.effectNarrativeOnly"}}</span>
|
||||||
|
{{else if (eq moonResultTypeId "catastrophe")}}
|
||||||
|
<button type="button" class="moon-effect-btn moon-effect-negative" data-action="apply-moon-effect" data-effect="lose-anomaly">{{localize "CELESTOPOL.Moon.effectLoseAnomaly"}}</button>
|
||||||
|
<button type="button" class="moon-effect-btn moon-effect-negative" data-action="apply-moon-effect" data-effect="gain-spleen">{{localize "CELESTOPOL.Moon.effectGainSpleen"}}</button>
|
||||||
|
<span class="moon-effect-narrative">{{localize "CELESTOPOL.Moon.effectNarrativeOnly"}}</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{#each weapons as |item|}}
|
{{#each weapons as |item|}}
|
||||||
<div class="item-row weapon" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true">
|
<div class="item-row weapon {{#if item.system.equipped}}is-equipped{{/if}}" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true">
|
||||||
<img src="{{item.img}}" class="item-icon">
|
<img src="{{item.img}}" class="item-icon">
|
||||||
<span class="item-name">{{item.name}}</span>
|
<span class="item-name">{{item.name}}</span>
|
||||||
<span class="item-tag type">{{#if (eq item.system.type "melee")}}{{localize "CELESTOPOL.Weapon.typeMelee"}}{{else}}{{localize "CELESTOPOL.Weapon.typeDistance"}}{{/if}}</span>
|
<span class="item-tag type">{{#if (eq item.system.type "melee")}}{{localize "CELESTOPOL.Weapon.typeMelee"}}{{else}}{{localize "CELESTOPOL.Weapon.typeDistance"}}{{/if}}</span>
|
||||||
@@ -18,6 +18,11 @@
|
|||||||
{{#unless ../isEditMode}}
|
{{#unless ../isEditMode}}
|
||||||
<a data-action="attack" data-item-id="{{item.id}}" title="{{localize 'CELESTOPOL.Combat.attack'}}"><i class="fas fa-khanda"></i></a>
|
<a data-action="attack" data-item-id="{{item.id}}" title="{{localize 'CELESTOPOL.Combat.attack'}}"><i class="fas fa-khanda"></i></a>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
|
<a data-action="toggleWeapon" data-item-uuid="{{item.uuid}}"
|
||||||
|
title="{{#if item.system.equipped}}{{localize 'CELESTOPOL.Weapon.unequip'}}{{else}}{{localize 'CELESTOPOL.Weapon.equip'}}{{/if}}"
|
||||||
|
class="equip-toggle {{#if item.system.equipped}}equipped{{/if}}">
|
||||||
|
<i class="fas fa-khanda"></i>
|
||||||
|
</a>
|
||||||
<a data-action="edit" data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
|
<a data-action="edit" data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
|
||||||
{{#if ../isEditMode}}<a data-action="delete" data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>{{/if}}
|
{{#if ../isEditMode}}<a data-action="delete" data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
<div class="roll-form-rows">
|
<div class="roll-form-rows">
|
||||||
|
|
||||||
{{!-- Difficulté : Corps PNJ en combat, fixe 11 en test normal --}}
|
{{!-- Difficulté : Corps PNJ en combat, configurable via setting en test normal --}}
|
||||||
{{#if isCombat}}
|
{{#if isCombat}}
|
||||||
|
|
||||||
{{!-- Sélecteur de cible PNJ (si des tokens NPCs sont disponibles) --}}
|
{{!-- Sélecteur de cible PNJ (si des tokens NPCs sont disponibles) --}}
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
{{else}}
|
{{else}}
|
||||||
<div class="form-row-line form-threshold-fixed">
|
<div class="form-row-line form-threshold-fixed">
|
||||||
<label>{{localize "CELESTOPOL.Roll.threshold"}}</label>
|
<label>{{localize "CELESTOPOL.Roll.threshold"}}</label>
|
||||||
<span class="threshold-value" id="threshold-display">11</span>
|
<span class="threshold-value" id="threshold-display">{{getSetting "defaultRollThreshold"}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{!-- Test en opposition : le résultat sera masqué, MJ décide --}}
|
{{!-- Test en opposition : le résultat sera masqué, MJ décide --}}
|
||||||
@@ -220,9 +220,9 @@
|
|||||||
<div class="form-row-line form-visibility">
|
<div class="form-row-line form-visibility">
|
||||||
<label for="visibility">{{localize "CELESTOPOL.Roll.visibility"}}</label>
|
<label for="visibility">{{localize "CELESTOPOL.Roll.visibility"}}</label>
|
||||||
<select id="visibility" name="visibility">
|
<select id="visibility" name="visibility">
|
||||||
<option value="publicroll">{{localize "CELESTOPOL.Roll.visibilityPublic"}}</option>
|
<option value="public">{{localize "CELESTOPOL.Roll.visibilityPublic"}}</option>
|
||||||
<option value="gmroll">{{localize "CELESTOPOL.Roll.visibilityGM"}}</option>
|
<option value="gm">{{localize "CELESTOPOL.Roll.visibilityGM"}}</option>
|
||||||
<option value="selfroll">{{localize "CELESTOPOL.Roll.visibilitySelf"}}</option>
|
<option value="self">{{localize "CELESTOPOL.Roll.visibilitySelf"}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user