feat: Loksyu & TinJi standalone AppV2 apps with chat buttons and dice automation

- CDELoksyuApp: standalone HandlebarsApplicationMixin(ApplicationV2) app
  - 5-element Wu Xing grid with yin/yang inputs per element
  - Per-element reset buttons + global reset-all
  - Auto-refresh via updateActor hook

- CDETinjiApp: standalone AppV2 for the collective Tin Ji dice pool
  - Large neon counter with +/- buttons and direct input
  - Spend button sends a chat message with remaining count

- singletons.js: shared utilities
  - getSingletonActor: find or auto-create singleton actor
  - updateLoksyuFromRoll: compute lokAspect from Wu Xing cycle, update yin/yang
  - updateTinjiFromRoll: add tinji face count to value

- rolling.js: auto-update both singletons after every dice roll
  (weapon path + main roll path)

- system.js: renderChatLog hook injects Loksyu/TinJi footer buttons
  in the chat sidebar

- loksyu.js / tinji.js: actor sheets redirect to standalone apps
  when opened via the sidebar

- CSS: .cde-loksyu-standalone, .cde-tinji-standalone, .cde-chat-app-buttons,
  .cde-tinji-spend-msg styles added

- i18n: new keys in fr-cde.json and en-cde.json for all new UI strings
  (LoksyuNotFound, TinjiNotFound, Reset, ResetAll, SpendTinji, etc.)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-03-30 09:51:39 +02:00
parent 6fda4b9246
commit 0689fae792
41 changed files with 1558 additions and 13 deletions

View File

@@ -0,0 +1,55 @@
{{!-- Loksyu standalone app --}}
<div class="cde-loksyu-app-body">
{{#unless hasActor}}
<p class="cde-empty-list"><i class="fas fa-exclamation-triangle"></i> {{ localize "CDE.LoksyuNotFound" }}</p>
{{/unless}}
{{#if hasActor}}
<div class="cde-loksyu-elements">
{{#each elements as |el|}}
<div class="cde-lok-card cde-lok-card--{{el.key}}">
<div class="cde-lok-header">
<img class="cde-lok-icon" src="{{el.img}}" alt="{{localize el.nameKey}}" width="32" height="32" />
<div class="cde-lok-titles">
<span class="cde-lok-name">{{ localize el.nameKey }}</span>
<span class="cde-lok-qual">{{ localize el.qualKey }}</span>
</div>
<a class="cde-lok-reset" data-action="resetElement" data-element="{{el.key}}" title="{{ localize 'CDE.Reset' }}">
<i class="fas fa-rotate-left"></i>
</a>
</div>
<div class="cde-lok-values">
<div class="cde-lok-polarity cde-lok-polarity--yang">
<span class="cde-lok-pol-label">○ {{ localize "CDE.Yang" }}</span>
<input class="cde-lok-input" type="number" min="0"
data-field="system.{{el.key}}.yang.value"
value="{{el.yang}}"
{{#unless ../canEdit}}disabled{{/unless}} />
</div>
<div class="cde-lok-polarity cde-lok-polarity--yin">
<span class="cde-lok-pol-label">● {{ localize "CDE.Yin" }}</span>
<input class="cde-lok-input" type="number" min="0"
data-field="system.{{el.key}}.yin.value"
value="{{el.yin}}"
{{#unless ../canEdit}}disabled{{/unless}} />
</div>
</div>
</div>
{{/each}}
</div>
<div class="cde-loksyu-visual-row">
<img class="cde-lok-visual" src="systems/fvtt-chroniques-de-l-etrange/images/loksyu_long.webp" alt="Loksyu" />
</div>
{{#if canEdit}}
<div class="cde-lok-footer">
<button class="cde-lok-reset-all" data-action="resetAll">
<i class="fas fa-rotate-left"></i> {{ localize "CDE.ResetAll" }}
</button>
</div>
{{/if}}
{{/if}}
</div>

View File

@@ -0,0 +1,41 @@
{{!-- Tin Ji standalone app --}}
<div class="cde-tinji-app-body">
{{#unless hasActor}}
<p class="cde-empty-list"><i class="fas fa-exclamation-triangle"></i> {{ localize "CDE.TinjiNotFound" }}</p>
{{/unless}}
{{#if hasActor}}
<div class="cde-tinji-display">
<div class="cde-tinji-chinese-large">天機</div>
<div class="cde-tinji-label">{{ localize "CDE.UpperCaseTinJi" }}</div>
<div class="cde-tinji-counter">
{{#if canEdit}}
<button class="cde-tinji-step" data-action="decrement" title="{{ localize 'CDE.Decrement' }}"></button>
{{/if}}
<input class="cde-tinji-direct" type="number" min="0" value="{{value}}"
{{#unless canEdit}}disabled{{/unless}} />
{{#if canEdit}}
<button class="cde-tinji-step" data-action="increment" title="{{ localize 'CDE.Increment' }}">+</button>
{{/if}}
</div>
<div class="cde-tinji-hint">{{ localize "CDE.AuspiciousDice" }}</div>
<div class="cde-tinji-actions">
<button class="cde-tinji-spend-btn" data-action="spend" {{#unless value}}disabled{{/unless}}>
<i class="fas fa-star"></i> {{ localize "CDE.SpendTinji" }}
</button>
{{#if canEdit}}
<button class="cde-tinji-reset-btn" data-action="reset">
<i class="fas fa-rotate-left"></i> {{ localize "CDE.Reset" }}
</button>
{{/if}}
</div>
</div>
<img class="cde-tinji-visual" src="systems/fvtt-chroniques-de-l-etrange/images/tinji.webp" alt="Tin Ji" />
{{/if}}
</div>