Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
215a8a1a45 | ||
|
|
1b24d0223a | ||
|
|
33d4c26619 | ||
|
|
cc81acce5b | ||
|
|
c56903c8e4 | ||
|
|
d27d580d8c | ||
|
|
967383f5b3 | ||
|
|
e4cc556705 | ||
|
|
405bcd7cf5 | ||
|
|
846e6f88b7 | ||
|
|
1a0f4cd3e9 |
@@ -59,5 +59,5 @@ jobs:
|
|||||||
version: ${{github.event.release.tag_name}}
|
version: ${{github.event.release.tag_name}}
|
||||||
manifest: "https://www.uberwald.me/gitea/public/bol/releases/download/latest/system.json"
|
manifest: "https://www.uberwald.me/gitea/public/bol/releases/download/latest/system.json"
|
||||||
notes: "https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/bol.zip"
|
notes: "https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/bol.zip"
|
||||||
compatibility-minimum: "13"
|
compatibility-minimum: "14"
|
||||||
compatibility-verified: "14"
|
compatibility-verified: "14"
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# BoL — FoundryVTT Game System
|
||||||
|
|
||||||
|
FoundryVTT game system for Barbarians of Lemuria (French edition, Ludospherik). System id `bol`. Compatible Foundry v13–v14.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
| Command | Action |
|
||||||
|
|---------|--------|
|
||||||
|
| `npm run css` | Compile LESS → `css/bol.css` (one-shot) |
|
||||||
|
| `npm run watch` / `npm start` | Watch `styles/**/*.less`, recompile on change |
|
||||||
|
|
||||||
|
No test or lint scripts exist.
|
||||||
|
|
||||||
|
## Entry Point & Architecture
|
||||||
|
|
||||||
|
`module/bol.js` — wires everything in `Hooks.once('init', ...)` and `Hooks.once('ready', ...)`.
|
||||||
|
|
||||||
|
| Path | Role |
|
||||||
|
|------|------|
|
||||||
|
| `module/bol.js` | System init, sheet/data model registration, socket setup |
|
||||||
|
| `module/system/config.js` | `BOL` constants, `System.debugMode` flag |
|
||||||
|
| `module/system/bol-utility.js` | Static helpers, settings (`bol` namespace), socket handler (`system.bol`) |
|
||||||
|
| `module/controllers/bol-rolls.js` | All roll logic — `BoLRoll` static methods |
|
||||||
|
| `module/models/` | DataModel classes (`.mjs`) for Actor/Item types |
|
||||||
|
| `module/applications/sheets/` | **AppV2 sheets** (`ActorSheetV2`/`ItemSheetV2` + `HandlebarsApplicationMixin`) |
|
||||||
|
| `styles/` | LESS sources → compiled to `css/bol.css` |
|
||||||
|
| `templates/` | Handlebars `.hbs` partials |
|
||||||
|
| `lang/` | `fr.json`, `en.json`, `de.json`, `es.json` |
|
||||||
|
|
||||||
|
## Key Conventions
|
||||||
|
|
||||||
|
- **AppV2 sheets** — base classes are `foundry.applications.sheets.ActorSheetV2` / `ItemSheetV2` mixed with `HandlebarsApplicationMixin`. Do NOT use `foundry.appv1.sheets.*`.
|
||||||
|
- **`game.bol`** — system exposes `BoLActor`, `BoLItem`, `BoLRoll`, `BoLUtility`, `Macros`, `BOL` config, `models`, `sheets` on this namespace after init.
|
||||||
|
- **i18n prefix** — all keys start with `BOL.`; use `game.i18n.localize("BOL.xxx")`.
|
||||||
|
- **FR-first** — `fr.json` is most complete. EN compendium translation requires [Babele](https://gitlab.com/riccisi/foundryvtt-babele) module. A warning fires at startup if EN is selected without Babele.
|
||||||
|
- **`System.debugMode = true`** in `module/system/config.js:8` — set to `false` before release.
|
||||||
|
- **LESS only** — never edit `css/bol.css` directly. Edit `.less` files under `styles/`, recompile with `npm run css`.
|
||||||
|
- **Data models** — `template.json` defines schema via `Actor.types` (character, encounter, horde, vehicle) and `Item.types` (item, feature). All data lives under `.system`.
|
||||||
|
- **Sheet partials** — registered in `module/system/templates.js`. Add new partials there.
|
||||||
|
- **Static classes** — `BoLRoll` and `BoLUtility` are purely static; never instantiate.
|
||||||
|
- **`template.json.SAVED`** in root is the data model reference; the actual `template.json` may need regeneration.
|
||||||
|
- **`package.json` and lockfile are in `.gitignore`** — npm is dev-only for LESS compilation. Not needed to run the system in Foundry.
|
||||||
|
- **`{{formInput}}` for HTML fields** — always use `{{formInput fieldDef enriched=x value=y name="system.path" toggled=isEditable}}` for `HTMLField` in AppV2 sheets. Never use raw `<prose-mirror>` elements; they break form submission.
|
||||||
|
- **Tab switching** — use CSS-only toggle (no `this.render()`) to preserve ProseMirror editor state. See `base-item-sheet.mjs` pattern.
|
||||||
|
|
||||||
|
## CI & Release
|
||||||
|
|
||||||
|
- CI triggers **only on release publish** (`.gitea/workflows/main.yml`).
|
||||||
|
- Release zips: `system.json template.json README.md LICENSE assets/ compendiums/ css/ fonts/ images/ lang/ module/ packs/ styles/ templates/ ui/`.
|
||||||
|
- Version/URL manifest/download are substituted in `system.json` during CI.
|
||||||
|
- Published to Foundry package registry via `foundryvtt-publish-package-action`.
|
||||||
@@ -1,286 +0,0 @@
|
|||||||
# Migration AppV2 - Item Sheets
|
|
||||||
|
|
||||||
## Vue d'ensemble
|
|
||||||
|
|
||||||
Migration des feuilles d'items de BoL vers l'architecture **ApplicationV2** de Foundry VTT v12+.
|
|
||||||
|
|
||||||
## Fichiers créés
|
|
||||||
|
|
||||||
### Classes AppV2 (module/applications/sheets/)
|
|
||||||
|
|
||||||
1. **base-item-sheet.mjs** - Classe de base pour tous les item sheets
|
|
||||||
- Hérite de `foundry.applications.sheets.ItemSheetV2`
|
|
||||||
- Utilise `HandlebarsApplicationMixin`
|
|
||||||
- Gère les tabs, drag & drop, actions communes
|
|
||||||
- 272 lignes de code
|
|
||||||
|
|
||||||
2. **item-sheet.mjs** - Sheet pour le type "item"
|
|
||||||
- Équipements, armes, protections, sorts, etc.
|
|
||||||
- Hérite de `BoLBaseItemSheet`
|
|
||||||
- Contexte spécifique aux items
|
|
||||||
|
|
||||||
3. **feature-sheet.mjs** - Sheet pour le type "feature"
|
|
||||||
- Boons, flaws, careers, origins, races, etc.
|
|
||||||
- Hérite de `BoLBaseItemSheet`
|
|
||||||
- Contexte spécifique aux features
|
|
||||||
|
|
||||||
4. **_module.mjs** - Export des sheets
|
|
||||||
|
|
||||||
### Templates (templates/item/)
|
|
||||||
|
|
||||||
1. **item-sheet.hbs** - Template pour les items
|
|
||||||
2. **feature-sheet.hbs** - Template pour les features
|
|
||||||
3. **parts/item-header.hbs** - Header mis à jour pour AppV2
|
|
||||||
|
|
||||||
### Backups
|
|
||||||
|
|
||||||
- `templates/item.backup/` - Backup des templates originaux
|
|
||||||
- `module/item.backup/` - Backup de l'ancienne classe ItemSheet
|
|
||||||
- `templates/item/parts/item-header.hbs.backup` - Backup du header
|
|
||||||
|
|
||||||
## Architecture AppV2
|
|
||||||
|
|
||||||
### Différences avec AppV1
|
|
||||||
|
|
||||||
| Aspect | AppV1 (avant) | AppV2 (après) |
|
|
||||||
|--------|---------------|---------------|
|
|
||||||
| Classe de base | `ItemSheet` | `ItemSheetV2` |
|
|
||||||
| Options | `static get defaultOptions()` | `static DEFAULT_OPTIONS` |
|
|
||||||
| getData | `async getData()` | `async _prepareContext()` |
|
|
||||||
| Template | Unique | Peut utiliser PARTS |
|
|
||||||
| Tabs | Automatiques | Gestion manuelle |
|
|
||||||
| Actions | Event listeners | `actions:` dans OPTIONS |
|
|
||||||
| Render | `activateListeners()` | `_onRender()` |
|
|
||||||
|
|
||||||
### Structure de BoLBaseItemSheet
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
class BoLBaseItemSheet extends ItemSheetV2 {
|
|
||||||
// Options statiques
|
|
||||||
static DEFAULT_OPTIONS = {
|
|
||||||
classes, position, form, window,
|
|
||||||
actions, dragDrop, tabs
|
|
||||||
}
|
|
||||||
|
|
||||||
// State
|
|
||||||
tabGroups = { primary: "description" }
|
|
||||||
|
|
||||||
// Méthodes principales
|
|
||||||
async _prepareContext() // Prépare les données
|
|
||||||
_onRender() // Après le render
|
|
||||||
_activateTabs() // Active les tabs
|
|
||||||
_activateListeners() // Event listeners
|
|
||||||
|
|
||||||
// Actions
|
|
||||||
static #onEditImage() // data-action="editImage"
|
|
||||||
static #onPostItem() // data-action="postItem"
|
|
||||||
|
|
||||||
// Drag & Drop
|
|
||||||
#createDragDropHandlers()
|
|
||||||
_canDragStart()
|
|
||||||
_onDragStart()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Fonctionnalités migrées
|
|
||||||
|
|
||||||
### ✅ Depuis l'ancien BoLItemSheet
|
|
||||||
|
|
||||||
1. **getData** → **_prepareContext**
|
|
||||||
- Enrichissement de la description
|
|
||||||
- Configuration des données dynamiques
|
|
||||||
- Gestion des catégories
|
|
||||||
- Propriétés des items
|
|
||||||
- Careers depuis l'actor
|
|
||||||
|
|
||||||
2. **Tabs**
|
|
||||||
- Navigation entre Description et Properties
|
|
||||||
- State persistant avec `tabGroups`
|
|
||||||
- Activation manuelle des tabs
|
|
||||||
|
|
||||||
3. **Actions**
|
|
||||||
- Edit Image (FilePicker)
|
|
||||||
- Post Item (chat)
|
|
||||||
|
|
||||||
4. **Listeners spécifiques**
|
|
||||||
- Armor quality → soak formula
|
|
||||||
|
|
||||||
5. **Dynamic defaults**
|
|
||||||
- Category par défaut
|
|
||||||
- Spell conditions (mandatory/optional)
|
|
||||||
- Equipment slots
|
|
||||||
|
|
||||||
## Utilisation dans les templates
|
|
||||||
|
|
||||||
### Actions (data-action)
|
|
||||||
|
|
||||||
```handlebars
|
|
||||||
{{!-- Éditer l'image --}}
|
|
||||||
<img data-action="editImage" src="{{item.img}}" />
|
|
||||||
|
|
||||||
{{!-- Poster au chat --}}
|
|
||||||
<button data-action="postItem">
|
|
||||||
<i class="fas fa-comment"></i>
|
|
||||||
</button>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tabs
|
|
||||||
|
|
||||||
```handlebars
|
|
||||||
{{!-- Navigation --}}
|
|
||||||
<nav class="tabs" data-group="primary">
|
|
||||||
{{#each tabs}}
|
|
||||||
<a data-tab="{{this.id}}" class="{{#if (eq ../activeTab this.id)}}active{{/if}}">
|
|
||||||
{{localize this.label}}
|
|
||||||
</a>
|
|
||||||
{{/each}}
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
{{!-- Contenu --}}
|
|
||||||
<div class="tab {{#if (eq activeTab 'description')}}active{{/if}}"
|
|
||||||
data-tab="description">
|
|
||||||
...
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Editor
|
|
||||||
|
|
||||||
```handlebars
|
|
||||||
{{!-- AppV2 avec ProseMirror --}}
|
|
||||||
{{editor enrichedDescription
|
|
||||||
target="system.description"
|
|
||||||
button=true
|
|
||||||
editable=isEditable
|
|
||||||
engine="prosemirror"}}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Context disponible dans les templates
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
// Document & system
|
|
||||||
fields: schema.fields,
|
|
||||||
systemFields: system.schema.fields,
|
|
||||||
item: document,
|
|
||||||
system: document.system,
|
|
||||||
source: document.toObject(),
|
|
||||||
|
|
||||||
// Content
|
|
||||||
enrichedDescription: "HTML enrichi",
|
|
||||||
category: "equipment|weapon|spell|...",
|
|
||||||
itemProperties: ["prop1", "prop2"],
|
|
||||||
|
|
||||||
// Config
|
|
||||||
config: game.bol.config,
|
|
||||||
isGM: boolean,
|
|
||||||
isEditable: boolean,
|
|
||||||
|
|
||||||
// Tabs
|
|
||||||
tabs: [{id, label, icon}],
|
|
||||||
activeTab: "description|properties",
|
|
||||||
|
|
||||||
// Type-specific (item-sheet.mjs)
|
|
||||||
isItem: true,
|
|
||||||
isEquipment: boolean,
|
|
||||||
isWeapon: boolean,
|
|
||||||
isProtection: boolean,
|
|
||||||
isSpell: boolean,
|
|
||||||
|
|
||||||
// Type-specific (feature-sheet.mjs)
|
|
||||||
isFeature: true,
|
|
||||||
isBoon: boolean,
|
|
||||||
isFlaw: boolean,
|
|
||||||
isCareer: boolean,
|
|
||||||
isOrigin: boolean,
|
|
||||||
isRace: boolean,
|
|
||||||
|
|
||||||
// Optional
|
|
||||||
careers: actor.careers // Si item sur actor
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration dans bol.js
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Import
|
|
||||||
import * as sheets from "./applications/sheets/_module.mjs"
|
|
||||||
|
|
||||||
// Enregistrement
|
|
||||||
foundry.documents.collections.Items.unregisterSheet("core", ...)
|
|
||||||
foundry.documents.collections.Items.registerSheet("bol",
|
|
||||||
sheets.BoLItemSheet,
|
|
||||||
{ types: ["item"], makeDefault: true }
|
|
||||||
)
|
|
||||||
foundry.documents.collections.Items.registerSheet("bol",
|
|
||||||
sheets.BoLFeatureSheet,
|
|
||||||
{ types: ["feature"], makeDefault: true }
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Avantages de AppV2
|
|
||||||
|
|
||||||
1. **Performance** : Meilleur rendu et gestion des updates
|
|
||||||
2. **Structure** : Code plus organisé et maintenable
|
|
||||||
3. **Actions** : Système d'actions déclaratif
|
|
||||||
4. **Context** : Préparation des données séparée du template
|
|
||||||
5. **Standard** : Aligné sur Foundry VTT v12+
|
|
||||||
6. **Future-proof** : Architecture pérenne
|
|
||||||
|
|
||||||
## Points d'attention
|
|
||||||
|
|
||||||
### Compatibilité
|
|
||||||
|
|
||||||
- Les données restent 100% compatibles
|
|
||||||
- Seule l'interface de sheet change
|
|
||||||
- Pas de migration de données nécessaire
|
|
||||||
|
|
||||||
### Tabs
|
|
||||||
|
|
||||||
Les tabs ne sont plus automatiques dans AppV2 :
|
|
||||||
- Navigation manuelle avec `_activateTabs()`
|
|
||||||
- State persistant avec `tabGroups`
|
|
||||||
- CSS `.active` géré manuellement
|
|
||||||
|
|
||||||
### Editor
|
|
||||||
|
|
||||||
ProseMirror est maintenant le moteur par défaut :
|
|
||||||
```handlebars
|
|
||||||
{{editor content engine="prosemirror"}}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Actions
|
|
||||||
|
|
||||||
Système déclaratif :
|
|
||||||
```javascript
|
|
||||||
actions: {
|
|
||||||
myAction: ClassName.#onMyAction
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Dans le template :
|
|
||||||
```handlebars
|
|
||||||
<button data-action="myAction">Click</button>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Prochaines étapes
|
|
||||||
|
|
||||||
### Court terme
|
|
||||||
1. Tester les sheets dans Foundry
|
|
||||||
2. Vérifier toutes les fonctionnalités
|
|
||||||
3. Ajuster les CSS si nécessaire
|
|
||||||
|
|
||||||
### Moyen terme
|
|
||||||
4. Migrer les actor sheets vers AppV2
|
|
||||||
5. Ajouter des features AppV2 (parts, etc.)
|
|
||||||
6. Optimiser les templates
|
|
||||||
|
|
||||||
### Long terme
|
|
||||||
7. Utiliser PARTS pour modularité
|
|
||||||
8. Ajouter des actions avancées
|
|
||||||
9. Améliorer la UX
|
|
||||||
|
|
||||||
## Références
|
|
||||||
|
|
||||||
- [Foundry AppV2 Documentation](https://foundryvtt.com/api/classes/foundry.applications.api.ApplicationV2.html)
|
|
||||||
- [ItemSheetV2 API](https://foundryvtt.com/api/classes/foundry.applications.sheets.ItemSheetV2.html)
|
|
||||||
- Exemples : fvtt-cthulhu-eternal, fvtt-mournblade
|
|
||||||
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 151 KiB |
|
After Width: | Height: | Size: 517 KiB |
|
After Width: | Height: | Size: 109 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 272 KiB |
|
After Width: | Height: | Size: 275 KiB |
|
After Width: | Height: | Size: 247 KiB |
|
After Width: | Height: | Size: 248 KiB |
|
After Width: | Height: | Size: 242 KiB |
|
After Width: | Height: | Size: 274 KiB |
|
After Width: | Height: | Size: 102 KiB |
@@ -0,0 +1,63 @@
|
|||||||
|
{
|
||||||
|
"label": "Game Aid",
|
||||||
|
"mapping": {
|
||||||
|
"name": "name",
|
||||||
|
"description": "content",
|
||||||
|
"categories": {
|
||||||
|
"path": "categories",
|
||||||
|
"converter": "nameCollection"
|
||||||
|
},
|
||||||
|
"pages": {
|
||||||
|
"path": "pages",
|
||||||
|
"converter": "pages"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entries": {
|
||||||
|
"Aide du Jeu": "Game Aid",
|
||||||
|
"8ihDiCxC47fcdKVA": {
|
||||||
|
"name": "Game Aid",
|
||||||
|
"pages": {
|
||||||
|
"8agBoLYo99u530d1": {
|
||||||
|
"name": "Credits",
|
||||||
|
"text": "<p>This system was started by Zigmund, then taken over, completed and maintained by LeRatierBretonnien.</p><p>You can contact me on the French Foundry Discord: LeRatierBretonnien#2065</p><p>The git repository is available here: <a href=\"https://www.uberwald.me/gitea/public/bol\">https://www.uberwald.me/gitea/public/bol</a></p><p>Barbarians of Lemuria is a game by Simon Washbourne (Beyond Belief Games), translated into French by Ludospherik.</p><p>The full range is available on this page: <a href=\"http://www.ludospherik.fr/content/14-barbarians-of-lemuria\">http://www.ludospherik.fr/content/14-barbarians-of-lemuria</a></p><img src=\"systems/bol/assets/pages/b9BjVFaWB6uyyKsD-pages-8agBoLYo99u530d1-image-Rg2nVaMlglfJ6Qcm.png\" />"
|
||||||
|
},
|
||||||
|
"NAcpMm6NlyhwvWRA": {
|
||||||
|
"name": "Features",
|
||||||
|
"text": "<p>The BoL system under Foundry allows you to:</p><ul><li><p>create characters and NPCs (minions, toughs, rivals),</p></li><li><p>create creatures,</p></li><li><p>make dice rolls for attributes, aptitudes, and careers,</p></li><li><p>make dice rolls for combat attacks,</p></li><li><p>manage initiative,</p></li><li><p>make dice rolls to cast spells or perform alchemical recipes,</p></li><li><p>manage damage and lifeblood loss,</p></li><li><p>display and manage automations in chat windows, with assistance for the use of Hero Points and critical successes.</p></li></ul>"
|
||||||
|
},
|
||||||
|
"hdQixhZGfAytdbSg": {
|
||||||
|
"name": "Compendiums",
|
||||||
|
"text": "<p>The system comes with a series of compendiums providing quick access to careers, boons, and equipment.</p><p>The official cards are available, with the kind permission of Ludospherik.</p><p>To use content from a compendium, simply drag and drop the item into the world. For example: open the armours compendium, select <em>Light Armour</em>, and drag it onto a character sheet.</p><img src=\"systems/bol/assets/pages/help-en-compendium.png\" />"
|
||||||
|
},
|
||||||
|
"UfvTY80U49k6YFwe": {
|
||||||
|
"name": "Dice Rolls (Attributes/Aptitudes)",
|
||||||
|
"text": "<p>When a player clicks an attribute or aptitude, the following window appears:</p><img src=\"systems/bol/assets/pages/help-en-attribute-dialog.png\" /><ol><li><p>Attribute the player clicked on. It can be changed with this drop-down menu.</p></li><li><p>Career to apply if needed. Left-click to select, CTRL+left-click to deselect. When selected, the career rank is applied.</p></li><li><p>Available boons (i.e. those that grant a bonus die). Selection mode is identical to careers. When selected, the bonus die is applied to the roll.</p></li><li><p>Available flaws (i.e. those that impose a penalty die). Selection mode is identical to careers. When selected, the penalty die is applied to the roll.</p></li><li><p>Effects. Effects are permanent modifiers that affect certain rolls. See the corresponding chapter.</p></li><li><p>Manual addition of penalty or bonus dice.</p></li><li><p>Manual modifiers, according to the GM's ruling.</p></li><li><p>Reminder of the number of dice, based on the choices made in the dialog.</p></li><li><p>Complete list of modifiers applied to the roll.</p></li></ol>"
|
||||||
|
},
|
||||||
|
"4CLyyt3dtpG6YNMi": {
|
||||||
|
"name": "Dice Rolls (Weapon)",
|
||||||
|
"text": "<p>To make an attack with a weapon, go to the <strong>Actions</strong> tab and click the weapon's name. Targeting an opponent is recommended in order to take advantage of the system automations.</p><img src=\"systems/bol/assets/pages/help-en-weapon-dialog.png\" /><ol><li><p>Default weapon attribute. It can be changed with this drop-down menu.</p></li><li><p>Default weapon aptitude. It can be changed with this drop-down menu.</p></li><li><p>Possible weapon bonus on the attack roll.</p></li><li><p>Target defence, when an opponent is targeted.</p></li><li><p>Career to apply if needed. Left-click to select, CTRL+left-click to deselect. When selected, the career rank is applied.</p></li><li><p>Available boons (i.e. those that grant a bonus die). Selection mode is identical to careers. When selected, the bonus die is applied to the roll.</p></li><li><p>Available flaws (i.e. those that impose a penalty die). Selection mode is identical to careers. When selected, the penalty die is applied to the roll.</p></li><li><p>Effects. Effects are permanent modifiers that affect certain rolls. See the corresponding chapter.</p></li><li><p>Manual addition of penalty or bonus dice.</p></li><li><p>Information area if the weapon has the <em>Bonus Die</em> option enabled.</p></li><li><p>Agility penalty from armour and shield.</p></li><li><p>Manual modifiers, according to the GM's ruling.</p></li><li><p>Reminder of the number of dice, based on the choices made in the dialog.</p></li><li><p>Complete list of modifiers applied to the roll.</p></li></ol>"
|
||||||
|
},
|
||||||
|
"r003R5yIaiKxThOc": {
|
||||||
|
"name": "Character Sheet",
|
||||||
|
"text": "<h2>Attributes</h2><img src=\"systems/bol/assets/pages/help-en-sheet-attributes.png\" /><ol><li><p>Name + Experience area.</p></li><li><p>Tab bar for moving between sections.</p></li><li><p>Attributes area. Clicking a name opens the roll dialog, clicking a number allows editing.</p></li><li><p>Aptitudes area, same idea as attributes.</p></li><li><p>Counters area. The red value is the current one, the black value underneath is the maximum.</p></li></ol><h2>Actions</h2><img src=\"systems/bol/assets/pages/help-en-sheet-actions.png\" /><ol><li><p>Weapons. Clicking the name opens the attack dialog for that weapon.</p></li><li><p>Damage. Clicking the damage formula rolls it.</p></li><li><p>List of protections.</p></li><li><p>Clicking the protection formula rolls it.</p></li><li><p>List of shields.</p></li><li><p>Combat options the character knows. Once activated, they appear in the weapon attack dialog.</p></li></ol><h2>Traits</h2><img src=\"systems/bol/assets/pages/help-en-sheet-traits.png\" /><ol><li><p>List of careers. Left-click a career for details.</p></li><li><p>Career rank helper.</p></li><li><p>List of origins. Left-click for details.</p></li><li><p>List of boons. Left-click for details.</p></li><li><p>List of flaws. Left-click for details.</p></li><li><p>List of spoken languages. Left-click for details.</p></li><li><p>List of known combat options. Left-click for details.</p></li><li><p>List of beliefs. Left-click for details.</p></li><li><p>List of active effects. Left-click for details.</p></li></ol><h2>Equipment</h2><img src=\"systems/bol/assets/pages/help-en-sheet-equipment.png\" /><ol><li><p>Quick equipment creation controls.</p></li><li><p>Purse state (optional rule, system setting).</p></li><li><p>Weapons, with quantity management.</p></li><li><p>Shield equip / unequip control.</p></li><li><p>List of protections.</p></li><li><p>Armour equip / unequip control.</p></li></ol><h2>Spells & Alchemy</h2><p>This tab is only available if the character has the Alchemist or Sorcerer career.</p><img src=\"systems/bol/assets/pages/help-en-sheet-spells.png\" /><ol><li><p>List of spells. Left-click the name to open the dedicated roll dialog.</p></li><li><p>Reminder of circle and difficulty.</p></li><li><p>The square button opens the spell details.</p></li><li><p>List of known alchemical preparations.</p></li><li><p>Crafting progress management.</p></li><li><p>The square button opens the preparation details.</p></li></ol><h2>Description</h2><img src=\"systems/bol/assets/pages/help-en-sheet-description.png\" /><p>The description area contains free-form fields for customising the character.</p>"
|
||||||
|
},
|
||||||
|
"eRbEqbCW4AhU0cpm": {
|
||||||
|
"name": "Effects",
|
||||||
|
"text": "<p>Effects allow permanent modifiers to be applied as long as they are present on the character sheet.</p><p><span style=\"text-decoration:underline\"><span style=\"text-decoration:underline\">Example</span></span>: a character is poisoned, and the poison causes mental fatigue. In game terms, they suffer a -2 penalty to all Mind rolls. To represent this, create an <em>Effect</em> like this:</p><img src=\"systems/bol/assets/pages/help-en-effect-sheet.png\" /><ol><li><p>Create a <em>Trait</em>, and in the <em>Details</em> tab select the subtype <em>Effect</em>.</p></li><li><p>Select <em>Mind</em>.</p></li><li><p>Set a -2 modifier.</p></li></ol><p>Once placed on a character, the penalty is automatically applied whenever a Mind roll is requested. Remove the effect from the character sheet (<em>Traits</em> tab) to remove both the effect and its penalty.<br />A compendium of basic effects is available in the system.</p>"
|
||||||
|
},
|
||||||
|
"QmNF6p0lJf3pJoAy": {
|
||||||
|
"name": "Commands",
|
||||||
|
"text": "<p>The system provides commands (currently just one) for a few automated tasks.</p><p><strong><span style=\"text-decoration:underline\">This command is only available if the BoL-rulebook module is installed.</span></strong></p><h3>/adventure command</h3><img src=\"systems/bol/assets/pages/help-en-command.png\" /><ol><li><p>Type <code>/adventure</code> in the chat input area (or trigger it from a macro).</p></li><li><p>The system generates an adventure from the core rulebook tables and posts the result in chat.</p></li></ol>"
|
||||||
|
},
|
||||||
|
"MOWru5Dbvs4iozXm": {
|
||||||
|
"name": "Macros",
|
||||||
|
"text": "<p>The system exposes macros through <code>game.bol.macros</code>. They provide quick access to the most common rolls from a Foundry macro.</p><p><strong>Automatic actor selection:</strong></p><ul><li><p>if exactly one token is selected, the macro uses it;</p></li><li><p>if several tokens are selected, the macro shows a warning;</p></li><li><p>if no token is selected, a GM must select one; a player automatically falls back to their assigned character.</p></li></ul><p><strong>Available rolls</strong></p><p>Attributes (internal keys):</p><pre><code>game.bol.macros.rollAttribute(\"vigor\")\ngame.bol.macros.rollAttribute(\"agility\")\ngame.bol.macros.rollAttribute(\"mind\")\ngame.bol.macros.rollAttribute(\"appeal\")</code></pre><p>Aptitudes:</p><pre><code>game.bol.macros.rollAptitude(\"init\")\ngame.bol.macros.rollAptitude(\"melee\")\ngame.bol.macros.rollAptitude(\"ranged\")\ngame.bol.macros.rollAptitude(\"def\")</code></pre><p>Weapons, spells, and alchemy:</p><pre><code>game.bol.macros.rollWeapon(\"Spear\")\ngame.bol.macros.rollWeapon(0)\n\ngame.bol.macros.rollSpell(\"Javelin\")\ngame.bol.macros.rollSpell(0)\n\ngame.bol.macros.rollAlchemy(\"Fire\")\ngame.bol.macros.rollAlchemy(0)</code></pre><p>For weapons, spells, and alchemical preparations, name lookup is <strong>partial</strong> and <strong>case-insensitive</strong>. You may also use a numeric index.</p><p>Horoscope:</p><pre><code>game.bol.macros.rollHoroscope(\"minor\")\ngame.bol.macros.rollHoroscope(\"major\")</code></pre><p><strong>Generic macro</strong></p><pre><code>game.bol.macros.roll(\"attribute\", \"vigor\")\ngame.bol.macros.roll(\"aptitude\", \"melee\")\ngame.bol.macros.roll(\"weapon\", \"Spear\")\ngame.bol.macros.roll(\"spell\", \"Javelin\")\ngame.bol.macros.roll(\"alchemy\", 0)\ngame.bol.macros.roll(\"horoscope\", \"minor\")</code></pre><p><strong>Compatibility</strong></p><p>The legacy entry point <code>game.bol.macros.rollMacro(type, key)</code> is still available for existing macros.</p>"
|
||||||
|
},
|
||||||
|
"rERizrPxSAsvsZY2": {
|
||||||
|
"name": "Initiative",
|
||||||
|
"text": "<p>In BoL, initiative is rolled once at the start of combat.</p><p>You can request it automatically through the Combat Tracker, or roll Initiative manually and tick the corresponding box in the dialog:</p><img src=\"systems/bol/assets/pages/help-en-initiative-dialog.png\" /><p>According to the roll result, an initiative rank from 10 to 3 is assigned as follows:</p><p><strong>10</strong> - PC: Legendary Success<br /><strong>9</strong> - PC: Heroic Success<br /><strong>8</strong> - PC: Normal Success<br /><strong>7</strong> - NPC: Opponents or creatures larger than medium size<br /><strong>6</strong> - NPC: Toughs or creatures of medium size or smaller<br /><strong>5</strong> - PC: Normal Failure<br /><strong>4</strong> - NPC: Minions<br /><strong>3</strong> - PC: Critical Failure</p>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -96,6 +96,10 @@
|
|||||||
"name": "Plains-Born",
|
"name": "Plains-Born",
|
||||||
"description": "<h1>Plains-Born</h1><p>You grew up on the plains. When tracking, trapping, hunting, or carrying out other similar activities (not fighting) in a plains environment, you receive a bonus die.</p>"
|
"description": "<h1>Plains-Born</h1><p>You grew up on the plains. When tracking, trapping, hunting, or carrying out other similar activities (not fighting) in a plains environment, you receive a bonus die.</p>"
|
||||||
},
|
},
|
||||||
|
"Envoûtant": {
|
||||||
|
"name": "Beguiling",
|
||||||
|
"description": "<h1>Beguiling</h1><p> Your looks and bearing are such that people who might be attracted to your type are enchanted by you. Once per day you may suggest a course of action to a number of rabble equal to appeal + d6, who will do their best to please you, even if it potentially puts them in danger.</p><p>You must have the temptress career to take this boon.</p>"
|
||||||
|
},
|
||||||
"Fortuné": {
|
"Fortuné": {
|
||||||
"name": "Great Wealth",
|
"name": "Great Wealth",
|
||||||
"description": "<h1>Great Wealth</h1><p>You have a source of income or an inheritance. Roll a bonus die on any attempt to obtain any goods, services, or other items you need whilst in your home city.</p>"
|
"description": "<h1>Great Wealth</h1><p>You have a source of income or an inheritance. Roll a bonus die on any attempt to obtain any goods, services, or other items you need whilst in your home city.</p>"
|
||||||
|
|||||||
@@ -5,6 +5,30 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"entries": {
|
"entries": {
|
||||||
|
"Arc de guerre de Tyrus": {
|
||||||
|
"name": "Tyrus Warbow",
|
||||||
|
"description": "<h1>Tyrus Warbow</h1><p> The archers of Tyrus train from a very young age in the use of this powerful bow. Tyrus archers have fun with other warriors by lending their bows to them and then watching them struggle to aim at the proverbial “barn door”.</p>"
|
||||||
|
},
|
||||||
|
"Épée Valgardienne (1 Main)": {
|
||||||
|
"name": "Valgardian Blade (1H)",
|
||||||
|
"description": "<h1>Valgardian Blade (1H)</h1><p>Around 3’-4’ in length, the Valgardian blade is used either in one hand or in both. The Valgardian bladesmiths guard the secret of their work closely, although many have tried to copy it. It is rumoured that the strength of the blades due mainly to the quality of the iron mined locally.</p>"
|
||||||
|
},
|
||||||
|
"Épée Valgardienne (2 mains)": {
|
||||||
|
"name": "Valgardian Blade (2H)",
|
||||||
|
"description": "<h1>Valgardian Blade (2H)</h1><p>Around 3’-4’ in length, the Valgardian blade is used either in one hand or in both. The Valgardian bladesmiths guard the secret of their work closely, although many have tried to copy it. It is rumoured that the strength of the blades due mainly to the quality of the iron mined locally.</p>"
|
||||||
|
},
|
||||||
|
"Fronde de l’Axos": {
|
||||||
|
"name": "Axish Sling",
|
||||||
|
"description": "<h1>Axish Sling</h1><p>Sling: The sling is inexpensive and easy to build. It is a simple leather thong whirled around the head to cast small stones or cast lead bullets with some force, at 30’ range increments. Two-handed versions are fitted onto a staff and are called staff-slings. This imparts a greater range, making the increments 60’. The Axish sling is actually little different to any other common sling; it’s just that the people of the Axos mountains are particularly proficient with them. They have however played up the idea that there is some special plant fibre that the thongs are made from that gives them their extra range.</p>"
|
||||||
|
},
|
||||||
|
"Hache d’abordage de Parsool (1 main)": {
|
||||||
|
"name": "Parsool Sea Axe (1H)",
|
||||||
|
"description": "<h1>Parsool Sea Axe (1H)</h1><p>A boarding axe used by Parsool seamen which can be used one or two-handed.</p>"
|
||||||
|
},
|
||||||
|
"Hache d’abordage de Parsool (2 mains)": {
|
||||||
|
"name": "Parsool Sea Axe (2H)",
|
||||||
|
"description": "<h1>Parsool Sea Axe (2H)</h1><p>A boarding axe used by Parsool seamen which can be used one or two-handed.</p>"
|
||||||
|
},
|
||||||
"Arbalète": {
|
"Arbalète": {
|
||||||
"name": "Crossbow",
|
"name": "Crossbow",
|
||||||
"description": "<h1>Crossbow</h1><p>A crossbow is a simple device for firing a short bolt or quarrel with some force and little training. They take a round to load (ready to fire on the second round).</p>"
|
"description": "<h1>Crossbow</h1><p>A crossbow is a simple device for firing a short bolt or quarrel with some force and little training. They take a round to load (ready to fire on the second round).</p>"
|
||||||
|
|||||||
@@ -1512,6 +1512,21 @@ h2.bad {
|
|||||||
.bol-welcome-card .welcome-body a {
|
.bol-welcome-card .welcome-body a {
|
||||||
color: darkred;
|
color: darkred;
|
||||||
}
|
}
|
||||||
|
.bol-welcome-card .welcome-body .welcome-premium {
|
||||||
|
margin-top: 6px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: #191813;
|
||||||
|
background: linear-gradient(135deg, #fdf7e6, #f6e8c8);
|
||||||
|
border: 1px solid #c9a227;
|
||||||
|
border-left: 4px solid #c9a227;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
.bol-welcome-card .welcome-body .welcome-premium a {
|
||||||
|
color: #7a5c00;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
.bol-welcome-card .welcome-footer {
|
.bol-welcome-card .welcome-footer {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
padding: 4px 10px;
|
padding: 4px 10px;
|
||||||
@@ -1522,15 +1537,6 @@ h2.bad {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.5px;
|
||||||
}
|
}
|
||||||
.bol-welcome-card .welcome-warning {
|
|
||||||
margin-top: 6px;
|
|
||||||
padding: 4px 8px;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
color: #7a0000;
|
|
||||||
background: #fff3f3;
|
|
||||||
border: 1px solid #e57373;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
/* Component Styles */
|
/* Component Styles */
|
||||||
/* ----------------------------------------- */
|
/* ----------------------------------------- */
|
||||||
/* Common Sheet Styles */
|
/* Common Sheet Styles */
|
||||||
@@ -1538,8 +1544,16 @@ h2.bad {
|
|||||||
body.system-bol img#logo {
|
body.system-bol img#logo {
|
||||||
content: url("/systems/bol/ui/logo2.webp");
|
content: url("/systems/bol/ui/logo2.webp");
|
||||||
}
|
}
|
||||||
.journal-page-content {
|
.journal-page-content,
|
||||||
/* Reserved for future use */
|
.journal-page-content p,
|
||||||
|
.journal-page-content div,
|
||||||
|
.journal-page-content span {
|
||||||
|
color: #191813 !important;
|
||||||
|
}
|
||||||
|
.sheet.journal-entry prose-mirror.journal-page-content,
|
||||||
|
prose-mirror.journal-page-content {
|
||||||
|
background-color: white;
|
||||||
|
background: white;
|
||||||
}
|
}
|
||||||
.bol.dialog > section.window-content {
|
.bol.dialog > section.window-content {
|
||||||
background: white;
|
background: white;
|
||||||
|
|||||||
@@ -469,7 +469,8 @@
|
|||||||
"BOL.chat.welcome4": "Im Discord findet ihr Support für die FoundryVTT-Implementierung dieses Systems: https://discord.gg/pPSDNJk",
|
"BOL.chat.welcome4": "Im Discord findet ihr Support für die FoundryVTT-Implementierung dieses Systems: https://discord.gg/pPSDNJk",
|
||||||
"BOL.chat.welcome5": "Auf ein gutes Spiel in Lemuria!",
|
"BOL.chat.welcome5": "Auf ein gutes Spiel in Lemuria!",
|
||||||
"BOL.chat.welcome6": "",
|
"BOL.chat.welcome6": "",
|
||||||
"BOL.chat.bolRulebookMessage": "Don't miss the full Rulebook module (including Sagas) available at : https://www.ludospherik-editions.com/en_gb/ !",
|
"BOL.chat.bolRulebookMessage": "Don't miss the premium Rulebook module (including Sagas), available on the Foundry website : <a href='https://foundryvtt.com/packages/bol-rulebook' target='_blank'>https://foundryvtt.com/packages/bol-rulebook</a>",
|
||||||
|
"BOL.chat.bolChroniclesMessage": "Discover the premium Chronicles of Lemuria module (vol. 1), available on the Foundry website : <a href='https://foundryvtt.com/packages/bol-chronicles-1' target='_blank'>https://foundryvtt.com/packages/bol-chronicles-1</a>",
|
||||||
|
|
||||||
"BOL.settings.rollArmor": "Roll for armor",
|
"BOL.settings.rollArmor": "Roll for armor",
|
||||||
"BOL.settings.rollArmorTooltip": "Roll for armor value, fixed value if unchecked",
|
"BOL.settings.rollArmorTooltip": "Roll for armor value, fixed value if unchecked",
|
||||||
|
|||||||
@@ -545,7 +545,8 @@
|
|||||||
"BOL.chat.criticalbuttonjournal": "Legendary/Heroic Success",
|
"BOL.chat.criticalbuttonjournal": "Legendary/Heroic Success",
|
||||||
"BOL.chat.nodamage": "Do not apply damages",
|
"BOL.chat.nodamage": "Do not apply damages",
|
||||||
"BOL.chat.armorRoll": "Armor roll",
|
"BOL.chat.armorRoll": "Armor roll",
|
||||||
"BOL.chat.bolRulebookMessage": "Don't miss the full Rulebook module (including Sagas) available at : https://www.ludospherik-editions.com/en_gb/ !",
|
"BOL.chat.bolRulebookMessage": "Don't miss the premium Rulebook module (including Sagas), available on the Foundry website : <a href='https://foundryvtt.com/packages/bol-rulebook' target='_blank'>https://foundryvtt.com/packages/bol-rulebook</a>",
|
||||||
|
"BOL.chat.bolChroniclesMessage": "Discover the premium Chronicles of Lemuria module (vol. 1), available on the Foundry website : <a href='https://foundryvtt.com/packages/bol-chronicles-1' target='_blank'>https://foundryvtt.com/packages/bol-chronicles-1</a>",
|
||||||
|
|
||||||
"BOL.dialog.soeasy": "So easy (+4)",
|
"BOL.dialog.soeasy": "So easy (+4)",
|
||||||
"BOL.dialog.soeasy3": "So easy (+3)",
|
"BOL.dialog.soeasy3": "So easy (+3)",
|
||||||
|
|||||||
@@ -535,7 +535,8 @@
|
|||||||
"BOL.chat.criticalinfo": "¡Esto es un éxito Asombroso o Legendario! Escoge tus opciones y efectos",
|
"BOL.chat.criticalinfo": "¡Esto es un éxito Asombroso o Legendario! Escoge tus opciones y efectos",
|
||||||
"BOL.chat.criticalbuttonjournal": "Éxito Asombroso/Legendario",
|
"BOL.chat.criticalbuttonjournal": "Éxito Asombroso/Legendario",
|
||||||
"BOL.chat.armorRoll": "Tirada de Armadura",
|
"BOL.chat.armorRoll": "Tirada de Armadura",
|
||||||
"BOL.chat.bolRulebookMessage": "Don't miss the full Rulebook module (including Sagas) available at : https://www.ludospherik-editions.com/en_gb/ !",
|
"BOL.chat.bolRulebookMessage": "Don't miss the premium Rulebook module (including Sagas), available on the Foundry website : <a href='https://foundryvtt.com/packages/bol-rulebook' target='_blank'>https://foundryvtt.com/packages/bol-rulebook</a>",
|
||||||
|
"BOL.chat.bolChroniclesMessage": "Discover the premium Chronicles of Lemuria module (vol. 1), available on the Foundry website : <a href='https://foundryvtt.com/packages/bol-chronicles-1' target='_blank'>https://foundryvtt.com/packages/bol-chronicles-1</a>",
|
||||||
|
|
||||||
"BOL.dialog.soeasy": "Demasiado fácil (+4)",
|
"BOL.dialog.soeasy": "Demasiado fácil (+4)",
|
||||||
"BOL.dialog.veryeasy": "Muy fácil (+2)",
|
"BOL.dialog.veryeasy": "Muy fácil (+2)",
|
||||||
|
|||||||
@@ -571,7 +571,8 @@
|
|||||||
"BOL.chat.criticalinfo": "C'est un succès Héroïque ! Choisissez vos options et effets !",
|
"BOL.chat.criticalinfo": "C'est un succès Héroïque ! Choisissez vos options et effets !",
|
||||||
"BOL.chat.criticallegendaryinfo": "C'est un succès Légendaire ! Choisissez vos options et effets !",
|
"BOL.chat.criticallegendaryinfo": "C'est un succès Légendaire ! Choisissez vos options et effets !",
|
||||||
"BOL.chat.criticalbuttonjournal": "Succès Héroïque/Légendaire",
|
"BOL.chat.criticalbuttonjournal": "Succès Héroïque/Légendaire",
|
||||||
"BOL.chat.bolRulebookMessage": "N'oubliez pas le module complet du Livre de Règle et des Sagas disponible ici : https://www.ludospherik-editions.com !",
|
"BOL.chat.bolRulebookMessage": "N'oubliez pas le module premium du Livre de Règle et des Sagas, disponible sur le site Foundry : <a href='https://foundryvtt.com/packages/bol-rulebook' target='_blank'>https://foundryvtt.com/packages/bol-rulebook</a>",
|
||||||
|
"BOL.chat.bolChroniclesMessage": "Découvrez le module premium des Chroniques de Lémurie (vol. 1), disponible sur le site Foundry : <a href='https://foundryvtt.com/packages/bol-chronicles-1' target='_blank'>https://foundryvtt.com/packages/bol-chronicles-1</a>",
|
||||||
"BOL.chat.losshp": "{name} a perdu {lossHP} points de Vitalité. Si il se repose quelques minutes, il peut récupérer {recupHP} points de Vitalité.",
|
"BOL.chat.losshp": "{name} a perdu {lossHP} points de Vitalité. Si il se repose quelques minutes, il peut récupérer {recupHP} points de Vitalité.",
|
||||||
"BOL.chat.applyrecup": "Récupérer pendant quelques minutes (+{recupHP} Vitalité)",
|
"BOL.chat.applyrecup": "Récupérer pendant quelques minutes (+{recupHP} Vitalité)",
|
||||||
"BOL.chat.inforecup": "{name} vient de récupérer {recupHP} points de Vitalité après quelques minutes de repos.",
|
"BOL.chat.inforecup": "{name} vient de récupérer {recupHP} points de Vitalité après quelques minutes de repos.",
|
||||||
|
|||||||
@@ -866,12 +866,12 @@ export class BoLActor extends Actor {
|
|||||||
if (this.system.resources.hp.value <= 0) {
|
if (this.system.resources.hp.value <= 0) {
|
||||||
if (!prone) {
|
if (!prone) {
|
||||||
await this.createEmbeddedDocuments("ActiveEffect", [
|
await this.createEmbeddedDocuments("ActiveEffect", [
|
||||||
{ name: game.i18n.localize('EFFECT.StatusProne'), icon: 'icons/svg/falling.svg', statuses: 'prone' }
|
{ name: game.i18n.localize('EFFECT.StatusProne'), img: 'icons/svg/falling.svg', statuses: ['prone'] }
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
if (this.system.resources.hp.value < -5 && !dead) {
|
if (this.system.resources.hp.value < -5 && !dead) {
|
||||||
await this.createEmbeddedDocuments("ActiveEffect", [
|
await this.createEmbeddedDocuments("ActiveEffect", [
|
||||||
{ name: game.i18n.localize('EFFECT.StatusDead'), icon: 'icons/svg/skull.svg', statuses: 'dead' }
|
{ name: game.i18n.localize('EFFECT.StatusDead'), img: 'icons/svg/skull.svg', statuses: ['dead'] }
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
ChatMessage.create({
|
ChatMessage.create({
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ export default class BoLBaseActorSheet extends HandlebarsApplicationMixin(foundr
|
|||||||
return {
|
return {
|
||||||
actor,
|
actor,
|
||||||
system: actor.system,
|
system: actor.system,
|
||||||
|
systemFields: actor.system.schema.fields,
|
||||||
config: game.bol.config,
|
config: game.bol.config,
|
||||||
isGM: game.user.isGM,
|
isGM: game.user.isGM,
|
||||||
isEditable: this.isEditable,
|
isEditable: this.isEditable,
|
||||||
@@ -112,7 +113,8 @@ export default class BoLBaseActorSheet extends HandlebarsApplicationMixin(foundr
|
|||||||
link.addEventListener("click", (event) => {
|
link.addEventListener("click", (event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
this.tabGroups[group] = tab
|
this.tabGroups[group] = tab
|
||||||
this.render()
|
nav.querySelectorAll("[data-tab]").forEach(l => l.classList.toggle("active", l.dataset.tab === tab))
|
||||||
|
this.element.querySelectorAll(`[data-group="${group}"][data-tab]`).forEach(c => c.classList.toggle("active", c.dataset.tab === tab))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -101,24 +101,26 @@ Hooks.once('init', async function () {
|
|||||||
// Register hooks
|
// Register hooks
|
||||||
registerHooks()
|
registerHooks()
|
||||||
|
|
||||||
if (typeof Babele !== 'undefined') {
|
});
|
||||||
Babele.get().setSystemTranslationsDir("compendiums");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
Hooks.once("babele.init", (babele) => {
|
||||||
|
console.log("Initializing Babele translations")
|
||||||
|
babele.setSystemTranslationsDir("compendiums");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async function welcomeMessage() {
|
async function welcomeMessage() {
|
||||||
const noRulebook = !game.modules.find(m => m.id === "bol-rulebook")
|
const noRulebook = !game.modules.get("bol-rulebook")?.active
|
||||||
|
const noChronicles = !game.modules.get("bol-chronicles-1")?.active
|
||||||
const content = await foundry.applications.handlebars.renderTemplate(
|
const content = await foundry.applications.handlebars.renderTemplate(
|
||||||
"systems/bol/templates/chat/chat-welcome.hbs",
|
"systems/bol/templates/chat/chat-welcome.hbs",
|
||||||
{ noRulebook }
|
{ noRulebook, noChronicles }
|
||||||
)
|
)
|
||||||
ChatMessage.create({ user: game.user.id, whisper: [game.user.id], content })
|
ChatMessage.create({ user: game.user.id, whisper: [game.user.id], content })
|
||||||
|
|
||||||
if (game.user.isGM && game.i18n.lang == 'en' && !game.modules.find(m => m.id == "babele")) {
|
if (game.user.isGM && game.i18n.lang == 'en' && !game.modules.get("babele")?.active) {
|
||||||
ChatMessage.create({
|
ChatMessage.create({
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
whisper: [game.user.id],
|
whisper: [game.user.id],
|
||||||
|
|||||||
@@ -191,6 +191,11 @@ export class BoLRoll {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
alchemy = foundry.utils.duplicate(alchemy)
|
alchemy = foundry.utils.duplicate(alchemy)
|
||||||
|
return this.alchemyCheckWithItem(actor, alchemy)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static alchemyCheckWithItem(actor, alchemy) {
|
||||||
let alchemyData = alchemy.system
|
let alchemyData = alchemy.system
|
||||||
if (alchemyData.properties.pccurrent < alchemyData.properties.pccost) {
|
if (alchemyData.properties.pccurrent < alchemyData.properties.pccost) {
|
||||||
ui.notifications.warn("Pas assez de Points de Création investis dans la Préparation !")
|
ui.notifications.warn("Pas assez de Points de Création investis dans la Préparation !")
|
||||||
|
|||||||
@@ -1,119 +0,0 @@
|
|||||||
import { BoLUtility } from "../system/bol-utility.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extend the basic ItemSheet with some very simple modifications
|
|
||||||
* @extends {ItemSheet}
|
|
||||||
*/
|
|
||||||
export class BoLItemSheet extends foundry.appv1.sheets.ItemSheet {
|
|
||||||
|
|
||||||
/** @override */
|
|
||||||
static get defaultOptions() {
|
|
||||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
|
||||||
classes: ["bol", "sheet", "item"],
|
|
||||||
template: "systems/bol/templates/item/item-sheet.hbs",
|
|
||||||
width: 650,
|
|
||||||
height: 780,
|
|
||||||
dragDrop: [{ dragSelector: null, dropSelector: null }],
|
|
||||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "description" }]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/** @override */
|
|
||||||
async getData(options) {
|
|
||||||
const data = super.getData(options)
|
|
||||||
let itemData = foundry.utils.duplicate(data.document)
|
|
||||||
data.config = game.bol.config
|
|
||||||
data.item = itemData
|
|
||||||
data.category = itemData.system.category
|
|
||||||
data.isGM = game.user.isGM;
|
|
||||||
data.itemProperties = this.item.itemProperties;
|
|
||||||
data.description = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.description, { async: true })
|
|
||||||
if (data.document.actor) {
|
|
||||||
data.careers = data.document.actor.careers
|
|
||||||
}
|
|
||||||
// Dynamic default data fix/adapt
|
|
||||||
if (itemData.type == "item") {
|
|
||||||
if (!itemData.system.category) {
|
|
||||||
itemData.system.category = "equipment"
|
|
||||||
}
|
|
||||||
if (itemData.system.category == "equipment" && itemData.system.properties.equipable) {
|
|
||||||
if (!itemData.system.properties.slot) {
|
|
||||||
itemData.system.properties.slot = "-"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (itemData.system.category == 'spell') {
|
|
||||||
if (!itemData.system.properties.mandatoryconditions) {
|
|
||||||
itemData.system.properties.mandatoryconditions = []
|
|
||||||
}
|
|
||||||
if (!itemData.system.properties.optionnalconditions) {
|
|
||||||
itemData.system.properties.optionnalconditions = []
|
|
||||||
}
|
|
||||||
for (let i = 0; i < 4; i++) {
|
|
||||||
itemData.system.properties.mandatoryconditions[i] = itemData.system.properties.mandatoryconditions[i] ?? ""
|
|
||||||
}
|
|
||||||
for (let i = 0; i < 8; i++) {
|
|
||||||
itemData.system.properties.optionnalconditions[i] = itemData.system.properties.optionnalconditions[i] ?? ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!itemData.system.subtype) {
|
|
||||||
itemData.system.category = "origin"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("ITEMDATA", data);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
_getHeaderButtons() {
|
|
||||||
let buttons = super._getHeaderButtons();
|
|
||||||
buttons.unshift({
|
|
||||||
class: "post",
|
|
||||||
icon: "fas fa-comment",
|
|
||||||
onclick: ev => this.postItem()
|
|
||||||
});
|
|
||||||
return buttons
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
postItem() {
|
|
||||||
let chatData = foundry.utils.duplicate(this.item)
|
|
||||||
if (this.actor) {
|
|
||||||
chatData.actor = { id: this.actor.id };
|
|
||||||
}
|
|
||||||
BoLUtility.postItem(chatData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/** @override */
|
|
||||||
setPosition(options = {}) {
|
|
||||||
const position = super.setPosition(options);
|
|
||||||
const sheetBody = this.element.find(".sheet-body");
|
|
||||||
const bodyHeight = position.height - 192;
|
|
||||||
sheetBody.css("height", bodyHeight);
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
|
|
||||||
/** @override */
|
|
||||||
activateListeners(html) {
|
|
||||||
|
|
||||||
super.activateListeners(html);
|
|
||||||
|
|
||||||
// Everything below here is only needed if the sheet is editable
|
|
||||||
if (!this.options.editable) return;
|
|
||||||
// Roll handlers, click handlers, etc. would go here.
|
|
||||||
|
|
||||||
html.find('.armorQuality').change(ev => {
|
|
||||||
const li = $(ev.currentTarget);
|
|
||||||
console.log(game.bol.config.soakFormulas[li.val()]);
|
|
||||||
$('.soakFormula').val(game.bol.config.soakFormulas[li.val()]);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
import { BoLUtility } from "../system/bol-utility.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extend the basic ItemSheet with some very simple modifications
|
|
||||||
* @extends {ItemSheet}
|
|
||||||
*/
|
|
||||||
export class BoLItemSheet extends foundry.appv1.sheets.ItemSheet {
|
|
||||||
|
|
||||||
/** @override */
|
|
||||||
static get defaultOptions() {
|
|
||||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
|
||||||
classes: ["bol", "sheet", "item"],
|
|
||||||
template: "systems/bol/templates/item/item-sheet.hbs",
|
|
||||||
width: 650,
|
|
||||||
height: 780,
|
|
||||||
dragDrop: [{ dragSelector: null, dropSelector: null }],
|
|
||||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "description" }]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/** @override */
|
|
||||||
async getData(options) {
|
|
||||||
const data = super.getData(options)
|
|
||||||
let itemData = foundry.utils.duplicate(data.document)
|
|
||||||
data.config = game.bol.config
|
|
||||||
data.item = itemData
|
|
||||||
data.category = itemData.system.category
|
|
||||||
data.isGM = game.user.isGM;
|
|
||||||
data.itemProperties = this.item.itemProperties;
|
|
||||||
data.description = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.description, { async: true })
|
|
||||||
if (data.document.actor) {
|
|
||||||
data.careers = data.document.actor.careers
|
|
||||||
}
|
|
||||||
// Dynamic default data fix/adapt
|
|
||||||
if (itemData.type == "item") {
|
|
||||||
if (!itemData.system.category) {
|
|
||||||
itemData.system.category = "equipment"
|
|
||||||
}
|
|
||||||
if (itemData.system.category == "equipment" && itemData.system.properties.equipable) {
|
|
||||||
if (!itemData.system.properties.slot) {
|
|
||||||
itemData.system.properties.slot = "-"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (itemData.system.category == 'spell') {
|
|
||||||
if (!itemData.system.properties.mandatoryconditions) {
|
|
||||||
itemData.system.properties.mandatoryconditions = []
|
|
||||||
}
|
|
||||||
if (!itemData.system.properties.optionnalconditions) {
|
|
||||||
itemData.system.properties.optionnalconditions = []
|
|
||||||
}
|
|
||||||
for (let i = 0; i < 4; i++) {
|
|
||||||
itemData.system.properties.mandatoryconditions[i] = itemData.system.properties.mandatoryconditions[i] ?? ""
|
|
||||||
}
|
|
||||||
for (let i = 0; i < 8; i++) {
|
|
||||||
itemData.system.properties.optionnalconditions[i] = itemData.system.properties.optionnalconditions[i] ?? ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!itemData.system.subtype) {
|
|
||||||
itemData.system.category = "origin"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("ITEMDATA", data);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
_getHeaderButtons() {
|
|
||||||
let buttons = super._getHeaderButtons();
|
|
||||||
buttons.unshift({
|
|
||||||
class: "post",
|
|
||||||
icon: "fas fa-comment",
|
|
||||||
onclick: ev => this.postItem()
|
|
||||||
});
|
|
||||||
return buttons
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
postItem() {
|
|
||||||
let chatData = foundry.utils.duplicate(this.item)
|
|
||||||
if (this.actor) {
|
|
||||||
chatData.actor = { id: this.actor.id };
|
|
||||||
}
|
|
||||||
BoLUtility.postItem(chatData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/** @override */
|
|
||||||
setPosition(options = {}) {
|
|
||||||
const position = super.setPosition(options);
|
|
||||||
const sheetBody = this.element.find(".sheet-body");
|
|
||||||
const bodyHeight = position.height - 192;
|
|
||||||
sheetBody.css("height", bodyHeight);
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
|
|
||||||
/** @override */
|
|
||||||
activateListeners(html) {
|
|
||||||
|
|
||||||
super.activateListeners(html);
|
|
||||||
|
|
||||||
// Everything below here is only needed if the sheet is editable
|
|
||||||
if (!this.options.editable) return;
|
|
||||||
// Roll handlers, click handlers, etc. would go here.
|
|
||||||
|
|
||||||
html.find('.armorQuality').change(ev => {
|
|
||||||
const li = $(ev.currentTarget);
|
|
||||||
console.log(game.bol.config.soakFormulas[li.val()]);
|
|
||||||
$('.soakFormula').val(game.bol.config.soakFormulas[li.val()]);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/**
|
|
||||||
* Extend the basic Item with some very simple modifications.
|
|
||||||
* @extends {Item}
|
|
||||||
*/
|
|
||||||
export class BoLItem extends Item {
|
|
||||||
/**
|
|
||||||
* Augment the basic Item data model with additional dynamic data.
|
|
||||||
*/
|
|
||||||
prepareData() {
|
|
||||||
super.prepareData()
|
|
||||||
|
|
||||||
const actorData = this.actor ? this.actor.system : {}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
get properties() {
|
|
||||||
return this.system.properties
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
/**
|
|
||||||
* Get the Array of item properties which are used in the small sidebar of the description tab
|
|
||||||
* @return {Array}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
get itemProperties() {
|
|
||||||
const props = [];
|
|
||||||
if ( this.type === "item" ) {
|
|
||||||
const entries = Object.entries(this.system.properties)
|
|
||||||
props.push(...entries.filter(e => e[1] === true).map(e => { return game.bol.config.itemProperties2[e[0]] }))
|
|
||||||
}
|
|
||||||
return props.filter(p => !!p)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
# BoL DataModels
|
|
||||||
|
|
||||||
Ce dossier contient les DataModels pour le système Barbarians of Lemuria (BoL).
|
|
||||||
|
|
||||||
## Structure
|
|
||||||
|
|
||||||
### Actors DataModels
|
|
||||||
|
|
||||||
- **character.mjs** : Personnages joueurs
|
|
||||||
- Attributs (Vigor, Agility, Mind, Appeal)
|
|
||||||
- Aptitudes (Initiative, Mêlée, Distance, Défense)
|
|
||||||
- Ressources (HP, Hero Points, Faith, Power, Alchemy, Astrology)
|
|
||||||
- XP et création
|
|
||||||
- Bougette (argent)
|
|
||||||
|
|
||||||
- **encounter.mjs** : PNJ et créatures
|
|
||||||
- Mêmes attributs que character
|
|
||||||
- Champs spécifiques : chartype (tough/villain), isundead, size, environment
|
|
||||||
|
|
||||||
- **horde.mjs** : Hordes de créatures
|
|
||||||
- Mêmes attributs de base
|
|
||||||
- Champs spécifiques : hordesize, hordebasehp, hasdamagerule, damagerule
|
|
||||||
|
|
||||||
- **vehicle.mjs** : Véhicules (navires, chars, etc.)
|
|
||||||
- Attributs véhicules : hull, crew, resources
|
|
||||||
- Champs spécifiques : vehicletype, row, spur, status
|
|
||||||
|
|
||||||
### Items DataModels
|
|
||||||
|
|
||||||
- **item.mjs** : Équipements et objets
|
|
||||||
- Propriétés (weapon, armor, magical, etc.)
|
|
||||||
- Équipement (quantity, weight, price, worn)
|
|
||||||
- Category et subtype
|
|
||||||
|
|
||||||
- **feature.mjs** : Capacités, traits, sorts
|
|
||||||
- Rank (niveau/rang)
|
|
||||||
- Description
|
|
||||||
- Category et subtype
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
Tous les DataModels héritent de `foundry.abstract.TypeDataModel` et définissent leur schéma via `defineSchema()`.
|
|
||||||
|
|
||||||
Exemple de structure :
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
export default class BoLCharacterDataModel extends foundry.abstract.TypeDataModel {
|
|
||||||
static defineSchema() {
|
|
||||||
const fields = foundry.data.fields;
|
|
||||||
const requiredInteger = { required: true, nullable: false, integer: true };
|
|
||||||
|
|
||||||
return {
|
|
||||||
// Définition des champs
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static LOCALIZATION_PREFIXES = ["BOL.Character"];
|
|
||||||
|
|
||||||
// Méthodes personnalisées (à ajouter)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Types de champs utilisés
|
|
||||||
|
|
||||||
- `StringField` : Chaînes de caractères
|
|
||||||
- `NumberField` : Nombres (avec option `integer: true` pour entiers)
|
|
||||||
- `BooleanField` : Booléens
|
|
||||||
- `HTMLField` : HTML enrichi (descriptions, biographies)
|
|
||||||
- `ArrayField` : Tableaux
|
|
||||||
- `SchemaField` : Objets imbriqués
|
|
||||||
|
|
||||||
## Export
|
|
||||||
|
|
||||||
Le fichier `_module.mjs` exporte tous les DataModels :
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
export { default as BoLCharacter } from "./character.mjs"
|
|
||||||
export { default as BoLEncounter } from "./encounter.mjs"
|
|
||||||
export { default as BoLHorde } from "./horde.mjs"
|
|
||||||
export { default as BoLVehicle } from "./vehicle.mjs"
|
|
||||||
export { default as BoLItem } from "./item.mjs"
|
|
||||||
export { default as BoLFeature } from "./feature.mjs"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration dans bol.js
|
|
||||||
|
|
||||||
Les DataModels sont enregistrés dans `CONFIG` :
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
CONFIG.Actor.dataModels = {
|
|
||||||
character: models.BoLCharacter,
|
|
||||||
encounter: models.BoLEncounter,
|
|
||||||
horde: models.BoLHorde,
|
|
||||||
vehicle: models.BoLVehicle
|
|
||||||
}
|
|
||||||
|
|
||||||
CONFIG.Item.dataModels = {
|
|
||||||
item: models.BoLItem,
|
|
||||||
feature: models.BoLFeature
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Compatibilité
|
|
||||||
|
|
||||||
Les DataModels sont compatibles avec le `template.json` existant. La migration est transparente pour les données existantes.
|
|
||||||
|
|
||||||
## Prochaines étapes
|
|
||||||
|
|
||||||
1. Ajouter `prepareDerivedData()` pour les calculs automatiques
|
|
||||||
2. Migrer la logique métier depuis actor.js
|
|
||||||
3. Ajouter des validations personnalisées
|
|
||||||
4. Documenter avec JSDoc
|
|
||||||
@@ -413,108 +413,108 @@ BOL.bolEffectModifier = {
|
|||||||
BOL.statusEffects = [
|
BOL.statusEffects = [
|
||||||
{
|
{
|
||||||
"id": "dead",
|
"id": "dead",
|
||||||
"label": "EFFECT.StatusDead",
|
"name": "EFFECT.StatusDead",
|
||||||
"icon": "icons/svg/skull.svg"
|
"img": "icons/svg/skull.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "unconscious",
|
"id": "unconscious",
|
||||||
"label": "EFFECT.StatusUnconscious",
|
"name": "EFFECT.StatusUnconscious",
|
||||||
"icon": "icons/svg/unconscious.svg"
|
"img": "icons/svg/unconscious.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "sleep",
|
"id": "sleep",
|
||||||
"label": "EFFECT.StatusAsleep",
|
"name": "EFFECT.StatusAsleep",
|
||||||
"icon": "icons/svg/sleep.svg"
|
"img": "icons/svg/sleep.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "stun",
|
"id": "stun",
|
||||||
"label": "EFFECT.StatusStunned",
|
"name": "EFFECT.StatusStunned",
|
||||||
"icon": "icons/svg/daze.svg"
|
"img": "icons/svg/daze.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "prone",
|
"id": "prone",
|
||||||
"label": "EFFECT.StatusProne",
|
"name": "EFFECT.StatusProne",
|
||||||
"icon": "icons/svg/falling.svg"
|
"img": "icons/svg/falling.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "restrain",
|
"id": "restrain",
|
||||||
"label": "EFFECT.StatusRestrained",
|
"name": "EFFECT.StatusRestrained",
|
||||||
"icon": "icons/svg/net.svg"
|
"img": "icons/svg/net.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "paralysis",
|
"id": "paralysis",
|
||||||
"label": "EFFECT.StatusParalysis",
|
"name": "EFFECT.StatusParalysis",
|
||||||
"icon": "icons/svg/paralysis.svg"
|
"img": "icons/svg/paralysis.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "fly",
|
"id": "fly",
|
||||||
"label": "EFFECT.StatusFlying",
|
"name": "EFFECT.StatusFlying",
|
||||||
"icon": "icons/svg/wing.svg"
|
"img": "icons/svg/wing.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "blind",
|
"id": "blind",
|
||||||
"label": "EFFECT.StatusBlind",
|
"name": "EFFECT.StatusBlind",
|
||||||
"icon": "icons/svg/blind.svg"
|
"img": "icons/svg/blind.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "deaf",
|
"id": "deaf",
|
||||||
"label": "EFFECT.StatusDeaf",
|
"name": "EFFECT.StatusDeaf",
|
||||||
"icon": "icons/svg/deaf.svg"
|
"img": "icons/svg/deaf.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "silence",
|
"id": "silence",
|
||||||
"label": "EFFECT.StatusSilenced",
|
"name": "EFFECT.StatusSilenced",
|
||||||
"icon": "icons/svg/silenced.svg"
|
"img": "icons/svg/silenced.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "fear",
|
"id": "fear",
|
||||||
"label": "EFFECT.StatusFear",
|
"name": "EFFECT.StatusFear",
|
||||||
"icon": "icons/svg/terror.svg"
|
"img": "icons/svg/terror.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "burning",
|
"id": "burning",
|
||||||
"label": "EFFECT.StatusBurning",
|
"name": "EFFECT.StatusBurning",
|
||||||
"icon": "icons/svg/fire.svg"
|
"img": "icons/svg/fire.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "frozen",
|
"id": "frozen",
|
||||||
"label": "EFFECT.StatusFrozen",
|
"name": "EFFECT.StatusFrozen",
|
||||||
"icon": "icons/svg/frozen.svg"
|
"img": "icons/svg/frozen.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "shock",
|
"id": "shock",
|
||||||
"label": "EFFECT.StatusShocked",
|
"name": "EFFECT.StatusShocked",
|
||||||
"icon": "icons/svg/lightning.svg"
|
"img": "icons/svg/lightning.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "disease",
|
"id": "disease",
|
||||||
"label": "EFFECT.StatusDisease",
|
"name": "EFFECT.StatusDisease",
|
||||||
"icon": "icons/svg/biohazard.svg"
|
"img": "icons/svg/biohazard.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "poison",
|
"id": "poison",
|
||||||
"label": "EFFECT.StatusPoison",
|
"name": "EFFECT.StatusPoison",
|
||||||
"icon": "icons/svg/poison.svg"
|
"img": "icons/svg/poison.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "curse",
|
"id": "curse",
|
||||||
"label": "EFFECT.StatusCursed",
|
"name": "EFFECT.StatusCursed",
|
||||||
"icon": "icons/svg/sun.svg"
|
"img": "icons/svg/sun.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "invisible",
|
"id": "invisible",
|
||||||
"label": "EFFECT.StatusInvisible",
|
"name": "EFFECT.StatusInvisible",
|
||||||
"icon": "icons/svg/invisible.svg"
|
"img": "icons/svg/invisible.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "target",
|
"id": "target",
|
||||||
"label": "EFFECT.StatusTarget",
|
"name": "EFFECT.StatusTarget",
|
||||||
"icon": "icons/svg/target.svg"
|
"img": "icons/svg/target.svg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "eye",
|
"id": "eye",
|
||||||
"label": "EFFECT.StatusMarked",
|
"name": "EFFECT.StatusMarked",
|
||||||
"icon": "icons/svg/eye.svg"
|
"img": "icons/svg/eye.svg"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -1,52 +1,228 @@
|
|||||||
import {BoLRoll} from "../controllers/bol-rolls.js";
|
import { BoLRoll } from "../controllers/bol-rolls.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BoL Macro API — accessible via game.bol.macros
|
||||||
|
*
|
||||||
|
* Usage examples (in a Foundry macro):
|
||||||
|
*
|
||||||
|
* game.bol.macros.rollAttribute("vigor")
|
||||||
|
* game.bol.macros.rollAttribute("mind")
|
||||||
|
*
|
||||||
|
* game.bol.macros.rollAptitude("melee")
|
||||||
|
* game.bol.macros.rollAptitude("ranged")
|
||||||
|
* game.bol.macros.rollAptitude("def")
|
||||||
|
* game.bol.macros.rollAptitude("init")
|
||||||
|
*
|
||||||
|
* game.bol.macros.rollWeapon("Épée courte") // by name (partial match)
|
||||||
|
* game.bol.macros.rollWeapon(0) // by index (first weapon)
|
||||||
|
*
|
||||||
|
* game.bol.macros.rollSpell("Boule de feu") // by name (partial match)
|
||||||
|
* game.bol.macros.rollSpell(0) // by index
|
||||||
|
*
|
||||||
|
* game.bol.macros.rollAlchemy("Potion de soin") // by name (partial match)
|
||||||
|
* game.bol.macros.rollAlchemy(0) // by index
|
||||||
|
*
|
||||||
|
* game.bol.macros.rollHoroscope("minor")
|
||||||
|
* game.bol.macros.rollHoroscope("major")
|
||||||
|
*
|
||||||
|
* // Generic dispatcher:
|
||||||
|
* game.bol.macros.roll("attribute", "vigor")
|
||||||
|
* game.bol.macros.roll("aptitude", "melee")
|
||||||
|
* game.bol.macros.roll("weapon", "Épée courte")
|
||||||
|
* game.bol.macros.roll("spell", "Boule de feu")
|
||||||
|
* game.bol.macros.roll("alchemy", 0)
|
||||||
|
* game.bol.macros.roll("horoscope", "minor")
|
||||||
|
*/
|
||||||
export class Macros {
|
export class Macros {
|
||||||
/**
|
|
||||||
* @name getSpeakersActor
|
|
||||||
* @description
|
|
||||||
*
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
static getSpeakersActor = function(){
|
|
||||||
// Vérifie qu'un seul token est sélectionné
|
|
||||||
const tokens = canvas.tokens.controlled;
|
|
||||||
if (tokens.length > 1) {
|
|
||||||
ui.notifications.warn(game.i18n.localize('BOL.notification.MacroMultipleTokensSelected'));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const speaker = ChatMessage.getSpeaker();
|
/* -------------------------------------------- */
|
||||||
let actor;
|
/**
|
||||||
// Si un token est sélectionné, le prendre comme acteur cible
|
* Resolves the actor for macro use:
|
||||||
if (speaker.token) actor = game.actors.tokens[speaker.token];
|
* - If multiple tokens are selected → error (always)
|
||||||
// Sinon prendre l'acteur par défaut pour l'utilisateur courrant
|
* - If exactly one token is selected → use it (GM or player)
|
||||||
if (!actor) actor = game.actors.get(speaker.actor);
|
* - If no token selected and user is GM → error (GM must select a token)
|
||||||
return actor;
|
* - If no token selected and user is a player → use their assigned character
|
||||||
|
* @returns {Actor|null}
|
||||||
|
*/
|
||||||
|
static getSpeakersActor() {
|
||||||
|
const tokens = canvas.tokens?.controlled ?? []
|
||||||
|
|
||||||
|
if (tokens.length > 1) {
|
||||||
|
ui.notifications.warn(game.i18n.localize('BOL.notification.MacroMultipleTokensSelected'))
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
static rollMacro = async function (rollType, key, adv, mod){
|
if (tokens.length === 1) {
|
||||||
const actor = this.getSpeakersActor();
|
return tokens[0].actor ?? null
|
||||||
// Several tokens selected
|
|
||||||
if (actor === null) return;
|
|
||||||
// No token selected
|
|
||||||
if (actor === undefined) return ui.notifications.error(game.i18n.localize("BOL.notification.MacroNoTokenSelected"));
|
|
||||||
|
|
||||||
const actorData = {};
|
|
||||||
actorData.data = {
|
|
||||||
features : actor.buildFeatures()
|
|
||||||
};
|
|
||||||
|
|
||||||
if(rollType === "attribute") {
|
|
||||||
let attribute = eval(`actor.system.attributes.${key}`);
|
|
||||||
let rollLabel = (attribute.label) ? game.i18n.localize(attribute.label) : null;
|
|
||||||
let description = actor.name + " - " + game.i18n.localize('BOL.ui.attributeCheck') + " - " + game.i18n.localize(attribute.label) ;
|
|
||||||
BoLRoll.attributeRollDialog(actor, actorData, attribute, rollLabel, description, adv, mod);
|
|
||||||
}
|
|
||||||
else if(rollType === "aptitude") {
|
|
||||||
let aptitude = eval(`actor.system.aptitudes.${key}`);
|
|
||||||
let rollLabel = (aptitude.label) ? game.i18n.localize(aptitude.label) : null;
|
|
||||||
let description = actor.name + " - " + game.i18n.localize('BOL.ui.aptitudeCheck') + " - " + game.i18n.localize(aptitude.label) ;
|
|
||||||
BoLRoll.aptitudeRollDialog(actor, actorData, aptitude, rollLabel, description, adv, mod);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No token selected
|
||||||
|
if (game.user.isGM) {
|
||||||
|
ui.notifications.error(game.i18n.localize("BOL.notification.MacroNoTokenSelected"))
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// Player: fall back to their assigned character
|
||||||
|
const actor = game.user.character
|
||||||
|
if (!actor) {
|
||||||
|
ui.notifications.error(game.i18n.localize("BOL.notification.MacroNoTokenSelected"))
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return actor
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Finds an item on an actor by name (partial, case-insensitive) or index.
|
||||||
|
* @param {Actor} actor
|
||||||
|
* @param {string} type - item type: "weapon", "spell", "alchemy"
|
||||||
|
* @param {string|number} nameOrIndex
|
||||||
|
* @returns {object|undefined}
|
||||||
|
*/
|
||||||
|
static _findItem(actor, type, nameOrIndex) {
|
||||||
|
const items = actor.items.filter(i => i.type === type)
|
||||||
|
if (items.length === 0) {
|
||||||
|
ui.notifications.warn(`${actor.name} : aucun(e) ${type} trouvé(e).`)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
if (nameOrIndex === undefined || nameOrIndex === null) {
|
||||||
|
if (items.length === 1) return foundry.utils.duplicate(items[0])
|
||||||
|
const names = items.map((it, i) => `[${i}] ${it.name}`).join(', ')
|
||||||
|
ui.notifications.warn(`Précisez le nom ou l'index : ${names}`)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
if (typeof nameOrIndex === "number") {
|
||||||
|
const item = items[nameOrIndex]
|
||||||
|
if (!item) {
|
||||||
|
ui.notifications.warn(`${actor.name} : index ${nameOrIndex} invalide pour ${type}.`)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
return foundry.utils.duplicate(item)
|
||||||
|
}
|
||||||
|
const lower = String(nameOrIndex).toLowerCase()
|
||||||
|
const found = items.find(i => i.name.toLowerCase().includes(lower))
|
||||||
|
if (!found) {
|
||||||
|
ui.notifications.warn(`${actor.name} : ${type} "${nameOrIndex}" introuvable.`)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
return foundry.utils.duplicate(found)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Roll an attribute check.
|
||||||
|
* @param {string} key - "vigor" | "agility" | "mind" | "appeal"
|
||||||
|
* @param {Actor} [actor] - optional, defaults to selected/owned token
|
||||||
|
*/
|
||||||
|
static rollAttribute(key = "vigor", actor = undefined) {
|
||||||
|
actor = actor ?? this.getSpeakersActor()
|
||||||
|
if (!actor) return
|
||||||
|
if (!actor.system.attributes[key]) {
|
||||||
|
ui.notifications.warn(`Attribut inconnu : "${key}". Valeurs : vigor, agility, mind, appeal`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return BoLRoll.attributeCheck(actor, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Roll an aptitude check.
|
||||||
|
* @param {string} key - "init" | "melee" | "ranged" | "def"
|
||||||
|
* @param {Actor} [actor] - optional, defaults to selected/owned token
|
||||||
|
*/
|
||||||
|
static rollAptitude(key = "melee", actor = undefined) {
|
||||||
|
actor = actor ?? this.getSpeakersActor()
|
||||||
|
if (!actor) return
|
||||||
|
if (!actor.system.aptitudes[key]) {
|
||||||
|
ui.notifications.warn(`Aptitude inconnue : "${key}". Valeurs : init, melee, ranged, def`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return BoLRoll.aptitudeCheck(actor, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Roll a weapon attack.
|
||||||
|
* @param {string|number} [nameOrIndex] - weapon name (partial) or index. Defaults to first weapon if only one.
|
||||||
|
* @param {Actor} [actor] - optional, defaults to selected/owned token
|
||||||
|
*/
|
||||||
|
static rollWeapon(nameOrIndex = undefined, actor = undefined) {
|
||||||
|
actor = actor ?? this.getSpeakersActor()
|
||||||
|
if (!actor) return
|
||||||
|
const weapon = this._findItem(actor, "weapon", nameOrIndex)
|
||||||
|
if (!weapon) return
|
||||||
|
return BoLRoll.weaponCheckWithWeapon(actor, weapon)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Roll a spell check.
|
||||||
|
* @param {string|number} [nameOrIndex] - spell name (partial) or index
|
||||||
|
* @param {Actor} [actor] - optional, defaults to selected/owned token
|
||||||
|
*/
|
||||||
|
static rollSpell(nameOrIndex = undefined, actor = undefined) {
|
||||||
|
actor = actor ?? this.getSpeakersActor()
|
||||||
|
if (!actor) return
|
||||||
|
if ((actor.system.resources.power?.value ?? 1) <= 0) {
|
||||||
|
ui.notifications.warn("Plus assez de points de Pouvoir !")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const spell = this._findItem(actor, "spell", nameOrIndex)
|
||||||
|
if (!spell) return
|
||||||
|
return BoLRoll.spellCheckWithSpell(actor, spell)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Roll an alchemy check.
|
||||||
|
* @param {string|number} [nameOrIndex] - alchemy item name (partial) or index
|
||||||
|
* @param {Actor} [actor] - optional, defaults to selected/owned token
|
||||||
|
*/
|
||||||
|
static rollAlchemy(nameOrIndex = undefined, actor = undefined) {
|
||||||
|
actor = actor ?? this.getSpeakersActor()
|
||||||
|
if (!actor) return
|
||||||
|
const alchemy = this._findItem(actor, "alchemy", nameOrIndex)
|
||||||
|
if (!alchemy) return
|
||||||
|
return BoLRoll.alchemyCheckWithItem(actor, alchemy)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Roll a horoscope check.
|
||||||
|
* @param {"minor"|"major"} [type="minor"]
|
||||||
|
* @param {Actor} [actor] - optional, defaults to selected/owned token
|
||||||
|
*/
|
||||||
|
static rollHoroscope(type = "minor", actor = undefined) {
|
||||||
|
actor = actor ?? this.getSpeakersActor()
|
||||||
|
if (!actor) return
|
||||||
|
return BoLRoll.horoscopeCheck(actor, undefined, type)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Generic roll dispatcher.
|
||||||
|
* @param {"attribute"|"aptitude"|"weapon"|"spell"|"alchemy"|"horoscope"} type
|
||||||
|
* @param {string|number} [key] - attribute/aptitude key, item name/index, or horoscope type
|
||||||
|
* @param {Actor} [actor] - optional, defaults to selected/owned token
|
||||||
|
*/
|
||||||
|
static roll(type, key = undefined, actor = undefined) {
|
||||||
|
switch (type) {
|
||||||
|
case "attribute": return this.rollAttribute(key ?? "vigor", actor)
|
||||||
|
case "aptitude": return this.rollAptitude(key ?? "melee", actor)
|
||||||
|
case "weapon": return this.rollWeapon(key, actor)
|
||||||
|
case "spell": return this.rollSpell(key, actor)
|
||||||
|
case "alchemy": return this.rollAlchemy(key, actor)
|
||||||
|
case "horoscope": return this.rollHoroscope(key ?? "minor", actor)
|
||||||
|
default:
|
||||||
|
ui.notifications.warn(`Type de jet inconnu : "${type}". Types valides : attribute, aptitude, weapon, spell, alchemy, horoscope`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
// Kept for backward-compat (previously called by old macros)
|
||||||
|
static rollMacro = async function (rollType, key) {
|
||||||
|
const actor = Macros.getSpeakersActor()
|
||||||
|
if (!actor) return
|
||||||
|
return Macros.roll(rollType, key, actor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
MANIFEST-001084
|
MANIFEST-001233
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
2026/03/16-19:46:09.197185 7f766a3fe6c0 Delete type=3 #1
|
2026/08/03-06:19:48.779385 7f0fa7fff6c0 Recovering log #1231
|
||||||
2026/03/16-20:16:08.421989 7f7668bfb6c0 Level-0 table #1087: started
|
2026/08/03-06:19:48.790078 7f0fa7fff6c0 Delete type=3 #1229
|
||||||
2026/03/16-20:16:08.422032 7f7668bfb6c0 Level-0 table #1087: 0 bytes OK
|
2026/08/03-06:19:48.790149 7f0fa7fff6c0 Delete type=0 #1231
|
||||||
2026/03/16-20:16:08.428629 7f7668bfb6c0 Delete type=0 #1085
|
2026/08/03-06:38:26.831982 7f0fa6ffd6c0 Level-0 table #1236: started
|
||||||
2026/03/16-20:16:08.454903 7f7668bfb6c0 Manual compaction at level-0 from '!journal!3xJg1rCxnWvEmoxS' @ 72057594037927935 : 1 .. '!journal.pages!veAAxCtCKcFIsnln.0kUgZspxXO7VS8bd' @ 0 : 0; will stop at '!journal.pages!veAAxCtCKcFIsnln.0kUgZspxXO7VS8bd' @ 283 : 1
|
2026/08/03-06:38:26.832007 7f0fa6ffd6c0 Level-0 table #1236: 0 bytes OK
|
||||||
2026/03/16-20:16:08.454928 7f7668bfb6c0 Compacting 1@0 + 0@1 files
|
2026/08/03-06:38:26.838786 7f0fa6ffd6c0 Delete type=0 #1234
|
||||||
2026/03/16-20:16:08.459641 7f7668bfb6c0 Generated table #1088@0: 24 keys, 28007 bytes
|
2026/08/03-06:38:26.853917 7f0fa6ffd6c0 Manual compaction at level-0 from '!journal!6cCdSvQgEHJ1bvX4' @ 72057594037927935 : 1 .. '!journal.pages!veAAxCtCKcFIsnln.0kUgZspxXO7VS8bd' @ 0 : 0; will stop at (end)
|
||||||
2026/03/16-20:16:08.459663 7f7668bfb6c0 Compacted 1@0 + 0@1 files => 28007 bytes
|
|
||||||
2026/03/16-20:16:08.466040 7f7668bfb6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
|
|
||||||
2026/03/16-20:16:08.466219 7f7668bfb6c0 Delete type=2 #774
|
|
||||||
2026/03/16-20:16:08.488702 7f7668bfb6c0 Manual compaction at level-0 from '!journal.pages!veAAxCtCKcFIsnln.0kUgZspxXO7VS8bd' @ 283 : 1 .. '!journal.pages!veAAxCtCKcFIsnln.0kUgZspxXO7VS8bd' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
2026/03/16-19:46:09.175786 7f766a3fe6c0 Log #1082: 0 ops saved to Table #1083 OK
|
2026/08/03-05:42:23.756827 7f0ff4ffe6c0 Recovering log #1227
|
||||||
2026/03/16-19:46:09.176080 7f766a3fe6c0 Archiving /home/morr/foundry/foundrydata-v13/Data/systems/bol/packs/aides-de-jeu/001082.log: OK
|
2026/08/03-05:42:23.787896 7f0ff4ffe6c0 Delete type=3 #1225
|
||||||
2026/03/16-19:46:09.177100 7f766a3fe6c0 Table #774: 24 entries OK
|
2026/08/03-05:42:23.787958 7f0ff4ffe6c0 Delete type=0 #1227
|
||||||
2026/03/16-19:46:09.180960 7f766a3fe6c0 **** Repaired leveldb /home/morr/foundry/foundrydata-v13/Data/systems/bol/packs/aides-de-jeu; recovered 1 files; 28007 bytes. Some data may have been lost. ****
|
2026/08/03-06:19:13.177131 7f0fa6ffd6c0 Level-0 table #1232: started
|
||||||
|
2026/08/03-06:19:13.177159 7f0fa6ffd6c0 Level-0 table #1232: 0 bytes OK
|
||||||
|
2026/08/03-06:19:13.184606 7f0fa6ffd6c0 Delete type=0 #1230
|
||||||
|
2026/08/03-06:19:13.191444 7f0fa6ffd6c0 Manual compaction at level-0 from '!journal!6cCdSvQgEHJ1bvX4' @ 72057594037927935 : 1 .. '!journal.pages!veAAxCtCKcFIsnln.0kUgZspxXO7VS8bd' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
MANIFEST-000989
|
MANIFEST-001134
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
2026/03/16-19:46:09.143692 7f7669bfd6c0 Delete type=3 #1
|
2026/08/03-06:19:48.750852 7f0ff57ff6c0 Recovering log #1132
|
||||||
2026/03/16-20:16:08.436084 7f7668bfb6c0 Level-0 table #992: started
|
2026/08/03-06:19:48.761758 7f0ff57ff6c0 Delete type=3 #1130
|
||||||
2026/03/16-20:16:08.436127 7f7668bfb6c0 Level-0 table #992: 0 bytes OK
|
2026/08/03-06:19:48.761842 7f0ff57ff6c0 Delete type=0 #1132
|
||||||
2026/03/16-20:16:08.443698 7f7668bfb6c0 Delete type=0 #990
|
2026/08/03-06:38:26.817856 7f0fa6ffd6c0 Level-0 table #1137: started
|
||||||
2026/03/16-20:16:08.477884 7f7668bfb6c0 Manual compaction at level-0 from '!items!G3dZTHIabA3LA1hY' @ 72057594037927935 : 1 .. '!items!xhEcsi3WHjbt2ro9' @ 0 : 0; will stop at '!items!xhEcsi3WHjbt2ro9' @ 42 : 1
|
2026/08/03-06:38:26.817889 7f0fa6ffd6c0 Level-0 table #1137: 0 bytes OK
|
||||||
2026/03/16-20:16:08.477902 7f7668bfb6c0 Compacting 1@0 + 0@1 files
|
2026/08/03-06:38:26.824151 7f0fa6ffd6c0 Delete type=0 #1135
|
||||||
2026/03/16-20:16:08.481701 7f7668bfb6c0 Generated table #993@0: 6 keys, 5424 bytes
|
2026/08/03-06:38:26.824513 7f0fa6ffd6c0 Manual compaction at level-0 from '!items!G3dZTHIabA3LA1hY' @ 72057594037927935 : 1 .. '!items!xhEcsi3WHjbt2ro9' @ 0 : 0; will stop at (end)
|
||||||
2026/03/16-20:16:08.481748 7f7668bfb6c0 Compacted 1@0 + 0@1 files => 5424 bytes
|
|
||||||
2026/03/16-20:16:08.488315 7f7668bfb6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
|
|
||||||
2026/03/16-20:16:08.488463 7f7668bfb6c0 Delete type=2 #679
|
|
||||||
2026/03/16-20:16:08.488751 7f7668bfb6c0 Manual compaction at level-0 from '!items!xhEcsi3WHjbt2ro9' @ 42 : 1 .. '!items!xhEcsi3WHjbt2ro9' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
2026/03/16-19:46:09.120613 7f7669bfd6c0 Log #987: 0 ops saved to Table #988 OK
|
2026/08/03-05:42:23.674797 7f0fa7fff6c0 Recovering log #1128
|
||||||
2026/03/16-19:46:09.120850 7f7669bfd6c0 Archiving /home/morr/foundry/foundrydata-v13/Data/systems/bol/packs/armors/000987.log: OK
|
2026/08/03-05:42:23.703359 7f0fa7fff6c0 Delete type=3 #1126
|
||||||
2026/03/16-19:46:09.121424 7f7669bfd6c0 Table #679: 6 entries OK
|
2026/08/03-05:42:23.703453 7f0fa7fff6c0 Delete type=0 #1128
|
||||||
2026/03/16-19:46:09.125224 7f7669bfd6c0 **** Repaired leveldb /home/morr/foundry/foundrydata-v13/Data/systems/bol/packs/armors; recovered 1 files; 5424 bytes. Some data may have been lost. ****
|
2026/08/03-06:19:13.162949 7f0fa6ffd6c0 Level-0 table #1133: started
|
||||||
|
2026/08/03-06:19:13.162995 7f0fa6ffd6c0 Level-0 table #1133: 0 bytes OK
|
||||||
|
2026/08/03-06:19:13.170299 7f0fa6ffd6c0 Delete type=0 #1131
|
||||||
|
2026/08/03-06:19:13.184757 7f0fa6ffd6c0 Manual compaction at level-0 from '!items!G3dZTHIabA3LA1hY' @ 72057594037927935 : 1 .. '!items!xhEcsi3WHjbt2ro9' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
MANIFEST-001083
|
MANIFEST-001228
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
2026/03/16-19:46:08.857890 7f766abff6c0 Delete type=3 #1
|
2026/08/03-06:19:48.636406 7f0ff4ffe6c0 Recovering log #1226
|
||||||
2026/03/16-20:16:08.265157 7f7668bfb6c0 Level-0 table #1086: started
|
2026/08/03-06:19:48.647892 7f0ff4ffe6c0 Delete type=3 #1224
|
||||||
2026/03/16-20:16:08.265207 7f7668bfb6c0 Level-0 table #1086: 0 bytes OK
|
2026/08/03-06:19:48.647974 7f0ff4ffe6c0 Delete type=0 #1226
|
||||||
2026/03/16-20:16:08.272133 7f7668bfb6c0 Delete type=0 #1084
|
2026/08/03-06:38:26.769280 7f0fa6ffd6c0 Level-0 table #1231: started
|
||||||
2026/03/16-20:16:08.299945 7f7668bfb6c0 Manual compaction at level-0 from '!items!039ZF3E3MtAGwbiX' @ 72057594037927935 : 1 .. '!items!zgspy1QKaxdEetEw' @ 0 : 0; will stop at '!items!zgspy1QKaxdEetEw' @ 533 : 1
|
2026/08/03-06:38:26.769359 7f0fa6ffd6c0 Level-0 table #1231: 0 bytes OK
|
||||||
2026/03/16-20:16:08.299966 7f7668bfb6c0 Compacting 1@0 + 0@1 files
|
2026/08/03-06:38:26.776073 7f0fa6ffd6c0 Delete type=0 #1229
|
||||||
2026/03/16-20:16:08.305068 7f7668bfb6c0 Generated table #1087@0: 61 keys, 20970 bytes
|
2026/08/03-06:38:26.797077 7f0fa6ffd6c0 Manual compaction at level-0 from '!items!039ZF3E3MtAGwbiX' @ 72057594037927935 : 1 .. '!items!zgspy1QKaxdEetEw' @ 0 : 0; will stop at (end)
|
||||||
2026/03/16-20:16:08.305111 7f7668bfb6c0 Compacted 1@0 + 0@1 files => 20970 bytes
|
|
||||||
2026/03/16-20:16:08.311829 7f7668bfb6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
|
|
||||||
2026/03/16-20:16:08.312005 7f7668bfb6c0 Delete type=2 #843
|
|
||||||
2026/03/16-20:16:08.335606 7f7668bfb6c0 Manual compaction at level-0 from '!items!zgspy1QKaxdEetEw' @ 533 : 1 .. '!items!zgspy1QKaxdEetEw' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
2026/03/16-19:46:08.539383 7f766abff6c0 Log #1081: 0 ops saved to Table #1082 OK
|
2026/08/03-05:42:23.425060 7f0fa7fff6c0 Recovering log #1222
|
||||||
2026/03/16-19:46:08.539570 7f766abff6c0 Archiving /home/morr/foundry/foundrydata-v13/Data/systems/bol/packs/boons/001081.log: OK
|
2026/08/03-05:42:23.456278 7f0fa7fff6c0 Delete type=3 #1220
|
||||||
2026/03/16-19:46:08.540406 7f766abff6c0 Table #843: 61 entries OK
|
2026/08/03-05:42:23.456346 7f0fa7fff6c0 Delete type=0 #1222
|
||||||
2026/03/16-19:46:08.544540 7f766abff6c0 **** Repaired leveldb /home/morr/foundry/foundrydata-v13/Data/systems/bol/packs/boons; recovered 1 files; 20970 bytes. Some data may have been lost. ****
|
2026/08/03-06:19:13.105722 7f0fa6ffd6c0 Level-0 table #1227: started
|
||||||
|
2026/08/03-06:19:13.105794 7f0fa6ffd6c0 Level-0 table #1227: 0 bytes OK
|
||||||
|
2026/08/03-06:19:13.112554 7f0fa6ffd6c0 Delete type=0 #1225
|
||||||
|
2026/08/03-06:19:13.133354 7f0fa6ffd6c0 Manual compaction at level-0 from '!items!039ZF3E3MtAGwbiX' @ 72057594037927935 : 1 .. '!items!zgspy1QKaxdEetEw' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
MANIFEST-001082
|
MANIFEST-001227
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
2026/03/16-19:46:08.909016 7f76693fc6c0 Delete type=3 #1
|
2026/08/03-06:19:48.651558 7f0ff57ff6c0 Recovering log #1225
|
||||||
2026/03/16-20:16:08.272330 7f7668bfb6c0 Level-0 table #1085: started
|
2026/08/03-06:19:48.662260 7f0ff57ff6c0 Delete type=3 #1223
|
||||||
2026/03/16-20:16:08.272372 7f7668bfb6c0 Level-0 table #1085: 0 bytes OK
|
2026/08/03-06:19:48.662354 7f0ff57ff6c0 Delete type=0 #1225
|
||||||
2026/03/16-20:16:08.279546 7f7668bfb6c0 Delete type=0 #1083
|
2026/08/03-06:38:26.782903 7f0fa6ffd6c0 Level-0 table #1230: started
|
||||||
2026/03/16-20:16:08.312273 7f7668bfb6c0 Manual compaction at level-0 from '!items!CoqlfsDV1gL5swbK' @ 72057594037927935 : 1 .. '!items!yofwG0YrsL902G77' @ 0 : 0; will stop at '!items!yofwG0YrsL902G77' @ 64 : 1
|
2026/08/03-06:38:26.782939 7f0fa6ffd6c0 Level-0 table #1230: 0 bytes OK
|
||||||
2026/03/16-20:16:08.312291 7f7668bfb6c0 Compacting 1@0 + 0@1 files
|
2026/08/03-06:38:26.790042 7f0fa6ffd6c0 Delete type=0 #1228
|
||||||
2026/03/16-20:16:08.316030 7f7668bfb6c0 Generated table #1086@0: 8 keys, 2453 bytes
|
2026/08/03-06:38:26.797110 7f0fa6ffd6c0 Manual compaction at level-0 from '!items!CoqlfsDV1gL5swbK' @ 72057594037927935 : 1 .. '!items!yofwG0YrsL902G77' @ 0 : 0; will stop at (end)
|
||||||
2026/03/16-20:16:08.316070 7f7668bfb6c0 Compacted 1@0 + 0@1 files => 2453 bytes
|
|
||||||
2026/03/16-20:16:08.323057 7f7668bfb6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
|
|
||||||
2026/03/16-20:16:08.323234 7f7668bfb6c0 Delete type=2 #772
|
|
||||||
2026/03/16-20:16:08.335626 7f7668bfb6c0 Manual compaction at level-0 from '!items!yofwG0YrsL902G77' @ 64 : 1 .. '!items!yofwG0YrsL902G77' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
2026/03/16-19:46:08.865328 7f76693fc6c0 Log #1080: 0 ops saved to Table #1081 OK
|
2026/08/03-05:42:23.460746 7f0fa77fe6c0 Recovering log #1221
|
||||||
2026/03/16-19:46:08.865565 7f76693fc6c0 Archiving /home/morr/foundry/foundrydata-v13/Data/systems/bol/packs/boonsflawscreatures/001080.log: OK
|
2026/08/03-05:42:23.486451 7f0fa77fe6c0 Delete type=3 #1219
|
||||||
2026/03/16-19:46:08.865990 7f76693fc6c0 Table #772: 8 entries OK
|
2026/08/03-05:42:23.486511 7f0fa77fe6c0 Delete type=0 #1221
|
||||||
2026/03/16-19:46:08.869744 7f76693fc6c0 **** Repaired leveldb /home/morr/foundry/foundrydata-v13/Data/systems/bol/packs/boonsflawscreatures; recovered 1 files; 2453 bytes. Some data may have been lost. ****
|
2026/08/03-06:19:13.112716 7f0fa6ffd6c0 Level-0 table #1226: started
|
||||||
|
2026/08/03-06:19:13.112749 7f0fa6ffd6c0 Level-0 table #1226: 0 bytes OK
|
||||||
|
2026/08/03-06:19:13.119007 7f0fa6ffd6c0 Delete type=0 #1224
|
||||||
|
2026/08/03-06:19:13.133376 7f0fa6ffd6c0 Manual compaction at level-0 from '!items!CoqlfsDV1gL5swbK' @ 72057594037927935 : 1 .. '!items!yofwG0YrsL902G77' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
MANIFEST-001082
|
MANIFEST-001227
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
2026/03/16-19:46:09.002243 7f76693fc6c0 Delete type=3 #1
|
2026/08/03-06:19:48.681657 7f0ff4ffe6c0 Recovering log #1225
|
||||||
2026/03/16-20:16:08.279807 7f7668bfb6c0 Level-0 table #1085: started
|
2026/08/03-06:19:48.692268 7f0ff4ffe6c0 Delete type=3 #1223
|
||||||
2026/03/16-20:16:08.279852 7f7668bfb6c0 Level-0 table #1085: 0 bytes OK
|
2026/08/03-06:19:48.692351 7f0ff4ffe6c0 Delete type=0 #1225
|
||||||
2026/03/16-20:16:08.287482 7f7668bfb6c0 Delete type=0 #1083
|
2026/08/03-06:38:26.790164 7f0fa6ffd6c0 Level-0 table #1230: started
|
||||||
2026/03/16-20:16:08.323479 7f7668bfb6c0 Manual compaction at level-0 from '!items!4S4xAfMXGnuU0O1a' @ 72057594037927935 : 1 .. '!items!zxY3sW0iCJBvwjOS' @ 0 : 0; will stop at '!items!zxY3sW0iCJBvwjOS' @ 215 : 1
|
2026/08/03-06:38:26.790190 7f0fa6ffd6c0 Level-0 table #1230: 0 bytes OK
|
||||||
2026/03/16-20:16:08.323495 7f7668bfb6c0 Compacting 1@0 + 0@1 files
|
2026/08/03-06:38:26.796894 7f0fa6ffd6c0 Delete type=0 #1228
|
||||||
2026/03/16-20:16:08.328403 7f7668bfb6c0 Generated table #1086@0: 27 keys, 42639 bytes
|
2026/08/03-06:38:26.797197 7f0fa6ffd6c0 Manual compaction at level-0 from '!items!4S4xAfMXGnuU0O1a' @ 72057594037927935 : 1 .. '!items!zxY3sW0iCJBvwjOS' @ 0 : 0; will stop at (end)
|
||||||
2026/03/16-20:16:08.328434 7f7668bfb6c0 Compacted 1@0 + 0@1 files => 42639 bytes
|
|
||||||
2026/03/16-20:16:08.335062 7f7668bfb6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
|
|
||||||
2026/03/16-20:16:08.335267 7f7668bfb6c0 Delete type=2 #772
|
|
||||||
2026/03/16-20:16:08.335642 7f7668bfb6c0 Manual compaction at level-0 from '!items!zxY3sW0iCJBvwjOS' @ 215 : 1 .. '!items!zxY3sW0iCJBvwjOS' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
2026/03/16-19:46:08.971933 7f76693fc6c0 Log #1080: 0 ops saved to Table #1081 OK
|
2026/08/03-05:42:23.515629 7f0fa77fe6c0 Recovering log #1221
|
||||||
2026/03/16-19:46:08.972193 7f76693fc6c0 Archiving /home/morr/foundry/foundrydata-v13/Data/systems/bol/packs/careers/001080.log: OK
|
2026/08/03-05:42:23.541236 7f0fa77fe6c0 Delete type=3 #1219
|
||||||
2026/03/16-19:46:08.973605 7f76693fc6c0 Table #772: 27 entries OK
|
2026/08/03-05:42:23.541308 7f0fa77fe6c0 Delete type=0 #1221
|
||||||
2026/03/16-19:46:08.977409 7f76693fc6c0 **** Repaired leveldb /home/morr/foundry/foundrydata-v13/Data/systems/bol/packs/careers; recovered 1 files; 42639 bytes. Some data may have been lost. ****
|
2026/08/03-06:19:13.126577 7f0fa6ffd6c0 Level-0 table #1226: started
|
||||||
|
2026/08/03-06:19:13.126609 7f0fa6ffd6c0 Level-0 table #1226: 0 bytes OK
|
||||||
|
2026/08/03-06:19:13.133180 7f0fa6ffd6c0 Delete type=0 #1224
|
||||||
|
2026/08/03-06:19:13.133414 7f0fa6ffd6c0 Manual compaction at level-0 from '!items!4S4xAfMXGnuU0O1a' @ 72057594037927935 : 1 .. '!items!zxY3sW0iCJBvwjOS' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
MANIFEST-001080
|
MANIFEST-001225
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
2026/03/16-19:46:09.384452 7f766abff6c0 Delete type=3 #1
|
2026/08/03-06:19:48.879803 7f0ff57ff6c0 Recovering log #1223
|
||||||
2026/03/16-20:16:08.596026 7f7668bfb6c0 Level-0 table #1083: started
|
2026/08/03-06:19:48.890084 7f0ff57ff6c0 Delete type=3 #1221
|
||||||
2026/03/16-20:16:08.596072 7f7668bfb6c0 Level-0 table #1083: 0 bytes OK
|
2026/08/03-06:19:48.890177 7f0ff57ff6c0 Delete type=0 #1223
|
||||||
2026/03/16-20:16:08.604284 7f7668bfb6c0 Delete type=0 #1081
|
2026/08/03-06:38:26.891447 7f0fa6ffd6c0 Level-0 table #1228: started
|
||||||
2026/03/16-20:16:08.616512 7f7668bfb6c0 Manual compaction at level-0 from '!items!6fTZ6hOKR4pWbWOe' @ 72057594037927935 : 1 .. '!items!zwSNMO9HpiqUCMt8' @ 0 : 0; will stop at '!items!zwSNMO9HpiqUCMt8' @ 24 : 1
|
2026/08/03-06:38:26.891477 7f0fa6ffd6c0 Level-0 table #1228: 0 bytes OK
|
||||||
2026/03/16-20:16:08.616529 7f7668bfb6c0 Compacting 1@0 + 0@1 files
|
2026/08/03-06:38:26.898218 7f0fa6ffd6c0 Delete type=0 #1226
|
||||||
2026/03/16-20:16:08.620595 7f7668bfb6c0 Generated table #1084@0: 4 keys, 990 bytes
|
2026/08/03-06:38:26.913139 7f0fa6ffd6c0 Manual compaction at level-0 from '!items!6fTZ6hOKR4pWbWOe' @ 72057594037927935 : 1 .. '!items!zwSNMO9HpiqUCMt8' @ 0 : 0; will stop at (end)
|
||||||
2026/03/16-20:16:08.620628 7f7668bfb6c0 Compacted 1@0 + 0@1 files => 990 bytes
|
|
||||||
2026/03/16-20:16:08.627657 7f7668bfb6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
|
|
||||||
2026/03/16-20:16:08.627801 7f7668bfb6c0 Delete type=2 #770
|
|
||||||
2026/03/16-20:16:08.667532 7f7668bfb6c0 Manual compaction at level-0 from '!items!zwSNMO9HpiqUCMt8' @ 24 : 1 .. '!items!zwSNMO9HpiqUCMt8' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
2026/03/16-19:46:09.364109 7f766abff6c0 Log #1078: 0 ops saved to Table #1079 OK
|
2026/08/03-05:42:23.971932 7f0fa7fff6c0 Recovering log #1219
|
||||||
2026/03/16-19:46:09.364398 7f766abff6c0 Archiving /home/morr/foundry/foundrydata-v13/Data/systems/bol/packs/effets-exemples/001078.log: OK
|
2026/08/03-05:42:24.003012 7f0fa7fff6c0 Delete type=3 #1217
|
||||||
2026/03/16-19:46:09.364562 7f766abff6c0 Table #770: 4 entries OK
|
2026/08/03-05:42:24.003097 7f0fa7fff6c0 Delete type=0 #1219
|
||||||
2026/03/16-19:46:09.368408 7f766abff6c0 **** Repaired leveldb /home/morr/foundry/foundrydata-v13/Data/systems/bol/packs/effets-exemples; recovered 1 files; 990 bytes. Some data may have been lost. ****
|
2026/08/03-06:19:13.219392 7f0fa6ffd6c0 Level-0 table #1224: started
|
||||||
|
2026/08/03-06:19:13.219417 7f0fa6ffd6c0 Level-0 table #1224: 0 bytes OK
|
||||||
|
2026/08/03-06:19:13.225913 7f0fa6ffd6c0 Delete type=0 #1222
|
||||||
|
2026/08/03-06:19:13.239931 7f0fa6ffd6c0 Manual compaction at level-0 from '!items!6fTZ6hOKR4pWbWOe' @ 72057594037927935 : 1 .. '!items!zwSNMO9HpiqUCMt8' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
MANIFEST-001083
|
MANIFEST-001228
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
2026/03/16-19:46:09.085657 7f766abff6c0 Delete type=3 #1
|
2026/08/03-06:19:48.722782 7f0ff57ff6c0 Recovering log #1226
|
||||||
2026/03/16-20:16:08.351512 7f7668bfb6c0 Level-0 table #1086: started
|
2026/08/03-06:19:48.732938 7f0ff57ff6c0 Delete type=3 #1224
|
||||||
2026/03/16-20:16:08.351558 7f7668bfb6c0 Level-0 table #1086: 0 bytes OK
|
2026/08/03-06:19:48.733013 7f0ff57ff6c0 Delete type=0 #1226
|
||||||
2026/03/16-20:16:08.358533 7f7668bfb6c0 Delete type=0 #1084
|
2026/08/03-06:38:26.811182 7f0fa6ffd6c0 Level-0 table #1231: started
|
||||||
2026/03/16-20:16:08.390133 7f7668bfb6c0 Manual compaction at level-0 from '!items!0ErhyqifZLDCmMfT' @ 72057594037927935 : 1 .. '!items!yE8UH6YAgNGjKDEu' @ 0 : 0; will stop at '!items!yE8UH6YAgNGjKDEu' @ 499 : 1
|
2026/08/03-06:38:26.811213 7f0fa6ffd6c0 Level-0 table #1231: 0 bytes OK
|
||||||
2026/03/16-20:16:08.390150 7f7668bfb6c0 Compacting 1@0 + 0@1 files
|
2026/08/03-06:38:26.817698 7f0fa6ffd6c0 Delete type=0 #1229
|
||||||
2026/03/16-20:16:08.394184 7f7668bfb6c0 Generated table #1087@0: 43 keys, 9886 bytes
|
2026/08/03-06:38:26.824339 7f0fa6ffd6c0 Manual compaction at level-0 from '!items!0ErhyqifZLDCmMfT' @ 72057594037927935 : 1 .. '!items!yE8UH6YAgNGjKDEu' @ 0 : 0; will stop at (end)
|
||||||
2026/03/16-20:16:08.394206 7f7668bfb6c0 Compacted 1@0 + 0@1 files => 9886 bytes
|
|
||||||
2026/03/16-20:16:08.401465 7f7668bfb6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
|
|
||||||
2026/03/16-20:16:08.401654 7f7668bfb6c0 Delete type=2 #773
|
|
||||||
2026/03/16-20:16:08.413820 7f7668bfb6c0 Manual compaction at level-0 from '!items!yE8UH6YAgNGjKDEu' @ 499 : 1 .. '!items!yE8UH6YAgNGjKDEu' @ 0 : 0; will stop at (end)
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
2026/03/16-19:46:09.065759 7f766abff6c0 Log #1081: 0 ops saved to Table #1082 OK
|
2026/08/03-05:42:23.605916 7f0fa7fff6c0 Recovering log #1222
|
||||||
2026/03/16-19:46:09.065989 7f766abff6c0 Archiving /home/morr/foundry/foundrydata-v13/Data/systems/bol/packs/equipment/001081.log: OK
|
2026/08/03-05:42:23.631047 7f0fa7fff6c0 Delete type=3 #1220
|
||||||
2026/03/16-19:46:09.066756 7f766abff6c0 Table #773: 43 entries OK
|
2026/08/03-05:42:23.631116 7f0fa7fff6c0 Delete type=0 #1222
|
||||||
2026/03/16-19:46:09.070319 7f766abff6c0 **** Repaired leveldb /home/morr/foundry/foundrydata-v13/Data/systems/bol/packs/equipment; recovered 1 files; 9886 bytes. Some data may have been lost. ****
|
2026/08/03-06:19:13.148540 7f0fa6ffd6c0 Level-0 table #1227: started
|
||||||
|
2026/08/03-06:19:13.148573 7f0fa6ffd6c0 Level-0 table #1227: 0 bytes OK
|
||||||
|
2026/08/03-06:19:13.155217 7f0fa6ffd6c0 Delete type=0 #1225
|
||||||
|
2026/08/03-06:19:13.162717 7f0fa6ffd6c0 Manual compaction at level-0 from '!items!0ErhyqifZLDCmMfT' @ 72057594037927935 : 1 .. '!items!yE8UH6YAgNGjKDEu' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
MANIFEST-001082
|
MANIFEST-001227
|
||||||
|
|||||||