Compare commits
11 Commits
14.0.3
..
98c319767e
| Author | SHA1 | Date | |
|---|---|---|---|
| 98c319767e | |||
| 50038a13f9 | |||
| 4cb8e26333 | |||
| faf8c4ca92 | |||
| 20b41f2cd4 | |||
| 34b7e32d08 | |||
| 75f79c1c08 | |||
| 188717c925 | |||
| 066e3bbaf5 | |||
| 440755d8a1 | |||
| a9c70c004d |
@@ -0,0 +1,65 @@
|
|||||||
|
# Copilot Instructions — fvtt-chroniques-de-l-etrange
|
||||||
|
|
||||||
|
FoundryVTT v13 game system for *Les Chroniques de l'Étrange* (Antre-Monde Éditions). The codebase is entirely in **ES modules** (`"type": "module"`) bundled with esbuild. There are no tests.
|
||||||
|
|
||||||
|
## Build commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build # compile LESS → CSS and bundle src/system.js → dist/system.js
|
||||||
|
npm run build:css # LESS only
|
||||||
|
npm run build:js # esbuild bundle only
|
||||||
|
npm run build:watch # rebuild on file changes
|
||||||
|
npm run build:full # compile compendiums then build
|
||||||
|
|
||||||
|
npm run pack:compile # compile packs-src/ → packs/ (LevelDB)
|
||||||
|
npm run pack:extract # extract packs/ → packs-src/ (YAML source)
|
||||||
|
```
|
||||||
|
|
||||||
|
The built output goes to `dist/system.js` (sourced via the unbuilt `src/system.js` in `system.json` `esmodules`).
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
The entry point is `src/system.js`, which wires up all FoundryVTT hooks (`init`, `ready`, `renderChatLog`, etc.).
|
||||||
|
|
||||||
|
### Layer structure
|
||||||
|
|
||||||
|
| Layer | Path | Purpose |
|
||||||
|
|---|---|---|
|
||||||
|
| **Config** | `src/config/` | Constants, i18n pre-localization, runtime config, settings |
|
||||||
|
| **Data Models** | `src/data/` | `TypeDataModel` subclasses defining actor/item schemas |
|
||||||
|
| **Documents** | `src/documents/` | `CDEActor`, `CDEItem`, `CDEMessage` — thin document class overrides |
|
||||||
|
| **UI / Sheets** | `src/ui/sheets/` | ApplicationV2 sheets for actors and items |
|
||||||
|
| **UI / Apps** | `src/ui/apps/` | Standalone apps: `CDELoksyuApp`, `CDETinjiApp` (singletons) |
|
||||||
|
| **UI / Core** | `src/ui/` | Rolling engine, dice registration, Handlebars helpers, initiative |
|
||||||
|
|
||||||
|
### Key domain concepts
|
||||||
|
|
||||||
|
- **Wu Xing cycle**: Five aspects (metal, water, earth, fire, wood) drive all dice resolution. Each aspect maps to two d10 faces (see `ASPECT_FACES` in `constants.js`). `WU_XING_CYCLE` maps an active aspect to the five result categories: successes / auspicious / noxious / **loksyu** / **tinji**.
|
||||||
|
- **Loksyu / Tin Ji**: Persistent world-level counters stored in game settings (`loksyuData`, `tinjiData`). Managed via `CDELoksyuApp` / `CDETinjiApp` singleton apps; updated from roll results in `ui/apps/singletons.js`.
|
||||||
|
- **Three Treasures** (`threetreasures`): The character's Hei-Yang and Hei-Yin pools plus dice-level branches — used as the primary/secondary token attribute.
|
||||||
|
- **Magics**: Five schools (`internalcinnabar`, `alchemy`, `masteryoftheway`, `exorcism`, `geomancy`), each with five specialities. Fully defined in `MAGICS` constant.
|
||||||
|
|
||||||
|
### Data model pattern
|
||||||
|
|
||||||
|
All data models live in `src/data/` and extend `foundry.abstract.TypeDataModel`. Schema fields are defined with local factory helpers (`numberField`, `stringField`, `boolField`, `htmlField`) — prefer reusing these helpers when adding new fields.
|
||||||
|
|
||||||
|
### Sheet pattern
|
||||||
|
|
||||||
|
Actor and item sheets extend `HandlebarsApplicationMixin(ActorSheetV2)` via `CDEBaseActorSheet` (`src/ui/sheets/actors/base.js`). Key conventions:
|
||||||
|
- `static DEFAULT_OPTIONS` with `form: { submitOnChange: true }` — forms auto-save on every change.
|
||||||
|
- Tab state is manually restored in `_onRender` by iterating `this.tabGroups` and calling `this.changeTab()` (AppV2 does not persist tab state natively).
|
||||||
|
- Sheet actions (create/edit/delete item, editImage) are static private methods registered in `DEFAULT_OPTIONS.actions`.
|
||||||
|
- `_prepareContext()` exposes both `system` and `systemData` (same reference) for template compatibility.
|
||||||
|
|
||||||
|
### Compendium source
|
||||||
|
|
||||||
|
Human-editable compendium content lives in `packs-src/` as YAML. Use `npm run pack:compile` before building when pack content has changed, and `npm run pack:extract` after importing new data in Foundry.
|
||||||
|
|
||||||
|
## Key conventions
|
||||||
|
|
||||||
|
- All user-visible strings go through i18n with the `CDE.` prefix namespace. New labels must be added to `lang/fr-cde.json`.
|
||||||
|
- Handlebars templates live in `templates/` and are referenced by their full system path (`systems/fvtt-chroniques-de-l-etrange/templates/...`). Partials are pre-registered from `TEMPLATE_PARTIALS` in `constants.js`.
|
||||||
|
- The system ID constant (`SYSTEM_ID = "fvtt-chroniques-de-l-etrange"`) is used everywhere — never hardcode the string.
|
||||||
|
- CSS is authored in LESS (`css/cde-theme.less`) and compiled to `css/cde-theme.css`. Do not edit the `.css` file directly.
|
||||||
|
- Global macro access is via `game.cde` (exposes `CDELoksyuApp` and `CDETinjiApp`).
|
||||||
|
- The `dist/` directory is generated — do not commit it manually; it is rebuilt by `npm run build`.
|
||||||
@@ -8,6 +8,6 @@ Chroniques de l'ETrange is a game written by Romain d'Huissier and Cédric Lamei
|
|||||||
|
|
||||||
This system for FoundryVTT has been approved and authorized by Antre-Monde Edition.
|
This system for FoundryVTT has been approved and authorized by Antre-Monde Edition.
|
||||||
|
|
||||||
Ce système s'inspire d'un système précédent "chroniquesdeletrange" développé par David R.D. 'Mystery Man From Outerspace' Bercovici et Christophe 'Kristov / Qaw' Laudon. Le code a été intégralément réécrit pour être compatible avec la version 14 de FoundryVTT, et pour intégrer les nouvelles mécaniques de jeu introduites dans la nouvelle édition de Chroniques de l'Etrange, et n'a donc aucun lien de code avec le système précédent.
|
Ce système s'inspire d'un système précédent "chroniquesdeletrange" développé par David R.D. 'Mystery Man From Outerspace' Bercovici et Christophe 'Kristov / Qaw' Laudon. Le code a été intégralément réécrit pour être compatible avec la version 14 de FoundryVTT, et pour intégrer le maximum de mécaniques de jeu des Chroniques de l'Etrange, et n'a donc aucun lien de code avec le système précédent.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
+146
-2
@@ -396,17 +396,22 @@ section.npc .cde-neon-tabs .item.active {
|
|||||||
.cde-tab-body {
|
.cde-tab-body {
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
background: #0d1520;
|
background: #0d1520;
|
||||||
border: 1px solid #1a2436;
|
border: 1px solid #1a2436;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
border-radius: 0 0 8px 8px;
|
border-radius: 0 0 8px 8px;
|
||||||
overflow-y: auto;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.cde-tab-body .tab {
|
.cde-tab-body .tab {
|
||||||
display: none;
|
display: none;
|
||||||
|
flex: 1 1 0;
|
||||||
|
min-height: 0;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.cde-tab-body .tab.active {
|
.cde-tab-body .tab.active {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -447,12 +452,25 @@ section.npc .cde-neon-tabs .item.active {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
.cde-notes-editor .editor {
|
.cde-notes-editor .editor {
|
||||||
flex: 1 1 0;
|
flex: 1 1 auto;
|
||||||
min-height: 200px;
|
min-height: 200px;
|
||||||
|
height: 100%;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 1px solid #1a2436;
|
border: 1px solid #1a2436;
|
||||||
background: #101622;
|
background: #101622;
|
||||||
}
|
}
|
||||||
|
.cde-notes-editor .editor .tox {
|
||||||
|
height: 100% !important;
|
||||||
|
min-height: 100% !important;
|
||||||
|
}
|
||||||
|
.cde-notes-editor .editor .tox-editor-container {
|
||||||
|
height: 100% !important;
|
||||||
|
min-height: 100% !important;
|
||||||
|
}
|
||||||
|
.cde-notes-editor .editor iframe {
|
||||||
|
height: 100% !important;
|
||||||
|
min-height: 100% !important;
|
||||||
|
}
|
||||||
.cde-technique-card {
|
.cde-technique-card {
|
||||||
border-left: 3px solid #ff3d5a;
|
border-left: 3px solid #ff3d5a;
|
||||||
background: rgba(16, 22, 34, 0.8);
|
background: rgba(16, 22, 34, 0.8);
|
||||||
@@ -2161,6 +2179,25 @@ section.npc .cde-neon-tabs .item.active {
|
|||||||
.cde-magic-toggle:hover i {
|
.cde-magic-toggle:hover i {
|
||||||
color: #e2e8f4;
|
color: #e2e8f4;
|
||||||
}
|
}
|
||||||
|
.cde-magic-order-btn {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #7d94b8;
|
||||||
|
border-radius: 3px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
transition: color 0.12s, background 0.12s;
|
||||||
|
}
|
||||||
|
.cde-magic-order-btn i {
|
||||||
|
font-size: 9px;
|
||||||
|
}
|
||||||
|
.cde-magic-order-btn:hover {
|
||||||
|
color: #e2e8f4;
|
||||||
|
background: rgba(38, 56, 83, 0.25);
|
||||||
|
}
|
||||||
.cde-magic-specialities {
|
.cde-magic-specialities {
|
||||||
border-top: 1px solid #1a2436;
|
border-top: 1px solid #1a2436;
|
||||||
padding: 4px 0;
|
padding: 4px 0;
|
||||||
@@ -3172,7 +3209,9 @@ ol.item-list li.item h4.item-name {
|
|||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
color: #e2e8f4;
|
color: #e2e8f4;
|
||||||
|
font-family: "Signika", sans-serif;
|
||||||
}
|
}
|
||||||
ol.item-list li.item .cde-item-stat {
|
ol.item-list li.item .cde-item-stat {
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
@@ -3505,6 +3544,12 @@ ol.item-list li.item .item-controls a.item-control:hover {
|
|||||||
color: var(--rr-accent, #e2e8f4);
|
color: var(--rr-accent, #e2e8f4);
|
||||||
text-shadow: 0 0 12px var(--rr-accent, transparent);
|
text-shadow: 0 0 12px var(--rr-accent, transparent);
|
||||||
}
|
}
|
||||||
|
.cde-roll-result .cde-rr-hero .cde-rr-spell-power .cde-rr-spell-power-formula {
|
||||||
|
font-size: 10px;
|
||||||
|
color: #7d94b8;
|
||||||
|
margin: 2px 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
.cde-roll-result .cde-rr-hero .cde-rr-spell-power .cde-rr-spell-power-label {
|
.cde-roll-result .cde-rr-hero .cde-rr-spell-power .cde-rr-spell-power-label {
|
||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@@ -4400,6 +4445,105 @@ ol.item-list li.item .item-controls a.item-control:hover {
|
|||||||
color: #7d94b8;
|
color: #7d94b8;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
/* Duplicate row highlight */
|
||||||
|
.cde-migration-row-duplicate {
|
||||||
|
background: rgba(212, 175, 55, 0.15);
|
||||||
|
}
|
||||||
|
.cde-migration-duplicate-icon {
|
||||||
|
color: #d4af37;
|
||||||
|
margin-right: 4px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
/* Confirmation bar */
|
||||||
|
.cde-migration-confirm-bar {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid rgba(212, 175, 55, 0.7);
|
||||||
|
border-radius: 6px;
|
||||||
|
background: rgba(212, 175, 55, 0.1);
|
||||||
|
}
|
||||||
|
.cde-migration-confirm-msg {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #e2e8f4;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
.cde-migration-confirm-msg i {
|
||||||
|
color: #d4af37;
|
||||||
|
}
|
||||||
|
.cde-migration-confirm-duplicates {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 11px;
|
||||||
|
color: #e07070;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
.cde-migration-confirm-duplicates i {
|
||||||
|
color: #e07070;
|
||||||
|
}
|
||||||
|
.cde-migration-confirm-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
.cde-migration-confirm-btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 9px 24px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: #4a9eff;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: filter 0.15s;
|
||||||
|
}
|
||||||
|
.cde-migration-confirm-btn:hover {
|
||||||
|
filter: brightness(1.15);
|
||||||
|
}
|
||||||
|
.cde-migration-cancel-btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 9px 24px;
|
||||||
|
border: 1px solid #1a2436;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: none;
|
||||||
|
color: #7d94b8;
|
||||||
|
font-size: 13px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color 0.15s, border-color 0.15s;
|
||||||
|
}
|
||||||
|
.cde-migration-cancel-btn:hover {
|
||||||
|
color: #e04444;
|
||||||
|
border-color: #e04444;
|
||||||
|
}
|
||||||
|
/* Progress section */
|
||||||
|
.cde-migration-progress {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #e2e8f4;
|
||||||
|
}
|
||||||
|
.cde-migration-progress i {
|
||||||
|
color: #4a9eff;
|
||||||
|
}
|
||||||
|
.cde-migration-progress-count {
|
||||||
|
font-weight: 700;
|
||||||
|
color: #4a9eff;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
}
|
||||||
.cde-welcome-message {
|
.cde-welcome-message {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
+153
-3
@@ -381,17 +381,22 @@ section.npc .cde-neon-tabs .item.active { color: @cde-supernatural; borde
|
|||||||
.cde-tab-body {
|
.cde-tab-body {
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
padding: @cde-gap;
|
padding: @cde-gap;
|
||||||
background: @cde-surface2;
|
background: @cde-surface2;
|
||||||
border: 1px solid @cde-border;
|
border: 1px solid @cde-border;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
border-radius: 0 0 @cde-radius @cde-radius;
|
border-radius: 0 0 @cde-radius @cde-radius;
|
||||||
overflow-y: auto;
|
overflow: hidden;
|
||||||
|
|
||||||
.tab {
|
.tab {
|
||||||
display: none;
|
display: none;
|
||||||
|
flex: 1 1 0;
|
||||||
|
min-height: 0;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: @cde-gap;
|
gap: @cde-gap;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab.active {
|
.tab.active {
|
||||||
@@ -445,11 +450,26 @@ section.npc .cde-neon-tabs .item.active { color: @cde-supernatural; borde
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.editor {
|
.editor {
|
||||||
flex: 1 1 0;
|
flex: 1 1 auto;
|
||||||
min-height: 200px;
|
min-height: 200px;
|
||||||
|
height: 100%;
|
||||||
border-radius: @cde-radius;
|
border-radius: @cde-radius;
|
||||||
border: 1px solid @cde-border;
|
border: 1px solid @cde-border;
|
||||||
background: @cde-surface;
|
background: @cde-surface;
|
||||||
|
|
||||||
|
// Force TinyMCE to fill the container
|
||||||
|
.tox {
|
||||||
|
height: 100% !important;
|
||||||
|
min-height: 100% !important;
|
||||||
|
}
|
||||||
|
.tox-editor-container {
|
||||||
|
height: 100% !important;
|
||||||
|
min-height: 100% !important;
|
||||||
|
}
|
||||||
|
iframe {
|
||||||
|
height: 100% !important;
|
||||||
|
min-height: 100% !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2233,6 +2253,23 @@ section.npc .cde-neon-tabs .item.active { color: @cde-supernatural; borde
|
|||||||
&:hover i { color: @cde-text; }
|
&:hover i { color: @cde-text; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cde-magic-order-btn {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
color: @cde-muted;
|
||||||
|
border-radius: 3px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
transition: color 0.12s, background 0.12s;
|
||||||
|
|
||||||
|
i { font-size: 9px; }
|
||||||
|
|
||||||
|
&:hover { color: @cde-text; background: fade(@cde-border-hi, 25%); }
|
||||||
|
}
|
||||||
|
|
||||||
// Specialities list
|
// Specialities list
|
||||||
.cde-magic-specialities {
|
.cde-magic-specialities {
|
||||||
border-top: 1px solid @cde-border;
|
border-top: 1px solid @cde-border;
|
||||||
@@ -3227,7 +3264,7 @@ ol.item-list {
|
|||||||
|
|
||||||
img { border: none; border-radius: 3px; flex-shrink: 0; }
|
img { border: none; border-radius: 3px; flex-shrink: 0; }
|
||||||
|
|
||||||
h4.item-name { flex: 1 1 0; margin: 0; font-size: 13px; color: @cde-text; }
|
h4.item-name { flex: 1 1 0; margin: 0; font-size: 13px; font-weight: 600; color: @cde-text; font-family: "Signika", sans-serif; }
|
||||||
|
|
||||||
.cde-item-stat {
|
.cde-item-stat {
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
@@ -3562,6 +3599,13 @@ ol.item-list {
|
|||||||
text-shadow: 0 0 12px var(--rr-accent, transparent);
|
text-shadow: 0 0 12px var(--rr-accent, transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cde-rr-spell-power-formula {
|
||||||
|
font-size: 10px;
|
||||||
|
color: @cde-muted;
|
||||||
|
margin: 2px 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.cde-rr-spell-power-label {
|
.cde-rr-spell-power-label {
|
||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@@ -4587,6 +4631,112 @@ ol.item-list {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Duplicate row highlight */
|
||||||
|
.cde-migration-row-duplicate {
|
||||||
|
background: fadeout(#d4af37, 85%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cde-migration-duplicate-icon {
|
||||||
|
color: #d4af37;
|
||||||
|
margin-right: 4px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Confirmation bar */
|
||||||
|
.cde-migration-confirm-bar {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid fadeout(#d4af37, 30%);
|
||||||
|
border-radius: 6px;
|
||||||
|
background: fadeout(#d4af37, 90%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cde-migration-confirm-msg {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 12px;
|
||||||
|
color: @cde-text;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
|
i { color: #d4af37; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.cde-migration-confirm-duplicates {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 11px;
|
||||||
|
color: #e07070;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
|
i { color: #e07070; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.cde-migration-confirm-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cde-migration-confirm-btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 9px 24px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: @cde-spell;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: filter 0.15s;
|
||||||
|
|
||||||
|
&:hover { filter: brightness(1.15); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.cde-migration-cancel-btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 9px 24px;
|
||||||
|
border: 1px solid @cde-border;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: none;
|
||||||
|
color: @cde-muted;
|
||||||
|
font-size: 13px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color 0.15s, border-color 0.15s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #e04444;
|
||||||
|
border-color: #e04444;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Progress section */
|
||||||
|
.cde-migration-progress {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: @cde-text;
|
||||||
|
|
||||||
|
i { color: @cde-spell; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.cde-migration-progress-count {
|
||||||
|
font-weight: 700;
|
||||||
|
color: @cde-spell;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// Welcome message
|
// Welcome message
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Vendored
+399
-82
@@ -311,6 +311,89 @@ function migrateSupernaturalItem(oldItem) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
function migrateWeaponItem(oldItem) {
|
||||||
|
const s = oldItem.system ?? {};
|
||||||
|
return {
|
||||||
|
name: oldItem.name,
|
||||||
|
type: "weapon",
|
||||||
|
img: oldItem.img || DEFAULT_ITEM_IMG,
|
||||||
|
system: {
|
||||||
|
reference: s.reference ?? "",
|
||||||
|
description: s.description ?? "",
|
||||||
|
hasSpeciality: Boolean(s.hasSpeciality),
|
||||||
|
weaponType: s.weaponType || "melee",
|
||||||
|
material: s.material ?? "",
|
||||||
|
damageAspect: elementKey(s.damageAspect ?? ""),
|
||||||
|
damageBase: Number(s.damageBase ?? 0),
|
||||||
|
range: s.range || "contact",
|
||||||
|
obtainLevel: Number(s.obtainLevel ?? 0),
|
||||||
|
obtainDifficulty: Number(s.obtainDifficulty ?? 0),
|
||||||
|
quantity: Number(s.quantity ?? 1),
|
||||||
|
notes: s.notes ?? ""
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function migrateArmorItem(oldItem) {
|
||||||
|
const s = oldItem.system ?? {};
|
||||||
|
return {
|
||||||
|
name: oldItem.name,
|
||||||
|
type: "armor",
|
||||||
|
img: oldItem.img || DEFAULT_ITEM_IMG,
|
||||||
|
system: {
|
||||||
|
reference: s.reference ?? "",
|
||||||
|
description: s.description ?? "",
|
||||||
|
protectionValue: Number(s.protectionValue ?? 0),
|
||||||
|
domain: s.domain ?? "",
|
||||||
|
obtainLevel: Number(s.obtainLevel ?? 0),
|
||||||
|
obtainDifficulty: Number(s.obtainDifficulty ?? 0),
|
||||||
|
quantity: Number(s.quantity ?? 1),
|
||||||
|
notes: s.notes ?? ""
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function migrateSanheiItem(oldItem) {
|
||||||
|
const s = oldItem.system ?? {};
|
||||||
|
const props = s.properties ?? {};
|
||||||
|
const propSchema = (p) => ({
|
||||||
|
name: p?.name ?? "",
|
||||||
|
heiCost: Number(p?.heiCost ?? 0),
|
||||||
|
heiType: heiKey(p?.heiType ?? ""),
|
||||||
|
description: p?.description ?? ""
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
name: oldItem.name,
|
||||||
|
type: "sanhei",
|
||||||
|
img: oldItem.img || DEFAULT_ITEM_IMG,
|
||||||
|
system: {
|
||||||
|
reference: s.reference ?? "",
|
||||||
|
description: s.description ?? "",
|
||||||
|
heiType: heiKey(s.heiType ?? ""),
|
||||||
|
properties: {
|
||||||
|
prop1: propSchema(props.prop1),
|
||||||
|
prop2: propSchema(props.prop2),
|
||||||
|
prop3: propSchema(props.prop3)
|
||||||
|
},
|
||||||
|
notes: s.notes ?? ""
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function migrateIngredientItem(oldItem) {
|
||||||
|
const s = oldItem.system ?? {};
|
||||||
|
return {
|
||||||
|
name: oldItem.name,
|
||||||
|
type: "ingredient",
|
||||||
|
img: oldItem.img || DEFAULT_ITEM_IMG,
|
||||||
|
system: {
|
||||||
|
reference: s.reference ?? "",
|
||||||
|
description: s.description ?? "",
|
||||||
|
school: s.school ?? "all",
|
||||||
|
obtainLevel: Number(s.obtainLevel ?? 0),
|
||||||
|
obtainDifficulty: Number(s.obtainDifficulty ?? 0),
|
||||||
|
quantity: Number(s.quantity ?? 1),
|
||||||
|
notes: s.notes ?? ""
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
function migrateItem(oldItem) {
|
function migrateItem(oldItem) {
|
||||||
switch (oldItem.type) {
|
switch (oldItem.type) {
|
||||||
case "item":
|
case "item":
|
||||||
@@ -321,6 +404,14 @@ function migrateItem(oldItem) {
|
|||||||
return migrateSpellItem(oldItem);
|
return migrateSpellItem(oldItem);
|
||||||
case "supernatural":
|
case "supernatural":
|
||||||
return migrateSupernaturalItem(oldItem);
|
return migrateSupernaturalItem(oldItem);
|
||||||
|
case "weapon":
|
||||||
|
return migrateWeaponItem(oldItem);
|
||||||
|
case "armor":
|
||||||
|
return migrateArmorItem(oldItem);
|
||||||
|
case "sanhei":
|
||||||
|
return migrateSanheiItem(oldItem);
|
||||||
|
case "ingredient":
|
||||||
|
return migrateIngredientItem(oldItem);
|
||||||
default:
|
default:
|
||||||
return migrateEquipmentItem({ ...oldItem, type: "item" });
|
return migrateEquipmentItem({ ...oldItem, type: "item" });
|
||||||
}
|
}
|
||||||
@@ -394,6 +485,7 @@ function migrateCharacter(old) {
|
|||||||
resources,
|
resources,
|
||||||
component,
|
component,
|
||||||
magics,
|
magics,
|
||||||
|
magicOrder: [],
|
||||||
threetreasures,
|
threetreasures,
|
||||||
experience: {
|
experience: {
|
||||||
value: Number(s.experience?.value ?? 0),
|
value: Number(s.experience?.value ?? 0),
|
||||||
@@ -471,10 +563,12 @@ var CDEMigrationApp = class _CDEMigrationApp extends foundry.applications.api.Ha
|
|||||||
icon: "fas fa-file-import",
|
icon: "fas fa-file-import",
|
||||||
resizable: false
|
resizable: false
|
||||||
},
|
},
|
||||||
position: { width: 560, height: "auto" },
|
position: { width: 600, height: "auto" },
|
||||||
actions: {
|
actions: {
|
||||||
clearFiles: _CDEMigrationApp.#clearFiles,
|
clearFiles: _CDEMigrationApp.#clearFiles,
|
||||||
doImport: _CDEMigrationApp.#doImport
|
doImport: _CDEMigrationApp.#doImport,
|
||||||
|
confirmImport: _CDEMigrationApp.#confirmImport,
|
||||||
|
cancelImport: _CDEMigrationApp.#cancelImport
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
@@ -484,13 +578,28 @@ var CDEMigrationApp = class _CDEMigrationApp extends foundry.applications.api.Ha
|
|||||||
#pending = [];
|
#pending = [];
|
||||||
/** @type {string[]} - error messages per file */
|
/** @type {string[]} - error messages per file */
|
||||||
#errors = [];
|
#errors = [];
|
||||||
|
/** @type {"idle"|"confirm"|"importing"} */
|
||||||
|
#importState = "idle";
|
||||||
|
/** @type {number} - actors created so far (during importing) */
|
||||||
|
#progress = 0;
|
||||||
async _prepareContext(options) {
|
async _prepareContext(options) {
|
||||||
|
const enrichDuplicate = (a) => ({
|
||||||
|
...a,
|
||||||
|
_duplicate: game.actors?.getName(a.name) !== null
|
||||||
|
});
|
||||||
|
const pending = this.#pending.map(enrichDuplicate);
|
||||||
|
const duplicateCount = pending.filter((a) => a._duplicate).length;
|
||||||
return {
|
return {
|
||||||
pending: this.#pending,
|
pending,
|
||||||
errors: this.#errors,
|
errors: this.#errors,
|
||||||
hasPending: this.#pending.length > 0,
|
hasPending: this.#pending.length > 0,
|
||||||
hasErrors: this.#errors.length > 0,
|
hasErrors: this.#errors.length > 0,
|
||||||
count: this.#pending.length
|
hasDuplicates: duplicateCount > 0,
|
||||||
|
duplicateCount,
|
||||||
|
count: this.#pending.length,
|
||||||
|
importState: this.#importState,
|
||||||
|
progress: this.#progress,
|
||||||
|
total: this.#pending.length
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/** After render, wire up the file input. */
|
/** After render, wire up the file input. */
|
||||||
@@ -528,37 +637,59 @@ var CDEMigrationApp = class _CDEMigrationApp extends foundry.applications.api.Ha
|
|||||||
const actors = parseLegacyJson(text);
|
const actors = parseLegacyJson(text);
|
||||||
for (const actor of actors) {
|
for (const actor of actors) {
|
||||||
actor._srcFile = file.name;
|
actor._srcFile = file.name;
|
||||||
if (!this.#pending.some((p) => p.name === actor.name)) {
|
if (this.#pending.some((p) => p.name === actor.name)) {
|
||||||
this.#pending.push(actor);
|
this.#errors.push(`\xAB ${actor.name} \xBB ignor\xE9 (nom d\xE9j\xE0 dans la liste d'attente, fichier \xAB ${file.name} \xBB)`);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
this.#pending.push(actor);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.#errors.push(game.i18n.format("CDE.MigrationErrorParse", { file: file.name, error: err.message }));
|
this.#errors.push(game.i18n.format("CDE.MigrationErrorParse", { file: file.name, error: err.message }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.#importState = "idle";
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
static async #clearFiles() {
|
static async #clearFiles() {
|
||||||
this.#pending = [];
|
this.#pending = [];
|
||||||
this.#errors = [];
|
this.#errors = [];
|
||||||
|
this.#importState = "idle";
|
||||||
|
this.#progress = 0;
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
/** First click: switch to confirmation state instead of importing immediately. */
|
||||||
static async #doImport() {
|
static async #doImport() {
|
||||||
if (!this.#pending.length) return;
|
if (!this.#pending.length) return;
|
||||||
|
this.#importState = "confirm";
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
/** Second click: actually perform the import. */
|
||||||
|
static async #confirmImport() {
|
||||||
|
if (!this.#pending.length) return;
|
||||||
|
this.#importState = "importing";
|
||||||
|
this.#progress = 0;
|
||||||
|
this.render();
|
||||||
|
const total = this.#pending.length;
|
||||||
const created = [];
|
const created = [];
|
||||||
const failed = [];
|
const failed = [];
|
||||||
for (const data of this.#pending) {
|
for (let i = 0; i < total; i++) {
|
||||||
|
const data = this.#pending[i];
|
||||||
try {
|
try {
|
||||||
const { _srcFile, ...actorData } = data;
|
const { _srcFile, ...actorData } = data;
|
||||||
const actor = await Actor.create(actorData);
|
const actor = await Actor.create(actorData);
|
||||||
created.push(actor.name);
|
created.push(actor.name);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
failed.push(`${data.name}: ${err.message}`);
|
failed.push(`${data.name}: ${err.message}`);
|
||||||
console.error(`CHRONIQUESDELETRANGE | Migration failed for "${data.name}":`, err);
|
console.error(`CHRONIQUESDELETRANGE | Import failed for "${data.name}":`, err);
|
||||||
}
|
}
|
||||||
|
this.#progress = i + 1;
|
||||||
|
const progEl = this.element?.querySelector(".cde-migration-progress-count");
|
||||||
|
if (progEl) progEl.textContent = `${this.#progress}/${total}`;
|
||||||
}
|
}
|
||||||
this.#pending = [];
|
this.#pending = [];
|
||||||
this.#errors = failed;
|
this.#errors = failed;
|
||||||
|
this.#importState = "idle";
|
||||||
|
this.#progress = 0;
|
||||||
this.render();
|
this.render();
|
||||||
if (created.length) {
|
if (created.length) {
|
||||||
ui.notifications.info(
|
ui.notifications.info(
|
||||||
@@ -571,6 +702,10 @@ var CDEMigrationApp = class _CDEMigrationApp extends foundry.applications.api.Ha
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static async #cancelImport() {
|
||||||
|
this.#importState = "idle";
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// src/config/settings.js
|
// src/config/settings.js
|
||||||
@@ -595,6 +730,20 @@ function registerSettings() {
|
|||||||
water: { yin: 0, yang: 0 }
|
water: { yin: 0, yang: 0 }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
game.settings.register(SYSTEM_ID, "loksyuConsumptionOrder", {
|
||||||
|
name: "CDE.Settings.LoksyuConsumptionOrder",
|
||||||
|
hint: "CDE.Settings.LoksyuConsumptionOrderHint",
|
||||||
|
scope: "world",
|
||||||
|
config: true,
|
||||||
|
type: String,
|
||||||
|
choices: {
|
||||||
|
"yang-first": "CDE.Settings.LoksyuOrderYangFirst",
|
||||||
|
"yin-first": "CDE.Settings.LoksyuOrderYinFirst",
|
||||||
|
"balanced": "CDE.Settings.LoksyuOrderBalanced"
|
||||||
|
},
|
||||||
|
default: "yang-first",
|
||||||
|
onChange: () => Hooks.callAll("cde:loksyuUpdated")
|
||||||
|
});
|
||||||
game.settings.register(SYSTEM_ID, "tinjiData", {
|
game.settings.register(SYSTEM_ID, "tinjiData", {
|
||||||
scope: "world",
|
scope: "world",
|
||||||
config: false,
|
config: false,
|
||||||
@@ -647,6 +796,7 @@ function preLocalizeConfig() {
|
|||||||
magic.aspectlabel = game.i18n.localize(magic.aspectlabel);
|
magic.aspectlabel = game.i18n.localize(magic.aspectlabel);
|
||||||
Object.values(magic.speciality).forEach((spec) => {
|
Object.values(magic.speciality).forEach((spec) => {
|
||||||
spec.label = game.i18n.localize(spec.label);
|
spec.label = game.i18n.localize(spec.label);
|
||||||
|
spec.labelelementkey = spec.labelelement;
|
||||||
spec.labelelement = game.i18n.localize(spec.labelelement);
|
spec.labelelement = game.i18n.localize(spec.labelelement);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -760,9 +910,8 @@ var CharacterDataModel = class extends foundry.abstract.TypeDataModel {
|
|||||||
typeofthrow: numberField(0),
|
typeofthrow: numberField(0),
|
||||||
aspectskill: numberField(0),
|
aspectskill: numberField(0),
|
||||||
bonusmalusskill: numberField(0),
|
bonusmalusskill: numberField(0),
|
||||||
aspectspeciality: numberField(0),
|
|
||||||
rolldifficulty: numberField(0),
|
rolldifficulty: numberField(0),
|
||||||
bonusmalusspeciality: numberField(0)
|
freepowerlevels: numberField(0)
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
aspect: new fields.SchemaField({
|
aspect: new fields.SchemaField({
|
||||||
@@ -801,6 +950,10 @@ var CharacterDataModel = class extends foundry.abstract.TypeDataModel {
|
|||||||
nine: componentField(),
|
nine: componentField(),
|
||||||
zero: componentField()
|
zero: componentField()
|
||||||
}),
|
}),
|
||||||
|
magicOrder: new fields.ArrayField(
|
||||||
|
new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||||||
|
{ required: true, initial: [] }
|
||||||
|
),
|
||||||
magics: new fields.SchemaField({
|
magics: new fields.SchemaField({
|
||||||
internalcinnabar: magicField(),
|
internalcinnabar: magicField(),
|
||||||
alchemy: magicField(),
|
alchemy: magicField(),
|
||||||
@@ -917,7 +1070,7 @@ var KungfuDataModel = class extends foundry.abstract.TypeDataModel {
|
|||||||
orientation: stringField("yin"),
|
orientation: stringField("yin"),
|
||||||
// yin | yang | yinyang
|
// yin | yang | yinyang
|
||||||
aspect: stringField("metal"),
|
aspect: stringField("metal"),
|
||||||
// metal | eau | terre | feu | bois
|
// metal | water | earth | fire | wood
|
||||||
skill: stringField("kungfu"),
|
skill: stringField("kungfu"),
|
||||||
// kungfu | rangedcombat
|
// kungfu | rangedcombat
|
||||||
speciality: stringField(""),
|
speciality: stringField(""),
|
||||||
@@ -943,7 +1096,7 @@ var SpellDataModel = class extends foundry.abstract.TypeDataModel {
|
|||||||
description: htmlField(""),
|
description: htmlField(""),
|
||||||
specialityname: stringField(""),
|
specialityname: stringField(""),
|
||||||
associatedelement: stringField("metal"),
|
associatedelement: stringField("metal"),
|
||||||
// metal | eau | terre | feu | bois
|
// metal | water | earth | fire | wood
|
||||||
hei: stringField(""),
|
hei: stringField(""),
|
||||||
realizationtimeritual: stringField(""),
|
realizationtimeritual: stringField(""),
|
||||||
realizationtimeaccelerated: stringField(""),
|
realizationtimeaccelerated: stringField(""),
|
||||||
@@ -985,18 +1138,20 @@ var WeaponDataModel = class extends foundry.abstract.TypeDataModel {
|
|||||||
const stringField = (initial = "") => new fields.StringField({ required: true, nullable: false, initial });
|
const stringField = (initial = "") => new fields.StringField({ required: true, nullable: false, initial });
|
||||||
const htmlField = (initial = "") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true });
|
const htmlField = (initial = "") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true });
|
||||||
const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts });
|
const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts });
|
||||||
|
const boolField = (initial = false) => new fields.BooleanField({ required: true, initial });
|
||||||
return {
|
return {
|
||||||
reference: stringField(""),
|
reference: stringField(""),
|
||||||
description: htmlField(""),
|
description: htmlField(""),
|
||||||
|
hasSpeciality: boolField(false),
|
||||||
weaponType: stringField("melee"),
|
weaponType: stringField("melee"),
|
||||||
material: stringField(""),
|
material: stringField(""),
|
||||||
damageAspect: stringField("metal"),
|
damageAspect: stringField("metal"),
|
||||||
damageBase: intField(1),
|
damageBase: intField(0),
|
||||||
range: stringField("contact"),
|
range: stringField("contact"),
|
||||||
// contact | courte | mediane | longue | extreme
|
// contact | courte | mediane | longue | extreme
|
||||||
obtainLevel: intField(0, { min: 0, max: 5 }),
|
obtainLevel: intField(0, { min: 0, max: 5 }),
|
||||||
obtainDifficulty: intField(0, { min: 0, max: 3 }),
|
obtainDifficulty: intField(0, { min: 0, max: 3 }),
|
||||||
quantity: intField(1),
|
quantity: intField(1, { min: 0 }),
|
||||||
notes: htmlField("")
|
notes: htmlField("")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1016,7 +1171,7 @@ var ArmorDataModel = class extends foundry.abstract.TypeDataModel {
|
|||||||
domain: stringField(""),
|
domain: stringField(""),
|
||||||
obtainLevel: intField(0, { min: 0, max: 5 }),
|
obtainLevel: intField(0, { min: 0, max: 5 }),
|
||||||
obtainDifficulty: intField(0, { min: 0, max: 3 }),
|
obtainDifficulty: intField(0, { min: 0, max: 3 }),
|
||||||
quantity: intField(1),
|
quantity: intField(1, { min: 0 }),
|
||||||
notes: htmlField("")
|
notes: htmlField("")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1062,7 +1217,7 @@ var IngredientDataModel = class extends foundry.abstract.TypeDataModel {
|
|||||||
school: stringField("all"),
|
school: stringField("all"),
|
||||||
obtainLevel: intField(0, { min: 0, max: 5 }),
|
obtainLevel: intField(0, { min: 0, max: 5 }),
|
||||||
obtainDifficulty: intField(0, { min: 0, max: 3 }),
|
obtainDifficulty: intField(0, { min: 0, max: 3 }),
|
||||||
quantity: intField(1),
|
quantity: intField(1, { min: 0 }),
|
||||||
notes: htmlField("")
|
notes: htmlField("")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1406,6 +1561,7 @@ async function rollInitiativeNPC(actor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// src/ui/apps/singletons.js
|
// src/ui/apps/singletons.js
|
||||||
|
var SOCKET_CHANNEL = `system.${SYSTEM_ID}`;
|
||||||
function getLoksyuData() {
|
function getLoksyuData() {
|
||||||
return game.settings.get(SYSTEM_ID, "loksyuData") ?? {
|
return game.settings.get(SYSTEM_ID, "loksyuData") ?? {
|
||||||
wood: { yin: 0, yang: 0 },
|
wood: { yin: 0, yang: 0 },
|
||||||
@@ -1415,16 +1571,75 @@ function getLoksyuData() {
|
|||||||
water: { yin: 0, yang: 0 }
|
water: { yin: 0, yang: 0 }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
async function setLoksyuData(data) {
|
async function writeLoksyuData(data) {
|
||||||
await game.settings.set(SYSTEM_ID, "loksyuData", data);
|
await game.settings.set(SYSTEM_ID, "loksyuData", data);
|
||||||
Hooks.callAll("cde:loksyuUpdated", data);
|
Hooks.callAll("cde:loksyuUpdated", data);
|
||||||
}
|
}
|
||||||
|
async function writeTinjiValue(value) {
|
||||||
|
value = Math.max(0, value);
|
||||||
|
await game.settings.set(SYSTEM_ID, "tinjiData", value);
|
||||||
|
Hooks.callAll("cde:tinjiUpdated", value);
|
||||||
|
}
|
||||||
|
async function setLoksyuData(data) {
|
||||||
|
if (game.user.isGM) return writeLoksyuData(data);
|
||||||
|
game.socket.emit(SOCKET_CHANNEL, { action: "setLoksyuData", data });
|
||||||
|
}
|
||||||
function getTinjiValue() {
|
function getTinjiValue() {
|
||||||
return game.settings.get(SYSTEM_ID, "tinjiData") ?? 0;
|
return game.settings.get(SYSTEM_ID, "tinjiData") ?? 0;
|
||||||
}
|
}
|
||||||
async function setTinjiValue(value) {
|
async function setTinjiValue(value) {
|
||||||
await game.settings.set(SYSTEM_ID, "tinjiData", Math.max(0, value));
|
if (game.user.isGM) return writeTinjiValue(value);
|
||||||
Hooks.callAll("cde:tinjiUpdated", Math.max(0, value));
|
game.socket.emit(SOCKET_CHANNEL, { action: "setTinjiValue", value });
|
||||||
|
}
|
||||||
|
function requestLoksyuDraw(aspect, order) {
|
||||||
|
game.socket.emit(SOCKET_CHANNEL, { action: "loksyuDraw", aspect, order });
|
||||||
|
}
|
||||||
|
function requestTinjiSpend() {
|
||||||
|
game.socket.emit(SOCKET_CHANNEL, { action: "tinjiSpend" });
|
||||||
|
}
|
||||||
|
function registerSingletonSocket() {
|
||||||
|
game.socket.on(SOCKET_CHANNEL, async (payload) => {
|
||||||
|
if (!game.user.isGM) return;
|
||||||
|
switch (payload.action) {
|
||||||
|
case "setLoksyuData":
|
||||||
|
await writeLoksyuData(payload.data);
|
||||||
|
break;
|
||||||
|
case "setTinjiValue":
|
||||||
|
await writeTinjiValue(payload.value);
|
||||||
|
break;
|
||||||
|
case "updateLoksyuFromRoll":
|
||||||
|
await updateLoksyuFromRoll(payload.activeAspect, payload.faces);
|
||||||
|
break;
|
||||||
|
case "updateTinjiFromRoll":
|
||||||
|
await updateTinjiFromRoll(payload.delta);
|
||||||
|
break;
|
||||||
|
case "loksyuDraw": {
|
||||||
|
const data = getLoksyuData();
|
||||||
|
const entry = data[payload.aspect] ?? { yin: 0, yang: 0 };
|
||||||
|
const order = payload.order ?? "yang-first";
|
||||||
|
if (order === "yin-first") {
|
||||||
|
if (entry.yin > 0) entry.yin--;
|
||||||
|
else entry.yang--;
|
||||||
|
} else if (order === "balanced") {
|
||||||
|
if (entry.yin > entry.yang) entry.yin--;
|
||||||
|
else if (entry.yang > entry.yin) entry.yang--;
|
||||||
|
else if (entry.yang > 0) entry.yang--;
|
||||||
|
else entry.yin--;
|
||||||
|
} else {
|
||||||
|
if (entry.yang > 0) entry.yang--;
|
||||||
|
else entry.yin--;
|
||||||
|
}
|
||||||
|
data[payload.aspect] = entry;
|
||||||
|
await writeLoksyuData(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "tinjiSpend": {
|
||||||
|
const cur = getTinjiValue();
|
||||||
|
if (cur > 0) await writeTinjiValue(cur - 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
async function updateLoksyuFromRoll(activeAspect, faces) {
|
async function updateLoksyuFromRoll(activeAspect, faces) {
|
||||||
const cycle = WU_XING_CYCLE[activeAspect];
|
const cycle = WU_XING_CYCLE[activeAspect];
|
||||||
@@ -1435,18 +1650,23 @@ async function updateLoksyuFromRoll(activeAspect, faces) {
|
|||||||
const yinCount = faces[yinFace] ?? 0;
|
const yinCount = faces[yinFace] ?? 0;
|
||||||
const yangCount = faces[yangFace] ?? 0;
|
const yangCount = faces[yangFace] ?? 0;
|
||||||
if (yinCount === 0 && yangCount === 0) return;
|
if (yinCount === 0 && yangCount === 0) return;
|
||||||
|
if (game.user.isGM) {
|
||||||
const data = getLoksyuData();
|
const data = getLoksyuData();
|
||||||
const current = data[lokAspect] ?? { yin: 0, yang: 0 };
|
const current = data[lokAspect] ?? { yin: 0, yang: 0 };
|
||||||
data[lokAspect] = {
|
data[lokAspect] = { yin: (current.yin ?? 0) + yinCount, yang: (current.yang ?? 0) + yangCount };
|
||||||
yin: (current.yin ?? 0) + yinCount,
|
await writeLoksyuData(data);
|
||||||
yang: (current.yang ?? 0) + yangCount
|
} else {
|
||||||
};
|
game.socket.emit(SOCKET_CHANNEL, { action: "updateLoksyuFromRoll", activeAspect, faces });
|
||||||
await setLoksyuData(data);
|
}
|
||||||
}
|
}
|
||||||
async function updateTinjiFromRoll(count) {
|
async function updateTinjiFromRoll(count) {
|
||||||
if (!count || count <= 0) return;
|
if (!count || count <= 0) return;
|
||||||
|
if (game.user.isGM) {
|
||||||
const current = getTinjiValue();
|
const current = getTinjiValue();
|
||||||
await setTinjiValue(current + count);
|
await writeTinjiValue(current + count);
|
||||||
|
} else {
|
||||||
|
game.socket.emit(SOCKET_CHANNEL, { action: "updateTinjiFromRoll", delta: count });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/ui/rolling.js
|
// src/ui/rolling.js
|
||||||
@@ -1552,20 +1772,16 @@ async function showMagicPrompt(params) {
|
|||||||
aspectskill: Number(params.aspectskill ?? 0),
|
aspectskill: Number(params.aspectskill ?? 0),
|
||||||
bonusmalusskill: params.bonusmalusskill ?? 0,
|
bonusmalusskill: params.bonusmalusskill ?? 0,
|
||||||
bonusauspiciousdice: params.bonusauspiciousdice ?? 0,
|
bonusauspiciousdice: params.bonusauspiciousdice ?? 0,
|
||||||
aspectspeciality: Number(params.aspectspeciality ?? 0),
|
|
||||||
rolldifficulty: params.rolldifficulty ?? 1,
|
rolldifficulty: params.rolldifficulty ?? 1,
|
||||||
bonusmalusspeciality: params.bonusmalusspeciality ?? 0,
|
freepowerlevels: params.freepowerlevels ?? 0,
|
||||||
heispend: params.heispend ?? 0,
|
|
||||||
typeofthrow: Number(params.typeofthrow ?? 0)
|
typeofthrow: Number(params.typeofthrow ?? 0)
|
||||||
},
|
},
|
||||||
fields: [
|
fields: [
|
||||||
"aspectskill",
|
"aspectskill",
|
||||||
"bonusmalusskill",
|
"bonusmalusskill",
|
||||||
"bonusauspiciousdice",
|
"bonusauspiciousdice",
|
||||||
"aspectspeciality",
|
|
||||||
"rolldifficulty",
|
"rolldifficulty",
|
||||||
"bonusmalusspeciality",
|
"freepowerlevels",
|
||||||
"heispend",
|
|
||||||
"typeofthrow"
|
"typeofthrow"
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
@@ -1580,7 +1796,7 @@ async function showWeaponPrompt(params) {
|
|||||||
weaponTypeLabel: params.weaponTypeLabel ?? "CDE.Weapon",
|
weaponTypeLabel: params.weaponTypeLabel ?? "CDE.Weapon",
|
||||||
weaponAspectIcon: params.weaponAspectIcon ?? "",
|
weaponAspectIcon: params.weaponAspectIcon ?? "",
|
||||||
weaponAspectLabel: params.weaponAspectLabel ?? "",
|
weaponAspectLabel: params.weaponAspectLabel ?? "",
|
||||||
damageBase: params.damageBase ?? 1,
|
damageBase: params.damageBase ?? 0,
|
||||||
weaponskill: params.weaponskill ?? "kungfu",
|
weaponskill: params.weaponskill ?? "kungfu",
|
||||||
aspect: Number(params.aspect ?? 0),
|
aspect: Number(params.aspect ?? 0),
|
||||||
effectiverange: params.effectiverange ?? "contact",
|
effectiverange: params.effectiverange ?? "contact",
|
||||||
@@ -1695,7 +1911,9 @@ async function rollForActor(actor, rollKey) {
|
|||||||
const kfSkill = kfItem.system.skill ?? "kungfu";
|
const kfSkill = kfItem.system.skill ?? "kungfu";
|
||||||
numberofdice = sys.skills?.[kfSkill]?.value ?? 0;
|
numberofdice = sys.skills?.[kfSkill]?.value ?? 0;
|
||||||
title = `${kfItem.name} [${game.i18n.localize(sys.skills?.[kfSkill]?.label ?? "CDE.KungFu")}]`;
|
title = `${kfItem.name} [${game.i18n.localize(sys.skills?.[kfSkill]?.label ?? "CDE.KungFu")}]`;
|
||||||
kfDefaultAspect = ASPECT_NAMES.indexOf(kfItem.system.aspect ?? "metal");
|
const kfAspect = kfItem.system.aspect?.toLowerCase() ?? "metal";
|
||||||
|
const ASPECT_NORMALIZE = { eau: "water", terre: "earth", feu: "fire", bois: "wood" };
|
||||||
|
kfDefaultAspect = ASPECT_NAMES.indexOf(ASPECT_NORMALIZE[kfAspect] ?? kfAspect);
|
||||||
if (kfDefaultAspect < 0) kfDefaultAspect = 0;
|
if (kfDefaultAspect < 0) kfDefaultAspect = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1724,7 +1942,7 @@ async function rollForActor(actor, rollKey) {
|
|||||||
weaponTypeLabel: WEAPON_TYPE_LABELS[wpType] ?? "CDE.Weapon",
|
weaponTypeLabel: WEAPON_TYPE_LABELS[wpType] ?? "CDE.Weapon",
|
||||||
weaponAspectIcon: ASPECT_ICONS[ASPECT_NAMES[wpAspectIdx]] ?? "",
|
weaponAspectIcon: ASPECT_ICONS[ASPECT_NAMES[wpAspectIdx]] ?? "",
|
||||||
weaponAspectLabel: game.i18n.localize(ASPECT_LABELS[ASPECT_NAMES[wpAspectIdx]] ?? ""),
|
weaponAspectLabel: game.i18n.localize(ASPECT_LABELS[ASPECT_NAMES[wpAspectIdx]] ?? ""),
|
||||||
damageBase: wpItem.system.damageBase ?? 1,
|
damageBase: wpItem.system.damageBase ?? 0,
|
||||||
weaponskill: wpSkill,
|
weaponskill: wpSkill,
|
||||||
aspect: wpAspectIdx,
|
aspect: wpAspectIdx,
|
||||||
effectiverange: wpRange,
|
effectiverange: wpRange,
|
||||||
@@ -1743,8 +1961,9 @@ async function rollForActor(actor, rollKey) {
|
|||||||
const wpWoundMalus = Number(wParams.woundmalus ?? 0);
|
const wpWoundMalus = Number(wParams.woundmalus ?? 0);
|
||||||
const wpBonusAusp = Number(wParams.bonusauspiciousdice ?? 0);
|
const wpBonusAusp = Number(wParams.bonusauspiciousdice ?? 0);
|
||||||
const wpThrowMode = Number(wParams.typeofthrow ?? 0);
|
const wpThrowMode = Number(wParams.typeofthrow ?? 0);
|
||||||
const wpDamageBase = wpItem.system.damageBase ?? 1;
|
const wpDamageBase = wpItem.system.damageBase ?? 0;
|
||||||
const wpTotalDice = wpSkillDice + wpAspectDice + wpRangeMalus + wpBonusMalus - wpWoundMalus;
|
const wpSpecialtyBonus = wpItem.system.hasSpeciality ? 1 : 0;
|
||||||
|
const wpTotalDice = wpSkillDice + wpAspectDice + wpRangeMalus + wpBonusMalus - wpWoundMalus + wpSpecialtyBonus;
|
||||||
if (wpTotalDice <= 0) {
|
if (wpTotalDice <= 0) {
|
||||||
ui.notifications.warn(game.i18n.localize("CDE.Error0"));
|
ui.notifications.warn(game.i18n.localize("CDE.Error0"));
|
||||||
return;
|
return;
|
||||||
@@ -1760,6 +1979,11 @@ async function rollForActor(actor, rollKey) {
|
|||||||
if (wpBonusMalus !== 0) wpModParts.push(`${wpBonusMalus > 0 ? "+" : ""}${wpBonusMalus} ${game.i18n.localize("CDE.BonusMalus")}`);
|
if (wpBonusMalus !== 0) wpModParts.push(`${wpBonusMalus > 0 ? "+" : ""}${wpBonusMalus} ${game.i18n.localize("CDE.BonusMalus")}`);
|
||||||
if (wpWoundMalus !== 0) wpModParts.push(`-${wpWoundMalus} ${game.i18n.localize("CDE.WoundMalus")}`);
|
if (wpWoundMalus !== 0) wpModParts.push(`-${wpWoundMalus} ${game.i18n.localize("CDE.WoundMalus")}`);
|
||||||
if (wpBonusAusp !== 0) wpModParts.push(`+${wpBonusAusp} ${game.i18n.localize("CDE.BonusAuspiciousDice")}`);
|
if (wpBonusAusp !== 0) wpModParts.push(`+${wpBonusAusp} ${game.i18n.localize("CDE.BonusAuspiciousDice")}`);
|
||||||
|
const wpDamageAspectRaw = wpItem.system.damageAspect ?? "metal";
|
||||||
|
const wpDamageAspectIdx = WEAPON_ASPECT_INDEX[wpDamageAspectRaw] ?? 0;
|
||||||
|
const wpDamageAspectName = ASPECT_NAMES[wpDamageAspectIdx];
|
||||||
|
const wpDamageAspectValue = sys.aspect?.[wpDamageAspectName]?.value ?? 0;
|
||||||
|
const wpDamageAspectLabel = game.i18n.localize(ASPECT_LABELS[wpDamageAspectName] ?? "");
|
||||||
const wpMsg = await sendResultMessage(actor, {
|
const wpMsg = await sendResultMessage(actor, {
|
||||||
rollLabel: `${wpItem.name}`,
|
rollLabel: `${wpItem.name}`,
|
||||||
aspectName: wpAspectName,
|
aspectName: wpAspectName,
|
||||||
@@ -1774,7 +1998,9 @@ async function rollForActor(actor, rollKey) {
|
|||||||
// weapon-specific
|
// weapon-specific
|
||||||
weaponName: wpItem.name,
|
weaponName: wpItem.name,
|
||||||
damageBase: wpDamageBase,
|
damageBase: wpDamageBase,
|
||||||
totalDamage: wpResults.successesdice * wpDamageBase,
|
damageAspectValue: wpDamageAspectValue,
|
||||||
|
damageAspectLabel: wpDamageAspectLabel,
|
||||||
|
totalDamage: wpDamageBase + wpDamageAspectValue,
|
||||||
...wpResults,
|
...wpResults,
|
||||||
aspect: wpAspectName,
|
aspect: wpAspectName,
|
||||||
d1: wpFaces[1],
|
d1: wpFaces[1],
|
||||||
@@ -1789,7 +2015,10 @@ async function rollForActor(actor, rollKey) {
|
|||||||
d0: wpFaces[0]
|
d0: wpFaces[0]
|
||||||
}, wpRoll, ROLL_MODES[wpThrowMode] ?? "roll");
|
}, wpRoll, ROLL_MODES[wpThrowMode] ?? "roll");
|
||||||
if (game.modules.get("dice-so-nice")?.active && wpMsg?.id) {
|
if (game.modules.get("dice-so-nice")?.active && wpMsg?.id) {
|
||||||
|
try {
|
||||||
await game.dice3d.waitFor3DAnimationByMessageID(wpMsg.id);
|
await game.dice3d.waitFor3DAnimationByMessageID(wpMsg.id);
|
||||||
|
} catch (_e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((wpResults.loksyudice ?? 0) > 0) await updateLoksyuFromRoll(wpAspectName, wpFaces);
|
if ((wpResults.loksyudice ?? 0) > 0) await updateLoksyuFromRoll(wpAspectName, wpFaces);
|
||||||
if ((wpResults.tinjidice ?? 0) > 0) await updateTinjiFromRoll(wpResults.tinjidice);
|
if ((wpResults.tinjidice ?? 0) > 0) await updateTinjiFromRoll(wpResults.tinjidice);
|
||||||
@@ -1822,14 +2051,6 @@ async function rollForActor(actor, rollKey) {
|
|||||||
if (kfDefaultAspect >= 0) {
|
if (kfDefaultAspect >= 0) {
|
||||||
defaultAspect = kfDefaultAspect;
|
defaultAspect = kfDefaultAspect;
|
||||||
}
|
}
|
||||||
let defaultSpecialAspect = 0;
|
|
||||||
if (isMagicSpecial && specialLibel) {
|
|
||||||
const specialCfg = MAGICS?.[skillLibel]?.speciality?.[specialLibel];
|
|
||||||
const aspectName = LABELELEMENT_TO_ASPECT[specialCfg?.labelelement];
|
|
||||||
if (aspectName) {
|
|
||||||
defaultSpecialAspect = ASPECT_NAMES.indexOf(aspectName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let params;
|
let params;
|
||||||
if (isMagic) {
|
if (isMagic) {
|
||||||
params = await showMagicPrompt({
|
params = await showMagicPrompt({
|
||||||
@@ -1838,10 +2059,8 @@ async function rollForActor(actor, rollKey) {
|
|||||||
aspectskill: defaultAspect,
|
aspectskill: defaultAspect,
|
||||||
bonusmalusskill: 0,
|
bonusmalusskill: 0,
|
||||||
bonusauspiciousdice: 0,
|
bonusauspiciousdice: 0,
|
||||||
aspectspeciality: defaultSpecialAspect,
|
|
||||||
rolldifficulty: 1,
|
rolldifficulty: 1,
|
||||||
bonusmalusspeciality: 0,
|
freepowerlevels: 0,
|
||||||
heispend: 0,
|
|
||||||
typeofthrow: typeOfThrow
|
typeofthrow: typeOfThrow
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -1858,20 +2077,16 @@ async function rollForActor(actor, rollKey) {
|
|||||||
}
|
}
|
||||||
if (!params) return;
|
if (!params) return;
|
||||||
let aspectIndex, bonusMalus, bonusAuspicious, throwMode;
|
let aspectIndex, bonusMalus, bonusAuspicious, throwMode;
|
||||||
let spellAspectIndex = null;
|
|
||||||
let rollDifficulty = 1;
|
let rollDifficulty = 1;
|
||||||
if (isMagic) {
|
if (isMagic) {
|
||||||
const skillAspectIndex = Number(params.aspectskill ?? 0);
|
const skillAspectIndex = Number(params.aspectskill ?? 0);
|
||||||
spellAspectIndex = Number(params.aspectspeciality ?? skillAspectIndex);
|
|
||||||
aspectIndex = skillAspectIndex;
|
aspectIndex = skillAspectIndex;
|
||||||
bonusMalus = Number(params.bonusmalusskill ?? 0);
|
bonusMalus = Number(params.bonusmalusskill ?? 0);
|
||||||
bonusAuspicious = Number(params.bonusauspiciousdice ?? 0);
|
bonusAuspicious = Number(params.bonusauspiciousdice ?? 0);
|
||||||
rollDifficulty = Math.max(1, Number(params.rolldifficulty ?? 1));
|
rollDifficulty = Math.max(1, Number(params.rolldifficulty ?? 1));
|
||||||
throwMode = Number(params.typeofthrow ?? 0);
|
throwMode = Number(params.typeofthrow ?? 0);
|
||||||
const aspectDice = sys.aspect?.[ASPECT_NAMES[aspectIndex]]?.value ?? 0;
|
const aspectDice = sys.aspect?.[ASPECT_NAMES[aspectIndex]]?.value ?? 0;
|
||||||
const bonusSpec = Number(params.bonusmalusspeciality ?? 0);
|
numberofdice = numberofdice + aspectDice + bonusMalus + 1;
|
||||||
const heiDice = Number(params.heispend ?? 0);
|
|
||||||
numberofdice = numberofdice + aspectDice + bonusMalus + 1 + bonusSpec + heiDice;
|
|
||||||
} else {
|
} else {
|
||||||
aspectIndex = Number(params.aspect ?? 0);
|
aspectIndex = Number(params.aspect ?? 0);
|
||||||
bonusMalus = Number(params.bonusmalus ?? 0);
|
bonusMalus = Number(params.bonusmalus ?? 0);
|
||||||
@@ -1889,22 +2104,33 @@ async function rollForActor(actor, rollKey) {
|
|||||||
const roll = new Roll(`${numberofdice}d10`);
|
const roll = new Roll(`${numberofdice}d10`);
|
||||||
await roll.evaluate();
|
await roll.evaluate();
|
||||||
const rollModeKey = ROLL_MODES[throwMode] ?? "roll";
|
const rollModeKey = ROLL_MODES[throwMode] ?? "roll";
|
||||||
const wuXingAspectName = spellAspectIndex !== null ? ASPECT_NAMES[spellAspectIndex] : ASPECT_NAMES[aspectIndex];
|
let spellPower = null;
|
||||||
|
let spellPowerAspectName = null;
|
||||||
|
let spellPowerAspectValue = null;
|
||||||
|
if (isMagic) {
|
||||||
|
if (isMagicSpecial && specialLibel) {
|
||||||
|
const specialCfg = MAGICS?.[skillLibel]?.speciality?.[specialLibel];
|
||||||
|
const elemName = LABELELEMENT_TO_ASPECT[specialCfg?.labelelementkey];
|
||||||
|
if (elemName) spellPowerAspectName = elemName;
|
||||||
|
}
|
||||||
|
if (!spellPowerAspectName) spellPowerAspectName = ASPECT_NAMES[aspectIndex];
|
||||||
|
spellPowerAspectValue = sys.aspect?.[spellPowerAspectName]?.value ?? 0;
|
||||||
|
const freePowerLevels = Number(params.freepowerlevels ?? 0);
|
||||||
|
spellPower = rollDifficulty * (spellPowerAspectValue + freePowerLevels);
|
||||||
|
}
|
||||||
|
const wuXingAspectName = ASPECT_NAMES[aspectIndex];
|
||||||
const allResults = roll.dice[0]?.results ?? [];
|
const allResults = roll.dice[0]?.results ?? [];
|
||||||
const faces = countFaces(allResults);
|
const faces = countFaces(allResults);
|
||||||
const results = computeWuXingResults(faces, wuXingAspectName, bonusAuspicious);
|
const results = computeWuXingResults(faces, wuXingAspectName, bonusAuspicious);
|
||||||
if (!results) return;
|
if (!results) return;
|
||||||
const spellPower = isMagic ? results.successesdice * rollDifficulty : null;
|
|
||||||
const modParts = [];
|
const modParts = [];
|
||||||
if (isMagic) {
|
if (isMagic) {
|
||||||
const bm = Number(params.bonusmalusskill ?? 0);
|
const bm = Number(params.bonusmalusskill ?? 0);
|
||||||
const bs = Number(params.bonusmalusspeciality ?? 0);
|
|
||||||
const hs = Number(params.heispend ?? 0);
|
|
||||||
const ba = Number(params.bonusauspiciousdice ?? 0);
|
const ba = Number(params.bonusauspiciousdice ?? 0);
|
||||||
|
const fp = Number(params.freepowerlevels ?? 0);
|
||||||
if (bm !== 0) modParts.push(`${bm > 0 ? "+" : ""}${bm} ${game.i18n.localize("CDE.BonusMalus")}`);
|
if (bm !== 0) modParts.push(`${bm > 0 ? "+" : ""}${bm} ${game.i18n.localize("CDE.BonusMalus")}`);
|
||||||
if (bs !== 0) modParts.push(`${bs > 0 ? "+" : ""}${bs} ${game.i18n.localize("CDE.SpellBonus")}`);
|
|
||||||
if (ba !== 0) modParts.push(`+${ba} ${game.i18n.localize("CDE.BonusAuspiciousDice")}`);
|
if (ba !== 0) modParts.push(`+${ba} ${game.i18n.localize("CDE.BonusAuspiciousDice")}`);
|
||||||
if (hs !== 0) modParts.push(`${hs} ${game.i18n.localize("CDE.HeiSpend")}`);
|
if (fp !== 0) modParts.push(`+${fp} ${game.i18n.localize("CDE.FreePowerLevels")}`);
|
||||||
if (rollDifficulty !== 1) modParts.push(`\xD7${rollDifficulty} ${game.i18n.localize("CDE.RollDifficulty")}`);
|
if (rollDifficulty !== 1) modParts.push(`\xD7${rollDifficulty} ${game.i18n.localize("CDE.RollDifficulty")}`);
|
||||||
} else {
|
} else {
|
||||||
const bm = Number(params.bonusmalus ?? 0);
|
const bm = Number(params.bonusmalus ?? 0);
|
||||||
@@ -1924,6 +2150,9 @@ async function rollForActor(actor, rollKey) {
|
|||||||
modifiersText: modParts.length ? modParts.join(" \xB7 ") : "",
|
modifiersText: modParts.length ? modParts.join(" \xB7 ") : "",
|
||||||
// Spell power (magic only)
|
// Spell power (magic only)
|
||||||
spellPower,
|
spellPower,
|
||||||
|
spellPowerAspectLabel: spellPowerAspectName ? game.i18n.localize(ASPECT_LABELS[spellPowerAspectName] ?? "") : "",
|
||||||
|
spellPowerAspectValue,
|
||||||
|
spellPowerFreeLevels: isMagic ? Number(params.freepowerlevels ?? 0) : 0,
|
||||||
rollDifficulty: isMagic ? rollDifficulty : null,
|
rollDifficulty: isMagic ? rollDifficulty : null,
|
||||||
// Actor info
|
// Actor info
|
||||||
actorName: actor.name ?? "",
|
actorName: actor.name ?? "",
|
||||||
@@ -1944,7 +2173,10 @@ async function rollForActor(actor, rollKey) {
|
|||||||
d0: faces[0]
|
d0: faces[0]
|
||||||
}, roll, rollModeKey);
|
}, roll, rollModeKey);
|
||||||
if (game.modules.get("dice-so-nice")?.active && msg?.id) {
|
if (game.modules.get("dice-so-nice")?.active && msg?.id) {
|
||||||
|
try {
|
||||||
await game.dice3d.waitFor3DAnimationByMessageID(msg.id);
|
await game.dice3d.waitFor3DAnimationByMessageID(msg.id);
|
||||||
|
} catch (_e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((results.loksyudice ?? 0) > 0) await updateLoksyuFromRoll(wuXingAspectName, faces);
|
if ((results.loksyudice ?? 0) > 0) await updateLoksyuFromRoll(wuXingAspectName, faces);
|
||||||
if ((results.tinjidice ?? 0) > 0) await updateTinjiFromRoll(results.tinjidice);
|
if ((results.tinjidice ?? 0) > 0) await updateTinjiFromRoll(results.tinjidice);
|
||||||
@@ -2040,9 +2272,13 @@ var CDEBaseActorSheet = class _CDEBaseActorSheet extends HandlebarsApplicationMi
|
|||||||
};
|
};
|
||||||
|
|
||||||
// src/ui/sheets/actors/character.js
|
// src/ui/sheets/actors/character.js
|
||||||
var CDECharacterSheet = class extends CDEBaseActorSheet {
|
var CDECharacterSheet = class _CDECharacterSheet extends CDEBaseActorSheet {
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
classes: ["character"]
|
classes: ["character"],
|
||||||
|
actions: {
|
||||||
|
moveMagicUp: _CDECharacterSheet.#onMoveMagicUp,
|
||||||
|
moveMagicDown: _CDECharacterSheet.#onMoveMagicDown
|
||||||
|
}
|
||||||
};
|
};
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
main: { template: "systems/fvtt-chroniques-de-l-etrange/templates/actor/cde-character-sheet.html" }
|
main: { template: "systems/fvtt-chroniques-de-l-etrange/templates/actor/cde-character-sheet.html" }
|
||||||
@@ -2065,8 +2301,7 @@ var CDECharacterSheet = class extends CDEBaseActorSheet {
|
|||||||
spellsByDiscipline[disc].push(spell);
|
spellsByDiscipline[disc].push(spell);
|
||||||
}
|
}
|
||||||
const systemMagics = context.systemData.magics ?? {};
|
const systemMagics = context.systemData.magics ?? {};
|
||||||
context.magicsDisplay = Object.fromEntries(
|
const magicEntries = Object.entries(MAGICS).map(([magicKey, magicDef]) => {
|
||||||
Object.entries(MAGICS).map(([magicKey, magicDef]) => {
|
|
||||||
const magicData = systemMagics[magicKey] ?? {};
|
const magicData = systemMagics[magicKey] ?? {};
|
||||||
return [
|
return [
|
||||||
magicKey,
|
magicKey,
|
||||||
@@ -2082,8 +2317,19 @@ var CDECharacterSheet = class extends CDEBaseActorSheet {
|
|||||||
grimoire: spellsByDiscipline[magicKey] ?? []
|
grimoire: spellsByDiscipline[magicKey] ?? []
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
})
|
});
|
||||||
);
|
const order = context.systemData.magicOrder ?? [];
|
||||||
|
if (order.length > 0) {
|
||||||
|
magicEntries.sort((a, b) => {
|
||||||
|
const ia = order.indexOf(a[0]);
|
||||||
|
const ib = order.indexOf(b[0]);
|
||||||
|
if (ia === -1 && ib === -1) return 0;
|
||||||
|
if (ia === -1) return 1;
|
||||||
|
if (ib === -1) return -1;
|
||||||
|
return ia - ib;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
context.magicsDisplay = Object.fromEntries(magicEntries);
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
_onRender(context, options) {
|
_onRender(context, options) {
|
||||||
@@ -2167,7 +2413,7 @@ var CDECharacterSheet = class extends CDEBaseActorSheet {
|
|||||||
cell.addEventListener("click", (event) => {
|
cell.addEventListener("click", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const rollKey = cell.dataset.libelId;
|
const rollKey = cell.dataset.libelId;
|
||||||
if (rollKey) rollForActor(this.document, rollKey);
|
if (rollKey) rollForActor(this.document, rollKey)?.catch((err) => console.error("Roll failed:", err));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2181,6 +2427,26 @@ var CDECharacterSheet = class extends CDEBaseActorSheet {
|
|||||||
}).render(true);
|
}).render(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
static async #onMoveMagicUp(event, target) {
|
||||||
|
const key = target.dataset.magicKey;
|
||||||
|
let order = this.document.system.magicOrder ?? [];
|
||||||
|
if (!order.length) order = [...Object.keys(MAGICS)];
|
||||||
|
else order = [...order];
|
||||||
|
const idx = order.indexOf(key);
|
||||||
|
if (idx <= 0) return;
|
||||||
|
[order[idx - 1], order[idx]] = [order[idx], order[idx - 1]];
|
||||||
|
await this.document.update({ "system.magicOrder": order });
|
||||||
|
}
|
||||||
|
static async #onMoveMagicDown(event, target) {
|
||||||
|
const key = target.dataset.magicKey;
|
||||||
|
let order = this.document.system.magicOrder ?? [];
|
||||||
|
if (!order.length) order = [...Object.keys(MAGICS)];
|
||||||
|
else order = [...order];
|
||||||
|
const idx = order.indexOf(key);
|
||||||
|
if (idx === -1 || idx >= order.length - 1) return;
|
||||||
|
[order[idx], order[idx + 1]] = [order[idx + 1], order[idx]];
|
||||||
|
await this.document.update({ "system.magicOrder": order });
|
||||||
|
}
|
||||||
#bindComponentRandomize() {
|
#bindComponentRandomize() {
|
||||||
const btn = this.element?.querySelector("[data-action='randomize-component']");
|
const btn = this.element?.querySelector("[data-action='randomize-component']");
|
||||||
if (!btn) return;
|
if (!btn) return;
|
||||||
@@ -2250,7 +2516,7 @@ var CDENpcSheet = class extends CDEBaseActorSheet {
|
|||||||
cell.addEventListener("click", (event) => {
|
cell.addEventListener("click", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const rollKey = cell.dataset.libelId;
|
const rollKey = cell.dataset.libelId;
|
||||||
if (rollKey) rollForActor(this.document, rollKey);
|
if (rollKey) rollForActor(this.document, rollKey)?.catch((err) => console.error("Roll failed:", err));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2437,11 +2703,11 @@ var CDESanheiSheet = class extends CDEBaseItemSheet {
|
|||||||
async _prepareContext() {
|
async _prepareContext() {
|
||||||
const context = await super._prepareContext();
|
const context = await super._prepareContext();
|
||||||
const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? "", { async: true });
|
const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? "", { async: true });
|
||||||
const props = this.document.system.properties;
|
const props = this.document.system.properties ?? {};
|
||||||
context.prop1DescriptionHTML = await enrich(props.prop1.description);
|
context.prop1DescriptionHTML = await enrich(props.prop1?.description);
|
||||||
context.prop2DescriptionHTML = await enrich(props.prop2.description);
|
context.prop2DescriptionHTML = await enrich(props.prop2?.description);
|
||||||
context.prop3DescriptionHTML = await enrich(props.prop3.description);
|
context.prop3DescriptionHTML = await enrich(props.prop3?.description);
|
||||||
context.propFields = this.document.system.schema.fields.properties.fields;
|
context.propFields = this.document.system.schema.fields.properties?.fields;
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -2484,6 +2750,8 @@ var CDELoksyuApp = class _CDELoksyuApp extends foundry.applications.api.Handleba
|
|||||||
};
|
};
|
||||||
/** @type {Function|null} bound hook handler */
|
/** @type {Function|null} bound hook handler */
|
||||||
_updateHook = null;
|
_updateHook = null;
|
||||||
|
/** @type {Function|null} updateSetting hook handler (for socket-propagated writes) */
|
||||||
|
_settingHook = null;
|
||||||
/** Singleton accessor — open or bring to front */
|
/** Singleton accessor — open or bring to front */
|
||||||
static open() {
|
static open() {
|
||||||
const existing = Array.from(foundry.applications.instances.values()).find(
|
const existing = Array.from(foundry.applications.instances.values()).find(
|
||||||
@@ -2518,13 +2786,24 @@ var CDELoksyuApp = class _CDELoksyuApp extends foundry.applications.api.Handleba
|
|||||||
_onRender(context, options) {
|
_onRender(context, options) {
|
||||||
super._onRender(context, options);
|
super._onRender(context, options);
|
||||||
this.#bindInputs();
|
this.#bindInputs();
|
||||||
|
if (!this._updateHook) {
|
||||||
this._updateHook = Hooks.on("cde:loksyuUpdated", () => this.render());
|
this._updateHook = Hooks.on("cde:loksyuUpdated", () => this.render());
|
||||||
}
|
}
|
||||||
|
if (!this._settingHook) {
|
||||||
|
this._settingHook = Hooks.on("updateSetting", (setting) => {
|
||||||
|
if (setting.key === `${SYSTEM_ID}.loksyuData`) this.render();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
_onClose(options) {
|
_onClose(options) {
|
||||||
if (this._updateHook !== null) {
|
if (this._updateHook !== null) {
|
||||||
Hooks.off("cde:loksyuUpdated", this._updateHook);
|
Hooks.off("cde:loksyuUpdated", this._updateHook);
|
||||||
this._updateHook = null;
|
this._updateHook = null;
|
||||||
}
|
}
|
||||||
|
if (this._settingHook !== null) {
|
||||||
|
Hooks.off("updateSetting", this._settingHook);
|
||||||
|
this._settingHook = null;
|
||||||
|
}
|
||||||
super._onClose(options);
|
super._onClose(options);
|
||||||
}
|
}
|
||||||
#bindInputs() {
|
#bindInputs() {
|
||||||
@@ -2593,6 +2872,8 @@ var CDETinjiApp = class _CDETinjiApp extends foundry.applications.api.Handlebars
|
|||||||
};
|
};
|
||||||
/** @type {Function|null} */
|
/** @type {Function|null} */
|
||||||
_updateHook = null;
|
_updateHook = null;
|
||||||
|
/** @type {Function|null} */
|
||||||
|
_settingHook = null;
|
||||||
static open() {
|
static open() {
|
||||||
const existing = Array.from(foundry.applications.instances.values()).find(
|
const existing = Array.from(foundry.applications.instances.values()).find(
|
||||||
(app2) => app2 instanceof _CDETinjiApp
|
(app2) => app2 instanceof _CDETinjiApp
|
||||||
@@ -2614,13 +2895,24 @@ var CDETinjiApp = class _CDETinjiApp extends foundry.applications.api.Handlebars
|
|||||||
_onRender(context, options) {
|
_onRender(context, options) {
|
||||||
super._onRender(context, options);
|
super._onRender(context, options);
|
||||||
this.#bindDirectInput();
|
this.#bindDirectInput();
|
||||||
|
if (!this._updateHook) {
|
||||||
this._updateHook = Hooks.on("cde:tinjiUpdated", () => this.render());
|
this._updateHook = Hooks.on("cde:tinjiUpdated", () => this.render());
|
||||||
}
|
}
|
||||||
|
if (!this._settingHook) {
|
||||||
|
this._settingHook = Hooks.on("updateSetting", (setting) => {
|
||||||
|
if (setting.key === `${SYSTEM_ID}.tinjiData`) this.render();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
_onClose(options) {
|
_onClose(options) {
|
||||||
if (this._updateHook !== null) {
|
if (this._updateHook !== null) {
|
||||||
Hooks.off("cde:tinjiUpdated", this._updateHook);
|
Hooks.off("cde:tinjiUpdated", this._updateHook);
|
||||||
this._updateHook = null;
|
this._updateHook = null;
|
||||||
}
|
}
|
||||||
|
if (this._settingHook !== null) {
|
||||||
|
Hooks.off("updateSetting", this._settingHook);
|
||||||
|
this._settingHook = null;
|
||||||
|
}
|
||||||
super._onClose(options);
|
super._onClose(options);
|
||||||
}
|
}
|
||||||
#bindDirectInput() {
|
#bindDirectInput() {
|
||||||
@@ -2649,7 +2941,7 @@ var CDETinjiApp = class _CDETinjiApp extends foundry.applications.api.Handlebars
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await setTinjiValue(current - 1);
|
await setTinjiValue(current - 1);
|
||||||
ChatMessage.create({
|
await ChatMessage.create({
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
content: `<div class="cde-tinji-spend-msg">
|
content: `<div class="cde-tinji-spend-msg">
|
||||||
<i class="fas fa-star"></i>
|
<i class="fas fa-star"></i>
|
||||||
@@ -2668,7 +2960,7 @@ var CDECombat = class extends Combat {
|
|||||||
* for each selected combatant, then sync the result to the Combatant document.
|
* for each selected combatant, then sync the result to the Combatant document.
|
||||||
*/
|
*/
|
||||||
async rollInitiative(ids, options = {}) {
|
async rollInitiative(ids, options = {}) {
|
||||||
const combatantIds = typeof ids === "string" ? [ids] : ids;
|
const combatantIds = ids ? typeof ids === "string" ? [ids] : ids : this.combatants.map((c) => c.id);
|
||||||
for (const id of combatantIds) {
|
for (const id of combatantIds) {
|
||||||
const combatant = this.combatants.get(id);
|
const combatant = this.combatants.get(id);
|
||||||
if (!combatant) continue;
|
if (!combatant) continue;
|
||||||
@@ -2877,8 +3169,7 @@ function refreshRollActions(rollCard, aspect, message) {
|
|||||||
const tinji = getTinjiValue();
|
const tinji = getTinjiValue();
|
||||||
const successAvail = (loksyu[aspect]?.yin ?? 0) + (loksyu[aspect]?.yang ?? 0);
|
const successAvail = (loksyu[aspect]?.yin ?? 0) + (loksyu[aspect]?.yang ?? 0);
|
||||||
const fasteAvail = (loksyu[fasteAspect]?.yin ?? 0) + (loksyu[fasteAspect]?.yang ?? 0);
|
const fasteAvail = (loksyu[fasteAspect]?.yin ?? 0) + (loksyu[fasteAspect]?.yang ?? 0);
|
||||||
const isGM = game.user.isGM;
|
const hasSomething = successAvail > 0 || fasteAvail > 0 || tinji > 0;
|
||||||
const hasSomething = successAvail > 0 || fasteAvail > 0 || isGM && tinji > 0;
|
|
||||||
if (!hasSomething) return;
|
if (!hasSomething) return;
|
||||||
const aspLabel = game.i18n.localize(ASPECT_LABELS[aspect]);
|
const aspLabel = game.i18n.localize(ASPECT_LABELS[aspect]);
|
||||||
const fasteLabel = game.i18n.localize(ASPECT_LABELS[fasteAspect]);
|
const fasteLabel = game.i18n.localize(ASPECT_LABELS[fasteAspect]);
|
||||||
@@ -2897,7 +3188,7 @@ function refreshRollActions(rollCard, aspect, message) {
|
|||||||
<span class="cde-roll-action-count">${fasteAvail}</span>
|
<span class="cde-roll-action-count">${fasteAvail}</span>
|
||||||
</button>`;
|
</button>`;
|
||||||
}
|
}
|
||||||
if (isGM && tinji > 0) {
|
if (tinji > 0) {
|
||||||
btns += `<button class="cde-roll-action-btn cde-roll-action--tinji" data-action="tinji">
|
btns += `<button class="cde-roll-action-btn cde-roll-action--tinji" data-action="tinji">
|
||||||
<span class="cde-roll-action-tinji-char">\u5929</span>
|
<span class="cde-roll-action-tinji-char">\u5929</span>
|
||||||
<span class="cde-roll-action-label">${game.i18n.localize("CDE.TinJi2")}</span>
|
<span class="cde-roll-action-label">${game.i18n.localize("CDE.TinJi2")}</span>
|
||||||
@@ -2936,17 +3227,32 @@ async function _drawFromLoksyu(message, aspect, type, aspectLabel) {
|
|||||||
ui.notifications.warn(game.i18n.localize("CDE.LoksyuEmpty"));
|
ui.notifications.warn(game.i18n.localize("CDE.LoksyuEmpty"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const order = game.settings.get(SYSTEM_ID, "loksyuConsumptionOrder");
|
||||||
|
if (order === "yin-first") {
|
||||||
|
if (entry.yin > 0) entry.yin--;
|
||||||
|
else entry.yang--;
|
||||||
|
} else if (order === "balanced") {
|
||||||
|
if (entry.yin > entry.yang) entry.yin--;
|
||||||
|
else if (entry.yang > entry.yin) entry.yang--;
|
||||||
|
else if (entry.yang > 0) entry.yang--;
|
||||||
|
else entry.yin--;
|
||||||
|
} else {
|
||||||
if (entry.yang > 0) entry.yang--;
|
if (entry.yang > 0) entry.yang--;
|
||||||
else entry.yin--;
|
else entry.yin--;
|
||||||
|
}
|
||||||
data[aspect] = entry;
|
data[aspect] = entry;
|
||||||
|
if (game.user.isGM) {
|
||||||
await setLoksyuData(data);
|
await setLoksyuData(data);
|
||||||
|
} else {
|
||||||
|
requestLoksyuDraw(aspect, order);
|
||||||
|
}
|
||||||
const flags = message?.flags?.[SYSTEM_ID];
|
const flags = message?.flags?.[SYSTEM_ID];
|
||||||
if (flags?.rollResult && message.isOwner) {
|
if (flags?.rollResult && message.isOwner) {
|
||||||
const updated = foundry.utils.deepClone(flags.rollResult);
|
const updated = foundry.utils.deepClone(flags.rollResult);
|
||||||
if (type === "success") {
|
if (type === "success") {
|
||||||
updated.successesdice = (updated.successesdice ?? 0) + 1;
|
updated.successesdice = (updated.successesdice ?? 0) + 1;
|
||||||
updated.loksyuBonusSuc = (updated.loksyuBonusSuc ?? 0) + 1;
|
updated.loksyuBonusSuc = (updated.loksyuBonusSuc ?? 0) + 1;
|
||||||
if (updated.damageBase) updated.totalDamage = updated.successesdice * updated.damageBase;
|
if (updated.damageBase != null) updated.totalDamage = updated.damageBase + (updated.damageAspectValue ?? 0);
|
||||||
} else {
|
} else {
|
||||||
updated.auspiciousdice = (updated.auspiciousdice ?? 0) + 1;
|
updated.auspiciousdice = (updated.auspiciousdice ?? 0) + 1;
|
||||||
updated.loksyuBonusFaste = (updated.loksyuBonusFaste ?? 0) + 1;
|
updated.loksyuBonusFaste = (updated.loksyuBonusFaste ?? 0) + 1;
|
||||||
@@ -2959,7 +3265,7 @@ async function _drawFromLoksyu(message, aspect, type, aspectLabel) {
|
|||||||
}
|
}
|
||||||
const remain = entry.yin + entry.yang;
|
const remain = entry.yin + entry.yang;
|
||||||
const typeLabel = type === "success" ? game.i18n.localize("CDE.Successes") : game.i18n.localize("CDE.AuspiciousDie");
|
const typeLabel = type === "success" ? game.i18n.localize("CDE.Successes") : game.i18n.localize("CDE.AuspiciousDie");
|
||||||
ChatMessage.create({
|
await ChatMessage.create({
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
content: `<div class="cde-loksyu-draw-msg">
|
content: `<div class="cde-loksyu-draw-msg">
|
||||||
<div class="cde-loksyu-draw-header">
|
<div class="cde-loksyu-draw-header">
|
||||||
@@ -2978,14 +3284,17 @@ async function _drawFromLoksyu(message, aspect, type, aspectLabel) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
async function _spendTinjiPostRoll() {
|
async function _spendTinjiPostRoll() {
|
||||||
if (!game.user.isGM) return;
|
|
||||||
const current = getTinjiValue();
|
const current = getTinjiValue();
|
||||||
if (current <= 0) {
|
if (current <= 0) {
|
||||||
ui.notifications.warn(game.i18n.localize("CDE.TinjiEmpty"));
|
ui.notifications.warn(game.i18n.localize("CDE.TinjiEmpty"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (game.user.isGM) {
|
||||||
await setTinjiValue(current - 1);
|
await setTinjiValue(current - 1);
|
||||||
ChatMessage.create({
|
} else {
|
||||||
|
requestTinjiSpend();
|
||||||
|
}
|
||||||
|
await ChatMessage.create({
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
content: `<div class="cde-tinji-spend-msg">
|
content: `<div class="cde-tinji-spend-msg">
|
||||||
<span class="cde-tinji-icon">\u5929</span>
|
<span class="cde-tinji-icon">\u5929</span>
|
||||||
@@ -3051,7 +3360,14 @@ function injectWelcomeActions(_message, html) {
|
|||||||
// src/system.js
|
// src/system.js
|
||||||
Hooks.once("i18nInit", preLocalizeConfig);
|
Hooks.once("i18nInit", preLocalizeConfig);
|
||||||
Hooks.once("init", async () => {
|
Hooks.once("init", async () => {
|
||||||
console.info(`CHRONIQUESDELETRANGE | Initializing ${SYSTEM_ID}`);
|
console.log(
|
||||||
|
"%c\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\n%c\u2551 Chroniques de l'\xC9trange \u2014 FoundryVTT \u2551\n%c\u2551 Syst\xE8me de jeu par Antre-Monde \xC9ditions \u2551\n%c\u2551 Made by Uberwald - https://www.ubwerwald.me \u2551\n%c\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D",
|
||||||
|
"color: #d4af37; font-weight: bold;",
|
||||||
|
"color: #e2e8f4;",
|
||||||
|
"color: #7d94b8;",
|
||||||
|
"color: #5a7a9a;",
|
||||||
|
"color: #d4af37; font-weight: bold;"
|
||||||
|
);
|
||||||
registerSettings();
|
registerSettings();
|
||||||
game.system.CONST = { MAGICS, SUBTYPES };
|
game.system.CONST = { MAGICS, SUBTYPES };
|
||||||
game.cde = { CDELoksyuApp, CDETinjiApp, CDEWheelApp };
|
game.cde = { CDELoksyuApp, CDETinjiApp, CDEWheelApp };
|
||||||
@@ -3135,6 +3451,7 @@ Hooks.once("ready", async () => {
|
|||||||
await migrateIfNeeded();
|
await migrateIfNeeded();
|
||||||
await loadWelcomeSceneIfNeeded();
|
await loadWelcomeSceneIfNeeded();
|
||||||
CDEWheelApp.registerHooks();
|
CDEWheelApp.registerHooks();
|
||||||
|
registerSingletonSocket();
|
||||||
if (game.user.isGM) showWelcomeMessage();
|
if (game.user.isGM) showWelcomeMessage();
|
||||||
});
|
});
|
||||||
Hooks.on("renderChatLog", (_app, html) => {
|
Hooks.on("renderChatLog", (_app, html) => {
|
||||||
|
|||||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
@@ -34,6 +34,7 @@
|
|||||||
"CDE.HeiSpend": "Dépense HEI",
|
"CDE.HeiSpend": "Dépense HEI",
|
||||||
"CDE.SpellBonus": "Bonus Sort",
|
"CDE.SpellBonus": "Bonus Sort",
|
||||||
"CDE.SpellPower": "Puissance du Sort",
|
"CDE.SpellPower": "Puissance du Sort",
|
||||||
|
"CDE.BonusMalus": "Bonus/Malus",
|
||||||
"CDE.Boss": "Boss",
|
"CDE.Boss": "Boss",
|
||||||
"CDE.Cancel": "Annuler",
|
"CDE.Cancel": "Annuler",
|
||||||
"CDE.CancelChanges": "Annuler les modifications",
|
"CDE.CancelChanges": "Annuler les modifications",
|
||||||
@@ -81,6 +82,7 @@
|
|||||||
"CDE.EarthlyPrayer": "Prière Terrestre",
|
"CDE.EarthlyPrayer": "Prière Terrestre",
|
||||||
"CDE.Effects": "Effets",
|
"CDE.Effects": "Effets",
|
||||||
"CDE.Elixirs": "Élixirs",
|
"CDE.Elixirs": "Élixirs",
|
||||||
|
"CDE.EnablePrompt": "Toujours demander avant de lancer",
|
||||||
"CDE.Error0": "Impossible de poursuivre : le nombre total de vos dés à lancer est inférieur à 1.",
|
"CDE.Error0": "Impossible de poursuivre : le nombre total de vos dés à lancer est inférieur à 1.",
|
||||||
"CDE.Error1": "Impossible de poursuivre : vous ne possédez pas cette Compétence.",
|
"CDE.Error1": "Impossible de poursuivre : vous ne possédez pas cette Compétence.",
|
||||||
"CDE.Error10": "Impossible de poursuivre : vous avez 0 ou moins dans cet Aspect.",
|
"CDE.Error10": "Impossible de poursuivre : vous avez 0 ou moins dans cet Aspect.",
|
||||||
@@ -148,6 +150,11 @@
|
|||||||
"CDE.MigrationPartialError": "{count} personnage(s) n'ont pas pu être importés.",
|
"CDE.MigrationPartialError": "{count} personnage(s) n'ont pas pu être importés.",
|
||||||
"CDE.MigrationErrorNotJson": "Le fichier « {file} » n'est pas un fichier JSON.",
|
"CDE.MigrationErrorNotJson": "Le fichier « {file} » n'est pas un fichier JSON.",
|
||||||
"CDE.MigrationErrorParse": "Erreur lors de la lecture de « {file} » : {error}",
|
"CDE.MigrationErrorParse": "Erreur lors de la lecture de « {file} » : {error}",
|
||||||
|
"CDE.MigrationConfirmAction": "Confirmer l'importation",
|
||||||
|
"CDE.MigrationDuplicate": "Ce nom existe déjà dans le monde",
|
||||||
|
"CDE.MigrationDuplicateCount": "{count} personnage(s) existent déjà dans le monde",
|
||||||
|
"CDE.MigrationImportConfirm": "Vous allez importer {count} personnage(s). Confirmez-vous ?",
|
||||||
|
"CDE.MigrationImporting": "Importation en cours...",
|
||||||
"CDE.InitiativeWheel": "Roue d'Initiative",
|
"CDE.InitiativeWheel": "Roue d'Initiative",
|
||||||
"CDE.InitiativeWheelOpen": "Ouvrir la Roue d'Initiative",
|
"CDE.InitiativeWheelOpen": "Ouvrir la Roue d'Initiative",
|
||||||
"CDE.InitiativeWheelHint": "Roue d'initiative – Les Chroniques de l'Étrange",
|
"CDE.InitiativeWheelHint": "Roue d'initiative – Les Chroniques de l'Étrange",
|
||||||
@@ -199,6 +206,7 @@
|
|||||||
"CDE.MartialArts": "Arts Martiaux",
|
"CDE.MartialArts": "Arts Martiaux",
|
||||||
"CDE.Masterized": "Vous maîtrisez cette Technique",
|
"CDE.Masterized": "Vous maîtrisez cette Technique",
|
||||||
"CDE.MasteryOfTheWay": "Maîtrise de la Voie",
|
"CDE.MasteryOfTheWay": "Maîtrise de la Voie",
|
||||||
|
"CDE.Material": "Matériau",
|
||||||
"CDE.Max": "Max",
|
"CDE.Max": "Max",
|
||||||
"CDE.Max-Present-Malus-Present-Max": "Max ● Actuel ● Malus ● Actuel ● Max",
|
"CDE.Max-Present-Malus-Present-Max": "Max ● Actuel ● Malus ● Actuel ● Max",
|
||||||
"CDE.Max-Present-Present-Max": "Max ● Actuel ● Actuel ● Max",
|
"CDE.Max-Present-Present-Max": "Max ● Actuel ● Actuel ● Max",
|
||||||
@@ -217,8 +225,11 @@
|
|||||||
"CDE.MsgMagic2": "s'élève à ",
|
"CDE.MsgMagic2": "s'élève à ",
|
||||||
"CDE.MsgMagic3": ". La puissance à invoquer est de ",
|
"CDE.MsgMagic3": ". La puissance à invoquer est de ",
|
||||||
"CDE.MsgMagic4": ", si toutefois le sort est lancé avec succès.",
|
"CDE.MsgMagic4": ", si toutefois le sort est lancé avec succès.",
|
||||||
|
"CDE.MoveUp": "Monter",
|
||||||
|
"CDE.MoveDown": "Descendre",
|
||||||
"CDE.NPCName": "Nom du PNJ",
|
"CDE.NPCName": "Nom du PNJ",
|
||||||
"CDE.FatSi": "Fat Si",
|
"CDE.FatSi": "Fat Si",
|
||||||
|
"CDE.FreePowerLevels": "Niveaux de puissance gratuits",
|
||||||
"CDE.PNJ": "PNJ",
|
"CDE.PNJ": "PNJ",
|
||||||
"CDE.Name": "Nom",
|
"CDE.Name": "Nom",
|
||||||
"CDE.Necromancy": "Nécromancie",
|
"CDE.Necromancy": "Nécromancie",
|
||||||
@@ -280,6 +291,7 @@
|
|||||||
"CDE.ResourceValue": "Valeur",
|
"CDE.ResourceValue": "Valeur",
|
||||||
"CDE.Resources": "Ressources",
|
"CDE.Resources": "Ressources",
|
||||||
"CDE.Results": "Résultats :",
|
"CDE.Results": "Résultats :",
|
||||||
|
"CDE.Roll": "Jet",
|
||||||
"CDE.RollDifficulty": "Difficulté du Jet",
|
"CDE.RollDifficulty": "Difficulté du Jet",
|
||||||
"CDE.SAN-ZING": "SAN ● ZING",
|
"CDE.SAN-ZING": "SAN ● ZING",
|
||||||
"CDE.Sanhei": "Sanhei",
|
"CDE.Sanhei": "Sanhei",
|
||||||
@@ -321,12 +333,18 @@
|
|||||||
"CDE.Technique": "Technique",
|
"CDE.Technique": "Technique",
|
||||||
"CDE.Technologies": "Technologies",
|
"CDE.Technologies": "Technologies",
|
||||||
"CDE.Threat": "Niveau de Menace",
|
"CDE.Threat": "Niveau de Menace",
|
||||||
|
"CDE.ThrowType": "Type de jet",
|
||||||
"CDE.TinJi": "Tin Ji :",
|
"CDE.TinJi": "Tin Ji :",
|
||||||
"CDE.TinJi2": "Tin Ji",
|
"CDE.TinJi2": "Tin Ji",
|
||||||
"CDE.TinJiName": "Nom de la Tin Ji",
|
"CDE.TinJiName": "Nom de la Tin Ji",
|
||||||
"CDE.TinjiNotFound": "Aucun acteur Tin Ji trouvé. Le Maître du Jeu doit en créer un.",
|
"CDE.TinjiNotFound": "Aucun acteur Tin Ji trouvé. Le Maître du Jeu doit en créer un.",
|
||||||
"CDE.TinjiEmpty": "Il n'y a plus de dés de Tin Ji disponibles.",
|
"CDE.TinjiEmpty": "Il n'y a plus de dés de Tin Ji disponibles.",
|
||||||
"CDE.TinjiSpent": "{name} dépense 1 dé de Tin Ji.",
|
"CDE.TinjiSpent": "{name} dépense 1 dé de Tin Ji.",
|
||||||
|
"CDE.Settings.LoksyuConsumptionOrder": "Ordre de consommation du Loksyu",
|
||||||
|
"CDE.Settings.LoksyuConsumptionOrderHint": "Définit quelle polarité (Yin ou Yang) est consommée en priorité lorsqu'un dé est puisé dans la réserve de Loksyu.",
|
||||||
|
"CDE.Settings.LoksyuOrderYangFirst": "Yang d'abord",
|
||||||
|
"CDE.Settings.LoksyuOrderYinFirst": "Yin d'abord",
|
||||||
|
"CDE.Settings.LoksyuOrderBalanced": "Équilibré (consomme la polarité la plus fournie)",
|
||||||
"CDE.PostRollActions": "Puiser dans le Loksyu / Dépenser Tin Ji",
|
"CDE.PostRollActions": "Puiser dans le Loksyu / Dépenser Tin Ji",
|
||||||
"CDE.LoksyuDrawsA": "pioche",
|
"CDE.LoksyuDrawsA": "pioche",
|
||||||
"CDE.LoksyuFromAspect": "du",
|
"CDE.LoksyuFromAspect": "du",
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
MANIFEST-000006
|
MANIFEST-000052
|
||||||
|
|||||||
+7
-15
@@ -1,15 +1,7 @@
|
|||||||
2026/05/12-00:36:56.314091 7ff671fef6c0 Recovering log #4
|
2026/06/14-22:49:59.100287 7f29d5fed6c0 Recovering log #50
|
||||||
2026/05/12-00:36:56.323263 7ff671fef6c0 Delete type=3 #2
|
2026/06/14-22:49:59.110340 7f29d5fed6c0 Delete type=3 #48
|
||||||
2026/05/12-00:36:56.323317 7ff671fef6c0 Delete type=0 #4
|
2026/06/14-22:49:59.110396 7f29d5fed6c0 Delete type=0 #50
|
||||||
2026/05/12-00:37:07.971141 7ff6637fe6c0 Level-0 table #9: started
|
2026/06/14-22:52:09.917197 7f29d4feb6c0 Level-0 table #55: started
|
||||||
2026/05/12-00:37:07.974291 7ff6637fe6c0 Level-0 table #9: 1387 bytes OK
|
2026/06/14-22:52:09.917225 7f29d4feb6c0 Level-0 table #55: 0 bytes OK
|
||||||
2026/05/12-00:37:07.980872 7ff6637fe6c0 Delete type=0 #7
|
2026/06/14-22:52:09.923646 7f29d4feb6c0 Delete type=0 #53
|
||||||
2026/05/12-00:37:08.009643 7ff6637fe6c0 Manual compaction at level-0 from '!items!3aig6MWvZCRoWXPW' @ 72057594037927935 : 1 .. '!items!cXaQG1TBE0jzrbNt' @ 0 : 0; will stop at (end)
|
2026/06/14-22:52:09.923831 7f29d4feb6c0 Manual compaction at level-0 from '!items!3aig6MWvZCRoWXPW' @ 72057594037927935 : 1 .. '!items!cXaQG1TBE0jzrbNt' @ 0 : 0; will stop at (end)
|
||||||
2026/05/12-00:37:08.009699 7ff6637fe6c0 Manual compaction at level-1 from '!items!3aig6MWvZCRoWXPW' @ 72057594037927935 : 1 .. '!items!cXaQG1TBE0jzrbNt' @ 0 : 0; will stop at '!items!cXaQG1TBE0jzrbNt' @ 8 : 1
|
|
||||||
2026/05/12-00:37:08.009706 7ff6637fe6c0 Compacting 1@1 + 1@2 files
|
|
||||||
2026/05/12-00:37:08.012872 7ff6637fe6c0 Generated table #10@1: 4 keys, 1387 bytes
|
|
||||||
2026/05/12-00:37:08.012903 7ff6637fe6c0 Compacted 1@1 + 1@2 files => 1387 bytes
|
|
||||||
2026/05/12-00:37:08.019075 7ff6637fe6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
|
||||||
2026/05/12-00:37:08.019187 7ff6637fe6c0 Delete type=2 #5
|
|
||||||
2026/05/12-00:37:08.019315 7ff6637fe6c0 Delete type=2 #9
|
|
||||||
2026/05/12-00:37:08.051276 7ff6637fe6c0 Manual compaction at level-1 from '!items!cXaQG1TBE0jzrbNt' @ 8 : 1 .. '!items!cXaQG1TBE0jzrbNt' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
2026/05/12-00:36:37.149746 7fdfd57ec6c0 Delete type=3 #1
|
2026/06/14-22:22:39.661219 7f29d6fef6c0 Recovering log #46
|
||||||
2026/05/12-00:36:37.152016 7fdfd4feb6c0 Level-0 table #5: started
|
2026/06/14-22:22:39.671056 7f29d6fef6c0 Delete type=3 #44
|
||||||
2026/05/12-00:36:37.155425 7fdfd4feb6c0 Level-0 table #5: 1330 bytes OK
|
2026/06/14-22:22:39.671114 7f29d6fef6c0 Delete type=0 #46
|
||||||
2026/05/12-00:36:37.161916 7fdfd4feb6c0 Delete type=0 #3
|
2026/06/14-22:32:37.952133 7f29d4feb6c0 Level-0 table #51: started
|
||||||
2026/05/12-00:36:37.162057 7fdfd4feb6c0 Manual compaction at level-0 from '!items!3aig6MWvZCRoWXPW' @ 72057594037927935 : 1 .. '!items!cXaQG1TBE0jzrbNt' @ 0 : 0; will stop at (end)
|
2026/06/14-22:32:37.952163 7f29d4feb6c0 Level-0 table #51: 0 bytes OK
|
||||||
|
2026/06/14-22:32:37.958637 7f29d4feb6c0 Delete type=0 #49
|
||||||
|
2026/06/14-22:32:37.965966 7f29d4feb6c0 Manual compaction at level-0 from '!items!3aig6MWvZCRoWXPW' @ 72057594037927935 : 1 .. '!items!cXaQG1TBE0jzrbNt' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000006
|
MANIFEST-000052
|
||||||
|
|||||||
+7
-15
@@ -1,15 +1,7 @@
|
|||||||
2026/05/12-00:36:56.374154 7ff663fff6c0 Recovering log #4
|
2026/06/14-22:49:59.185177 7f29d5fed6c0 Recovering log #50
|
||||||
2026/05/12-00:36:56.383721 7ff663fff6c0 Delete type=3 #2
|
2026/06/14-22:49:59.194849 7f29d5fed6c0 Delete type=3 #48
|
||||||
2026/05/12-00:36:56.383779 7ff663fff6c0 Delete type=0 #4
|
2026/06/14-22:49:59.194912 7f29d5fed6c0 Delete type=0 #50
|
||||||
2026/05/12-00:37:08.062905 7ff6637fe6c0 Level-0 table #9: started
|
2026/06/14-22:52:09.979071 7f29d4feb6c0 Level-0 table #55: started
|
||||||
2026/05/12-00:37:08.066411 7ff6637fe6c0 Level-0 table #9: 10124 bytes OK
|
2026/06/14-22:52:09.979102 7f29d4feb6c0 Level-0 table #55: 0 bytes OK
|
||||||
2026/05/12-00:37:08.072622 7ff6637fe6c0 Delete type=0 #7
|
2026/06/14-22:52:09.985673 7f29d4feb6c0 Delete type=0 #53
|
||||||
2026/05/12-00:37:08.086421 7ff6637fe6c0 Manual compaction at level-0 from '!journal!CDEGuideMain0001' @ 72057594037927935 : 1 .. '!journal.pages!CDEGuideMain0001.wgqIHHVlO9miegn1' @ 0 : 0; will stop at (end)
|
2026/06/14-22:52:10.010878 7f29d4feb6c0 Manual compaction at level-0 from '!journal!CDEGuideMain0001' @ 72057594037927935 : 1 .. '!journal.pages!CDEGuideMain0001.wgqIHHVlO9miegn1' @ 0 : 0; will stop at (end)
|
||||||
2026/05/12-00:37:08.096808 7ff6637fe6c0 Manual compaction at level-1 from '!journal!CDEGuideMain0001' @ 72057594037927935 : 1 .. '!journal.pages!CDEGuideMain0001.wgqIHHVlO9miegn1' @ 0 : 0; will stop at '!journal.pages!CDEGuideMain0001.wgqIHHVlO9miegn1' @ 17 : 1
|
|
||||||
2026/05/12-00:37:08.096817 7ff6637fe6c0 Compacting 1@1 + 1@2 files
|
|
||||||
2026/05/12-00:37:08.100204 7ff6637fe6c0 Generated table #10@1: 21 keys, 18033 bytes
|
|
||||||
2026/05/12-00:37:08.100229 7ff6637fe6c0 Compacted 1@1 + 1@2 files => 18033 bytes
|
|
||||||
2026/05/12-00:37:08.106245 7ff6637fe6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
|
||||||
2026/05/12-00:37:08.106373 7ff6637fe6c0 Delete type=2 #5
|
|
||||||
2026/05/12-00:37:08.106502 7ff6637fe6c0 Delete type=2 #9
|
|
||||||
2026/05/12-00:37:08.113213 7ff6637fe6c0 Manual compaction at level-1 from '!journal.pages!CDEGuideMain0001.wgqIHHVlO9miegn1' @ 17 : 1 .. '!journal.pages!CDEGuideMain0001.wgqIHHVlO9miegn1' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
2026/05/12-00:36:37.177388 7fdfd5fed6c0 Delete type=3 #1
|
2026/06/14-22:22:39.748395 7f29d6fef6c0 Recovering log #46
|
||||||
2026/05/12-00:36:37.178463 7fdfd4feb6c0 Level-0 table #5: started
|
2026/06/14-22:22:39.759263 7f29d6fef6c0 Delete type=3 #44
|
||||||
2026/05/12-00:36:37.181940 7fdfd4feb6c0 Level-0 table #5: 9307 bytes OK
|
2026/06/14-22:22:39.759326 7f29d6fef6c0 Delete type=0 #46
|
||||||
2026/05/12-00:36:37.188105 7fdfd4feb6c0 Delete type=0 #3
|
2026/06/14-22:32:38.022572 7f29d4feb6c0 Level-0 table #51: started
|
||||||
2026/05/12-00:36:37.188350 7fdfd4feb6c0 Manual compaction at level-0 from '!journal!CDEGuideMain0001' @ 72057594037927935 : 1 .. '!journal.pages!CDEGuideMain0001.CDEHelpP10Extra' @ 0 : 0; will stop at (end)
|
2026/06/14-22:32:38.022623 7f29d4feb6c0 Level-0 table #51: 0 bytes OK
|
||||||
|
2026/06/14-22:32:38.028952 7f29d4feb6c0 Delete type=0 #49
|
||||||
|
2026/06/14-22:32:38.054477 7f29d4feb6c0 Manual compaction at level-0 from '!journal!CDEGuideMain0001' @ 72057594037927935 : 1 .. '!journal.pages!CDEGuideMain0001.wgqIHHVlO9miegn1' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000006
|
MANIFEST-000052
|
||||||
|
|||||||
@@ -1,15 +1,7 @@
|
|||||||
2026/05/12-00:36:56.336872 7ff671fef6c0 Recovering log #4
|
2026/06/14-22:49:59.128336 7f29d5fed6c0 Recovering log #50
|
||||||
2026/05/12-00:36:56.346806 7ff671fef6c0 Delete type=3 #2
|
2026/06/14-22:49:59.138475 7f29d5fed6c0 Delete type=3 #48
|
||||||
2026/05/12-00:36:56.346886 7ff671fef6c0 Delete type=0 #4
|
2026/06/14-22:49:59.138521 7f29d5fed6c0 Delete type=0 #50
|
||||||
2026/05/12-00:37:07.990253 7ff6637fe6c0 Level-0 table #9: started
|
2026/06/14-22:52:09.937223 7f29d4feb6c0 Level-0 table #55: started
|
||||||
2026/05/12-00:37:07.993684 7ff6637fe6c0 Level-0 table #9: 8881 bytes OK
|
2026/06/14-22:52:09.937263 7f29d4feb6c0 Level-0 table #55: 0 bytes OK
|
||||||
2026/05/12-00:37:07.999919 7ff6637fe6c0 Delete type=0 #7
|
2026/06/14-22:52:09.944028 7f29d4feb6c0 Delete type=0 #53
|
||||||
2026/05/12-00:37:08.009675 7ff6637fe6c0 Manual compaction at level-0 from '!items!0NDBw1YB54q3hLH0' @ 72057594037927935 : 1 .. '!items!ykekdZlirabRobEF' @ 0 : 0; will stop at (end)
|
2026/06/14-22:52:09.951911 7f29d4feb6c0 Manual compaction at level-0 from '!items!0NDBw1YB54q3hLH0' @ 72057594037927935 : 1 .. '!items!ykekdZlirabRobEF' @ 0 : 0; will stop at (end)
|
||||||
2026/05/12-00:37:08.019406 7ff6637fe6c0 Manual compaction at level-1 from '!items!0NDBw1YB54q3hLH0' @ 72057594037927935 : 1 .. '!items!ykekdZlirabRobEF' @ 0 : 0; will stop at '!items!ykekdZlirabRobEF' @ 108 : 1
|
|
||||||
2026/05/12-00:37:08.019418 7ff6637fe6c0 Compacting 1@1 + 1@2 files
|
|
||||||
2026/05/12-00:37:08.023624 7ff6637fe6c0 Generated table #10@1: 54 keys, 8881 bytes
|
|
||||||
2026/05/12-00:37:08.023709 7ff6637fe6c0 Compacted 1@1 + 1@2 files => 8881 bytes
|
|
||||||
2026/05/12-00:37:08.029864 7ff6637fe6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
|
||||||
2026/05/12-00:37:08.030009 7ff6637fe6c0 Delete type=2 #5
|
|
||||||
2026/05/12-00:37:08.030163 7ff6637fe6c0 Delete type=2 #9
|
|
||||||
2026/05/12-00:37:08.051296 7ff6637fe6c0 Manual compaction at level-1 from '!items!ykekdZlirabRobEF' @ 108 : 1 .. '!items!ykekdZlirabRobEF' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
2026/05/12-00:36:37.205346 7fdfd6fef6c0 Delete type=3 #1
|
2026/06/14-22:22:39.688631 7f29d6fef6c0 Recovering log #46
|
||||||
2026/05/12-00:36:37.206616 7fdfd4feb6c0 Level-0 table #5: started
|
2026/06/14-22:22:39.699291 7f29d6fef6c0 Delete type=3 #44
|
||||||
2026/05/12-00:36:37.210149 7fdfd4feb6c0 Level-0 table #5: 5923 bytes OK
|
2026/06/14-22:22:39.699355 7f29d6fef6c0 Delete type=0 #46
|
||||||
2026/05/12-00:36:37.216280 7fdfd4feb6c0 Delete type=0 #3
|
2026/06/14-22:32:37.979476 7f29d4feb6c0 Level-0 table #51: started
|
||||||
2026/05/12-00:36:37.216387 7fdfd4feb6c0 Manual compaction at level-0 from '!items!0NDBw1YB54q3hLH0' @ 72057594037927935 : 1 .. '!items!ykekdZlirabRobEF' @ 0 : 0; will stop at (end)
|
2026/06/14-22:32:37.979507 7f29d4feb6c0 Level-0 table #51: 0 bytes OK
|
||||||
|
2026/06/14-22:32:37.985981 7f29d4feb6c0 Delete type=0 #49
|
||||||
|
2026/06/14-22:32:37.994186 7f29d4feb6c0 Manual compaction at level-0 from '!items!0NDBw1YB54q3hLH0' @ 72057594037927935 : 1 .. '!items!ykekdZlirabRobEF' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000006
|
MANIFEST-000052
|
||||||
|
|||||||
+7
-15
@@ -1,15 +1,7 @@
|
|||||||
2026/05/12-00:36:56.348871 7ff6717ee6c0 Recovering log #4
|
2026/06/14-22:49:59.141353 7f29d6fef6c0 Recovering log #50
|
||||||
2026/05/12-00:36:56.358876 7ff6717ee6c0 Delete type=3 #2
|
2026/06/14-22:49:59.151373 7f29d6fef6c0 Delete type=3 #48
|
||||||
2026/05/12-00:36:56.358970 7ff6717ee6c0 Delete type=0 #4
|
2026/06/14-22:49:59.151426 7f29d6fef6c0 Delete type=0 #50
|
||||||
2026/05/12-00:37:07.981024 7ff6637fe6c0 Level-0 table #9: started
|
2026/06/14-22:52:09.944165 7f29d4feb6c0 Level-0 table #55: started
|
||||||
2026/05/12-00:37:07.984143 7ff6637fe6c0 Level-0 table #9: 596 bytes OK
|
2026/06/14-22:52:09.944196 7f29d4feb6c0 Level-0 table #55: 0 bytes OK
|
||||||
2026/05/12-00:37:07.990088 7ff6637fe6c0 Delete type=0 #7
|
2026/06/14-22:52:09.951751 7f29d4feb6c0 Delete type=0 #53
|
||||||
2026/05/12-00:37:08.009661 7ff6637fe6c0 Manual compaction at level-0 from '!items!HKq5ANSGiBIdcnki' @ 72057594037927935 : 1 .. '!items!HKq5ANSGiBIdcnki' @ 0 : 0; will stop at (end)
|
2026/06/14-22:52:09.952015 7f29d4feb6c0 Manual compaction at level-0 from '!items!HKq5ANSGiBIdcnki' @ 72057594037927935 : 1 .. '!items!HKq5ANSGiBIdcnki' @ 0 : 0; will stop at (end)
|
||||||
2026/05/12-00:37:08.030253 7ff6637fe6c0 Manual compaction at level-1 from '!items!HKq5ANSGiBIdcnki' @ 72057594037927935 : 1 .. '!items!HKq5ANSGiBIdcnki' @ 0 : 0; will stop at '!items!HKq5ANSGiBIdcnki' @ 2 : 1
|
|
||||||
2026/05/12-00:37:08.030264 7ff6637fe6c0 Compacting 1@1 + 1@2 files
|
|
||||||
2026/05/12-00:37:08.033436 7ff6637fe6c0 Generated table #10@1: 1 keys, 596 bytes
|
|
||||||
2026/05/12-00:37:08.033469 7ff6637fe6c0 Compacted 1@1 + 1@2 files => 596 bytes
|
|
||||||
2026/05/12-00:37:08.040221 7ff6637fe6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
|
||||||
2026/05/12-00:37:08.040443 7ff6637fe6c0 Delete type=2 #5
|
|
||||||
2026/05/12-00:37:08.040599 7ff6637fe6c0 Delete type=2 #9
|
|
||||||
2026/05/12-00:37:08.051309 7ff6637fe6c0 Manual compaction at level-1 from '!items!HKq5ANSGiBIdcnki' @ 2 : 1 .. '!items!HKq5ANSGiBIdcnki' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
2026/05/12-00:36:37.230762 7fdfd67ee6c0 Delete type=3 #1
|
2026/06/14-22:22:39.702477 7f29d5fed6c0 Recovering log #46
|
||||||
2026/05/12-00:36:37.231622 7fdfd4feb6c0 Level-0 table #5: started
|
2026/06/14-22:22:39.712938 7f29d5fed6c0 Delete type=3 #44
|
||||||
2026/05/12-00:36:37.234740 7fdfd4feb6c0 Level-0 table #5: 559 bytes OK
|
2026/06/14-22:22:39.712993 7f29d5fed6c0 Delete type=0 #46
|
||||||
2026/05/12-00:36:37.240940 7fdfd4feb6c0 Delete type=0 #3
|
2026/06/14-22:32:37.986092 7f29d4feb6c0 Level-0 table #51: started
|
||||||
2026/05/12-00:36:37.241065 7fdfd4feb6c0 Manual compaction at level-0 from '!items!HKq5ANSGiBIdcnki' @ 72057594037927935 : 1 .. '!items!HKq5ANSGiBIdcnki' @ 0 : 0; will stop at (end)
|
2026/06/14-22:32:37.986120 7f29d4feb6c0 Level-0 table #51: 0 bytes OK
|
||||||
|
2026/06/14-22:32:37.994045 7f29d4feb6c0 Delete type=0 #49
|
||||||
|
2026/06/14-22:32:37.994361 7f29d4feb6c0 Manual compaction at level-0 from '!items!HKq5ANSGiBIdcnki' @ 72057594037927935 : 1 .. '!items!HKq5ANSGiBIdcnki' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000006
|
MANIFEST-000052
|
||||||
|
|||||||
+7
-15
@@ -1,15 +1,7 @@
|
|||||||
2026/05/12-00:36:56.263994 7ff663fff6c0 Recovering log #4
|
2026/06/14-22:49:59.045733 7f29d57ec6c0 Recovering log #50
|
||||||
2026/05/12-00:36:56.274398 7ff663fff6c0 Delete type=3 #2
|
2026/06/14-22:49:59.056842 7f29d57ec6c0 Delete type=3 #48
|
||||||
2026/05/12-00:36:56.274458 7ff663fff6c0 Delete type=0 #4
|
2026/06/14-22:49:59.056897 7f29d57ec6c0 Delete type=0 #50
|
||||||
2026/05/12-00:37:07.886611 7ff6637fe6c0 Level-0 table #9: started
|
2026/06/14-22:52:09.896535 7f29d4feb6c0 Level-0 table #55: started
|
||||||
2026/05/12-00:37:07.890996 7ff6637fe6c0 Level-0 table #9: 34454 bytes OK
|
2026/06/14-22:52:09.896595 7f29d4feb6c0 Level-0 table #55: 0 bytes OK
|
||||||
2026/05/12-00:37:07.897482 7ff6637fe6c0 Delete type=0 #7
|
2026/06/14-22:52:09.903914 7f29d4feb6c0 Delete type=0 #53
|
||||||
2026/05/12-00:37:07.928654 7ff6637fe6c0 Manual compaction at level-0 from '!items!2nKXEHLG0fXtSOdy' @ 72057594037927935 : 1 .. '!items!tlIc1bmIAbQeUwj7' @ 0 : 0; will stop at (end)
|
2026/06/14-22:52:09.923752 7f29d4feb6c0 Manual compaction at level-0 from '!items!2nKXEHLG0fXtSOdy' @ 72057594037927935 : 1 .. '!items!tlIc1bmIAbQeUwj7' @ 0 : 0; will stop at (end)
|
||||||
2026/05/12-00:37:07.928707 7ff6637fe6c0 Manual compaction at level-1 from '!items!2nKXEHLG0fXtSOdy' @ 72057594037927935 : 1 .. '!items!tlIc1bmIAbQeUwj7' @ 0 : 0; will stop at '!items!tlIc1bmIAbQeUwj7' @ 40 : 1
|
|
||||||
2026/05/12-00:37:07.928714 7ff6637fe6c0 Compacting 1@1 + 1@2 files
|
|
||||||
2026/05/12-00:37:07.932971 7ff6637fe6c0 Generated table #10@1: 20 keys, 34454 bytes
|
|
||||||
2026/05/12-00:37:07.932984 7ff6637fe6c0 Compacted 1@1 + 1@2 files => 34454 bytes
|
|
||||||
2026/05/12-00:37:07.939008 7ff6637fe6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
|
||||||
2026/05/12-00:37:07.939170 7ff6637fe6c0 Delete type=2 #5
|
|
||||||
2026/05/12-00:37:07.939306 7ff6637fe6c0 Delete type=2 #9
|
|
||||||
2026/05/12-00:37:07.970948 7ff6637fe6c0 Manual compaction at level-1 from '!items!tlIc1bmIAbQeUwj7' @ 40 : 1 .. '!items!tlIc1bmIAbQeUwj7' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
2026/05/12-00:36:37.257477 7fdfd57ec6c0 Delete type=3 #1
|
2026/06/14-22:22:39.603745 7f29d67ee6c0 Recovering log #46
|
||||||
2026/05/12-00:36:37.258479 7fdfd4feb6c0 Level-0 table #5: started
|
2026/06/14-22:22:39.614957 7f29d67ee6c0 Delete type=3 #44
|
||||||
2026/05/12-00:36:37.261916 7fdfd4feb6c0 Level-0 table #5: 32988 bytes OK
|
2026/06/14-22:22:39.615010 7f29d67ee6c0 Delete type=0 #46
|
||||||
2026/05/12-00:36:37.269084 7fdfd4feb6c0 Delete type=0 #3
|
2026/06/14-22:32:37.939036 7f29d4feb6c0 Level-0 table #51: started
|
||||||
2026/05/12-00:36:37.269269 7fdfd4feb6c0 Manual compaction at level-0 from '!items!2nKXEHLG0fXtSOdy' @ 72057594037927935 : 1 .. '!items!tlIc1bmIAbQeUwj7' @ 0 : 0; will stop at (end)
|
2026/06/14-22:32:37.939102 7f29d4feb6c0 Level-0 table #51: 0 bytes OK
|
||||||
|
2026/06/14-22:32:37.945655 7f29d4feb6c0 Delete type=0 #49
|
||||||
|
2026/06/14-22:32:37.965934 7f29d4feb6c0 Manual compaction at level-0 from '!items!2nKXEHLG0fXtSOdy' @ 72057594037927935 : 1 .. '!items!tlIc1bmIAbQeUwj7' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000006
|
MANIFEST-000052
|
||||||
|
|||||||
+7
-15
@@ -1,15 +1,7 @@
|
|||||||
2026/05/12-00:36:56.360962 7ff663fff6c0 Recovering log #4
|
2026/06/14-22:49:59.154286 7f29d5fed6c0 Recovering log #50
|
||||||
2026/05/12-00:36:56.371878 7ff663fff6c0 Delete type=3 #2
|
2026/06/14-22:49:59.165791 7f29d5fed6c0 Delete type=3 #48
|
||||||
2026/05/12-00:36:56.371942 7ff663fff6c0 Delete type=0 #4
|
2026/06/14-22:49:59.165837 7f29d5fed6c0 Delete type=0 #50
|
||||||
2026/05/12-00:37:08.051413 7ff6637fe6c0 Level-0 table #9: started
|
2026/06/14-22:52:09.952102 7f29d4feb6c0 Level-0 table #55: started
|
||||||
2026/05/12-00:37:08.055337 7ff6637fe6c0 Level-0 table #9: 50053 bytes OK
|
2026/06/14-22:52:09.952142 7f29d4feb6c0 Level-0 table #55: 0 bytes OK
|
||||||
2026/05/12-00:37:08.062742 7ff6637fe6c0 Delete type=0 #7
|
2026/06/14-22:52:09.958682 7f29d4feb6c0 Delete type=0 #53
|
||||||
2026/05/12-00:37:08.086408 7ff6637fe6c0 Manual compaction at level-0 from '!actors!4ZjFZ1HoJV9mJStt' @ 72057594037927935 : 1 .. '!actors!zVpmacwoWEG8YTCQ' @ 0 : 0; will stop at (end)
|
2026/06/14-22:52:09.978831 7f29d4feb6c0 Manual compaction at level-0 from '!actors!4ZjFZ1HoJV9mJStt' @ 72057594037927935 : 1 .. '!actors!zVpmacwoWEG8YTCQ' @ 0 : 0; will stop at (end)
|
||||||
2026/05/12-00:37:08.086444 7ff6637fe6c0 Manual compaction at level-1 from '!actors!4ZjFZ1HoJV9mJStt' @ 72057594037927935 : 1 .. '!actors!zVpmacwoWEG8YTCQ' @ 0 : 0; will stop at '!actors!zVpmacwoWEG8YTCQ' @ 98 : 1
|
|
||||||
2026/05/12-00:37:08.086448 7ff6637fe6c0 Compacting 1@1 + 1@2 files
|
|
||||||
2026/05/12-00:37:08.090154 7ff6637fe6c0 Generated table #10@1: 49 keys, 50053 bytes
|
|
||||||
2026/05/12-00:37:08.090193 7ff6637fe6c0 Compacted 1@1 + 1@2 files => 50053 bytes
|
|
||||||
2026/05/12-00:37:08.096495 7ff6637fe6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
|
||||||
2026/05/12-00:37:08.096568 7ff6637fe6c0 Delete type=2 #5
|
|
||||||
2026/05/12-00:37:08.096695 7ff6637fe6c0 Delete type=2 #9
|
|
||||||
2026/05/12-00:37:08.113181 7ff6637fe6c0 Manual compaction at level-1 from '!actors!zVpmacwoWEG8YTCQ' @ 98 : 1 .. '!actors!zVpmacwoWEG8YTCQ' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
2026/05/12-00:36:37.286062 7fdfd5fed6c0 Delete type=3 #1
|
2026/06/14-22:22:39.716564 7f29d6fef6c0 Recovering log #46
|
||||||
2026/05/12-00:36:37.287117 7fdfd4feb6c0 Level-0 table #5: started
|
2026/06/14-22:22:39.726981 7f29d6fef6c0 Delete type=3 #44
|
||||||
2026/05/12-00:36:37.291305 7fdfd4feb6c0 Level-0 table #5: 21686 bytes OK
|
2026/06/14-22:22:39.727264 7f29d6fef6c0 Delete type=0 #46
|
||||||
2026/05/12-00:36:37.297295 7fdfd4feb6c0 Delete type=0 #3
|
2026/06/14-22:32:37.994382 7f29d4feb6c0 Level-0 table #51: started
|
||||||
2026/05/12-00:36:37.297424 7fdfd4feb6c0 Manual compaction at level-0 from '!actors!4ZjFZ1HoJV9mJStt' @ 72057594037927935 : 1 .. '!actors!zVpmacwoWEG8YTCQ' @ 0 : 0; will stop at (end)
|
2026/06/14-22:32:37.994411 7f29d4feb6c0 Level-0 table #51: 0 bytes OK
|
||||||
|
2026/06/14-22:32:38.000939 7f29d4feb6c0 Delete type=0 #49
|
||||||
|
2026/06/14-22:32:38.022274 7f29d4feb6c0 Manual compaction at level-0 from '!actors!4ZjFZ1HoJV9mJStt' @ 72057594037927935 : 1 .. '!actors!zVpmacwoWEG8YTCQ' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
MANIFEST-000030
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
2026/06/14-22:49:59.169462 7f29d5fed6c0 Recovering log #28
|
||||||
|
2026/06/14-22:49:59.179433 7f29d5fed6c0 Delete type=3 #26
|
||||||
|
2026/06/14-22:49:59.179471 7f29d5fed6c0 Delete type=0 #28
|
||||||
|
2026/06/14-22:52:09.985789 7f29d4feb6c0 Level-0 table #33: started
|
||||||
|
2026/06/14-22:52:09.985816 7f29d4feb6c0 Level-0 table #33: 0 bytes OK
|
||||||
|
2026/06/14-22:52:09.992966 7f29d4feb6c0 Delete type=0 #31
|
||||||
|
2026/06/14-22:52:10.010894 7f29d4feb6c0 Manual compaction at level-0 from '!actors!5OGW1fRUn12aNMMV' @ 72057594037927935 : 1 .. '!actors.items!zSWwOmFiFjN4YxC9.w8LXSYQ1eIygtlKV' @ 0 : 0; will stop at (end)
|
||||||
|
2026/06/14-22:52:10.011012 7f29d4feb6c0 Manual compaction at level-1 from '!actors!5OGW1fRUn12aNMMV' @ 72057594037927935 : 1 .. '!actors.items!zSWwOmFiFjN4YxC9.w8LXSYQ1eIygtlKV' @ 0 : 0; will stop at (end)
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
2026/06/14-22:22:39.731841 7f29d6fef6c0 Recovering log #24
|
||||||
|
2026/06/14-22:22:39.741957 7f29d6fef6c0 Delete type=3 #22
|
||||||
|
2026/06/14-22:22:39.742028 7f29d6fef6c0 Delete type=0 #24
|
||||||
|
2026/06/14-22:32:38.007843 7f29d4feb6c0 Level-0 table #29: started
|
||||||
|
2026/06/14-22:32:38.007886 7f29d4feb6c0 Level-0 table #29: 0 bytes OK
|
||||||
|
2026/06/14-22:32:38.014714 7f29d4feb6c0 Delete type=0 #27
|
||||||
|
2026/06/14-22:32:38.022308 7f29d4feb6c0 Manual compaction at level-0 from '!actors!5OGW1fRUn12aNMMV' @ 72057594037927935 : 1 .. '!actors.items!zSWwOmFiFjN4YxC9.w8LXSYQ1eIygtlKV' @ 0 : 0; will stop at (end)
|
||||||
|
2026/06/14-22:32:38.022452 7f29d4feb6c0 Manual compaction at level-1 from '!actors!5OGW1fRUn12aNMMV' @ 72057594037927935 : 1 .. '!actors.items!zSWwOmFiFjN4YxC9.w8LXSYQ1eIygtlKV' @ 0 : 0; will stop at (end)
|
||||||
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000006
|
MANIFEST-000052
|
||||||
|
|||||||
+7
-15
@@ -1,15 +1,7 @@
|
|||||||
2026/05/12-00:36:56.324955 7ff6717ee6c0 Recovering log #4
|
2026/06/14-22:49:59.113546 7f29d67ee6c0 Recovering log #50
|
||||||
2026/05/12-00:36:56.335151 7ff6717ee6c0 Delete type=3 #2
|
2026/06/14-22:49:59.125289 7f29d67ee6c0 Delete type=3 #48
|
||||||
2026/05/12-00:36:56.335204 7ff6717ee6c0 Delete type=0 #4
|
2026/06/14-22:49:59.125333 7f29d67ee6c0 Delete type=0 #50
|
||||||
2026/05/12-00:37:08.000036 7ff6637fe6c0 Level-0 table #9: started
|
2026/06/14-22:52:09.930699 7f29d4feb6c0 Level-0 table #55: started
|
||||||
2026/05/12-00:37:08.003325 7ff6637fe6c0 Level-0 table #9: 4934 bytes OK
|
2026/06/14-22:52:09.930727 7f29d4feb6c0 Level-0 table #55: 0 bytes OK
|
||||||
2026/05/12-00:37:08.009477 7ff6637fe6c0 Delete type=0 #7
|
2026/06/14-22:52:09.937112 7f29d4feb6c0 Delete type=0 #53
|
||||||
2026/05/12-00:37:08.009687 7ff6637fe6c0 Manual compaction at level-0 from '!items!DC2kimCi9sWxqhXG' @ 72057594037927935 : 1 .. '!items!qzfAEhmvVxEMzm0k' @ 0 : 0; will stop at (end)
|
2026/06/14-22:52:09.951899 7f29d4feb6c0 Manual compaction at level-0 from '!items!DC2kimCi9sWxqhXG' @ 72057594037927935 : 1 .. '!items!qzfAEhmvVxEMzm0k' @ 0 : 0; will stop at (end)
|
||||||
2026/05/12-00:37:08.040730 7ff6637fe6c0 Manual compaction at level-1 from '!items!DC2kimCi9sWxqhXG' @ 72057594037927935 : 1 .. '!items!qzfAEhmvVxEMzm0k' @ 0 : 0; will stop at '!items!qzfAEhmvVxEMzm0k' @ 10 : 1
|
|
||||||
2026/05/12-00:37:08.040743 7ff6637fe6c0 Compacting 1@1 + 1@2 files
|
|
||||||
2026/05/12-00:37:08.044737 7ff6637fe6c0 Generated table #10@1: 5 keys, 4934 bytes
|
|
||||||
2026/05/12-00:37:08.044781 7ff6637fe6c0 Compacted 1@1 + 1@2 files => 4934 bytes
|
|
||||||
2026/05/12-00:37:08.050905 7ff6637fe6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
|
||||||
2026/05/12-00:37:08.051035 7ff6637fe6c0 Delete type=2 #5
|
|
||||||
2026/05/12-00:37:08.051186 7ff6637fe6c0 Delete type=2 #9
|
|
||||||
2026/05/12-00:37:08.051322 7ff6637fe6c0 Manual compaction at level-1 from '!items!qzfAEhmvVxEMzm0k' @ 10 : 1 .. '!items!qzfAEhmvVxEMzm0k' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
2026/05/12-00:36:37.311794 7fdfd6fef6c0 Delete type=3 #1
|
2026/06/14-22:22:39.674682 7f29d5fed6c0 Recovering log #46
|
||||||
2026/05/12-00:36:37.312497 7fdfd4feb6c0 Level-0 table #5: started
|
2026/06/14-22:22:39.685769 7f29d5fed6c0 Delete type=3 #44
|
||||||
2026/05/12-00:36:37.315659 7fdfd4feb6c0 Level-0 table #5: 4830 bytes OK
|
2026/06/14-22:22:39.685821 7f29d5fed6c0 Delete type=0 #46
|
||||||
2026/05/12-00:36:37.322060 7fdfd4feb6c0 Delete type=0 #3
|
2026/06/14-22:32:37.972754 7f29d4feb6c0 Level-0 table #51: started
|
||||||
2026/05/12-00:36:37.322200 7fdfd4feb6c0 Manual compaction at level-0 from '!items!DC2kimCi9sWxqhXG' @ 72057594037927935 : 1 .. '!items!qzfAEhmvVxEMzm0k' @ 0 : 0; will stop at (end)
|
2026/06/14-22:32:37.972783 7f29d4feb6c0 Level-0 table #51: 0 bytes OK
|
||||||
|
2026/06/14-22:32:37.979353 7f29d4feb6c0 Delete type=0 #49
|
||||||
|
2026/06/14-22:32:37.994176 7f29d4feb6c0 Manual compaction at level-0 from '!items!DC2kimCi9sWxqhXG' @ 72057594037927935 : 1 .. '!items!qzfAEhmvVxEMzm0k' @ 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-000022
|
MANIFEST-000072
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
2026/05/12-00:36:56.386114 7ff670fed6c0 Recovering log #20
|
2026/06/14-22:49:59.198719 7f29d57ec6c0 Recovering log #69
|
||||||
2026/05/12-00:36:56.396758 7ff670fed6c0 Delete type=3 #18
|
2026/06/14-22:49:59.210387 7f29d57ec6c0 Delete type=3 #67
|
||||||
2026/05/12-00:36:56.396824 7ff670fed6c0 Delete type=0 #20
|
2026/06/14-22:49:59.210425 7f29d57ec6c0 Delete type=0 #69
|
||||||
2026/05/12-00:37:08.080126 7ff6637fe6c0 Level-0 table #25: started
|
2026/06/14-22:52:09.958777 7f29d4feb6c0 Level-0 table #75: started
|
||||||
2026/05/12-00:37:08.080172 7ff6637fe6c0 Level-0 table #25: 0 bytes OK
|
2026/06/14-22:52:09.958803 7f29d4feb6c0 Level-0 table #75: 0 bytes OK
|
||||||
2026/05/12-00:37:08.086288 7ff6637fe6c0 Delete type=0 #23
|
2026/06/14-22:52:09.965059 7f29d4feb6c0 Delete type=0 #73
|
||||||
2026/05/12-00:37:08.096790 7ff6637fe6c0 Manual compaction at level-0 from '!scenes!2C6gyZpvPxWlsVZi' @ 72057594037927935 : 1 .. '!scenes.levels!olYe9bhuXwRWQ8j7.defaultLevel0000' @ 0 : 0; will stop at (end)
|
2026/06/14-22:52:09.978852 7f29d4feb6c0 Manual compaction at level-0 from '!scenes!2C6gyZpvPxWlsVZi' @ 72057594037927935 : 1 .. '!scenes.levels!olYe9bhuXwRWQ8j7.defaultLevel0000' @ 0 : 0; will stop at (end)
|
||||||
2026/05/12-00:37:08.113200 7ff6637fe6c0 Manual compaction at level-1 from '!scenes!2C6gyZpvPxWlsVZi' @ 72057594037927935 : 1 .. '!scenes.levels!olYe9bhuXwRWQ8j7.defaultLevel0000' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
2026/05/12-00:34:51.728359 7ff671fef6c0 Recovering log #16
|
2026/06/14-22:22:39.763440 7f29d67ee6c0 Recovering log #65
|
||||||
2026/05/12-00:34:51.737993 7ff671fef6c0 Delete type=3 #14
|
2026/06/14-22:22:39.773982 7f29d67ee6c0 Delete type=3 #63
|
||||||
2026/05/12-00:34:51.738056 7ff671fef6c0 Delete type=0 #16
|
2026/06/14-22:22:39.774029 7f29d67ee6c0 Delete type=0 #65
|
||||||
2026/05/12-00:35:02.012940 7ff6637fe6c0 Level-0 table #21: started
|
2026/06/14-22:32:38.029088 7f29d4feb6c0 Level-0 table #70: started
|
||||||
2026/05/12-00:35:02.012962 7ff6637fe6c0 Level-0 table #21: 0 bytes OK
|
2026/06/14-22:32:38.032823 7f29d4feb6c0 Level-0 table #70: 3169 bytes OK
|
||||||
2026/05/12-00:35:02.019210 7ff6637fe6c0 Delete type=0 #19
|
2026/06/14-22:32:38.039619 7f29d4feb6c0 Delete type=0 #68
|
||||||
2026/05/12-00:35:02.033237 7ff6637fe6c0 Manual compaction at level-0 from '!scenes!2C6gyZpvPxWlsVZi' @ 72057594037927935 : 1 .. '!scenes.levels!olYe9bhuXwRWQ8j7.defaultLevel0000' @ 0 : 0; will stop at (end)
|
2026/06/14-22:32:38.054502 7f29d4feb6c0 Manual compaction at level-0 from '!scenes!2C6gyZpvPxWlsVZi' @ 72057594037927935 : 1 .. '!scenes.levels!olYe9bhuXwRWQ8j7.defaultLevel0000' @ 0 : 0; will stop at '!scenes.levels!olYe9bhuXwRWQ8j7.defaultLevel0000' @ 29 : 1
|
||||||
2026/05/12-00:35:02.033284 7ff6637fe6c0 Manual compaction at level-1 from '!scenes!2C6gyZpvPxWlsVZi' @ 72057594037927935 : 1 .. '!scenes.levels!olYe9bhuXwRWQ8j7.defaultLevel0000' @ 0 : 0; will stop at (end)
|
2026/06/14-22:32:38.054509 7f29d4feb6c0 Compacting 1@0 + 1@1 files
|
||||||
|
2026/06/14-22:32:38.058254 7f29d4feb6c0 Generated table #71@0: 8 keys, 3169 bytes
|
||||||
|
2026/06/14-22:32:38.058277 7f29d4feb6c0 Compacted 1@0 + 1@1 files => 3169 bytes
|
||||||
|
2026/06/14-22:32:38.064919 7f29d4feb6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
|
||||||
|
2026/06/14-22:32:38.065170 7f29d4feb6c0 Delete type=2 #46
|
||||||
|
2026/06/14-22:32:38.065328 7f29d4feb6c0 Delete type=2 #70
|
||||||
|
2026/06/14-22:32:38.072993 7f29d4feb6c0 Manual compaction at level-0 from '!scenes.levels!olYe9bhuXwRWQ8j7.defaultLevel0000' @ 29 : 1 .. '!scenes.levels!olYe9bhuXwRWQ8j7.defaultLevel0000' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000006
|
MANIFEST-000052
|
||||||
|
|||||||
+7
-15
@@ -1,15 +1,7 @@
|
|||||||
2026/05/12-00:36:56.276952 7ff6717ee6c0 Recovering log #4
|
2026/06/14-22:49:59.060460 7f29d5fed6c0 Recovering log #50
|
||||||
2026/05/12-00:36:56.286901 7ff6717ee6c0 Delete type=3 #2
|
2026/06/14-22:49:59.070829 7f29d5fed6c0 Delete type=3 #48
|
||||||
2026/05/12-00:36:56.286957 7ff6717ee6c0 Delete type=0 #4
|
2026/06/14-22:49:59.070872 7f29d5fed6c0 Delete type=0 #50
|
||||||
2026/05/12-00:37:07.897667 7ff6637fe6c0 Level-0 table #9: started
|
2026/06/14-22:52:09.904026 7f29d4feb6c0 Level-0 table #55: started
|
||||||
2026/05/12-00:37:07.902498 7ff6637fe6c0 Level-0 table #9: 124022 bytes OK
|
2026/06/14-22:52:09.904053 7f29d4feb6c0 Level-0 table #55: 0 bytes OK
|
||||||
2026/05/12-00:37:07.909088 7ff6637fe6c0 Delete type=0 #7
|
2026/06/14-22:52:09.910627 7f29d4feb6c0 Delete type=0 #53
|
||||||
2026/05/12-00:37:07.928672 7ff6637fe6c0 Manual compaction at level-0 from '!items!2f51pcvFkcZjaxDk' @ 72057594037927935 : 1 .. '!items!yVN7PZw35iIaBl0H' @ 0 : 0; will stop at (end)
|
2026/06/14-22:52:09.923769 7f29d4feb6c0 Manual compaction at level-0 from '!items!2f51pcvFkcZjaxDk' @ 72057594037927935 : 1 .. '!items!yVN7PZw35iIaBl0H' @ 0 : 0; will stop at (end)
|
||||||
2026/05/12-00:37:07.949109 7ff6637fe6c0 Manual compaction at level-1 from '!items!2f51pcvFkcZjaxDk' @ 72057594037927935 : 1 .. '!items!yVN7PZw35iIaBl0H' @ 0 : 0; will stop at '!items!yVN7PZw35iIaBl0H' @ 50 : 1
|
|
||||||
2026/05/12-00:37:07.949120 7ff6637fe6c0 Compacting 1@1 + 1@2 files
|
|
||||||
2026/05/12-00:37:07.954259 7ff6637fe6c0 Generated table #10@1: 25 keys, 124022 bytes
|
|
||||||
2026/05/12-00:37:07.954276 7ff6637fe6c0 Compacted 1@1 + 1@2 files => 124022 bytes
|
|
||||||
2026/05/12-00:37:07.961206 7ff6637fe6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
|
||||||
2026/05/12-00:37:07.961331 7ff6637fe6c0 Delete type=2 #5
|
|
||||||
2026/05/12-00:37:07.961477 7ff6637fe6c0 Delete type=2 #9
|
|
||||||
2026/05/12-00:37:07.970977 7ff6637fe6c0 Manual compaction at level-1 from '!items!yVN7PZw35iIaBl0H' @ 50 : 1 .. '!items!yVN7PZw35iIaBl0H' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
2026/05/12-00:36:37.338931 7fdfd67ee6c0 Delete type=3 #1
|
2026/06/14-22:22:39.618536 7f29d57ec6c0 Recovering log #46
|
||||||
2026/05/12-00:36:37.341086 7fdfd4feb6c0 Level-0 table #5: started
|
2026/06/14-22:22:39.628785 7f29d57ec6c0 Delete type=3 #44
|
||||||
2026/05/12-00:36:37.345847 7fdfd4feb6c0 Level-0 table #5: 120353 bytes OK
|
2026/06/14-22:22:39.628834 7f29d57ec6c0 Delete type=0 #46
|
||||||
2026/05/12-00:36:37.352605 7fdfd4feb6c0 Delete type=0 #3
|
2026/06/14-22:32:37.966108 7f29d4feb6c0 Level-0 table #51: started
|
||||||
2026/05/12-00:36:37.352812 7fdfd4feb6c0 Manual compaction at level-0 from '!items!2f51pcvFkcZjaxDk' @ 72057594037927935 : 1 .. '!items!yVN7PZw35iIaBl0H' @ 0 : 0; will stop at (end)
|
2026/06/14-22:32:37.966141 7f29d4feb6c0 Level-0 table #51: 0 bytes OK
|
||||||
|
2026/06/14-22:32:37.972646 7f29d4feb6c0 Delete type=0 #49
|
||||||
|
2026/06/14-22:32:37.994161 7f29d4feb6c0 Manual compaction at level-0 from '!items!2f51pcvFkcZjaxDk' @ 72057594037927935 : 1 .. '!items!yVN7PZw35iIaBl0H' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000006
|
MANIFEST-000052
|
||||||
|
|||||||
@@ -1,15 +1,7 @@
|
|||||||
2026/05/12-00:36:56.290045 7ff671fef6c0 Recovering log #4
|
2026/06/14-22:49:59.074203 7f29d57ec6c0 Recovering log #50
|
||||||
2026/05/12-00:36:56.299803 7ff671fef6c0 Delete type=3 #2
|
2026/06/14-22:49:59.085196 7f29d57ec6c0 Delete type=3 #48
|
||||||
2026/05/12-00:36:56.299870 7ff671fef6c0 Delete type=0 #4
|
2026/06/14-22:49:59.085240 7f29d57ec6c0 Delete type=0 #50
|
||||||
2026/05/12-00:37:07.909338 7ff6637fe6c0 Level-0 table #9: started
|
2026/06/14-22:52:09.923913 7f29d4feb6c0 Level-0 table #55: started
|
||||||
2026/05/12-00:37:07.913145 7ff6637fe6c0 Level-0 table #9: 8790 bytes OK
|
2026/06/14-22:52:09.923940 7f29d4feb6c0 Level-0 table #55: 0 bytes OK
|
||||||
2026/05/12-00:37:07.919132 7ff6637fe6c0 Delete type=0 #7
|
2026/06/14-22:52:09.930579 7f29d4feb6c0 Delete type=0 #53
|
||||||
2026/05/12-00:37:07.928684 7ff6637fe6c0 Manual compaction at level-0 from '!items!APN91pQL0NBfZsG7' @ 72057594037927935 : 1 .. '!items!xxZKGqDVxAfr140W' @ 0 : 0; will stop at (end)
|
2026/06/14-22:52:09.951882 7f29d4feb6c0 Manual compaction at level-0 from '!items!APN91pQL0NBfZsG7' @ 72057594037927935 : 1 .. '!items!xxZKGqDVxAfr140W' @ 0 : 0; will stop at (end)
|
||||||
2026/05/12-00:37:07.961574 7ff6637fe6c0 Manual compaction at level-1 from '!items!APN91pQL0NBfZsG7' @ 72057594037927935 : 1 .. '!items!xxZKGqDVxAfr140W' @ 0 : 0; will stop at '!items!xxZKGqDVxAfr140W' @ 32 : 1
|
|
||||||
2026/05/12-00:37:07.961583 7ff6637fe6c0 Compacting 1@1 + 1@2 files
|
|
||||||
2026/05/12-00:37:07.964786 7ff6637fe6c0 Generated table #10@1: 16 keys, 8790 bytes
|
|
||||||
2026/05/12-00:37:07.964814 7ff6637fe6c0 Compacted 1@1 + 1@2 files => 8790 bytes
|
|
||||||
2026/05/12-00:37:07.970646 7ff6637fe6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
|
|
||||||
2026/05/12-00:37:07.970759 7ff6637fe6c0 Delete type=2 #5
|
|
||||||
2026/05/12-00:37:07.970874 7ff6637fe6c0 Delete type=2 #9
|
|
||||||
2026/05/12-00:37:07.970988 7ff6637fe6c0 Manual compaction at level-1 from '!items!xxZKGqDVxAfr140W' @ 32 : 1 .. '!items!xxZKGqDVxAfr140W' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
2026/05/12-00:36:37.372690 7fdfd57ec6c0 Delete type=3 #1
|
2026/06/14-22:22:39.633149 7f29d6fef6c0 Recovering log #46
|
||||||
2026/05/12-00:36:37.373512 7fdfd4feb6c0 Level-0 table #5: started
|
2026/06/14-22:22:39.644445 7f29d6fef6c0 Delete type=3 #44
|
||||||
2026/05/12-00:36:37.376679 7fdfd4feb6c0 Level-0 table #5: 8622 bytes OK
|
2026/06/14-22:22:39.644504 7f29d6fef6c0 Delete type=0 #46
|
||||||
2026/05/12-00:36:37.382725 7fdfd4feb6c0 Delete type=0 #3
|
2026/06/14-22:32:37.945805 7f29d4feb6c0 Level-0 table #51: started
|
||||||
2026/05/12-00:36:37.382856 7fdfd4feb6c0 Manual compaction at level-0 from '!items!APN91pQL0NBfZsG7' @ 72057594037927935 : 1 .. '!items!xxZKGqDVxAfr140W' @ 0 : 0; will stop at (end)
|
2026/06/14-22:32:37.945837 7f29d4feb6c0 Level-0 table #51: 0 bytes OK
|
||||||
|
2026/06/14-22:32:37.952016 7f29d4feb6c0 Delete type=0 #49
|
||||||
|
2026/06/14-22:32:37.965952 7f29d4feb6c0 Manual compaction at level-0 from '!items!APN91pQL0NBfZsG7' @ 72057594037927935 : 1 .. '!items!xxZKGqDVxAfr140W' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000006
|
MANIFEST-000052
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user