- Schéma xp dans CelestopolCharacter : actuel (éditable), log[] ({montant, raison, date}), depense (calculé dans prepareDerivedData)
- Bouton 'Dépenser XP' → DialogV2 (montant + raison) : décrémente actuel, logge l'entrée
- Suppression d'entrée de log avec remboursement des points (mode édition)
- Section XP en haut de l'onglet Biographie : compteurs, tableau du log, référentiel des coûts
- i18n : section CELESTOPOL.XP.* complète
- CSS : .xp-section avec compteurs, tableau de log et accordéon de référence
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
147 lines
6.6 KiB
Handlebars
147 lines
6.6 KiB
Handlebars
<div class="tab competences {{tab.cssClass}}" data-group="sheet" data-tab="competences">
|
||
{{!-- Grille des 4 stats × 4 domaines --}}
|
||
<div class="stats-grid">
|
||
{{#each stats as |stat statId|}}
|
||
<div class="stat-block">
|
||
<div class="stat-header">
|
||
<span class="stat-name">{{localize stat.label}}</span>
|
||
<div class="stat-res {{#unless ../isEditMode}}rollable{{/unless}}" data-stat-id="{{statId}}"
|
||
title="{{localize 'CELESTOPOL.Roll.resistanceClickToRoll'}}">
|
||
<label>{{localize "CELESTOPOL.Stat.res"}}</label>
|
||
<span class="stat-res-value">{{lookup (lookup ../system.stats statId) 'res'}}</span>
|
||
</div>
|
||
</div>
|
||
<div class="skills-list">
|
||
{{#each (lookup ../skills statId) as |skill skillId|}}
|
||
{{#if @root.isEditMode}}
|
||
<div class="skill-row edit-mode" data-stat-id="{{statId}}" data-skill-id="{{skillId}}">
|
||
<span class="skill-name">{{localize skill.label}}</span>
|
||
<div class="skill-checkboxes-container">
|
||
<div class="skill-checkboxes">
|
||
{{#each (range 8) as |lvl|}}
|
||
<span class="skill-level-dot {{#if (lte lvl (lookup @root.system.stats statId skillId 'value'))}}filled{{/if}}"
|
||
data-action="skillLevel" data-stat-id="{{statId}}" data-skill-id="{{skillId}}" data-index="{{lvl}}"></span>
|
||
{{/each}}
|
||
</div>
|
||
</div>
|
||
<span class="skill-value">{{lookup @root.system.stats statId skillId 'value'}}</span>
|
||
</div>
|
||
{{else}}
|
||
<div class="skill-row rollable" data-stat-id="{{statId}}" data-skill-id="{{skillId}}"
|
||
title="{{localize 'CELESTOPOL.Roll.clickToRoll'}}">
|
||
<span class="skill-name">{{localize skill.label}}</span>
|
||
<div class="skill-checkboxes-container">
|
||
<div class="skill-checkboxes">
|
||
{{#each (range 8) as |lvl|}}
|
||
<span class="skill-level-dot {{#if (lte lvl (lookup @root.system.stats statId skillId 'value'))}}filled{{/if}}"></span>
|
||
{{/each}}
|
||
</div>
|
||
</div>
|
||
<span class="skill-value">{{lookup @root.system.stats statId skillId 'value'}}</span>
|
||
</div>
|
||
{{/if}}
|
||
{{/each}}
|
||
</div>
|
||
</div>
|
||
{{/each}}
|
||
</div>
|
||
|
||
{{!-- Items : Anomalie (unique), Aspects, Attributs --}}
|
||
<div class="items-section">
|
||
{{!-- Anomalie : bloc proéminent unique --}}
|
||
<div class="anomaly-block">
|
||
<div class="anomaly-block-header">
|
||
<span class="anomaly-block-title">{{localize "CELESTOPOL.Item.anomaly"}}</span>
|
||
{{#if isEditMode}}
|
||
{{#unless anomaly}}
|
||
<a data-action="createAnomaly" title="{{localize 'CELESTOPOL.Item.newAnomaly'}}"><i class="fas fa-plus"></i></a>
|
||
{{/unless}}
|
||
{{/if}}
|
||
</div>
|
||
{{#if anomaly}}
|
||
<div class="anomaly-content" data-item-id="{{anomaly.id}}" data-item-uuid="{{anomaly.uuid}}" data-drag="true">
|
||
<div class="anomaly-info-row">
|
||
<img src="{{anomaly.img}}" class="anomaly-icon" alt="{{anomaly.name}}">
|
||
<div class="anomaly-details">
|
||
<div class="anomaly-name">{{anomaly.name}}</div>
|
||
<div class="anomaly-subtype">{{localize (lookup (lookup anomalyTypes anomaly.system.subtype) 'label')}}</div>
|
||
</div>
|
||
<div class="anomaly-controls">
|
||
<a data-action="edit" data-item-uuid="{{anomaly.uuid}}"><i class="fas fa-edit"></i></a>
|
||
{{#if isEditMode}}<a data-action="delete" data-item-uuid="{{anomaly.uuid}}"><i class="fas fa-trash"></i></a>{{/if}}
|
||
</div>
|
||
</div>
|
||
<div class="anomaly-level-row">
|
||
<span class="anomaly-level-label">{{localize "CELESTOPOL.Anomaly.level"}} :</span>
|
||
<div class="anomaly-level-dots">
|
||
{{#each (array 1 2 3 4) as |n|}}
|
||
<span class="anomaly-level-dot {{#if (lte n ../anomaly.system.level)}}active{{else}}inactive{{/if}}"></span>
|
||
{{/each}}
|
||
</div>
|
||
</div>
|
||
<div class="anomaly-uses-row">
|
||
<span class="anomaly-uses-label">{{localize "CELESTOPOL.Anomaly.usesRemaining"}} :</span>
|
||
<div class="anomaly-uses-dots">
|
||
{{#each (array 1 2 3 4) as |n|}}
|
||
{{#if (lte n ../anomaly.system.usesRemaining)}}
|
||
<span class="anomaly-dot available"></span>
|
||
{{else}}
|
||
{{#if (lte n ../anomaly.system.level)}}
|
||
<span class="anomaly-dot spent"></span>
|
||
{{else}}
|
||
<span class="anomaly-dot inactive"></span>
|
||
{{/if}}
|
||
{{/if}}
|
||
{{/each}}
|
||
</div>
|
||
<button class="anomaly-use-btn" data-action="useAnomaly" data-item-id="{{anomaly.id}}"
|
||
title="{{localize 'CELESTOPOL.Anomaly.use'}}"
|
||
{{#unless (gt anomaly.system.usesRemaining 0)}}disabled{{/unless}}>
|
||
<i class="fas fa-bolt"></i> {{localize "CELESTOPOL.Anomaly.use"}}
|
||
</button>
|
||
<a class="anomaly-reset-btn" data-action="resetAnomalyUses" data-item-id="{{anomaly.id}}"
|
||
title="{{localize 'CELESTOPOL.Anomaly.resetUses'}}">
|
||
<i class="fas fa-rotate-right"></i>
|
||
</a>
|
||
</div>
|
||
{{#if anomalySkillLabels.length}}
|
||
<div class="anomaly-skills">
|
||
<span class="anomaly-skills-label">{{localize "CELESTOPOL.Anomaly.applicableSkills"}} :</span>
|
||
{{#each anomalySkillLabels as |label|}}
|
||
<span class="anomaly-skill-chip">{{label}}</span>
|
||
{{/each}}
|
||
</div>
|
||
{{/if}}
|
||
</div>
|
||
{{else}}
|
||
<div class="anomaly-empty">
|
||
<i class="fas fa-ghost"></i>
|
||
<span>{{localize "CELESTOPOL.Anomaly.noAnomaly"}}</span>
|
||
</div>
|
||
{{/if}}
|
||
</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>
|