Compare commits

..

42 Commits

Author SHA1 Message Date
d75b6cb945 Second round de modifications 2026-04-24 13:37:59 +02:00
779b4c60f5 Release script
Some checks failed
Release Creation / build (release) Failing after 1m36s
2026-04-23 17:06:45 +02:00
84608ffbf7 Première release testée 2026-04-23 15:50:22 +02:00
2fbcfa52aa Première release testée 2026-04-23 15:49:58 +02:00
9e9d2c4f3e First round of changes 2026-04-23 14:31:06 +02:00
abe35cb537 First round of changes 2026-04-23 14:27:33 +02:00
f72230dd39 First round of changes 2026-04-23 14:27:27 +02:00
Vlyan
36a66d3eac Release v1.13.4 2026-03-01 12:39:48 +01:00
Vlyan
317411ce60 Sync languages files from English 2026-03-01 12:30:01 +01:00
Vlyan
3c6529bc99 Updated items from import 2026-03-01 12:04:57 +01:00
Litasa
061390df80 Edit CHANGELOG.md 2026-03-01 08:12:38 +00:00
Litasa
b4fd1c738f Updated CHANGELOG.md Release 1.13.4 2026-03-01 07:57:26 +00:00
Litasa
c7d6c6c5e5 Merge branch 'some_missing_items' into 'dev'
Updating compendiums:
* Adding some items for Starting Outfits that was not in the system
* Split Poison and Omamori into individual items since it makes sense
* Added the specific items contained in a "Travelers Pack"
* Added arrow types not added from core book

See merge request teaml5r/l5r5e!58
2026-03-01 07:39:24 +00:00
Litasa
31f094818e Updating compendiums:
* Adding some items for Starting Outfits that was not in the system
* Split Poison and Omamori into individual items since it makes sense (old items will now be generic)
* Added the specific items contained in a "Travelers Pack"
* Added arrow types not added from core book
2026-03-01 07:39:24 +00:00
Litasa
40afa53337 Merge branch 'better_select_for_combat_tracker' into 'dev'
Adding compendium style select circle for combat encounter. Removed styling...

See merge request teaml5r/l5r5e!62
2026-03-01 07:12:33 +00:00
Litasa
cb98d721c5 Adding compendium style select circle for combat encounter. Removed styling... 2026-03-01 07:12:32 +00:00
Litasa
6ba5137ea1 Added me (Litasa) to curret L5R team in README.md
Removed Carter from current L5R team.
2026-02-28 21:04:15 +00:00
Litasa
5377674a30 Merge branch 'issue_75_gm_toolbox_and_monitor_visibility_issues' into 'dev'
issue 75: Unable to see icons in GM ToolBox and text in GM Monitor

See merge request teaml5r/l5r5e!59
2026-02-28 20:58:16 +00:00
Litasa
f6ed462bce issue 75: Unable to see icons in GM ToolBox and text in GM Monitor 2026-02-28 20:58:16 +00:00
Litasa
890223021a Added Litasa as a maintainer 2026-02-27 18:14:43 +00:00
Litasa
b1f874b3c8 Merge branch 'refactor_compendium_pr' into 'dev'
Updating the compendium filter to make it more snappy

See merge request teaml5r/l5r5e!61
2026-02-27 04:15:11 +00:00
Litasa
2dd9ee19e9 Updating the compendium filter to make it more snappy 2026-02-27 04:15:10 +00:00
Litasa
aa203c546c Merge branch 'issue_74_wounded_condition_in_dice_picker' into 'dev'
Issue 74: Adding all active conditions to the top of dice-picker-dialog so you are...

See merge request teaml5r/l5r5e!60
2026-02-26 01:04:30 +00:00
Litasa
8f31031244 Issue 74: Adding all active conditions to the top of dice-picker-dialog so you are... 2026-02-26 01:04:30 +00:00
Litasa
84e367b79f Merge branch 'issue_64_next_rank_not_shown' into 'dev'
Issue 64: Fixing issue where the new rank did not show until after adding a new item....

See merge request teaml5r/l5r5e!57
2026-02-25 21:55:01 +00:00
Litasa
0854e25a66 Issue 64: Fixing issue where the new rank did not show until after adding a new item.... 2026-02-25 21:55:00 +00:00
Litasa
0c299db26f Merge branch 'issue_69_add_experience_button' into 'dev'
Issue 69: Adding incremental buttons to honor, glory and status. Renaming...

See merge request teaml5r/l5r5e!54
2026-02-25 21:39:21 +00:00
Litasa
f267d06536 Issue 69: Adding incremental buttons to honor, glory and status. Renaming... 2026-02-25 21:39:21 +00:00
Vlyan
494b027513 Merge branch 'issue72_missing_sidebar_icons' into 'dev'
Issue72: Missing Sidebar Icons

See merge request teaml5r/l5r5e!53
2026-02-25 08:08:10 +00:00
Litasa
35c58ff631 Issue72: Missing Sidebar Icons 2026-02-25 08:08:10 +00:00
Vlyan
e87cd6d73e Merge branch 'cruxis/update-wiki-content' into 'dev'
Cruxis/update wiki content

See merge request teaml5r/l5r5e!52
2026-02-25 08:05:13 +00:00
Norman Briggs
05b7a1181c Cruxis/update wiki content 2026-02-25 08:05:12 +00:00
Vlyan
2e91fe7ae4 Merge branch 'master' into 'dev'
Fix typo in English Courts of Stone title.

See merge request teaml5r/l5r5e!51
2026-02-25 08:03:34 +00:00
SagaTympana
9c3de358b3 Fix typo in English Courts of Stone title. 2026-02-06 13:03:01 -05:00
Vlyan
b1e73f0761 Release 1.13.3 2026-02-01 10:37:27 +01:00
Vlyan
222aa75a1d Added Translations for Tactical Grid, and some cleanup 2026-01-30 09:28:15 +01:00
Vlyan
caa78d7c45 Merge branch 'patch-1' into 'dev'
Title advancement auto-name/icon fix

See merge request teaml5r/l5r5e!50
2026-01-30 07:58:38 +00:00
SagaTympana
5edcaa373c Title advancement auto-name/icon fix 2026-01-30 07:58:38 +00:00
Vlyan
08e412b32f Merge branch 'tactical_range_bands_dev' into 'dev'
Tactical Grid Range Band

See merge request teaml5r/l5r5e!49
2026-01-07 13:31:28 +00:00
Litasa
4269946c30 Tactical Grid Range Band 2026-01-07 13:31:28 +00:00
Vlyan
607817302b Merge branch 'fix_demeanors_translation' into 'dev'
Update demeanors

See merge request teaml5r/l5r5e!48
2025-11-04 20:06:31 +00:00
Olivier Brencklé
dd39fa6113 Update demeanors 2025-11-04 20:06:30 +00:00
160 changed files with 9327 additions and 3940 deletions

View File

@@ -0,0 +1,91 @@
name: Release Creation
on:
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "💡 The ${{ gitea.repository }} repository will be cloned to the runner."
- uses: https://github.com/RouxAntoine/checkout@v3.5.4
# get part of the tag after the `v`
- name: Extract tag version number
id: get_version
uses: https://github.com/battila7/get-version-action@v2
# Compile SCSS → CSS before packaging
- name: Setup Node.js
uses: https://github.com/actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies and compile styles
run: npm ci && npm run compile
# Substitute the Manifest and Download URLs in system.json
- name: Substitute Manifest and Download Links For Versioned Ones
id: sub_manifest_link_version
uses: https://github.com/microsoft/variable-substitution@v1
with:
files: "system/system.json"
env:
version: ${{steps.get_version.outputs.version-without-v}}
url: https://www.uberwald.me/gitea/uberwald/l5rx-chiaroscuro
manifest: https://www.uberwald.me/gitea/uberwald/l5rx-chiaroscuro/releases/download/latest/system.json
download: https://www.uberwald.me/gitea/uberwald/l5rx-chiaroscuro/releases/download/${{github.event.release.tag_name}}/l5rx-chiaroscuro.zip
# Copy versioned system.json to root so it can be uploaded as-is
- name: Copy system.json to root
run: cp system/system.json system.json
# Create a zip file with all files required by the system
- run: |
apt update -y
apt install -y zip
- run: |
cd system
zip -r ../l5rx-chiaroscuro.zip \
assets/ \
babele/ \
fonts/ \
lang/ \
lib/ \
macros/ \
packs/ \
scripts/ \
styles/ \
templates/ \
system.json \
template.json
cd ..
zip -j ./l5rx-chiaroscuro.zip README.md CHANGELOG.md LICENSE.md
- name: Setup Go
uses: https://github.com/actions/setup-go@v4
with:
go-version: ">=1.20.1"
- name: Upload release assets to Gitea
id: use-go-action
uses: https://gitea.com/actions/release-action@main
with:
files: |-
./l5rx-chiaroscuro.zip
system.json
api_key: "${{secrets.ALLOW_PUSH_RELEASE}}"
- name: Publish to Foundry server
uses: https://github.com/djlechuck/foundryvtt-publish-package-action@v1
with:
token: ${{ secrets.FOUNDRYVTT_RELEASE_TOKEN }}
id: 'l5rx-chiaroscuro'
version: ${{github.event.release.tag_name}}
manifest: 'https://www.uberwald.me/gitea/uberwald/l5rx-chiaroscuro/releases/download/latest/system.json'
notes: 'https://www.uberwald.me/gitea/uberwald/l5rx-chiaroscuro/releases/tag/${{github.event.release.tag_name}}'
compatibility-minimum: '13'
compatibility-verified: '14'

2
.gitignore vendored
View File

@@ -13,3 +13,5 @@ system/l5r5e.lock
# v11 db files (will be added later) # v11 db files (will be added later)
system/packs/*/** system/packs/*/**
.github/
.history/

View File

@@ -6,6 +6,25 @@ Date format : day/month/year
> - `foundry-version`: Stick to the major version of FoundryVTT. > - `foundry-version`: Stick to the major version of FoundryVTT.
> - `system-version`: System functionalities and Fixes. > - `system-version`: System functionalities and Fixes.
## 1.13.4 - 01/03/2026 - UI Polish, Compendium Upgrades
Welcoming Litasa as a maintainer for the system!
- Fixing type in Courts of Stone title, thanks to SagaTympana (!51).
- Update to the [development wiki](https://gitlab.com/teaml5r/l5r5e/-/wikis/home), thanks to Norman Briggs (!52)
- Updating the sidebar icons to show L5r5e specific ones (#72)(!53) (Litasa)
- Adding incremental buttons for honor, glory, and status (#69)(!54) (Litasa)
- New rank is now shown directly when completing a school rank (#64)(!57) (Litasa)
- Adding Starting items to Compendiums that was missing. Split Poison and Omamori into individual items(!58) (Litasa)
- Some combinations of light and dark theme made the GM Toolbox and GM Monitor hard/impossible to use. Fixed now (#75)(!59) (Litasa)
- Conditions now show in the top of dice-picker and roll-n-keep (related to #74)(!60) (Litasa)
- Compendium filter is now a lot "snappier". New search box and now able to multi select elements/ranks/rarity. (!61) (Litasa)
- Adding selection circle to Combat encounter (!62) (Litasa)
## 1.13.3 - 01/02/2026 - Tactical Grid & Fixes
- Updated demeanors from books up to Imperfect Land (included), thanks to Olivier Brencklé (!48).
- Added Tactical Grid Range Band, thanks to Litasa (!49).
- Fix Title advancement auto-name/icon, thanks to SagaTympana (!50).
## 1.13.2 - 18/10/2025 - Conditions Icons & Fixes ## 1.13.2 - 18/10/2025 - Conditions Icons & Fixes
- Fix Actor Sheet for pressing key `Enter` in input trigger `no active Encounter...` message. - Fix Actor Sheet for pressing key `Enter` in input trigger `no active Encounter...` message.
- Fix Compendium `Astrolab` is duplicate with `Mantis Clan` and `Children of the Five Winds`. Renamed the `cotfw` version to `Astrolabe (Unicorn)`. - Fix Compendium `Astrolab` is duplicate with `Mantis Clan` and `Children of the Five Winds`. Renamed the `cotfw` version to `Astrolabe (Unicorn)`.
@@ -14,8 +33,8 @@ Date format : day/month/year
- Spanish language updated thanks to Alejabarr. - Spanish language updated thanks to Alejabarr.
## 1.13.1 - 21/09/2025 - Conditions & Fixes ## 1.13.1 - 21/09/2025 - Conditions & Fixes
- Fix for Clicking on items doesn't show item window (#65 Thx to Litasa) - Fix for Clicking on items doesn't show item window (#65 Thx to Litasa).
- Fix for fade configuration (#66) - Fix for fade configuration (#66).
- Added some Tooltips loading optimizations (#62 Thanks to KitCat). - Added some Tooltips loading optimizations (#62 Thanks to KitCat).
- Added some Properties loading optimizations (#63 Thanks to KitCat). - Added some Properties loading optimizations (#63 Thanks to KitCat).
- Conditions changes : - Conditions changes :

View File

@@ -18,13 +18,14 @@ See the [Wiki page - Installation](https://gitlab.com/teaml5r/l5r5e/-/wikis/user
## Current L5R team (alphabetical order) ## Current L5R team (alphabetical order)
- Carter (compendiums, adventure adaptation) - Litasa (development)
- Vlyan (development) - Vlyan (development)
## Historical L5R team (alphabetical order) ## Historical L5R team (alphabetical order)
- Carter (compendiums, adventure adaptation) - Carter (compendiums, adventure adaptation)
- Hrunh (compendiums, pre-gen characters adaptation) - Hrunh (compendiums, pre-gen characters adaptation)
- Litasa (development)
- Mandar (development) - Mandar (development)
- Sasmira (contributor) - Sasmira (contributor)
- Vlyan (development) - Vlyan (development)

Binary file not shown.

4
package-lock.json generated
View File

@@ -1,11 +1,11 @@
{ {
"name": "l5r5e", "name": "l5rx-chiaroscuro",
"version": "1.0.0", "version": "1.0.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "l5r5e", "name": "l5rx-chiaroscuro",
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {

View File

@@ -1,5 +1,5 @@
{ {
"name": "l5r5e", "name": "l5rx-chiaroscuro",
"version": "1.0.0", "version": "1.0.0",
"description": "This is a game system for Legend of the Five Rings (5th edition) by Edge Studio", "description": "This is a game system for Legend of the Five Rings (5th edition) by Edge Studio",
"main": "index.js", "main": "index.js",

View File

@@ -0,0 +1,393 @@
{
"id": "l5rx-chiaroscuro",
"title": "Legend of the Five Rings (5th Edition)",
"description": "This is an authorised multilingual game system En|Fr|Es, for Legend of the Five Rings (5th Edition) by <a href='https://edge-studio.net/'>Edge Studio</a> <p> - Join the official Discord server: <a href='https://discord.gg/foundryvtt'> Official Discord</a></p><p> - Rejoignez la communauté Francophone: <a href='https://discord.gg/pPSDNJk'>Francophone Discord</a></p>",
"url": "https://gitlab.com/teaml5r/l5r5e",
"readme": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/README.md",
"changelog": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/CHANGELOG.md",
"license": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/LICENSE.md",
"manifest": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/system/system.json",
"download": "https://gitlab.com/teaml5r/l5r5e/-/jobs/artifacts/v1.13.4/raw/l5r5e.zip?job=build",
"version": "1.13.4",
"compatibility": {
"minimum": "13",
"verified": "14"
},
"socket": true,
"authors": [
{
"name": "Vlyan",
"discord": "Vlyan#6771",
"url": "https://ko-fi.com/vlyan"
},
{
"name": "Mandar",
"discord": "Mandar#3440"
},
{
"name": "Carter",
"discord": "Carter#2703",
"url": "https://fr.tipeee.com/carter-foundryvtt"
},
{
"name": "Litasa",
"discord": "Litasa#3139"
}
],
"background": "systems/l5r5e/assets/l5r-header.webp",
"scripts": [],
"esmodules": [
"./scripts/main-l5r5e.js"
],
"styles": [
"./styles/l5r5e.css"
],
"packFolders": [
{
"name": "L5R5e System",
"color": "#9a0909",
"sorting": "m",
"folders": [
{
"name": "Character related",
"color": "#019806",
"sorting": "m",
"packs": [
"core-peculiarities-distinctions",
"core-peculiarities-passions",
"core-peculiarities-adversities",
"core-peculiarities-anxieties",
"core-bonds",
"core-titles",
"core-journal-school-curriculum",
"core-journal-great-clans-presentation"
]
},
{
"name": "Techniques",
"color": "#4b1eb3",
"sorting": "m",
"packs": [
"core-techniques-kata",
"core-techniques-kiho",
"core-techniques-inversions",
"core-techniques-invocations",
"core-techniques-rituals",
"core-techniques-shuji",
"core-techniques-maho",
"core-techniques-ninjutsu",
"core-techniques-mantra",
"core-techniques-school",
"core-techniques-mastery"
]
},
{
"name": "Objects related",
"color": "#0985ae",
"sorting": "m",
"packs": [
"core-properties",
"core-item-patterns",
"core-items",
"core-armors",
"core-weapons",
"core-signature-scrolls",
"core-celestial-implement-boons"
]
},
{
"name": "Helpers",
"color": "#6b3d1f",
"sorting": "m",
"packs": [
"core-journal-conditions",
"core-journal-terrain-qualities",
"core-journal-opportunities"
]
},
{
"name": "Tools",
"color": "#834949",
"sorting": "m",
"packs": [
"core-name-tables",
"core-macros"
]
}
]
}
],
"packs": [
{
"name": "core-properties",
"label": "Properties",
"path": "packs/core-properties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kata",
"label": "Techniques Kata",
"path": "packs/core-techniques-kata.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kiho",
"label": "Techniques Kihõ",
"path": "packs/core-techniques-kiho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-inversions",
"label": "Techniques Inversions",
"path": "packs/core-techniques-inversions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-invocations",
"label": "Techniques Invocations",
"path": "packs/core-techniques-invocations.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-rituals",
"label": "Techniques Rituals",
"path": "packs/core-techniques-rituals.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-shuji",
"label": "Techniques Shuji",
"path": "packs/core-techniques-shuji.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-maho",
"label": "Techniques Mahõ",
"path": "packs/core-techniques-maho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-ninjutsu",
"label": "Techniques Ninjutsu",
"path": "packs/core-techniques-ninjutsu.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mantra",
"label": "Techniques Mantra",
"path": "packs/core-techniques-mantra.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-school",
"label": "School Abilities",
"path": "packs/core-techniques-school.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mastery",
"label": "Mastery Abilities",
"path": "packs/core-techniques-mastery.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-items",
"label": "Items",
"path": "packs/core-items.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-armors",
"label": "Armors",
"path": "packs/core-armors.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-weapons",
"label": "Weapons",
"path": "packs/core-weapons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-distinctions",
"label": "Distinctions",
"path": "packs/core-peculiarities-distinctions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-passions",
"label": "Passions",
"path": "packs/core-peculiarities-passions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-adversities",
"label": "Adversities",
"path": "packs/core-peculiarities-adversities.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-anxieties",
"label": "Anxieties",
"path": "packs/core-peculiarities-anxieties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-bonds",
"label": "Bonds",
"path": "packs/core-bonds.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-titles",
"label": "Titles",
"path": "packs/core-titles.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-item-patterns",
"label": "Item Patterns",
"path": "packs/core-item-patterns.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-signature-scrolls",
"label": "Signature Scrolls",
"path": "packs/core-signature-scrolls.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-celestial-implement-boons",
"label": "Celestial Implement Boons",
"path": "packs/core-celestial-implement-boons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-journal-school-curriculum",
"label": "School Curriculum",
"path": "packs/core-journal-school-curriculum.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-conditions",
"label": "Conditions",
"path": "packs/core-journal-conditions.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-terrain-qualities",
"label": "Terrain Qualities",
"path": "packs/core-journal-terrain-qualities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-great-clans-presentation",
"label": "Great Clans Presentation",
"path": "packs/core-journal-great-clans-presentation.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-opportunities",
"label": "Opportunities",
"path": "packs/core-journal-opportunities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-name-tables",
"label": "Name Tables",
"path": "packs/core-name-tables.db",
"type": "RollTable",
"system": "l5r5e"
},
{
"name": "core-macros",
"label": "L5R5E Macros",
"path": "packs/core-macros.db",
"type": "Macro",
"system": "l5r5e"
}
],
"languages": [
{
"lang": "en",
"name": "English",
"path": "lang/en-en.json"
},
{
"lang": "fr",
"name": "French (France)",
"path": "lang/fr-fr.json"
},
{
"lang": "es",
"name": "Spanish (Spain)",
"path": "lang/es-es.json"
},
{
"lang": "it",
"name": "Italian (Italy)",
"path": "lang/it-it.json"
}
],
"media": [
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/login.jpg?raw=true",
"caption": "Login screen"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/roll.jpg?raw=true",
"caption": "DicePicker and Roll and Keep"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/school.jpg?raw=true",
"caption": "Experience and School"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_pc.jpg?raw=true",
"caption": "PC sheet"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_npc_army.jpg?raw=true",
"caption": "NPC and Army sheets"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/compendiums.jpg?raw=true",
"caption": "Compendiums"
}
]
}

View File

@@ -0,0 +1,393 @@
{
"id": "l5rx-chiaroscuro",
"title": "Legend of the Five Rings (5th Edition)",
"description": "This is an authorised multilingual game system En|Fr|Es, for Legend of the Five Rings (5th Edition) by <a href='https://edge-studio.net/'>Edge Studio</a> <p> - Join the official Discord server: <a href='https://discord.gg/foundryvtt'> Official Discord</a></p><p> - Rejoignez la communauté Francophone: <a href='https://discord.gg/pPSDNJk'>Francophone Discord</a></p>",
"url": "https://gitlab.com/teaml5r/l5r5e",
"readme": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/README.md",
"changelog": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/CHANGELOG.md",
"license": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/LICENSE.md",
"manifest": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/system/system.json",
"download": "https://gitlab.com/teaml5r/l5r5e/-/jobs/artifacts/v1.13.4/raw/l5r5e.zip?job=build",
"version": "1.13.4",
"compatibility": {
"minimum": "13",
"verified": "14"
},
"socket": true,
"authors": [
{
"name": "Vlyan",
"discord": "Vlyan#6771",
"url": "https://ko-fi.com/vlyan"
},
{
"name": "Mandar",
"discord": "Mandar#3440"
},
{
"name": "Carter",
"discord": "Carter#2703",
"url": "https://fr.tipeee.com/carter-foundryvtt"
},
{
"name": "Litasa",
"discord": "Litasa#3139"
}
],
"background": "systems/l5r5e/assets/l5r-header.webp",
"scripts": [],
"esmodules": [
"./scripts/main-l5r5e.js"
],
"styles": [
"./styles/l5r5e.css"
],
"packFolders": [
{
"name": "L5R5e System",
"color": "#9a0909",
"sorting": "m",
"folders": [
{
"name": "Character related",
"color": "#019806",
"sorting": "m",
"packs": [
"core-peculiarities-distinctions",
"core-peculiarities-passions",
"core-peculiarities-adversities",
"core-peculiarities-anxieties",
"core-bonds",
"core-titles",
"core-journal-school-curriculum",
"core-journal-great-clans-presentation"
]
},
{
"name": "Techniques",
"color": "#4b1eb3",
"sorting": "m",
"packs": [
"core-techniques-kata",
"core-techniques-kiho",
"core-techniques-inversions",
"core-techniques-invocations",
"core-techniques-rituals",
"core-techniques-shuji",
"core-techniques-maho",
"core-techniques-ninjutsu",
"core-techniques-mantra",
"core-techniques-school",
"core-techniques-mastery"
]
},
{
"name": "Objects related",
"color": "#0985ae",
"sorting": "m",
"packs": [
"core-properties",
"core-item-patterns",
"core-items",
"core-armors",
"core-weapons",
"core-signature-scrolls",
"core-celestial-implement-boons"
]
},
{
"name": "Helpers",
"color": "#6b3d1f",
"sorting": "m",
"packs": [
"core-journal-conditions",
"core-journal-terrain-qualities",
"core-journal-opportunities"
]
},
{
"name": "Tools",
"color": "#834949",
"sorting": "m",
"packs": [
"core-name-tables",
"core-macros"
]
}
]
}
],
"packs": [
{
"name": "core-properties",
"label": "Properties",
"path": "packs/core-properties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kata",
"label": "Techniques Kata",
"path": "packs/core-techniques-kata.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kiho",
"label": "Techniques Kihõ",
"path": "packs/core-techniques-kiho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-inversions",
"label": "Techniques Inversions",
"path": "packs/core-techniques-inversions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-invocations",
"label": "Techniques Invocations",
"path": "packs/core-techniques-invocations.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-rituals",
"label": "Techniques Rituals",
"path": "packs/core-techniques-rituals.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-shuji",
"label": "Techniques Shuji",
"path": "packs/core-techniques-shuji.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-maho",
"label": "Techniques Mahõ",
"path": "packs/core-techniques-maho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-ninjutsu",
"label": "Techniques Ninjutsu",
"path": "packs/core-techniques-ninjutsu.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mantra",
"label": "Techniques Mantra",
"path": "packs/core-techniques-mantra.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-school",
"label": "School Abilities",
"path": "packs/core-techniques-school.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mastery",
"label": "Mastery Abilities",
"path": "packs/core-techniques-mastery.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-items",
"label": "Items",
"path": "packs/core-items.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-armors",
"label": "Armors",
"path": "packs/core-armors.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-weapons",
"label": "Weapons",
"path": "packs/core-weapons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-distinctions",
"label": "Distinctions",
"path": "packs/core-peculiarities-distinctions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-passions",
"label": "Passions",
"path": "packs/core-peculiarities-passions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-adversities",
"label": "Adversities",
"path": "packs/core-peculiarities-adversities.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-anxieties",
"label": "Anxieties",
"path": "packs/core-peculiarities-anxieties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-bonds",
"label": "Bonds",
"path": "packs/core-bonds.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-titles",
"label": "Titles",
"path": "packs/core-titles.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-item-patterns",
"label": "Item Patterns",
"path": "packs/core-item-patterns.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-signature-scrolls",
"label": "Signature Scrolls",
"path": "packs/core-signature-scrolls.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-celestial-implement-boons",
"label": "Celestial Implement Boons",
"path": "packs/core-celestial-implement-boons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-journal-school-curriculum",
"label": "School Curriculum",
"path": "packs/core-journal-school-curriculum.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-conditions",
"label": "Conditions",
"path": "packs/core-journal-conditions.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-terrain-qualities",
"label": "Terrain Qualities",
"path": "packs/core-journal-terrain-qualities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-great-clans-presentation",
"label": "Great Clans Presentation",
"path": "packs/core-journal-great-clans-presentation.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-opportunities",
"label": "Opportunities",
"path": "packs/core-journal-opportunities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-name-tables",
"label": "Name Tables",
"path": "packs/core-name-tables.db",
"type": "RollTable",
"system": "l5r5e"
},
{
"name": "core-macros",
"label": "L5R5E Macros",
"path": "packs/core-macros.db",
"type": "Macro",
"system": "l5r5e"
}
],
"languages": [
{
"lang": "en",
"name": "English",
"path": "lang/en-en.json"
},
{
"lang": "fr",
"name": "French (France)",
"path": "lang/fr-fr.json"
},
{
"lang": "es",
"name": "Spanish (Spain)",
"path": "lang/es-es.json"
},
{
"lang": "it",
"name": "Italian (Italy)",
"path": "lang/it-it.json"
}
],
"media": [
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/login.jpg?raw=true",
"caption": "Login screen"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/roll.jpg?raw=true",
"caption": "DicePicker and Roll and Keep"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/school.jpg?raw=true",
"caption": "Experience and School"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_pc.jpg?raw=true",
"caption": "PC sheet"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_npc_army.jpg?raw=true",
"caption": "NPC and Army sheets"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/compendiums.jpg?raw=true",
"caption": "Compendiums"
}
]
}

View File

@@ -0,0 +1,393 @@
{
"id": "l5rx-chiaroscuro",
"title": "Legend of the Five Rings (5th Edition)",
"description": "This is an authorised multilingual game system En|Fr|Es, for Legend of the Five Rings (5th Edition) by <a href='https://edge-studio.net/'>Edge Studio</a> <p> - Join the official Discord server: <a href='https://discord.gg/foundryvtt'> Official Discord</a></p><p> - Rejoignez la communauté Francophone: <a href='https://discord.gg/pPSDNJk'>Francophone Discord</a></p>",
"url": "https://gitlab.com/teaml5r/l5r5e",
"readme": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/README.md",
"changelog": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/CHANGELOG.md",
"license": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/LICENSE.md",
"manifest": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/system/system.json",
"download": "https://gitlab.com/teaml5r/l5r5e/-/jobs/artifacts/v1.13.4/raw/l5r5e.zip?job=build",
"version": "14.0.0",
"compatibility": {
"minimum": "13",
"verified": "14"
},
"socket": true,
"authors": [
{
"name": "Vlyan",
"discord": "Vlyan#6771",
"url": "https://ko-fi.com/vlyan"
},
{
"name": "Mandar",
"discord": "Mandar#3440"
},
{
"name": "Carter",
"discord": "Carter#2703",
"url": "https://fr.tipeee.com/carter-foundryvtt"
},
{
"name": "Litasa",
"discord": "Litasa#3139"
}
],
"background": "systems/l5r5e/assets/l5r-header.webp",
"scripts": [],
"esmodules": [
"./scripts/main-l5r5e.js"
],
"styles": [
"./styles/l5r5e.css"
],
"packFolders": [
{
"name": "L5R5e System",
"color": "#9a0909",
"sorting": "m",
"folders": [
{
"name": "Character related",
"color": "#019806",
"sorting": "m",
"packs": [
"core-peculiarities-distinctions",
"core-peculiarities-passions",
"core-peculiarities-adversities",
"core-peculiarities-anxieties",
"core-bonds",
"core-titles",
"core-journal-school-curriculum",
"core-journal-great-clans-presentation"
]
},
{
"name": "Techniques",
"color": "#4b1eb3",
"sorting": "m",
"packs": [
"core-techniques-kata",
"core-techniques-kiho",
"core-techniques-inversions",
"core-techniques-invocations",
"core-techniques-rituals",
"core-techniques-shuji",
"core-techniques-maho",
"core-techniques-ninjutsu",
"core-techniques-mantra",
"core-techniques-school",
"core-techniques-mastery"
]
},
{
"name": "Objects related",
"color": "#0985ae",
"sorting": "m",
"packs": [
"core-properties",
"core-item-patterns",
"core-items",
"core-armors",
"core-weapons",
"core-signature-scrolls",
"core-celestial-implement-boons"
]
},
{
"name": "Helpers",
"color": "#6b3d1f",
"sorting": "m",
"packs": [
"core-journal-conditions",
"core-journal-terrain-qualities",
"core-journal-opportunities"
]
},
{
"name": "Tools",
"color": "#834949",
"sorting": "m",
"packs": [
"core-name-tables",
"core-macros"
]
}
]
}
],
"packs": [
{
"name": "core-properties",
"label": "Properties",
"path": "packs/core-properties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kata",
"label": "Techniques Kata",
"path": "packs/core-techniques-kata.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kiho",
"label": "Techniques Kihõ",
"path": "packs/core-techniques-kiho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-inversions",
"label": "Techniques Inversions",
"path": "packs/core-techniques-inversions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-invocations",
"label": "Techniques Invocations",
"path": "packs/core-techniques-invocations.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-rituals",
"label": "Techniques Rituals",
"path": "packs/core-techniques-rituals.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-shuji",
"label": "Techniques Shuji",
"path": "packs/core-techniques-shuji.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-maho",
"label": "Techniques Mahõ",
"path": "packs/core-techniques-maho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-ninjutsu",
"label": "Techniques Ninjutsu",
"path": "packs/core-techniques-ninjutsu.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mantra",
"label": "Techniques Mantra",
"path": "packs/core-techniques-mantra.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-school",
"label": "School Abilities",
"path": "packs/core-techniques-school.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mastery",
"label": "Mastery Abilities",
"path": "packs/core-techniques-mastery.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-items",
"label": "Items",
"path": "packs/core-items.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-armors",
"label": "Armors",
"path": "packs/core-armors.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-weapons",
"label": "Weapons",
"path": "packs/core-weapons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-distinctions",
"label": "Distinctions",
"path": "packs/core-peculiarities-distinctions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-passions",
"label": "Passions",
"path": "packs/core-peculiarities-passions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-adversities",
"label": "Adversities",
"path": "packs/core-peculiarities-adversities.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-anxieties",
"label": "Anxieties",
"path": "packs/core-peculiarities-anxieties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-bonds",
"label": "Bonds",
"path": "packs/core-bonds.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-titles",
"label": "Titles",
"path": "packs/core-titles.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-item-patterns",
"label": "Item Patterns",
"path": "packs/core-item-patterns.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-signature-scrolls",
"label": "Signature Scrolls",
"path": "packs/core-signature-scrolls.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-celestial-implement-boons",
"label": "Celestial Implement Boons",
"path": "packs/core-celestial-implement-boons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-journal-school-curriculum",
"label": "School Curriculum",
"path": "packs/core-journal-school-curriculum.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-conditions",
"label": "Conditions",
"path": "packs/core-journal-conditions.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-terrain-qualities",
"label": "Terrain Qualities",
"path": "packs/core-journal-terrain-qualities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-great-clans-presentation",
"label": "Great Clans Presentation",
"path": "packs/core-journal-great-clans-presentation.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-opportunities",
"label": "Opportunities",
"path": "packs/core-journal-opportunities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-name-tables",
"label": "Name Tables",
"path": "packs/core-name-tables.db",
"type": "RollTable",
"system": "l5r5e"
},
{
"name": "core-macros",
"label": "L5R5E Macros",
"path": "packs/core-macros.db",
"type": "Macro",
"system": "l5r5e"
}
],
"languages": [
{
"lang": "en",
"name": "English",
"path": "lang/en-en.json"
},
{
"lang": "fr",
"name": "French (France)",
"path": "lang/fr-fr.json"
},
{
"lang": "es",
"name": "Spanish (Spain)",
"path": "lang/es-es.json"
},
{
"lang": "it",
"name": "Italian (Italy)",
"path": "lang/it-it.json"
}
],
"media": [
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/login.jpg?raw=true",
"caption": "Login screen"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/roll.jpg?raw=true",
"caption": "DicePicker and Roll and Keep"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/school.jpg?raw=true",
"caption": "Experience and School"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_pc.jpg?raw=true",
"caption": "PC sheet"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_npc_army.jpg?raw=true",
"caption": "NPC and Army sheets"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/compendiums.jpg?raw=true",
"caption": "Compendiums"
}
]
}

View File

@@ -0,0 +1,393 @@
{
"id": "l5rx-chiaroscuro",
"title": "chiaroscuro - Legend of the Five Rings (5th Edition)",
"description": "This is an authorised multilingual game system En|Fr|Es, for Legend of the Five Rings (5th Edition) by <a href='https://edge-studio.net/'>Edge Studio</a> <p> - Join the official Discord server: <a href='https://discord.gg/foundryvtt'> Official Discord</a></p><p> - Rejoignez la communauté Francophone: <a href='https://discord.gg/pPSDNJk'>Francophone Discord</a></p>",
"url": "https://gitlab.com/teaml5r/l5r5e",
"readme": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/README.md",
"changelog": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/CHANGELOG.md",
"license": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/LICENSE.md",
"manifest": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/system/system.json",
"download": "https://gitlab.com/teaml5r/l5r5e/-/jobs/artifacts/v1.13.4/raw/l5r5e.zip?job=build",
"version": "14.0.0",
"compatibility": {
"minimum": "13",
"verified": "14"
},
"socket": true,
"authors": [
{
"name": "Vlyan",
"discord": "Vlyan#6771",
"url": "https://ko-fi.com/vlyan"
},
{
"name": "Mandar",
"discord": "Mandar#3440"
},
{
"name": "Carter",
"discord": "Carter#2703",
"url": "https://fr.tipeee.com/carter-foundryvtt"
},
{
"name": "Litasa",
"discord": "Litasa#3139"
}
],
"background": "systems/l5r5e/assets/l5r-header.webp",
"scripts": [],
"esmodules": [
"./scripts/main-l5r5e.js"
],
"styles": [
"./styles/l5r5e.css"
],
"packFolders": [
{
"name": "L5R5e System",
"color": "#9a0909",
"sorting": "m",
"folders": [
{
"name": "Character related",
"color": "#019806",
"sorting": "m",
"packs": [
"core-peculiarities-distinctions",
"core-peculiarities-passions",
"core-peculiarities-adversities",
"core-peculiarities-anxieties",
"core-bonds",
"core-titles",
"core-journal-school-curriculum",
"core-journal-great-clans-presentation"
]
},
{
"name": "Techniques",
"color": "#4b1eb3",
"sorting": "m",
"packs": [
"core-techniques-kata",
"core-techniques-kiho",
"core-techniques-inversions",
"core-techniques-invocations",
"core-techniques-rituals",
"core-techniques-shuji",
"core-techniques-maho",
"core-techniques-ninjutsu",
"core-techniques-mantra",
"core-techniques-school",
"core-techniques-mastery"
]
},
{
"name": "Objects related",
"color": "#0985ae",
"sorting": "m",
"packs": [
"core-properties",
"core-item-patterns",
"core-items",
"core-armors",
"core-weapons",
"core-signature-scrolls",
"core-celestial-implement-boons"
]
},
{
"name": "Helpers",
"color": "#6b3d1f",
"sorting": "m",
"packs": [
"core-journal-conditions",
"core-journal-terrain-qualities",
"core-journal-opportunities"
]
},
{
"name": "Tools",
"color": "#834949",
"sorting": "m",
"packs": [
"core-name-tables",
"core-macros"
]
}
]
}
],
"packs": [
{
"name": "core-properties",
"label": "Properties",
"path": "packs/core-properties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kata",
"label": "Techniques Kata",
"path": "packs/core-techniques-kata.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kiho",
"label": "Techniques Kihõ",
"path": "packs/core-techniques-kiho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-inversions",
"label": "Techniques Inversions",
"path": "packs/core-techniques-inversions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-invocations",
"label": "Techniques Invocations",
"path": "packs/core-techniques-invocations.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-rituals",
"label": "Techniques Rituals",
"path": "packs/core-techniques-rituals.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-shuji",
"label": "Techniques Shuji",
"path": "packs/core-techniques-shuji.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-maho",
"label": "Techniques Mahõ",
"path": "packs/core-techniques-maho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-ninjutsu",
"label": "Techniques Ninjutsu",
"path": "packs/core-techniques-ninjutsu.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mantra",
"label": "Techniques Mantra",
"path": "packs/core-techniques-mantra.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-school",
"label": "School Abilities",
"path": "packs/core-techniques-school.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mastery",
"label": "Mastery Abilities",
"path": "packs/core-techniques-mastery.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-items",
"label": "Items",
"path": "packs/core-items.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-armors",
"label": "Armors",
"path": "packs/core-armors.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-weapons",
"label": "Weapons",
"path": "packs/core-weapons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-distinctions",
"label": "Distinctions",
"path": "packs/core-peculiarities-distinctions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-passions",
"label": "Passions",
"path": "packs/core-peculiarities-passions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-adversities",
"label": "Adversities",
"path": "packs/core-peculiarities-adversities.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-anxieties",
"label": "Anxieties",
"path": "packs/core-peculiarities-anxieties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-bonds",
"label": "Bonds",
"path": "packs/core-bonds.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-titles",
"label": "Titles",
"path": "packs/core-titles.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-item-patterns",
"label": "Item Patterns",
"path": "packs/core-item-patterns.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-signature-scrolls",
"label": "Signature Scrolls",
"path": "packs/core-signature-scrolls.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-celestial-implement-boons",
"label": "Celestial Implement Boons",
"path": "packs/core-celestial-implement-boons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-journal-school-curriculum",
"label": "School Curriculum",
"path": "packs/core-journal-school-curriculum.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-conditions",
"label": "Conditions",
"path": "packs/core-journal-conditions.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-terrain-qualities",
"label": "Terrain Qualities",
"path": "packs/core-journal-terrain-qualities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-great-clans-presentation",
"label": "Great Clans Presentation",
"path": "packs/core-journal-great-clans-presentation.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-opportunities",
"label": "Opportunities",
"path": "packs/core-journal-opportunities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-name-tables",
"label": "Name Tables",
"path": "packs/core-name-tables.db",
"type": "RollTable",
"system": "l5r5e"
},
{
"name": "core-macros",
"label": "L5R5E Macros",
"path": "packs/core-macros.db",
"type": "Macro",
"system": "l5r5e"
}
],
"languages": [
{
"lang": "en",
"name": "English",
"path": "lang/en-en.json"
},
{
"lang": "fr",
"name": "French (France)",
"path": "lang/fr-fr.json"
},
{
"lang": "es",
"name": "Spanish (Spain)",
"path": "lang/es-es.json"
},
{
"lang": "it",
"name": "Italian (Italy)",
"path": "lang/it-it.json"
}
],
"media": [
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/login.jpg?raw=true",
"caption": "Login screen"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/roll.jpg?raw=true",
"caption": "DicePicker and Roll and Keep"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/school.jpg?raw=true",
"caption": "Experience and School"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_pc.jpg?raw=true",
"caption": "PC sheet"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_npc_army.jpg?raw=true",
"caption": "NPC and Army sheets"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/compendiums.jpg?raw=true",
"caption": "Compendiums"
}
]
}

View File

@@ -0,0 +1,393 @@
{
"id": "l5rx-chiaroscuro",
"title": "Chiaroscuro - Legend of the Five Rings (5th Edition)",
"description": "This is an authorised multilingual game system En|Fr|Es, for Legend of the Five Rings (5th Edition) by <a href='https://edge-studio.net/'>Edge Studio</a> <p> - Join the official Discord server: <a href='https://discord.gg/foundryvtt'> Official Discord</a></p><p> - Rejoignez la communauté Francophone: <a href='https://discord.gg/pPSDNJk'>Francophone Discord</a></p>",
"url": "https://gitlab.com/teaml5r/l5r5e",
"readme": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/README.md",
"changelog": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/CHANGELOG.md",
"license": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/LICENSE.md",
"manifest": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/system/system.json",
"download": "https://gitlab.com/teaml5r/l5r5e/-/jobs/artifacts/v1.13.4/raw/l5r5e.zip?job=build",
"version": "14.0.0",
"compatibility": {
"minimum": "13",
"verified": "14"
},
"socket": true,
"authors": [
{
"name": "Vlyan",
"discord": "Vlyan#6771",
"url": "https://ko-fi.com/vlyan"
},
{
"name": "Mandar",
"discord": "Mandar#3440"
},
{
"name": "Carter",
"discord": "Carter#2703",
"url": "https://fr.tipeee.com/carter-foundryvtt"
},
{
"name": "Litasa",
"discord": "Litasa#3139"
}
],
"background": "systems/l5r5e/assets/l5r-header.webp",
"scripts": [],
"esmodules": [
"./scripts/main-l5r5e.js"
],
"styles": [
"./styles/l5r5e.css"
],
"packFolders": [
{
"name": "L5R5e System",
"color": "#9a0909",
"sorting": "m",
"folders": [
{
"name": "Character related",
"color": "#019806",
"sorting": "m",
"packs": [
"core-peculiarities-distinctions",
"core-peculiarities-passions",
"core-peculiarities-adversities",
"core-peculiarities-anxieties",
"core-bonds",
"core-titles",
"core-journal-school-curriculum",
"core-journal-great-clans-presentation"
]
},
{
"name": "Techniques",
"color": "#4b1eb3",
"sorting": "m",
"packs": [
"core-techniques-kata",
"core-techniques-kiho",
"core-techniques-inversions",
"core-techniques-invocations",
"core-techniques-rituals",
"core-techniques-shuji",
"core-techniques-maho",
"core-techniques-ninjutsu",
"core-techniques-mantra",
"core-techniques-school",
"core-techniques-mastery"
]
},
{
"name": "Objects related",
"color": "#0985ae",
"sorting": "m",
"packs": [
"core-properties",
"core-item-patterns",
"core-items",
"core-armors",
"core-weapons",
"core-signature-scrolls",
"core-celestial-implement-boons"
]
},
{
"name": "Helpers",
"color": "#6b3d1f",
"sorting": "m",
"packs": [
"core-journal-conditions",
"core-journal-terrain-qualities",
"core-journal-opportunities"
]
},
{
"name": "Tools",
"color": "#834949",
"sorting": "m",
"packs": [
"core-name-tables",
"core-macros"
]
}
]
}
],
"packs": [
{
"name": "core-properties",
"label": "Properties",
"path": "packs/core-properties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kata",
"label": "Techniques Kata",
"path": "packs/core-techniques-kata.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kiho",
"label": "Techniques Kihõ",
"path": "packs/core-techniques-kiho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-inversions",
"label": "Techniques Inversions",
"path": "packs/core-techniques-inversions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-invocations",
"label": "Techniques Invocations",
"path": "packs/core-techniques-invocations.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-rituals",
"label": "Techniques Rituals",
"path": "packs/core-techniques-rituals.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-shuji",
"label": "Techniques Shuji",
"path": "packs/core-techniques-shuji.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-maho",
"label": "Techniques Mahõ",
"path": "packs/core-techniques-maho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-ninjutsu",
"label": "Techniques Ninjutsu",
"path": "packs/core-techniques-ninjutsu.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mantra",
"label": "Techniques Mantra",
"path": "packs/core-techniques-mantra.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-school",
"label": "School Abilities",
"path": "packs/core-techniques-school.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mastery",
"label": "Mastery Abilities",
"path": "packs/core-techniques-mastery.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-items",
"label": "Items",
"path": "packs/core-items.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-armors",
"label": "Armors",
"path": "packs/core-armors.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-weapons",
"label": "Weapons",
"path": "packs/core-weapons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-distinctions",
"label": "Distinctions",
"path": "packs/core-peculiarities-distinctions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-passions",
"label": "Passions",
"path": "packs/core-peculiarities-passions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-adversities",
"label": "Adversities",
"path": "packs/core-peculiarities-adversities.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-anxieties",
"label": "Anxieties",
"path": "packs/core-peculiarities-anxieties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-bonds",
"label": "Bonds",
"path": "packs/core-bonds.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-titles",
"label": "Titles",
"path": "packs/core-titles.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-item-patterns",
"label": "Item Patterns",
"path": "packs/core-item-patterns.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-signature-scrolls",
"label": "Signature Scrolls",
"path": "packs/core-signature-scrolls.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-celestial-implement-boons",
"label": "Celestial Implement Boons",
"path": "packs/core-celestial-implement-boons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-journal-school-curriculum",
"label": "School Curriculum",
"path": "packs/core-journal-school-curriculum.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-conditions",
"label": "Conditions",
"path": "packs/core-journal-conditions.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-terrain-qualities",
"label": "Terrain Qualities",
"path": "packs/core-journal-terrain-qualities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-great-clans-presentation",
"label": "Great Clans Presentation",
"path": "packs/core-journal-great-clans-presentation.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-opportunities",
"label": "Opportunities",
"path": "packs/core-journal-opportunities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-name-tables",
"label": "Name Tables",
"path": "packs/core-name-tables.db",
"type": "RollTable",
"system": "l5r5e"
},
{
"name": "core-macros",
"label": "L5R5E Macros",
"path": "packs/core-macros.db",
"type": "Macro",
"system": "l5r5e"
}
],
"languages": [
{
"lang": "en",
"name": "English",
"path": "lang/en-en.json"
},
{
"lang": "fr",
"name": "French (France)",
"path": "lang/fr-fr.json"
},
{
"lang": "es",
"name": "Spanish (Spain)",
"path": "lang/es-es.json"
},
{
"lang": "it",
"name": "Italian (Italy)",
"path": "lang/it-it.json"
}
],
"media": [
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/login.jpg?raw=true",
"caption": "Login screen"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/roll.jpg?raw=true",
"caption": "DicePicker and Roll and Keep"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/school.jpg?raw=true",
"caption": "Experience and School"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_pc.jpg?raw=true",
"caption": "PC sheet"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_npc_army.jpg?raw=true",
"caption": "NPC and Army sheets"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/compendiums.jpg?raw=true",
"caption": "Compendiums"
}
]
}

View File

@@ -0,0 +1,393 @@
{
"id": "l5rx-chiaroscuro",
"title": "Chiaroscuro - L5R",
"description": "This is an authorised multilingual game system En|Fr|Es, for Legend of the Five Rings (5th Edition) by <a href='https://edge-studio.net/'>Edge Studio</a> <p> - Join the official Discord server: <a href='https://discord.gg/foundryvtt'> Official Discord</a></p><p> - Rejoignez la communauté Francophone: <a href='https://discord.gg/pPSDNJk'>Francophone Discord</a></p>",
"url": "https://gitlab.com/teaml5r/l5r5e",
"readme": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/README.md",
"changelog": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/CHANGELOG.md",
"license": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/LICENSE.md",
"manifest": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/system/system.json",
"download": "https://gitlab.com/teaml5r/l5r5e/-/jobs/artifacts/v1.13.4/raw/l5r5e.zip?job=build",
"version": "14.0.0",
"compatibility": {
"minimum": "13",
"verified": "14"
},
"socket": true,
"authors": [
{
"name": "Vlyan",
"discord": "Vlyan#6771",
"url": "https://ko-fi.com/vlyan"
},
{
"name": "Mandar",
"discord": "Mandar#3440"
},
{
"name": "Carter",
"discord": "Carter#2703",
"url": "https://fr.tipeee.com/carter-foundryvtt"
},
{
"name": "Litasa",
"discord": "Litasa#3139"
}
],
"background": "systems/l5r5e/assets/l5r-header.webp",
"scripts": [],
"esmodules": [
"./scripts/main-l5r5e.js"
],
"styles": [
"./styles/l5r5e.css"
],
"packFolders": [
{
"name": "L5R5e System",
"color": "#9a0909",
"sorting": "m",
"folders": [
{
"name": "Character related",
"color": "#019806",
"sorting": "m",
"packs": [
"core-peculiarities-distinctions",
"core-peculiarities-passions",
"core-peculiarities-adversities",
"core-peculiarities-anxieties",
"core-bonds",
"core-titles",
"core-journal-school-curriculum",
"core-journal-great-clans-presentation"
]
},
{
"name": "Techniques",
"color": "#4b1eb3",
"sorting": "m",
"packs": [
"core-techniques-kata",
"core-techniques-kiho",
"core-techniques-inversions",
"core-techniques-invocations",
"core-techniques-rituals",
"core-techniques-shuji",
"core-techniques-maho",
"core-techniques-ninjutsu",
"core-techniques-mantra",
"core-techniques-school",
"core-techniques-mastery"
]
},
{
"name": "Objects related",
"color": "#0985ae",
"sorting": "m",
"packs": [
"core-properties",
"core-item-patterns",
"core-items",
"core-armors",
"core-weapons",
"core-signature-scrolls",
"core-celestial-implement-boons"
]
},
{
"name": "Helpers",
"color": "#6b3d1f",
"sorting": "m",
"packs": [
"core-journal-conditions",
"core-journal-terrain-qualities",
"core-journal-opportunities"
]
},
{
"name": "Tools",
"color": "#834949",
"sorting": "m",
"packs": [
"core-name-tables",
"core-macros"
]
}
]
}
],
"packs": [
{
"name": "core-properties",
"label": "Properties",
"path": "packs/core-properties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kata",
"label": "Techniques Kata",
"path": "packs/core-techniques-kata.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kiho",
"label": "Techniques Kihõ",
"path": "packs/core-techniques-kiho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-inversions",
"label": "Techniques Inversions",
"path": "packs/core-techniques-inversions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-invocations",
"label": "Techniques Invocations",
"path": "packs/core-techniques-invocations.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-rituals",
"label": "Techniques Rituals",
"path": "packs/core-techniques-rituals.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-shuji",
"label": "Techniques Shuji",
"path": "packs/core-techniques-shuji.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-maho",
"label": "Techniques Mahõ",
"path": "packs/core-techniques-maho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-ninjutsu",
"label": "Techniques Ninjutsu",
"path": "packs/core-techniques-ninjutsu.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mantra",
"label": "Techniques Mantra",
"path": "packs/core-techniques-mantra.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-school",
"label": "School Abilities",
"path": "packs/core-techniques-school.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mastery",
"label": "Mastery Abilities",
"path": "packs/core-techniques-mastery.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-items",
"label": "Items",
"path": "packs/core-items.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-armors",
"label": "Armors",
"path": "packs/core-armors.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-weapons",
"label": "Weapons",
"path": "packs/core-weapons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-distinctions",
"label": "Distinctions",
"path": "packs/core-peculiarities-distinctions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-passions",
"label": "Passions",
"path": "packs/core-peculiarities-passions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-adversities",
"label": "Adversities",
"path": "packs/core-peculiarities-adversities.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-anxieties",
"label": "Anxieties",
"path": "packs/core-peculiarities-anxieties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-bonds",
"label": "Bonds",
"path": "packs/core-bonds.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-titles",
"label": "Titles",
"path": "packs/core-titles.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-item-patterns",
"label": "Item Patterns",
"path": "packs/core-item-patterns.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-signature-scrolls",
"label": "Signature Scrolls",
"path": "packs/core-signature-scrolls.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-celestial-implement-boons",
"label": "Celestial Implement Boons",
"path": "packs/core-celestial-implement-boons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-journal-school-curriculum",
"label": "School Curriculum",
"path": "packs/core-journal-school-curriculum.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-conditions",
"label": "Conditions",
"path": "packs/core-journal-conditions.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-terrain-qualities",
"label": "Terrain Qualities",
"path": "packs/core-journal-terrain-qualities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-great-clans-presentation",
"label": "Great Clans Presentation",
"path": "packs/core-journal-great-clans-presentation.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-opportunities",
"label": "Opportunities",
"path": "packs/core-journal-opportunities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-name-tables",
"label": "Name Tables",
"path": "packs/core-name-tables.db",
"type": "RollTable",
"system": "l5r5e"
},
{
"name": "core-macros",
"label": "L5R5E Macros",
"path": "packs/core-macros.db",
"type": "Macro",
"system": "l5r5e"
}
],
"languages": [
{
"lang": "en",
"name": "English",
"path": "lang/en-en.json"
},
{
"lang": "fr",
"name": "French (France)",
"path": "lang/fr-fr.json"
},
{
"lang": "es",
"name": "Spanish (Spain)",
"path": "lang/es-es.json"
},
{
"lang": "it",
"name": "Italian (Italy)",
"path": "lang/it-it.json"
}
],
"media": [
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/login.jpg?raw=true",
"caption": "Login screen"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/roll.jpg?raw=true",
"caption": "DicePicker and Roll and Keep"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/school.jpg?raw=true",
"caption": "Experience and School"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_pc.jpg?raw=true",
"caption": "PC sheet"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_npc_army.jpg?raw=true",
"caption": "NPC and Army sheets"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/compendiums.jpg?raw=true",
"caption": "Compendiums"
}
]
}

View File

@@ -0,0 +1,393 @@
{
"id": "l5rx-chiaroscuro",
"title": "Chiaroscuro - L5R",
"description": "This is an authorised multilingual game system En|Fr|Es, for Legend of the Five Rings (5th Edition) by <a href='https://edge-studio.net/'>Edge Studio</a> <p> - Join the official Discord server: <a href='https://discord.gg/foundryvtt'> Official Discord</a></p><p> - Rejoignez la communauté Francophone: <a href='https://discord.gg/pPSDNJk'>Francophone Discord</a></p>",
"url": "https://gitlab.com/teaml5r/l5r5e",
"readme": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/README.md",
"changelog": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/CHANGELOG.md",
"license": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/LICENSE.md",
"manifest": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/system/system.json",
"download": "https://gitlab.com/teaml5r/l5r5e/-/jobs/artifacts/v1.13.4/raw/l5r5e.zip?job=build",
"version": "14.0.0",
"compatibility": {
"minimum": "13",
"verified": "14"
},
"socket": true,
"authors": [
{
"name": "Vlyan",
"discord": "Vlyan#6771",
"url": "https://ko-fi.com/vlyan"
},
{
"name": "Mandar",
"discord": "Mandar#3440"
},
{
"name": "Carter",
"discord": "Carter#2703",
"url": "https://fr.tipeee.com/carter-foundryvtt"
},
{
"name": "Litasa",
"discord": "Litasa#3139"
}
],
"background": "systems/l5r5e/assets/l5r-header.webp",
"scripts": [],
"esmodules": [
"./scripts/main-l5r5e.js"
],
"styles": [
"./styles/l5r5e.css"
],
"packFolders": [
{
"name": "L5R5e System",
"color": "#9a0909",
"sorting": "m",
"folders": [
{
"name": "Character related",
"color": "#019806",
"sorting": "m",
"packs": [
"core-peculiarities-distinctions",
"core-peculiarities-passions",
"core-peculiarities-adversities",
"core-peculiarities-anxieties",
"core-bonds",
"core-titles",
"core-journal-school-curriculum",
"core-journal-great-clans-presentation"
]
},
{
"name": "Techniques",
"color": "#4b1eb3",
"sorting": "m",
"packs": [
"core-techniques-kata",
"core-techniques-kiho",
"core-techniques-inversions",
"core-techniques-invocations",
"core-techniques-rituals",
"core-techniques-shuji",
"core-techniques-maho",
"core-techniques-ninjutsu",
"core-techniques-mantra",
"core-techniques-school",
"core-techniques-mastery"
]
},
{
"name": "Objects related",
"color": "#0985ae",
"sorting": "m",
"packs": [
"core-properties",
"core-item-patterns",
"core-items",
"core-armors",
"core-weapons",
"core-signature-scrolls",
"core-celestial-implement-boons"
]
},
{
"name": "Helpers",
"color": "#6b3d1f",
"sorting": "m",
"packs": [
"core-journal-conditions",
"core-journal-terrain-qualities",
"core-journal-opportunities"
]
},
{
"name": "Tools",
"color": "#834949",
"sorting": "m",
"packs": [
"core-name-tables",
"core-macros"
]
}
]
}
],
"packs": [
{
"name": "core-properties",
"label": "Properties",
"path": "packs/core-properties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kata",
"label": "Techniques Kata",
"path": "packs/core-techniques-kata.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kiho",
"label": "Techniques Kihõ",
"path": "packs/core-techniques-kiho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-inversions",
"label": "Techniques Inversions",
"path": "packs/core-techniques-inversions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-invocations",
"label": "Techniques Invocations",
"path": "packs/core-techniques-invocations.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-rituals",
"label": "Techniques Rituals",
"path": "packs/core-techniques-rituals.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-shuji",
"label": "Techniques Shuji",
"path": "packs/core-techniques-shuji.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-maho",
"label": "Techniques Mahõ",
"path": "packs/core-techniques-maho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-ninjutsu",
"label": "Techniques Ninjutsu",
"path": "packs/core-techniques-ninjutsu.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mantra",
"label": "Techniques Mantra",
"path": "packs/core-techniques-mantra.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-school",
"label": "School Abilities",
"path": "packs/core-techniques-school.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mastery",
"label": "Mastery Abilities",
"path": "packs/core-techniques-mastery.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-items",
"label": "Items",
"path": "packs/core-items.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-armors",
"label": "Armors",
"path": "packs/core-armors.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-weapons",
"label": "Weapons",
"path": "packs/core-weapons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-distinctions",
"label": "Distinctions",
"path": "packs/core-peculiarities-distinctions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-passions",
"label": "Passions",
"path": "packs/core-peculiarities-passions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-adversities",
"label": "Adversities",
"path": "packs/core-peculiarities-adversities.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-anxieties",
"label": "Anxieties",
"path": "packs/core-peculiarities-anxieties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-bonds",
"label": "Bonds",
"path": "packs/core-bonds.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-titles",
"label": "Titles",
"path": "packs/core-titles.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-item-patterns",
"label": "Item Patterns",
"path": "packs/core-item-patterns.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-signature-scrolls",
"label": "Signature Scrolls",
"path": "packs/core-signature-scrolls.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-celestial-implement-boons",
"label": "Celestial Implement Boons",
"path": "packs/core-celestial-implement-boons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-journal-school-curriculum",
"label": "School Curriculum",
"path": "packs/core-journal-school-curriculum.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-conditions",
"label": "Conditions",
"path": "packs/core-journal-conditions.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-terrain-qualities",
"label": "Terrain Qualities",
"path": "packs/core-journal-terrain-qualities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-great-clans-presentation",
"label": "Great Clans Presentation",
"path": "packs/core-journal-great-clans-presentation.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-opportunities",
"label": "Opportunities",
"path": "packs/core-journal-opportunities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-name-tables",
"label": "Name Tables",
"path": "packs/core-name-tables.db",
"type": "RollTable",
"system": "l5r5e"
},
{
"name": "core-macros",
"label": "L5R5E Macros",
"path": "packs/core-macros.db",
"type": "Macro",
"system": "l5r5e"
}
],
"languages": [
{
"lang": "en",
"name": "English",
"path": "lang/en-en.json"
},
{
"lang": "fr",
"name": "French (France)",
"path": "lang/fr-fr.json"
},
{
"lang": "es",
"name": "Spanish (Spain)",
"path": "lang/es-es.json"
},
{
"lang": "it",
"name": "Italian (Italy)",
"path": "lang/it-it.json"
}
],
"media": [
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/login.jpg?raw=true",
"caption": "Login screen"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/roll.jpg?raw=true",
"caption": "DicePicker and Roll and Keep"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/school.jpg?raw=true",
"caption": "Experience and School"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_pc.jpg?raw=true",
"caption": "PC sheet"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_npc_army.jpg?raw=true",
"caption": "NPC and Army sheets"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/compendiums.jpg?raw=true",
"caption": "Compendiums"
}
]
}

View File

@@ -0,0 +1,393 @@
{
"id": "l5rx-chiaroscuro",
"title": "Chiaroscuro - L5R",
"description": "This is an authorised multilingual game system En|Fr|Es, for Legend of the Five Rings (5th Edition) by <a href='https://edge-studio.net/'>Edge Studio</a> <p> - Join the official Discord server: <a href='https://discord.gg/foundryvtt'> Official Discord</a></p><p> - Rejoignez la communauté Francophone: <a href='https://discord.gg/pPSDNJk'>Francophone Discord</a></p>",
"url": "https://gitlab.com/teaml5r/l5r5e",
"readme": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/README.md",
"changelog": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/CHANGELOG.md",
"license": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/LICENSE.md",
"manifest": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/system/system.json",
"download": "https://gitlab.com/teaml5r/l5r5e/-/jobs/artifacts/v1.13.4/raw/l5r5e.zip?job=build",
"version": "14.0.0",
"compatibility": {
"minimum": "13",
"verified": "14"
},
"socket": true,
"authors": [
{
"name": "Vlyan",
"discord": "Vlyan#6771",
"url": "https://ko-fi.com/vlyan"
},
{
"name": "Mandar",
"discord": "Mandar#3440"
},
{
"name": "Carter",
"discord": "Carter#2703",
"url": "https://fr.tipeee.com/carter-foundryvtt"
},
{
"name": "Litasa",
"discord": "Litasa#3139"
}
],
"background": "systems/l5r5e/assets/l5r-header.webp",
"scripts": [],
"esmodules": [
"./scripts/main-l5r5e.js"
],
"styles": [
"./styles/l5r5e.css"
],
"packFolders": [
{
"name": "L5R5e System",
"color": "#9a0909",
"sorting": "m",
"folders": [
{
"name": "Character related",
"color": "#019806",
"sorting": "m",
"packs": [
"core-peculiarities-distinctions",
"core-peculiarities-passions",
"core-peculiarities-adversities",
"core-peculiarities-anxieties",
"core-bonds",
"core-titles",
"core-journal-school-curriculum",
"core-journal-great-clans-presentation"
]
},
{
"name": "Techniques",
"color": "#4b1eb3",
"sorting": "m",
"packs": [
"core-techniques-kata",
"core-techniques-kiho",
"core-techniques-inversions",
"core-techniques-invocations",
"core-techniques-rituals",
"core-techniques-shuji",
"core-techniques-maho",
"core-techniques-ninjutsu",
"core-techniques-mantra",
"core-techniques-school",
"core-techniques-mastery"
]
},
{
"name": "Objects related",
"color": "#0985ae",
"sorting": "m",
"packs": [
"core-properties",
"core-item-patterns",
"core-items",
"core-armors",
"core-weapons",
"core-signature-scrolls",
"core-celestial-implement-boons"
]
},
{
"name": "Helpers",
"color": "#6b3d1f",
"sorting": "m",
"packs": [
"core-journal-conditions",
"core-journal-terrain-qualities",
"core-journal-opportunities"
]
},
{
"name": "Tools",
"color": "#834949",
"sorting": "m",
"packs": [
"core-name-tables",
"core-macros"
]
}
]
}
],
"packs": [
{
"name": "core-properties",
"label": "Properties",
"path": "packs/core-properties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kata",
"label": "Techniques Kata",
"path": "packs/core-techniques-kata.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-kiho",
"label": "Techniques Kihõ",
"path": "packs/core-techniques-kiho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-inversions",
"label": "Techniques Inversions",
"path": "packs/core-techniques-inversions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-invocations",
"label": "Techniques Invocations",
"path": "packs/core-techniques-invocations.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-rituals",
"label": "Techniques Rituals",
"path": "packs/core-techniques-rituals.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-shuji",
"label": "Techniques Shuji",
"path": "packs/core-techniques-shuji.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-maho",
"label": "Techniques Mahõ",
"path": "packs/core-techniques-maho.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-ninjutsu",
"label": "Techniques Ninjutsu",
"path": "packs/core-techniques-ninjutsu.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mantra",
"label": "Techniques Mantra",
"path": "packs/core-techniques-mantra.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-school",
"label": "School Abilities",
"path": "packs/core-techniques-school.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-techniques-mastery",
"label": "Mastery Abilities",
"path": "packs/core-techniques-mastery.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-items",
"label": "Items",
"path": "packs/core-items.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-armors",
"label": "Armors",
"path": "packs/core-armors.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-weapons",
"label": "Weapons",
"path": "packs/core-weapons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-distinctions",
"label": "Distinctions",
"path": "packs/core-peculiarities-distinctions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-passions",
"label": "Passions",
"path": "packs/core-peculiarities-passions.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-adversities",
"label": "Adversities",
"path": "packs/core-peculiarities-adversities.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-peculiarities-anxieties",
"label": "Anxieties",
"path": "packs/core-peculiarities-anxieties.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-bonds",
"label": "Bonds",
"path": "packs/core-bonds.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-titles",
"label": "Titles",
"path": "packs/core-titles.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-item-patterns",
"label": "Item Patterns",
"path": "packs/core-item-patterns.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-signature-scrolls",
"label": "Signature Scrolls",
"path": "packs/core-signature-scrolls.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-celestial-implement-boons",
"label": "Celestial Implement Boons",
"path": "packs/core-celestial-implement-boons.db",
"type": "Item",
"system": "l5r5e"
},
{
"name": "core-journal-school-curriculum",
"label": "School Curriculum",
"path": "packs/core-journal-school-curriculum.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-conditions",
"label": "Conditions",
"path": "packs/core-journal-conditions.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-terrain-qualities",
"label": "Terrain Qualities",
"path": "packs/core-journal-terrain-qualities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-great-clans-presentation",
"label": "Great Clans Presentation",
"path": "packs/core-journal-great-clans-presentation.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-journal-opportunities",
"label": "Opportunities",
"path": "packs/core-journal-opportunities.db",
"type": "JournalEntry",
"system": "l5r5e"
},
{
"name": "core-name-tables",
"label": "Name Tables",
"path": "packs/core-name-tables.db",
"type": "RollTable",
"system": "l5r5e"
},
{
"name": "core-macros",
"label": "L5R5E Macros",
"path": "packs/core-macros.db",
"type": "Macro",
"system": "l5r5e"
}
],
"languages": [
{
"lang": "en",
"name": "English",
"path": "lang/en-en.json"
},
{
"lang": "fr",
"name": "French (France)",
"path": "lang/fr-fr.json"
},
{
"lang": "es",
"name": "Spanish (Spain)",
"path": "lang/es-es.json"
},
{
"lang": "it",
"name": "Italian (Italy)",
"path": "lang/it-it.json"
}
],
"media": [
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/login.jpg?raw=true",
"caption": "Login screen"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/roll.jpg?raw=true",
"caption": "DicePicker and Roll and Keep"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/school.jpg?raw=true",
"caption": "Experience and School"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_pc.jpg?raw=true",
"caption": "PC sheet"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/sheet_npc_army.jpg?raw=true",
"caption": "NPC and Army sheets"
},
{
"type": "screenshot",
"url": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/screenshoots/compendiums.jpg?raw=true",
"caption": "Compendiums"
}
]
}

View File

@@ -8,7 +8,7 @@
Created by potrace 1.15, written by Peter Selinger 2001-2017 Created by potrace 1.15, written by Peter Selinger 2001-2017
</metadata> </metadata>
<g transform="translate(0.000000,1264.000000) scale(0.100000,-0.100000)" <g transform="translate(0.000000,1264.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none"> fill="currentColor" stroke="none">
<path d="M5925 12625 c-248 -21 -380 -39 -378 -51 1 -7 -56 -18 -148 -29 -83 <path d="M5925 12625 c-248 -21 -380 -39 -378 -51 1 -7 -56 -18 -148 -29 -83
-9 -190 -25 -237 -35 -244 -53 -454 -105 -602 -151 -91 -28 -210 -64 -264 -81 -9 -190 -25 -237 -35 -244 -53 -454 -105 -602 -151 -91 -28 -210 -64 -264 -81
-465 -138 -1038 -415 -1493 -719 -234 -157 -585 -429 -773 -600 -215 -196 -465 -138 -1038 -415 -1493 -719 -234 -157 -585 -429 -773 -600 -215 -196

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@@ -1,13 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="48.2px" height="48.2px" viewBox="0 0 48.2 48.2" xml:space="preserve">
width="48.2px" height="48.2px" viewBox="0 0 48.2 48.2" style="enable-background:new 0 0 48.2 48.2;" xml:space="preserve"> <defs>
<linearGradient id="iconGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#E0E0E0;stop-opacity:1" />
<stop offset="100%" style="stop-color:#FFFFFF;stop-opacity:1" />
</linearGradient>
</defs>
<style type="text/css"> <style type="text/css">
.st0{fill:#030104;} /* Gradient fill with contrasting stroke */
.fill-gradient{fill:url(#iconGradient);}
.stroke-contrast{stroke:#2a2a2a;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;}
</style> </style>
<g> <g>
<g> <g>
<path class="st0" d="M43,40c-0.9-7.2-2.3-13.9-5.7-20.2c-1-1.9-2.6-3.5-3.8-5.3c-0.2-0.3-0.5-0.7-0.7-1.1c0.7-0.6,1.4-1.3,2.1-2 <path class="fill-gradient stroke-contrast" d="M43,40c-0.9-7.2-2.3-13.9-5.7-20.2c-1-1.9-2.6-3.5-3.8-5.3c-0.2-0.3-0.5-0.7-0.7-1.1c0.7-0.6,1.4-1.3,2.1-2
c0.8-0.8,1.5-1.5,2.1-2.3c0.7-0.8,1.2-1.5,1.7-2.1c1-1.3,1.5-2.3,1.5-2.3s-1,0.5-2.3,1.5c-0.7,0.5-1.4,1.1-2.1,1.7 c0.8-0.8,1.5-1.5,2.1-2.3c0.7-0.8,1.2-1.5,1.7-2.1c1-1.3,1.5-2.3,1.5-2.3s-1,0.5-2.3,1.5c-0.7,0.5-1.4,1.1-2.1,1.7
c-0.8,0.7-1.5,1.4-2.3,2.1c-0.4,0.4-0.9,0.9-1.3,1.4c-0.7-3.4-3.5-6.2-7-6.6c-3.7-0.5-7.6,1.7-8.5,5.4c-0.1,0.5-0.3,1-0.4,1.4 c-0.8,0.7-1.5,1.4-2.3,2.1c-0.4,0.4-0.9,0.9-1.3,1.4c-0.7-3.4-3.5-6.2-7-6.6c-3.7-0.5-7.6,1.7-8.5,5.4c-0.1,0.5-0.3,1-0.4,1.4
c-0.5-0.5-1-1-1.5-1.5C14,9.3,13.2,8.6,12.5,8c-0.8-0.7-1.5-1.2-2.1-1.7C9,5.3,8,4.8,8,4.8s0.5,1,1.5,2.3c0.5,0.7,1.1,1.4,1.7,2.1 c-0.5-0.5-1-1-1.5-1.5C14,9.3,13.2,8.6,12.5,8c-0.8-0.7-1.5-1.2-2.1-1.7C9,5.3,8,4.8,8,4.8s0.5,1,1.5,2.3c0.5,0.7,1.1,1.4,1.7,2.1
@@ -17,10 +24,10 @@
c0.5,0.1,1,0,1.4-0.2c0.4-0.2,0.8-0.6,1.1-1.1c0.5-0.7,0.7-0.3,1.3,0.6c0.5,0.9,1.6,1.2,3,1.4c2.9,0.4,2.8,0.6,2.5,3.5 c0.5,0.1,1,0,1.4-0.2c0.4-0.2,0.8-0.6,1.1-1.1c0.5-0.7,0.7-0.3,1.3,0.6c0.5,0.9,1.6,1.2,3,1.4c2.9,0.4,2.8,0.6,2.5,3.5
c0,0.5,0,1-0.1,1.4c-0.5,2.3,0.1,5.1-1.8,6.9c-0.8,0.7-1.6,1.1-1.5,1.2c0.1,0.1,1.1,0,2.1-0.1c2.4-0.3,4.9-0.7,7.4-1 c0,0.5,0,1-0.1,1.4c-0.5,2.3,0.1,5.1-1.8,6.9c-0.8,0.7-1.6,1.1-1.5,1.2c0.1,0.1,1.1,0,2.1-0.1c2.4-0.3,4.9-0.7,7.4-1
C42.3,42.1,43.1,41.1,43,40z M21.3,8.2C20.2,9,19.2,9.3,19,9s0.4-1.2,1.5-1.9c1-0.7,2.1-1.1,2.3-0.7C23,6.6,22.3,7.5,21.3,8.2z"/> C42.3,42.1,43.1,41.1,43,40z M21.3,8.2C20.2,9,19.2,9.3,19,9s0.4-1.2,1.5-1.9c1-0.7,2.1-1.1,2.3-0.7C23,6.6,22.3,7.5,21.3,8.2z"/>
<path class="st0" d="M32,35.9c0-0.2-0.9-0.2-1.9-0.1c-1,0.1-1.8,0.4-1.8,0.7c0,0.2,0.9,0.3,1.9,0.1C31.3,36.4,32,36.1,32,35.9z"/> <path class="fill-gradient stroke-contrast" d="M32,35.9c0-0.2-0.9-0.2-1.9-0.1c-1,0.1-1.8,0.4-1.8,0.7c0,0.2,0.9,0.3,1.9,0.1C31.3,36.4,32,36.1,32,35.9z"/>
<path class="st0" d="M18.2,35.8c-0.9-0.2-1.7-0.1-1.8,0.1c0,0.2,0.7,0.5,1.6,0.7c0.9,0.2,1.7,0.1,1.8-0.1 <path class="fill-gradient stroke-contrast" d="M18.2,35.8c-0.9-0.2-1.7-0.1-1.8,0.1c0,0.2,0.7,0.5,1.6,0.7c0.9,0.2,1.7,0.1,1.8-0.1
C19.9,36.3,19.2,36,18.2,35.8z"/> C19.9,36.3,19.2,36,18.2,35.8z"/>
<path class="st0" d="M25.3,40.3c-0.1,0-0.3,0-0.5-0.1c-0.1,0-0.2-0.1-0.3-0.1c-0.1,0-0.2,0-0.2-0.1c-0.1,0-0.3-0.1-0.4,0 <path class="fill-gradient stroke-contrast" d="M25.3,40.3c-0.1,0-0.3,0-0.5-0.1c-0.1,0-0.2-0.1-0.3-0.1c-0.1,0-0.2,0-0.2-0.1c-0.1,0-0.3-0.1-0.4,0
c-0.1,0-0.3,0-0.4,0c-0.1,0-0.2,0.1-0.2,0.1c-0.1,0-0.2,0.1-0.2,0.1c-0.2,0.1-0.4,0-0.5,0.1c-0.1,0-0.2,0.1-0.2,0.1s0,0.1,0,0.3 c-0.1,0-0.3,0-0.4,0c-0.1,0-0.2,0.1-0.2,0.1c-0.1,0-0.2,0.1-0.2,0.1c-0.2,0.1-0.4,0-0.5,0.1c-0.1,0-0.2,0.1-0.2,0.1s0,0.1,0,0.3
c0,0.2,0,0.3,0.1,0.6c0.1,0.1,0.1,0.2,0.3,0.3c0.1,0.1,0.2,0.2,0.4,0.3c0.1,0.1,0.3,0.2,0.4,0.2c0.2,0,0.3,0.1,0.5,0.1 c0,0.2,0,0.3,0.1,0.6c0.1,0.1,0.1,0.2,0.3,0.3c0.1,0.1,0.2,0.2,0.4,0.3c0.1,0.1,0.3,0.2,0.4,0.2c0.2,0,0.3,0.1,0.5,0.1
c0.2,0,0.3,0,0.5-0.1c0.2,0,0.3-0.1,0.4-0.2c0.3-0.1,0.5-0.4,0.6-0.6c0.1-0.2,0.2-0.4,0.2-0.6c0-0.2,0-0.2,0-0.2 c0.2,0,0.3,0,0.5-0.1c0.2,0,0.3-0.1,0.4-0.2c0.3-0.1,0.5-0.4,0.6-0.6c0.1-0.2,0.2-0.4,0.2-0.6c0-0.2,0-0.2,0-0.2

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="48.2px" height="48.2px" viewBox="0 0 48.2 48.2" style="enable-background:new 0 0 48.2 48.2;" xml:space="preserve"> width="48.2px" height="48.2px" viewBox="-1 -1 50.2 50.2" style="enable-background:new -1 -1 50.2 50.2;" xml:space="preserve">
<style type="text/css"> <style type="text/css">
.st0{fill:#1D1C1A;} .st0{fill:#030104;}
</style> </style>
<g> <g>
<path class="st0" d="M48.7,4.8c0,0-0.1,0-0.2,0.1c-0.9,0.6-4.4,2-9.3,3.1c-4.6,1-10.8,1.8-16.7,2.3c-6.2,0.6-14.9,0.8-21.3-0.5 <path class="st0" d="M48.7,4.8c0,0-0.1,0-0.2,0.1c-0.9,0.6-4.4,2-9.3,3.1c-4.6,1-10.8,1.8-16.7,2.3c-6.2,0.6-14.9,0.8-21.3-0.5

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -262,7 +262,7 @@
} }
}, },
{ {
"id": "Journal of observations", "id": "Journal of Observations",
"name": "Journal d'observations", "name": "Journal d'observations",
"description": "", "description": "",
"source_reference": { "source_reference": {
@@ -972,6 +972,198 @@
"source_reference": { "source_reference": {
"page": "" "page": ""
} }
},
{
"id": "Glass Ornament (Dragonfly)",
"name": "Le Verre de Libellule",
"description": "",
"source_reference": {
"page": ""
}
},
{
"id": "Arrows: Armor-Piercing",
"name": "Flèches : Perce-armure",
"description": "",
"source_reference": {
"page": "236"
}
},
{
"id": "Arrows: Flesh-Cutter",
"name": "Flèches : Fouilleuse dentrailles",
"description": "",
"source_reference": {
"page": "236"
}
},
{
"id": "Arrows: Humming-Bulb",
"name": "Flèches : Bulbe bourdonnant",
"description": "",
"source_reference": {
"page": "236"
}
},
{
"id": "Journal",
"name": "Journal",
"description": "",
"source_reference": {
"page": "66"
}
},
{
"id": "Smithing hammer",
"name": "Marteau de forgeron",
"description": "",
"source_reference": {
"page": ""
}
},
{
"id": "Sumai Garb",
"name": "Tenue de Sumai",
"description": "",
"source_reference": {
"page": "76"
}
},
{
"id": "Drafting Paper",
"name": "Papier à dessin",
"description": "",
"source_reference": {
"page": ""
}
},
{
"id": "Fine set of Chisels",
"name": "Ensemble de burins de grande qualité",
"description": "",
"source_reference": {
"page": ""
}
},
{
"id": "Omamori (Boon of Fukurokujin)",
"name": "Omamori (Bienfait de Fukurokujin)",
"description": "",
"source_reference": {
"page": "243"
}
},
{
"id": "Omamori (Boon of Bishamon)",
"name": "Omamori (Bienfait de Bishamon)",
"description": "",
"source_reference": {
"page": "243"
}
},
{
"id": "Omamori (Boon of Benten)",
"name": "Omamori (Bienfait de Benten)",
"description": "",
"source_reference": {
"page": "243"
}
},
{
"id": "Poison - Noxious Poison (One Vial)",
"name": "Poison - Toxines (un flacon)",
"description": "",
"source_reference": {
"page": "244"
}
},
{
"id": "Poison - Fire Biter (One Vial)",
"name": "Poison - Morsure Brûlante (un flacon)",
"description": "",
"source_reference": {
"page": "244"
}
},
{
"id": "Poison - Night Milk (One Vial)",
"name": "Poison - Lait de la Nuit (un flacon)",
"description": "",
"source_reference": {
"page": "244"
}
},
{
"id": "Blanket",
"name": "Couverture",
"description": "",
"source_reference": {
"page": "245"
}
},
{
"id": "Bowl",
"name": "Bol",
"description": "",
"source_reference": {
"page": "245"
}
},
{
"id": "Flint and Tinder",
"name": "Silex et amadou",
"description": "",
"source_reference": {
"page": "245"
}
},
{
"id": "Furoshiki",
"name": "Furoshiki",
"description": "",
"source_reference": {
"page": "245"
}
},
{
"id": "The Obsidian Journal",
"name": "Le Journal dobsidienne",
"description": "",
"source_reference": {
"page": "128"
}
},
{
"id": "Pouch of Insence",
"name": "Bourse dEncens",
"description": "",
"source_reference": {
"page": "85"
}
},
{
"id": "Religious texts",
"name": "Textes religieux",
"description": "",
"source_reference": {
"page": "86"
}
},
{
"id": "Small Sachel of Ingredients",
"name": "Petit sachet d'ingrédients",
"description": "",
"source_reference": {
"page": "80"
}
},
{
"id": "Blessed Glass vial",
"name": "Fiole en verre bénie",
"description": "",
"source_reference": {
"page": "80"
}
} }
] ]
} }

View File

@@ -1,804 +0,0 @@
{
"I18N": {
"Language": "English",
"Maintainers": ["Team L5R"]
},
"SETTINGS": {
"None": "No option",
"ReverseTokenBars": {
"Title": "Reverse tokens bar",
"Hint": "Change the order in which the bars under the tokens are filled in",
"None": "None",
"Fatigue": "Fatigue only",
"Strife": "Strife",
"Both": "Both Fatigue and Strife"
},
"RollNKeep": {
"DeleteOldMessage": "RnK Delete previous chat message",
"DeleteOldMessageHint": "Choose to keep or delete the previous message for a RnK series"
},
"Initiative": {
"SetTn1OnTypeChange": "Set TN to 1 on encounter change",
"SetTn1OnTypeChangeHint": "Set the TN to 1 when the encounter type is selected (Intrigue, Duel, Skirmish or Mass battle)"
},
"ShowAllStatusEffects": {
"Title": "Show all StatusEffects",
"Hint": "If uncheck (default), only L5R conditions are shown."
},
"CustomTechniques": {
"Title": "Use custom techniques",
"Hint": "Add 'Specificity' technique type to serve as a catch-all."
},
"CustomCompendiumName": {
"Title": "Custom Compendium Name",
"Hint": "For advanced users that want to change the name of the custom compendiums (Used to disables the embedded ones).",
"Notification": "Unable set Custom Compendium: '{name}'. Is it activated and registered with Babele?"
},
"CustomItemsHeight": {
"Title": "Default items windows height",
"Hint": "Set the default height for 'Items' windows types (techniques, weapons...), in pixels"
},
"Compendium": {
"HideDisabledSources": {
"Title": "[Compendium] Hide sources filter without reference",
"Hint": "Hide empty source with no elements in source filter."
},
"HideEmptySourcesFromPlayers": {
"Title": "[Compendium] Hide elements with empty reference",
"Hint": "Basically require a reference to be set in order for players to view the content in compendiums"
},
"AllowedOfficialSources": {
"Title": "[Compendium] Available official resources",
"Hint": "Useful if you as a GM want to limit the available official content to only books you own"
},
"AllowedUnofficialSources": {
"Title": "[Compendium] Available unofficial resources",
"Hint": "Useful if you have compendiums with custom items mixed with player facing items."
}
}
},
"TYPES": {
"Actor": {
"character": "Player Character",
"npc": "Non-Player Character",
"army": "Army"
},
"Item": {
"item": "Item",
"armor": "Armor",
"weapon": "Weapon",
"technique": "Technique",
"property": "Property",
"peculiarity": "Peculiarity",
"advancement": "Advancement",
"title": "Title",
"bond": "Bond",
"signature_scroll": "Signature Scroll",
"item_pattern": "Item Pattern",
"army_fortification": "Fortification",
"army_cohort": "Cohort"
},
"Journal": {
"journal": "Journal"
}
},
"l5r5e": {
"title": "Legend of the Five Rings",
"conditions": {
"afflicted": "Afflicted",
"bleeding": "Bleeding",
"burning": "Burning",
"centered": "Centered",
"compromised": "Compromised",
"dazed": "Dazed",
"disoriented": "Disoriented",
"dying": "Dying",
"emboldened": "Emboldened",
"enraged": "Enraged",
"exhausted": "Exhausted",
"immobilized": "Immobilized",
"illness_coughing_illness": "Illness: Coughing Illness",
"illness_fire_rash": "Illness: Fire Rash",
"illness_gut_sickness": "Illness: Gut Sickness",
"illness_oozing_sore_disease": "Illness: Oozing Sore Disease",
"illness_unsteady_illness": "Illness: Unsteady Illness",
"incapacitated": "Incapacitated",
"intoxicated": "Intoxicated",
"possessed": "Possessed",
"prone": "Prone",
"silenced": "Silenced",
"unconscious": "Unconscious",
"lightly_wounded_fire": "Lightly Wounded (Fire)",
"lightly_wounded_water": "Lightly Wounded (Water)",
"lightly_wounded_air": "Lightly Wounded (Air)",
"lightly_wounded_earth": "Lightly Wounded (Earth)",
"lightly_wounded_void": "Lightly Wounded (Void)",
"severely_wounded_fire": "Severely Wounded (Fire)",
"severely_wounded_water": "Severely Wounded (Water)",
"severely_wounded_air": "Severely Wounded (Air)",
"severely_wounded_earth": "Severely Wounded (Earth)",
"severely_wounded_void": "Severely Wounded (Void)"
},
"global": {
"edge_translation_disclaimer": "",
"add": "Add",
"edit": "Edit",
"delete_confirm": "Are you sure you want to delete '{name}' ?",
"drop_here": "Drop here",
"send_to_chat": "To Chat",
"locked": "Locked",
"unlocked": "Unlocked",
"random": "Random"
},
"multiselect": {
"empty_tag": "<blank>",
"placeholder": "Filter Sources",
"player_filter_label": "Player filter",
"player_filter_tooltip": "Apply player filter",
"already_in_filter": "Already in filter",
"sources_categories": {
"rules": "Rules",
"adventures": "Adventures",
"supplements": "Supplements",
"others": "Others"
}
},
"logo": {
"title": "Need help?",
"src": "systems/l5r5e/assets/l5r-logo.webp",
"alt": "Online Help",
"content": "Follow the guide :",
"edge": {
"title": "Go to the Edge-Studio website",
"info": "your browser will open the EDGE STUDIO website",
"link": "https://edge-studio.net/"
},
"drivethrurpg": {
"title": "Buy a PDF of the game...",
"info": "your browser will open the DriveThruRpg site of Edge Studio",
"link": "https://www.drivethrurpg.com/browse/pub/17946/EDGE-Studio"
},
"discord": {
"title": "FoundryVTT Official Discord",
"info": "Your browser will open on the official Foundry discord",
"link": "https://discordapp.com/invite/DDBZUDf"
},
"notes": {
"title": "Changelog",
"link": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/CHANGELOG.md"
},
"issues": {
"title": "Issues",
"link": "https://gitlab.com/teaml5r/l5r5e/-/issues"
},
"custom-compendiums": {
"title": "Compendiums",
"link": "https://gitlab.com/teaml5r/l5r5e/-/wikis/users/custom-compendiums.md"
},
"wiki": {
"title": "Wiki",
"link": "https://gitlab.com/teaml5r/l5r5e/-/wikis/home"
}
},
"rings": {
"title": "Rings",
"label": "Ring",
"earth": "Earth",
"air": "Air",
"water": "Water",
"fire": "Fire",
"void": "Void"
},
"sheets": {
"narrative": "Narrative",
"experience": "Experience",
"family": "Family",
"region": "Region",
"upbringing": "Upbringing",
"school": "School",
"description": "Description",
"bought_at_rank": "Bought at rank",
"types": "Types",
"source_reference": {
"reference": "Reference",
"page_abbreviation": "p."
},
"value": "Value",
"rarity": "Rarity",
"quantity": "Quantity",
"weight": "Weight",
"properties": "Properties",
"linked_property": "linked Property",
"removed_properties": "Cancel",
"notes": "Notes",
"inventory": "Inventory",
"equipment": "Equipment",
"rank": "Rank",
"name": "Name"
},
"dice": {
"chat": {
"successes": "Successes",
"explosives": "Explosions",
"opportunities": "Opportunities",
"strife": "Strife",
"difficulty": "TN",
"difficulty_hidden": "???",
"void_point_used": "Void point used",
"assistance_used": "Skill assistance used",
"roll_n_keep": "Roll & Keep",
"initiative_roll": "Initiative roll",
"success_text": "Success!",
"bonus_text": "bonus successes",
"fail_text": "Fail!",
"unknown_target": "Unknown target"
},
"dicepicker": {
"title": "Dice Picker",
"difficulty_title": "Difficulty",
"difficulty_hidden_label": "Hide TN",
"use_void_point_label": "Spend a",
"void_point_tooltip": "Void point",
"skill_assistance_label": "Assistance",
"roll_label": "Roll",
"bt_add_macro": "Add a macro",
"gm_request_dp_to_players": "Roll request sent to players"
},
"roll_n_keep": {
"title": "Roll & Keep",
"discard_drop_here": "Discard",
"reroll_drop_here": "Re-roll",
"swap_drop_here": "Swap",
"keep_drop_here": "Keep",
"max": "Max",
"bt_validate": "Finalize this step",
"bt_strife": "Apply strife",
"undo": "[GM] Undo the last step choices"
}
},
"gm": {
"toolbox": {
"title": "GM ToolBox",
"difficulty_hidden": "Change difficulty visibility",
"difficulty": "Change difficulty (Left click: add, Right: subtract, Middle: TN 2)",
"sleep": "Comfortable rest for all characters (Remove Water x2 fatigue. Left click: assigned characters only. Right: All actors)",
"sleep_info": "The characters had a good night's sleep.",
"scene_end": "End of scene (Conflict and Fatigue half reset for all characters. Left click: assigned characters only. Right: All actors)",
"scene_end_info": "The tension of the scene finally drops.",
"reset_void": "Start of the game: Reset the players' void points (Left click: assigned characters only. Right: All actors",
"reset_void_info": "Void points have been attributed."
},
"monitor": {
"title": "GM Monitor",
"switch_view": "Switch View",
"add_selected_tokens": "Add selected tokens",
"honor_glory_status": "H/G/S",
"focus_vigilance": "Foc./Vig.",
"mouse_control": "Left click +1, Right: -1, middle: set to 0"
}
},
"weapons": {
"title": "Weapons",
"damage": "Damage",
"range": "Range",
"stats": "Stats",
"sheathed": "Equipped / Sheathed",
"readied": "Readied",
"category": "Category",
"deadliness": "Deadliness",
"grips": "Grips",
"1hand": "1-hand",
"2hand": "2-hand"
},
"armors": {
"title": "Armors",
"type": "Resistances",
"physical": "physical",
"supernatural": "supernatural",
"equipped": "Equipped"
},
"items": {
"title": "Items"
},
"techniques": {
"title": "Techniques",
"not_allowed": "Your character does not use this type of technique.",
"only_one": "Your character can possess only one of theses technique.",
"type": "Allowed Techniques",
"kata": "Kata",
"kiho": "Kihõ",
"inversion": "Inversion",
"invocation": "Invocation",
"ritual": "Ritual",
"shuji": "Shuji",
"maho": "Mahõ",
"ninjutsu": "Ninjutsu",
"mantra": "Mantra",
"school_ability": "School Ability",
"mastery_ability": "Mastery Ability",
"title_ability": "Title Ability",
"specificity": "Specificity"
},
"peculiarities": {
"types": {
"distinction": "Distinction",
"passion": "Passion",
"adversity": "Adversity",
"anxiety": "Anxiety"
}
},
"money": {
"title": "Personal money",
"koku": "Koku",
"bu": "Bu",
"zeni": "Zeni"
},
"social": {
"title": "Social Standing",
"honor": "Honor",
"glory": "Glory",
"status": "Status",
"ninjo": "Ninjo",
"giri": "Giri",
"past": "Past",
"bushido_tenets": {
"title": "Bushido Tenets",
"paramount": "Paramount",
"less_significant": "Less Significant"
},
"titles": "Titles",
"attitude": "Demeanor:",
"advantages": "Distinctions and Passions",
"disadvantages": "Adversities and Anxieties",
"bonds": "Bonds",
"npc": {
"advantages": "Advantages",
"disadvantages": "Disadvantages",
"combat": "Combat",
"intrigue": "Intrigue"
},
"age": "Age",
"children": "Children",
"marital_status": {
"title": "Marital Status",
"partner": "Partner",
"married": "Married",
"betrothed": "Betrothed",
"unmarried": "Unmarried",
"widowed": "Widowed"
},
"gender": {
"title": "Gender",
"male": "Male",
"female": "Female"
}
},
"skills": {
"title": "Skills",
"label": "Skill",
"artisan": {
"title": "Artisan",
"aesthetics": "Aesthetics",
"composition": "Composition",
"design": "Design",
"smithing": "Smithing",
"air": "Refine",
"earth": "Restore",
"fire": "Invent",
"water": "Adapt",
"void": "Attune"
},
"martial": {
"title": "Martial",
"fitness": "Fitness",
"melee": "Martial Arts [Melee]",
"ranged": "Martial Arts [Ranged]",
"unarmed": "Martial Arts [Unarmed]",
"meditation": "Meditation",
"tactics": "Tactics",
"air": "Feint",
"earth": "Withstand",
"fire": "Overwhelm",
"water": "Shift",
"void": "Sacrifice"
},
"scholar": {
"title": "Scholar",
"culture": "Culture",
"government": "Government",
"medicine": "Medicine",
"sentiment": "Sentiment",
"theology": "Theology",
"air": "Analyze",
"earth": "Recall",
"fire": "Theorize",
"water": "Survey",
"void": "Sense"
},
"social": {
"title": "Social",
"command": "Command",
"courtesy": "Courtesy",
"games": "Games",
"performance": "Performance",
"air": "Trick",
"earth": "Reason",
"fire": "Incite",
"water": "Charm",
"void": "Enlighten"
},
"trade": {
"title": "Trade",
"commerce": "Commerce",
"labor": "Labor",
"seafaring": "Seafaring",
"skulduggery": "Skulduggery",
"survival": "Survival",
"air": "Con",
"earth": "Produce",
"fire": "Innovate",
"water": "Exchange",
"void": "Subsist"
}
},
"attributes": {
"title": "Attributes",
"endurance": "Endurance",
"endurancetip": "(Earth + Fire) x2",
"composure": "Composure",
"composuretip": "(Earth + Water) x2",
"focus": "Focus",
"focustip": "Air + Fire",
"vigilance": "Vigilance",
"vigilancetip": "(Air + Water) /2",
"voidpoints": "Void Points",
"fatigue": "Fatigue",
"strife": "Strife"
},
"conflict": {
"title": "Conflict",
"stance": "Stance",
"stances": {
"airtip": "+1 to TN of Attack and Scheme checks targeting you (+2 at rank 4+).",
"earthtip": "Others cannot spend Opportunity to inflict critical hits or conditions on you.",
"firetip": "If you succeed, +1 bonus success per Strife symbol on kept dice.",
"watertip": "Perform a second action on your turn that does not require a check or share a type with the first action.",
"voidtip": "You do not receive strife from Strife symbols on checks."
},
"initiative": {
"title": "Initiative",
"intrigue": "Intrigue",
"duel": "Duel",
"skirmish": "Skirmish",
"mass_battle": "Mass Battle",
"prepared_true": "Prepared",
"prepared_false": "Surprised",
"prepared_actor": "Defined in the character sheet (default)",
"already_set": "Your initiative has already been determined"
}
},
"advancements": {
"title": "Advancements",
"school_rank": "School rank",
"school_rank_0": "Bg",
"total": "Total",
"cost": "Cost",
"spent": "Used",
"saved": "Saved",
"total_xp_spent": "Xp spent",
"total_xp_curriculum": "Xp spent on curriculum",
"curriculum": "In curriculum",
"curriculum_validate": "Complete this rank",
"rarity_modifier": "Rarity modifier",
"item_pattern": "Item Patterns",
"signature_scroll": "Signature Scrolls",
"school_curriculum_journal": "Drop curriculum's journal in sheet to link it"
},
"character_types": {
"character": "Player Character",
"adversary": "Adversary",
"minion": "Minion"
},
"army": {
"warlord": "Warlord",
"allies_backers": "Allies and Backers",
"purpose_mustering": "Purpose for Mustering",
"battle_readiness": {
"title": "Battle Readiness",
"strength": "Strength",
"casualties": "Casualties",
"discipline": "Discipline",
"panic": "Panic"
},
"commander": "Commander",
"commander_abilities": "Commander's relevant abilities",
"army_abilities": "Army Abilities",
"commander_standing": "Commander's Standing",
"supplies_logistics": "Supplies and Logistics",
"past_battles": "Past Battles",
"cohort": {
"tab": "Cohorts",
"title": "Cohort",
"leader": "Leader",
"abilities": "Abilities"
},
"fortification": {
"tab": "Fortifications",
"title": "Fortification Held",
"difficulty": "Difficulty Value",
"attrition_reduction": "Attrition Reduction"
}
},
"twenty_questions": {
"title": "Twenty questions",
"bt_abrev": "20Q",
"bt_next": "Next",
"increase_ring1": "Ring increase (1)",
"increase_ring2": "Ring increase (2)",
"increase_skill1": "Skill increases (1)",
"increase_skill2": "Skill increases (2)",
"increase_skill3": "Skill increases (3-5)",
"choose_one_ring": "Pick one",
"choose_one_skill": "Pick one",
"or": "OR",
"and": "AND",
"error": "Oops it looks like there's an error:",
"part0": {
"intro": "You can use this sheet to fill in your answers to The Game of Twenty Questions, and to take notes for later!",
"section": "Legend of the Five Rings Core Rulebook, Chapter 2: Creating a character, p. 41-95",
"section_pow": "Legend of the Five Rings Path of Waves, Chapter 2: Creating a Character p. 3082",
"type": "Select the 20Q template you want to use",
"type_core": "Samurai (Core Rulebook)",
"type_pow": "Ronin (Path of Waves)"
},
"part1": {
"title": "Part I: Core Identity (Clan and Family)",
"title_pow": "Part I: Core Identity (Region and Upbringing)",
"q1": "1. What clan does your character belong to? (p. 41)",
"q1_pow": "1. What region does your character come from? (p. 31)",
"status": "Status",
"q2": "2. What family does your character belong to? (p. 49)",
"q2_pow": "2. What was your characters upbringing? (p. 43)",
"money": "Starting wealth in Koku",
"glory": "Glory"
},
"part2": {
"title": "Part II: Role and School",
"q3": "3. What is your characters school, and what roles does that school fall into? (p. 56)",
"q3_pow": "3. What is your characters school, and what are its associated roles? (p. 46)",
"school": "School",
"role": "Roles",
"honor": "Honor",
"access": "Technique types available",
"school_ability": "School ability",
"starting_techniques": "Starting techniques (2-6)",
"outfit": "Starting outfit",
"q4": "4. How does your character stand out within their school? (p. 88)",
"q4_pow": "4. What gets your character in and out of trouble? (p. 60)"
},
"part3": {
"title": "Part III: Honor and Glory",
"title_pow": "Part III: The Past and the Future they interact and process",
"q5": "5. Who is your lord and what is your characters duty to them? (p. 88)",
"q5_pow": "5. What is your characters past and how does it Affect them? (p. 60)",
"choose_giri": "Select giri",
"choose_past": "Select past",
"q6": "6. What does your character long for, and how might this impede their duty? (p. 90)",
"q6_pow": "6. What does your character long for, and how might their past impact their ninjō? (p. 62)",
"choose_ninjo": "Select ninjō",
"q7": "7. What is your characters relationship with their clan? (p. 91)",
"q7_pow": "7. What is your character known for? (p. 61)",
"increase_glory": "Glory increase",
"q8": "8. What does your character think of Bushidō? (p. 91)",
"q8_pow": "8. What does your character think of Bushidō? (p. 62)",
"increase_honor": "Honor increase",
"tenets": "Choose one tenet of Bushidō as paramount and one tenet as less significant (see The Clans Views of Bushidō, page 301 of the core rulebook):",
"object": "Item (Rarity 5 or lower)"
},
"part4": {
"title": "Part IV: Strengths and Weaknesses",
"q9": "9. What is your characters greatest accomplishment so far? (p. 92)",
"q9_pow": "9. What is your characters greatest accomplishment so far? (p. 64)",
"distinction": "Distinction (1)",
"q10": "10. What holds your character back the most in life? (p. 92)",
"q10_pow": "10. What holds your character back most in life? (p. 64)",
"adversity": "Adversity (1)",
"q11": "11. What activity Most makes your character feel at peace? (p. 93)",
"q11_pow": "11. What activity most makes your character feel at peace? (p. 65)",
"passion": "Passion (1)",
"q12": "12. What concern, fear, or foible troubles your character the most? (p. 93)",
"q12_pow": "12. What concern, fear, or foible troubles your character the most? (p. 65)",
"anxiety": "Anxiety (1)",
"q13": "13. Who has your character learned the most from during their life? (p. 93)",
"q13_pow": "13. Who has your character learned the most from during their life? (p. 65)",
"disadvantage": "Disadvantage (1)",
"advantage": "Advantage (1)"
},
"part5": {
"title": "Part V: Personality and Behavior",
"q14": "14. What do people notice first upon encountering your character? (p. 93)",
"q14_pow": "14. What is your characters most prized possession? (p. 66)",
"accoutrement": "Personal accoutrement",
"q15": "15. How does your character react to stressful situations? (p. 94)",
"q15_pow": "15. How does your character react to stressful situations? (p. 66)",
"q16": "16. What are your characters preexisting relationships with other clans, families, organizations, and traditions? (p. 94)",
"q16_pow": "16. What are your relationships to your family, the clans, peasants, and others? (p. 66)",
"object": "Item (Rarity 7 or lower)"
},
"part6": {
"title": "Part VI: Ancestry and Family",
"title_pow": "Part VI: Ancestry and Bonds",
"q17": "17. How would your characters parents describe them? (p. 95)",
"q17_pow": "17. What shared history do you have with your group? (p. 66)",
"bond": "Determine an appropriate bond to apply to your relationship",
"q18": "18. Who was your character named to honor? (p. 95)",
"q18_pow": "18. Who raised you? (p. 67)",
"d10r1": "D10 Result (1/2)",
"d10r1_choice": "1st D10 Effect",
"d10r2": "D10 Result (2/2)",
"d10r2_choice": "2nd D10 Effect",
"d10r2_drop_items": "Or a technique, a advantage, a object...",
"q19": "19. What is your characters personal name? (p. 95)",
"q19_pow": "19. What is your characters name? (p. 68)"
},
"part7": {
"title": "Part VII: Death",
"q20": "20. How should your character die? (p. 95)",
"q20_pow": "20. How should your character die? (p. 68)",
"summary": "Summary",
"generchar": "Generate the character",
"generchar_disclaimer": "Warning, this will erase character's current data!",
"generchar_errors": "Clear errors before continuing!"
}
},
"char_generator": {
"title": "Character Generator",
"head_bt_title": "Char. Generator",
"generate": "Generate",
"average_value": "Average value",
"identity": "Clan, gender, age, marital status",
"attributes": "Social standing, Rings, Attributes and Skills",
"demeanor": "Demeanor & rings affinities",
"peculiarities": "Advantages and Disadvantages",
"items": "Armors, Weapons, and Items",
"narrative": "Narrative (Description)"
},
"roles": {
"title": "Roles",
"artisan": "Artisan",
"bushi": "Bushi",
"courtier": "Courtier",
"monk": "Monk",
"sage": "Sage",
"shinobi": "Shinobi",
"shugenja": "Shugenja"
},
"clans": {
"title": "Clans",
"label": "Clan",
"imperial": "Imperial",
"crab": "Crab",
"crane": "Crane",
"dragon": "Dragon",
"lion": "Lion",
"phoenix": "Phoenix",
"scorpion": "Scorpion",
"unicorn": "Unicorn",
"mantis": "Mantis",
"ronin": "Ronin",
"badger": "Badger",
"bat": "Bat",
"boar": "Boar",
"dragonfly": "Dragonfly",
"firefly": "Firefly",
"fox": "Fox",
"hare": "Hare",
"monkey": "Monkey",
"oriole": "Oriole",
"ox": "Ox",
"sparrow": "Sparrow",
"tortoise": "Tortoise",
"ivory_kingdoms": "Ivory Kingdoms",
"qamarist": "Qamarist",
"ujik": "Ujik"
},
"demeanor": {
"adaptable": "Adaptable",
"aggressive": "Aggressive",
"ambitious": "Ambitious",
"amiable": "Amiable",
"analytical": "Analytical",
"angry": "Angry",
"arrogant": "Arrogant",
"assertive": "Assertive",
"beguiling": "Beguiling",
"bitter": "Bitter",
"bold": "Bold",
"calculating": "Calculating",
"calm": "Calm",
"capricious": "Capricious",
"cautious": "Cautious",
"clever": "Clever",
"compassionate": "Compassionate",
"confused": "Confused",
"courageous": "Courageous",
"cowardly": "Cowardly",
"curious": "Curious",
"dependable": "Dependable",
"detached": "Detached",
"disheartened": "Disheartened",
"enraged": "Enraged",
"feral": "Feral",
"fickle": "Fickle",
"fierce": "Fierce",
"flighty": "Flighty",
"flippant": "Flippant",
"friendly": "Friendly",
"gruff": "Gruff",
"hungry": "Hungry",
"intense": "Intense",
"intimidating": "Intimidating",
"irritable": "Irritable",
"loyal": "Loyal",
"mischievous": "Mischievous",
"morose": "Morose",
"nurturing": "Nurturing",
"obstinate": "Obstinate",
"opportunistic": "Opportunistic",
"passionate": "Passionate",
"playful": "Playful",
"power_hungry": "Power hungry",
"proud": "Proud",
"restrained": "Restrained",
"scheming": "Scheming",
"serene": "Serene",
"serious": "Serious",
"shrewd": "Shrewd",
"stubborn": "Stubborn",
"suspicious": "Suspicious",
"teasing": "Teasing",
"territorial": "Territorial",
"uncertain": "Uncertain",
"unenthused": "Unenthused",
"vain": "Vain",
"wary": "Wary"
},
"compendium": {
"filter_rank": "Show Rank",
"not_for_players": "Not shown to players",
"filter": {
"rank": "Rank",
"rarity": "Rarity",
"ring": "Ring"
}
},
"source_reference": {
"core_rulebook": "Core Rulebook",
"emerald_empire": "Emerald Empire",
"shadowlands": "Shadowlands",
"court_of_stones": "Court of Stones",
"path_of_waves": "Path of Waves",
"celestial_realms": "Celestial Realms",
"fields_of_victory": "Fields of Victory",
"writ_of_the_wild": "Writ of the Wild",
"gm_kit": "Game Master's Kit",
"beginner_game": "Beginner Game",
"the_mantis_clan": "The Mantis Clan",
"mask_of_the_oni": "Mask of the Oni",
"winters_embrace": "Winter's Embrace",
"sins_of_regret": "Sins of Regret",
"wheel_of_judgment": "Wheel of Judgment",
"blood_of_the_lioness": "Blood of the Lioness",
"imperfect_land": "Imperfect Land",
"in_the_palace_of_the_emerald_champion": "In the Palace of the Emerald Champion",
"the_highwayman": "The Highwayman",
"wedding_at_kyotei_castle": "Wedding at Kyotei Castle",
"the_knotted_tails": "The Knotted Tails",
"cresting_waves": "Cresting Waves",
"deathly_turns": "Deathly Turns",
"the_scroll_or_the_blade": "The Scroll or the Blade",
"legacies_of_war": "Legacies of War",
"children_of_the_five_winds": "Children of the Five Winds"
}
}
}

View File

@@ -1,804 +0,0 @@
{
"I18N": {
"Language": "Español",
"Maintainers": ["Team L5R"]
},
"SETTINGS": {
"None": "Sin opciones",
"ReverseTokenBars": {
"Title": "Barra de tokens inversa",
"Hint": "Cambia el orden en el que se rellenan las barras debajo de los tokens",
"None": "Ninguno",
"Fatigue": "Sólo Fatiga",
"Strife": "Conflicto",
"Both": "Tanto la Fatiga como el Conflicto"
},
"RollNKeep": {
"DeleteOldMessage": "TyG eliminar el mensaje anterior del chat",
"DeleteOldMessageHint": "Elige si mantener o borrar el mensaje anterior de la serie TyG"
},
"Initiative": {
"SetTn1OnTypeChange": "Poner el NO a 1 al seleccionar el tipo de encuentro",
"SetTn1OnTypeChangeHint": "Poner el NO a 1 cuando se elige el tipo de encuentro (Intriga, Duelo, Escaramuza o Batalla a gran escala)"
},
"ShowAllStatusEffects": {
"Title": "Mostrar todos los efectos de estado",
"Hint": "Si se desmarca (por defecto), solo se muestran las condiciones de L5A."
},
"CustomTechniques": {
"Title": "Usar técnicas personalizadas",
"Hint": "Añadir el tipo de técnica 'Particularidad' para que sirva como comodín."
},
"CustomCompendiumName": {
"Title": "Nombre de Compendio personalizado",
"Hint": "Permite a los usuarios avanzados cambiar el nombre de los compendios personalizados (utilizados para desactivar los compendios integrados).",
"Notification": "No se puede configurar el compendio personalizado: '{name}'. ¿Está activado y registrado con Babele?"
},
"CustomItemsHeight": {
"Title": "Altura predeterminada de las ventanas de objetos",
"Hint": "Establecer la altura predeterminada para las ventanas de 'objetos' (técnicas, armas...), en píxeles."
},
"Compendium": {
"HideDisabledSources": {
"Title": "[Compendio] Ocultar filtro de fuentes sin referencia",
"Hint": "Ocultar fuentes vacías sin elementos en el filtro de fuentes."
},
"HideEmptySourcesFromPlayers": {
"Title": "[Compendio] Ocultar elementos con referencias vacías",
"Hint": "Requiere que se establezca una referencia para que los jugadores puedan ver el contenido de los compendios."
},
"AllowedOfficialSources": {
"Title": "[Compendio] Recursos oficiales disponibles",
"Hint": "Útil si, como DJ, quieres limitar el contenido oficial disponible solo a los libros que tienes."
},
"AllowedUnofficialSources": {
"Title": "[Compendio] Recursos no oficiales disponibles",
"Hint": "Útil si tienes compendios con objetos personalizados mezclados con objetos destinados a los jugadores.."
}
}
},
"TYPES": {
"Actor": {
"character": "Personaje jugador",
"npc": "Personaje no jugador",
"army": "Ejército"
},
"Item": {
"item": "Objeto",
"armor": "Armadura",
"weapon": "Arma",
"technique": "Técnica",
"property": "Propiedad",
"peculiarity": "Peculiaridad",
"advancement": "Mejora",
"title": "Título",
"bond": "Vínculo",
"signature_scroll": "Pergamino especial",
"item_pattern": "Patrón de objeto",
"army_fortification": "Fortificación",
"army_cohort": "Cohorte"
},
"Journal": {
"journal": "Diario"
}
},
"l5r5e": {
"title": "La Leyenda de los Cinco Anillos",
"conditions": {
"afflicted": "Afligido",
"bleeding": "Hemorragia",
"burning": "Ardiendo",
"centered": "Centrado",
"compromised": "Comprometido",
"dazed": "Atontado",
"disoriented": "Desorientado",
"dying": "Moribundo",
"emboldened": "Alentado",
"enraged": "Enfurecido",
"exhausted": "Agotado",
"immobilized": "Inmovilizado",
"illness_coughing_illness": "Enfermedad: tos enfermiza",
"illness_fire_rash": "Enfermedad: sarpullido de fuego",
"illness_gut_sickness": "Enfermedad: malestar intestinal",
"illness_oozing_sore_disease": "Enfermedad: llagas supurantes",
"illness_unsteady_illness": "Enfermedad: temblores",
"incapacitated": "Incapacitado",
"intoxicated": "Intoxicado",
"possessed": "Poseído",
"prone": "Tumbado",
"silenced": "Silenciado",
"unconscious": "Inconsciente",
"lightly_wounded_fire": "Herida leve (Fuego)",
"lightly_wounded_water": "Herida leve (Agua)",
"lightly_wounded_air": "Herida leve (Aire)",
"lightly_wounded_earth": "Herida leve (Tierra)",
"lightly_wounded_void": "Herida leve (Vacío)",
"severely_wounded_fire": "Herida grave (Fuego)",
"severely_wounded_water": "Herida grave (Agua)",
"severely_wounded_air": "Herida grave (Aire)",
"severely_wounded_earth": "Herida grave (Tierra)",
"severely_wounded_void": "Herida grave (Vacío)"
},
"global": {
"edge_translation_disclaimer": "Edge Studio nos da su permiso para ofrecer este módulo a la comunidad, pero tanto los textos así como los códigos que lo constituyen no tienen su aprobación explícita.",
"add": "Añadir",
"edit": "Editar",
"delete_confirm": "¿Estás seguro de que quieres borrar '{name}'?",
"drop_here": "Dejar caer aquí",
"send_to_chat": "Al Chat",
"locked": "Bloqueado",
"unlocked": "Desbloqueado",
"random": "Aleatorio"
},
"multiselect": {
"empty_tag": "<blank>",
"placeholder": "Filtro de recursos",
"player_filter_label": "Filtro de jugador",
"player_filter_tooltip": "Aplicar filtro de jugador",
"already_in_filter": "Ya en el filtro",
"sources_categories": {
"rules": "Reglas",
"adventures": "Aventuras",
"supplements": "Suplementos",
"others": "Otros"
}
},
"logo": {
"títle": "¿Necesitas ayuda?",
"src": "systems/l5r5e/assets/l5r-logo.webp",
"alt": "Ayuda en línea",
"content": "Sigue la guía :",
"edge": {
"title": "Ir a la página web de Edge-Studio",
"info": "Tu navegador abrirá la página web de EDGE STUDIO",
"link": "https://edge-studio.net/"
},
"drivethrurpg": {
"title": "¿Comprar un PDF del juego?",
"info": "tu navegador abrirá el sitio DriveThruRpg de Edge Studio",
"link": "https://www.drivethrurpg.com/browse/pub/17946/EDGE-Studio"
},
"discord": {
"title": "Discord oficial de FoundryVTT",
"info": "Tu navegador abrirá el discord oficial de Foundry",
"link": "https://discordapp.com/invite/DDBZUDf"
},
"notes": {
"title": "Registro de cambios",
"link": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/CHANGELOG.md"
},
"issues": {
"title": "Problemas",
"link": "https://gitlab.com/teaml5r/l5r5e/-/issues"
},
"custom-compendiums": {
"title": "Compendios",
"link": "https://gitlab.com/teaml5r/l5r5e/-/wikis/users/custom-compendiums.md"
},
"wiki": {
"title": "Wiki",
"link": "https://gitlab.com/teaml5r/l5r5e/-/wikis/home"
}
},
"rings": {
"title": "Anillos",
"label": "Anillo",
"earth": "Tierra",
"air": "Aire",
"water": "Agua",
"fire": "Fuego",
"void": "Vacío"
},
"sheets": {
"narrative": "Narrativa",
"experience": "Experiencia",
"family": "Familia",
"region": "Region",
"upbringing": "Educación",
"school": "Escuela",
"description": "Descripción",
"bought_at_rank": "Adquirido en rango",
"types": "Tipos",
"source_reference": {
"reference": "Referencia",
"page_abbreviation": "p."
},
"value": "Valor",
"rarity": "Rareza",
"quantity": "Cantidad",
"weight": "Peso",
"properties": "Propiedades",
"linked_property": "Propiedad vínculada",
"removed_properties": "Anula",
"notes": "Notas",
"inventory": "Inventario",
"equipment": "Equipo",
"rank": "Rango",
"name": "Nombre"
},
"dice": {
"chat": {
"successes": "Éxitos",
"explosives": "Relanzables",
"opportunities": "Oportunidades",
"strife": "Conflictos",
"difficulty": "NO",
"difficulty_hidden": "???",
"void_point_used": "Punto de Vacío utilizado",
"assistance_used": "Asistencia de habilidad utilizada",
"roll_n_keep": "Tirar y guardar",
"initiative_roll": "Tirada de Iniciativa",
"success_text": "¡Éxito!",
"bonus_text": "Éxitos adicionales",
"fail_text": "¡Fallo!",
"unknown_target": "Objetivo desconocido"
},
"dicepicker": {
"title": "Selector de dados",
"difficulty_title": "Dificultad",
"difficulty_hidden_label": "Ocultar NO",
"use_void_point_label": "Gasta un",
"void_point_tooltip": "Punto de vacío",
"skill_assistance_label": "Asistencia",
"roll_label": "Tirar",
"bt_add_macro": "Añadir una macro",
"gm_request_dp_to_players": "Solicitud de tirada enviada a los jugadores"
},
"roll_n_keep": {
"title": "Tirar y guardar",
"discard_drop_here": "Descartar",
"reroll_drop_here": "Relanzar",
"swap_drop_here": "Cambiar cara",
"keep_drop_here": "Guardar",
"max": "Máx",
"bt_validate": "Terminar este paso",
"bt_strife": "Aplicar Conflicto",
"undo": "[GM] Deshacer los últimos cambios"
}
},
"gm": {
"toolbox": {
"title": "Caja de herramientas del DJ",
"difficulty_hidden": "Cambiar la dificultad visible",
"difficulty": "Cambiar dificultad (Izquierda: añadir, Derecha: sustraer, central: NO 2)",
"sleep": "Descanso confortable para todos los personajes (Eliminar fatiga = Agua x2. (Click Izquierdo: sólo a los personajes seleccionados. Derecho: a todos los actores)",
"sleep_info": "Los personajes han dormido bien.",
"scene_end": "Final de la escena (El Conflicto y la Fatiga de los personajes se reduce hasta la mitad del máximo del valor (Click Izquierdo: sólo a los personajes seleccionados. Derecho: a todos los actores)",
"scene_end_info": "La tensión de la escena por fin disminuye.",
"reset_void": "Comienzo de la partida: Resetea los puntos de Vacío de los jugadores (Click Izquierdo: sólo a los personajes seleccionados. Derecho: a todos los actores)",
"reset_void_info": "Se han adjudicado los puntos de Vacío."
},
"monitor": {
"title": "Pantalla del DJ",
"switch_view": "Cambiar vista",
"add_selected_tokens": "Add selected tokens",
"honor_glory_status": "H/G/E",
"focus_vigilance": "Con./Ale.",
"mouse_control": "Click Izquierdo +1, Derecho: -1, medio: poner a 0"
}
},
"weapons": {
"title": "Armas",
"damage": "Daño",
"range": "Alcance",
"stats": "Estadísticas",
"sheathed": "Equipado / Envainada",
"readied": "Preparado",
"category": "Categoría",
"deadliness": "Letalidad",
"grips": "Agarres",
"1hand": "1-mano",
"2hand": "2-manos"
},
"armors": {
"title": "Armaduras",
"type": "Defensa",
"physical": "Física",
"supernatural": "Sobrenatural",
"equipped": "Equipado"
},
"items": {
"title": "Objetos"
},
"techniques": {
"title": "Técnicas",
"not_allowed": "Tu personaje no puede utilizar este tipo de técnica.",
"only_one": "Tu personaje sólo puede poseer una de estas técnicas.",
"type": "Técnicas permitidas",
"kata": "Kata",
"kiho": "Kihõ",
"inversion": "Inversión",
"invocation": "Invocación",
"ritual": "Ritual",
"shuji": "Shuji",
"maho": "Mahõ",
"ninjutsu": "Ninjutsu",
"mantra": "Mantra",
"school_ability": "Capacidad de escuela",
"mastery_ability": "Habilidad de maestría",
"title_ability": "Capacidad de título",
"specificity": "Particularidad"
},
"peculiarities": {
"types": {
"distinction": "Distinción",
"passion": "Pasión",
"adversity": "Adversidad",
"anxiety": "Ansiedad"
}
},
"money": {
"title": "Dinero personal",
"koku": "Koku",
"bu": "Bu",
"zeni": "Zeni"
},
"social": {
"title": "Posición Social",
"honor": "Honor",
"glory": "Gloria",
"status": "Estatus",
"ninjo": "Ninjo",
"giri": "Giri",
"past": "Pasado",
"bushido_tenets": {
"title": "Preceptos del Bushidō",
"paramount": "Más importante",
"less_significant": "Menos significativo"
},
"titles": "Títulos",
"attitude": "Actitud:",
"advantages": "Distinciones y pasiones",
"disadvantages": "Adversidades y ansiedades",
"bonds": "Vínculos",
"npc": {
"advantages": "Ventajas",
"disadvantages": "Desventajas",
"combat": "Combate",
"intrigue": "Intriga"
},
"age": "Edad",
"children": "Vástagos",
"marital_status": {
"title": "Estado civil",
"partner": "Pareja",
"married": "Casado",
"betrothed": "Prometido",
"unmarried": "Soltero",
"widowed": "Viudo"
},
"gender": {
"title": "Género",
"male": "Masculino",
"female": "Femenino"
}
},
"skills": {
"title": "Habilidades",
"label": "Habilidad",
"artisan": {
"title": "Artesanales",
"aesthetics": "Estética",
"composition": "Composición",
"design": "Diseño",
"smithing": "Herrería",
"air": "Refinar",
"earth": "Restaurar",
"fire": "Inventar",
"water": "Adaptar",
"void": "Sintonizar"
},
"martial": {
"title": "Marciales",
"fitness": "Aptitud Física",
"melee": "Cuerpo a Cuerpo",
"ranged": "A distancia",
"unarmed": "Sin armas",
"meditation": "Meditación",
"tactics": "Estrategia",
"air": "Amagar",
"earth": "Resistir",
"fire": "Abrumar",
"water": "Alterar",
"void": "Sacrificarse"
},
"scholar": {
"title": "Académicas",
"culture": "Cultura",
"government": "Gobierno",
"medicine": "Medicina",
"sentiment": "Sentimiento",
"theology": "Teología",
"air": "Analizar",
"earth": "Recordar",
"fire": "Teorizar",
"water": "Examinar",
"void": "Percibir"
},
"social": {
"title": "Sociales",
"command": "Mando",
"courtesy": "Cortesía",
"games": "Pasatiempos",
"performance": "Interpretación",
"air": "Engañar",
"earth": "Razonar",
"fire": "Incitar",
"water": "Encandilar",
"void": "Iluminar"
},
"trade": {
"title": "Mercantiles",
"commerce": "Comercio",
"labor": "Trabajo manual",
"seafaring": "Navegación",
"skulduggery": "Actividad criminal",
"survival": "Supervivencia",
"air": "Estafar",
"earth": "Producir",
"fire": "Idear",
"water": "Intercambiar",
"void": "Subsistir"
}
},
"attributes": {
"title": "Atributos",
"endurance": "Aguante",
"endurancetip": "(Tierra + Fuego) x2",
"composure": "Compostura",
"composuretip": "(Tierra + Agua) x2",
"focus": "Concentración",
"focustip": "Aire + Fuego",
"vigilance": "Alerta",
"vigilancetip": "(Aire + Agua) /2",
"voidpoints": "Puntos de Vacío",
"fatigue": "Fatiga",
"strife": "Conflicto"
},
"conflict": {
"title": "Enfrentamiento",
"stance": "Actitud",
"stances": {
"airtip": "+1 al NO de las tiradas de ataque y maquinación que te tengan como objetivo (+2 a rango 4+).",
"earthtip": "Oponentes no pueden gastar Oportunidad para causarte impactos críticos ni estados.",
"firetip": "Si tienes éxito, +1 éxito adicional por cada símbolo de Conflicto.",
"watertip": "Efectúa una segunda acción durante tu turno que no requiera tirada ni comparta tipo con tu primera acción.",
"voidtip": "No acumulas Conflicto de los símbolos de Conflicto de tus tiradas."
},
"initiative": {
"title": "Iniciativa",
"intrigue": "Intriga",
"duel": "Duelo",
"skirmish": "Escaramuza",
"mass_battle": "Batalla a gran escala",
"prepared_true": "Preparado",
"prepared_false": "Sorprendido",
"prepared_actor": "Definido en la hoja de personaje (por defecto)",
"already_set": "Tu iniciativa ya ha sido establecida."
}
},
"advancements": {
"title": "Avances",
"school_rank": "Rango de la escuela",
"school_rank_0": "Inicial",
"total": "Total",
"cost": "Coste",
"spent": "Gastado",
"saved": "Guardado",
"total_xp_spent": "PE gastados",
"total_xp_curriculum": "PE gastados en el programa",
"curriculum": "En programa de estudio",
"curriculum_validate": "Completar este rango",
"rarity_modifier": "Modificador de rareza",
"item_pattern": "Patrones de objetos",
"signature_scroll": "Pergaminos espaciales",
"school_curriculum_journal": "Arrastra el diario del programa en la hoja para vincularlo"
},
"character_types": {
"character": "Personaje jugador",
"adversary": "Adversario",
"minion": "Esbirro"
},
"army": {
"warlord": "Señor de la guerra",
"allies_backers": "Aliados y apoyos",
"purpose_mustering": "Propósito de la movilización",
"battle_readiness": {
"title": "Preparación para la batalla",
"strength": "Fuerza",
"casualties": "Bajas",
"discipline": "Disciplina",
"panic": "Pánico"
},
"commander": "Comandante",
"commander_abilities": "Habilidades relevantes del comandante",
"army_abilities": "Habilidades del ejército",
"commander_standing": "Posición del comandante",
"supplies_logistics": "Logística y suministros",
"past_battles": "Batallas anteriores",
"cohort": {
"tab": "Cohortes",
"title": "Cohorte",
"leader": "Líder",
"abilities": "Habilidades"
},
"fortification": {
"tab": "Fortificaciones",
"title": "Fortificación",
"difficulty": "Valor de dificultad",
"attrition_reduction": "Reducción del desgaste"
}
},
"twenty_questions": {
"title": "Veinte preguntas",
"bt_abrev": "20P",
"bt_next": "Siguiente",
"increase_ring1": "Incremento de anillo (1)",
"increase_ring2": "Incremento de anillo (2)",
"increase_skill1": "Incremento de habilidad (1)",
"increase_skill2": "Incremento de habilidad (2)",
"increase_skill3": "Incremento de habilidad (3-5)",
"choose_one_ring": "Elige uno",
"choose_one_skill": "Elige una",
"or": "o",
"and": "y",
"error": "Uy, parece que hay un error:",
"part0": {
"intro": "Puedes usar esta hoja para rellenar tus respuestas al Juego de las 20 Preguntas, y para tomar notas para más tarde!",
"section": "Leyenda de los Cinco Anillos, capítulo 2: Creación de personajes, pp. 41-95",
"section_pow": "Leyenda de los Cinco Anillos Senda de las olas, capítulo 2: Creación de personajes pp. 3082",
"type": "Elige la plantilla de 20P que quieres usar",
"type_core": "Samurai (Libro básico)",
"type_pow": "Ronin (Senda de las olas)"
},
"part1": {
"title": "Parte I: Identidad básica (Clan y Familia)",
"title_pow": "Parte I: Identidad básica (Región y educación)",
"q1": "1. ¿A qué clan pertenece tu personaje? (p. 41)",
"q1_pow": "1. ¿De que región viene tu personaje? (p. 31)",
"status": "Estatus",
"q2": "2. ¿A qué familia pertenece tu personaje? (p. 49)",
"q2_pow": "2. ¿Cual fue la educación de tu personaje? (p. 43)",
"money": "Riqueza inicial en Koku",
"glory": "Gloria"
},
"part2": {
"title": "Parte II: Función y escuela",
"q3": "3. ¿Cuál es la escuela de tu personaje, y en qué funciones cumple esa escuela? (p. 56)",
"q3_pow": "3. ¿Cuál es la escuela de tu personaje y cuáles son sus funciones asociadas? (p. 46)",
"school": "Escuela",
"role": "Funciones",
"honor": "Honor",
"access": "Tipos de técnicas disponibles",
"school_ability": "Capacidad de escuela",
"starting_techniques": "Técnicas iniciales (2-6)",
"outfit": "Equipo inicial",
"q4": "4. ¿De qué manera destaca tu personaje dentro de su escuela? (p. 88)",
"q4_pow": "4. ¿Qué es lo que mete y saca a tu personaje de problemas? (p. 60)"
},
"part3": {
"title": "Parte III: Honor y Gloria",
"title_pow": "Parte III: El pasado y el futuro interactúan y se funden.",
"q5": "5. ¿Quién es tu señor y cuál es el deber de tu personaje hacia él? (p. 88)",
"q5_pow": "5. ¿Cuál es el pasado de tu personaje y cómo le afecta? (p. 60)",
"choose_giri": "Elige un giri:",
"choose_past": "Elige un pasado:",
"q6": "6. ¿Qué es lo que anhela tu personaje, y cómo podría esto interferir con su deber? (p. 90)",
"q6_pow": "6. ¿Qué anhela tu personaje y cómo podría afectar su pasado a su ninjō? (p. 62)",
"choose_ninjo": "Elige un ninjō:",
"q7": "7. ¿Cuál es la relación de tu personaje con tu clan? (p. 91)",
"q7_pow": "7. ¿Por qué es conocido tu personaje? (p. 61)",
"increase_glory": "Aumento de la gloria",
"q8": "8. ¿Qué piensa tu personaje acerca del Bushidō? (p. 91)",
"q8_pow": "8. ¿Qué piensa tu personaje acerca del Bushidō? (p. 62)",
"increase_honor": "Aumento del honor",
"tenets": "Escoge un precepto del Bushidō más importante y un precepto como menos significativo (ver las opiniones de los Clanes respecto del Bushidō, página 301 del libro de reglas básicas):",
"object": "Objeto (Rareza 5 o inferior)"
},
"part4": {
"title": "Parte IV: Fortalezas y Debilidades",
"q9": "9. ¿Cuál es el mayor logro de tu personaje hasta ahora? (p. 92)",
"q9_pow": "9. ¿Cuál es el mayor logro de tu personaje hasta ahora? (p. 64)",
"distinction": "Distinción (1)",
"q10": "10. ¿Qué es lo que más frena a tu personaje en la vida? (p. 92)",
"q10_pow": "10. ¿Qué es lo que más frena a tu personaje en la vida? (p. 64)",
"adversity": "Adversidad (1)",
"q11": "11. ¿Qué actividad hace que tu personaje se sienta más en paz? (p. 93)",
"q11_pow": "11. ¿Qué actividad hace que tu personaje se sienta más en paz? (p. 65)",
"passion": "Pasión (1)",
"q12": "12. ¿Qué preocupación, miedo o debilidad perturba más a tu personaje? (p. 93)",
"q12_pow": "12. ¿Qué preocupación, miedo o debilidad perturba más a tu personaje? (p. 65)",
"anxiety": "Ansiedad (1)",
"q13": "13. ¿Quién ha sido la persona de la que más ha aprendido tu personaje en el transcurso de su vida? (p. 93)",
"q13_pow": "13. ¿Quién ha sido la persona de la que más ha aprendido tu personaje en el transcurso de su vida? (p. 65)",
"disadvantage": "Desventaja (1)",
"advantage": "Ventaja (1)"
},
"part5": {
"title": "Parte V: Personalidad y Comportamiento",
"q14": "14. ¿Qué es lo que advierte primero la gente al encontrarse con tu personaje? (p. 93)",
"q14_pow": "14. ¿Cuál es la posesión más preciada de tu personaje? (p. 66)",
"accoutrement": "Accesorio estético distintivo",
"q15": "15. ¿Cómo reacciona tu personaje ante situaciones de tensión? (p. 94)",
"q15_pow": "15. ¿Cómo reacciona tu personaje ante situaciones de tensión? (p. 66)",
"q16": "16. ¿Cuáles son las relaciones previas de tu personaje con otros clanes, familias, organizaciones y tradiciones? (p. 94)",
"q16_pow": "16. ¿Cómo son tus relaciones con tu familia, los clanes, los campesinos y demás? (p. 66)",
"object": "Objeto (Rareza 7 o inferior)"
},
"part6": {
"title": "Parte VI: Ascestros y familia",
"title_pow": "Parte VI: Ascestros y vínculos",
"q17": "17. ¿Cómo describirían sus padres a tu personaje? (p. 95)",
"q17_pow": "17. ¿Qué historia compartes con tu grupo? (p. 66)",
"bond": "Determina el vínculo adecuado que debes aplicar a tu relación.",
"q18": "18. ¿En honor de quién se eligio el nombre de tu personaje? (p. 95)",
"q18_pow": "18. ¿Quién te crió? (p. 67)",
"d10r1": "Resultado D10 (1/2)",
"d10r1_choice": "Primer efecto de D10",
"d10r2": "Resultado D10 (2/2)",
"d10r2_choice": "Segundo efecto de D10",
"d10r2_drop_items": "O una técnica, una ventaja, un objeto...",
"q19": "19. ¿Cuál es el nombre personal de tu personaje? (p. 95)",
"q19_pow": "19. ¿Cuál es el nombre personal de tu personaje? (p. 68)"
},
"part7": {
"title": "Parte VII: Muerte",
"q20": "20. ¿Cómo debería morir tu personaje? (p. 95)",
"q20_pow": "20. ¿Cómo debería morir tu personaje? (p. 68)",
"summary": "Resumen",
"generchar": "Generar el personaje",
"generchar_disclaimer": "Advertencia, ¡esto borrará los datos actuales del personaje!",
"generchar_errors": "¡Borrar los errores antes de continuar!"
}
},
"char_generator": {
"title": "Generador de personajes",
"head_bt_title": "Generador de pj",
"generate": "Generar",
"average_value": "Valor medio",
"identity": "Clan, género, edad, estado civil",
"attributes": "Posición social, Anillos, Atributos y Habilidades",
"demeanor": "Comportamiento y afinidades con los anillos",
"peculiarities": "Ventajas y desventajas",
"items": "Armaduras, armas y objetos.",
"narrative": "Historia (descripción)"
},
"roles": {
"title": "Funciones",
"artisan": "Artesano",
"bushi": "Bushi",
"courtier": "Cortesano",
"monk": "Monje",
"sage": "Sabio",
"shinobi": "Shinobi",
"shugenja": "Shugenja"
},
"clans": {
"title": "Clanes",
"label": "Clan",
"imperial": "Imperial",
"crab": "Cangrejo",
"crane": "Grulla",
"dragon": "Dragón",
"lion": "León",
"phoenix": "Fénix",
"scorpion": "Escorpión",
"unicorn": "Unicornio",
"mantis": "Mantis",
"ronin": "Ronin",
"badger": "Tejón",
"bat": "Muerciélago",
"boar": "Jabalí",
"dragonfly": "Libélula",
"firefly": "Luciérnaga",
"fox": "Zorro",
"hare": "Liebre",
"monkey": "Mono",
"oriole": "Oropéndula",
"ox": "Buey",
"sparrow": "Gorrión",
"tortoise": "Tortuga",
"ivory_kingdoms": "Reinos de Marfil",
"qamarist": "Qamarista",
"ujik": "Ujik"
},
"demeanor": {
"adaptable": "Adaptable",
"aggressive": "Agresivo",
"ambitious": "Ambicioso",
"amiable": "Amigable",
"analytical": "Analítico",
"angry": "Enojado",
"arrogant": "Arrogante",
"assertive": "Firme",
"beguiling": "Seductor",
"bitter": "Amargado",
"bold": "Atrevido",
"calculating": "Calculador",
"calm": "Calmado",
"capricious": "Caprichoso",
"cautious": "Cuidadoso",
"clever": "Ingenioso",
"compassionate": "Compasivo",
"confused": "Confuso",
"courageous": "Valiente",
"cowardly": "Cobarde",
"curious": "Curioso",
"dependable": "Fiable",
"detached": "Desapegado",
"disheartened": "Desanimado",
"enraged": "Furioso",
"feral": "Salvaje",
"fickle": "Voluble",
"fierce": "Fiero",
"flighty": "Veleidoso",
"flippant": "Frívolo",
"friendly": "Amable",
"gruff": "Hosco",
"hungry": "Hambriento",
"intense": "Intenso",
"intimidating": "Intimidante",
"irritable": "Irritable",
"loyal": "Leal",
"mischievous": "Travieso",
"morose": "Taciturno",
"nurturing": "Animador",
"obstinate": "Obstinado",
"opportunistic": "Oportunista",
"passionate": "Apasionado",
"playful": "Juguetón",
"power_hungry": "Ávido de poder",
"proud": "Orgulloso",
"restrained": "Contenido",
"scheming": "Taimado",
"serene": "Sereno",
"serious": "Serio",
"shrewd": "Artero",
"stubborn": "Testarudo",
"suspicious": "Suspicaz",
"teasing": "Bromista",
"territorial": "Territorial",
"uncertain": "Inseguro",
"unenthused": "Sin entusiasmo",
"vain": "Vanidoso",
"wary": "Precavido"
},
"compendium": {
"filter_rank": "Mostrar rango",
"not_for_players": "No mostrar a los jugadores",
"filter": {
"rank": "Rango",
"rarity": "Rareza",
"ring": "Anillo"
}
},
"source_reference": {
"core_rulebook": "Libro básico",
"emerald_empire": "La guia del Imperio Esmeralda",
"shadowlands": "Las Tierras Sombrías",
"court_of_stones": "Cortes de piedra",
"path_of_waves": "Path of Waves",
"celestial_realms": "Celestial Realms",
"fields_of_victory": "Fields of Victory",
"writ_of_the_wild": "Writ of the Wild",
"gm_kit": "Pantalla del DJ",
"beginner_game": "Caja de inicio",
"the_mantis_clan": "El Clan de la Mantis",
"mask_of_the_oni": "La máscara del oni",
"winters_embrace": "El abrazo del invierno",
"sins_of_regret": "Sins of Regret",
"wheel_of_judgment": "Wheel of Judgment",
"blood_of_the_lioness": "Blood of the Lioness",
"imperfect_land": "Imperfect Land",
"in_the_palace_of_the_emerald_champion": "En el palacio del Campeón Esmeralda",
"the_highwayman": "The Highwayman",
"wedding_at_kyotei_castle": "Esponsales en el Castillo Kyotei",
"the_knotted_tails": "Las Colas Anudadas",
"cresting_waves": "Mareas Oscuras",
"deathly_turns": "Deathly Turns",
"the_scroll_or_the_blade": "El pergamino o la espada",
"legacies_of_war": "Legacies of War",
"children_of_the_five_winds": "Children of the Five Winds"
}
}
}

View File

@@ -1,7 +1,9 @@
{ {
"I18N": { "I18N": {
"Language": "Français", "Language": "Français",
"Maintainers": ["Team L5R"] "Maintainers": [
"Team L5R"
]
}, },
"SETTINGS": { "SETTINGS": {
"None": "Aucune option", "None": "Aucune option",
@@ -76,7 +78,10 @@
"signature_scroll": "Rouleau de marque", "signature_scroll": "Rouleau de marque",
"item_pattern": "Procédé de fabrication", "item_pattern": "Procédé de fabrication",
"army_fortification": "Fortification", "army_fortification": "Fortification",
"army_cohort": "Régiment" "army_cohort": "Régiment",
"arcane": "Arcane",
"etat": "État",
"mystere": "Mystère"
}, },
"Journal": { "Journal": {
"journal": "Journal" "journal": "Journal"
@@ -136,6 +141,7 @@
"player_filter_label": "Filtre joueur", "player_filter_label": "Filtre joueur",
"player_filter_tooltip": "Applique le filtre des joueurs", "player_filter_tooltip": "Applique le filtre des joueurs",
"already_in_filter": "Filtre déjà appliqué", "already_in_filter": "Filtre déjà appliqué",
"no_results": "Aucun résultat",
"sources_categories": { "sources_categories": {
"rules": "Règles", "rules": "Règles",
"adventures": "Aventures", "adventures": "Aventures",
@@ -317,7 +323,8 @@
"school_ability": "Capacité d'école", "school_ability": "Capacité d'école",
"mastery_ability": "Capacité de maîtrise", "mastery_ability": "Capacité de maîtrise",
"title_ability": "Capacité de Titre", "title_ability": "Capacité de Titre",
"specificity": "Particularité" "specificity": "Particularité",
"mot_invocation": "Mot d'Invocation"
}, },
"peculiarities": { "peculiarities": {
"types": { "types": {
@@ -378,67 +385,43 @@
"label": "Compétence", "label": "Compétence",
"artisan": { "artisan": {
"title": "Artisanales", "title": "Artisanales",
"aesthetics": "Esthétique", "art": "Art",
"composition": "Composition", "composition": "Composition",
"design": "Stylisme", "design": "Stylisme",
"smithing": "Forge", "smithing": "Forge",
"air": "Raffiner", "labor": "Travail Manuel"
"earth": "Restaurer",
"fire": "Inventer",
"water": "Adapter",
"void": "Sharmoniser"
}, },
"martial": { "martial": {
"title": "Martiales", "title": "Martiales",
"archery": "Archerie",
"fitness": "Forme", "fitness": "Forme",
"melee": "Arts martiaux (corps à corps)", "melee": "Mêlée",
"ranged": "Arts martiaux (distance)", "unarmed": "Mains nues",
"unarmed": "Arts martiaux (mains nues)", "meditation": "Méditation"
"meditation": "Méditation",
"tactics": "Tactique",
"air": "Feinter",
"earth": "Résister",
"fire": "Submerger",
"water": "Détourner",
"void": "Lâcher prise"
}, },
"scholar": { "scholar": {
"title": "Savantes", "title": "Connaissance",
"culture": "Culture", "culture": "Culture",
"government": "Gouvernement",
"medicine": "Médecine", "medicine": "Médecine",
"sentiment": "Sentiments", "sentiment": "Sentiments",
"theology": "Théologie", "tactics": "Tactique",
"air": "Analyser", "theology": "Théologie"
"earth": "Se remémorer",
"fire": "Théoriser",
"water": "Observer",
"void": "Ressentir"
}, },
"social": { "social": {
"title": "Sociales", "title": "Social",
"command": "Commandement", "command": "Commandement",
"courtesy": "Courtoisie", "courtesy": "Courtoisie",
"invocation": "Invocation",
"games": "Jeux", "games": "Jeux",
"performance": "Représentations", "performance": "Représentation"
"air": "Duper",
"earth": "Raisonner",
"fire": "Inciter",
"water": "Charmer",
"void": "Illuminer"
}, },
"trade": { "trade": {
"title": "Professionnelles", "title": "Professionnelles",
"animal": "Animal",
"commerce": "Commerce", "commerce": "Commerce",
"labor": "Travail manuel",
"seafaring": "Navigation", "seafaring": "Navigation",
"skulduggery": "Magouilles",
"survival": "Survie", "survival": "Survie",
"air": "Escroquer", "urban": "Urban"
"earth": "Produire",
"fire": "Innover",
"water": "Échanger",
"void": "Subsister"
} }
}, },
"attributes": { "attributes": {
@@ -492,7 +475,10 @@
"rarity_modifier": "Modificateur de rareté", "rarity_modifier": "Modificateur de rareté",
"item_pattern": "Procédés de fabrication", "item_pattern": "Procédés de fabrication",
"signature_scroll": "Rouleaux de marque", "signature_scroll": "Rouleaux de marque",
"school_curriculum_journal": "Déposer un journal de Cursus dans la feuille pour le lier" "school_curriculum_journal": "Déposer un journal de Cursus dans la feuille pour le lier",
"warning": {
"total_less_then_spent": "L'expérience totale est inférieure à l'expérience utilisée."
}
}, },
"character_types": { "character_types": {
"character": "Personnage Joueur", "character": "Personnage Joueur",
@@ -703,65 +689,103 @@
"ujik": "Ujik" "ujik": "Ujik"
}, },
"demeanor": { "demeanor": {
"adaptable": "Adaptable", "adaptable": "Malléable",
"aggressive": "Agressive", "aggressive": "Agressive",
"alluring": "Attirante",
"ambitious": "Ambitieuse", "ambitious": "Ambitieuse",
"amiable": "Sympathique", "amiable": "Aimable",
"analytical": "Réfléchie", "analytical": "Analytique",
"angry": "Enervée", "angry": "En colère",
"arrogant": "Arrogante", "arrogant": "Arrogante",
"assertive": "Assurée", "assertive": "Sûre de soi",
"beguiling": "Séduisante", "beguiling": "Envoûtante",
"bitter": "Amère", "bitter": "Amère",
"bold": "Audacieuse", "bloodthirsty": "Sanguinaire",
"bold": "Courageuse",
"calculating": "Calculatrice", "calculating": "Calculatrice",
"calm": "Calme", "calm": "Calme",
"capricious": "Capricieuse", "capricious": "Capricieuse",
"cautious": "Prudente", "cautious": "Prudente",
"clever": "Astucieuse", "clever": "Malicieuse",
"compassionate": "Compatissante", "compassionate": "Compatissante",
"confused": "Confuse", "confused": "Confuse",
"courageous": "Courageuse", "courageous": "Courageuse",
"cowardly": "Lâche", "cowardly": "Lâche",
"crestfallen": "Démoralisée",
"curious": "Curieuse", "curious": "Curieuse",
"defensive": "Sur la défensive",
"dependable": "Fiable", "dependable": "Fiable",
"detached": "Détachée", "detached": "Détachée",
"disheartened": "Découragée", "determined": "Déterminée",
"devoted": "Fervente",
"direct": "Directe",
"disheartened": "Abattue",
"dour": "Renfrognée",
"duplicitous": "Sournoise",
"effusive": "Communicative",
"enraged": "Enragée", "enraged": "Enragée",
"fanatical": "Fanatique",
"feral": "Sauvage", "feral": "Sauvage",
"fickle": "Inconstante", "fervent": "Dévote",
"fickle": "Volatile",
"fierce": "Féroce", "fierce": "Féroce",
"flighty": "Volage", "flighty": "Inconstante",
"flippant": "Désinvolte", "flippant": "Désinvolte",
"friendly": "Amicale", "friendly": "Amicale",
"gruff": "Bourrue", "gruff": "Bourrue",
"honorable": "Honorable",
"hubristic": "Prétentieuse",
"hungry": "Affamée", "hungry": "Affamée",
"intense": "Intense", "idealistic": "Idéaliste",
"imposing": "Impressionnante",
"inquisitive": "Inquisitrice",
"intense": "Excessive",
"intimidating": "Intimidante", "intimidating": "Intimidante",
"irritable": "Irritable", "irritable": "Colérique",
"loyal": "Fidèle", "loyal": "Loyale",
"mischievous": "Malicieuse", "methodical": "Méthodique",
"meticulous": "Méticuleuse",
"mischievous": "Taquine",
"moon_blessed": "Bénie par la Lune",
"morose": "Morose", "morose": "Morose",
"nurturing": "Encourageante", "near_feral": "Presque sauvage",
"nurturing": "Maternelle",
"obsessed": "Obsessionnelle",
"obstinate": "Obstinée", "obstinate": "Obstinée",
"opportunistic": "Opportuniste", "opportunistic": "Opportuniste",
"otherworldly": "Mystique",
"outgoing": "Agréable",
"passionate": "Passionnée", "passionate": "Passionnée",
"playful": "Enjouée", "patient": "Patiente",
"personable": "Avenante",
"playful": "Joueuse",
"power_hungry": "Avide de pouvoir", "power_hungry": "Avide de pouvoir",
"proud": "Fière", "proud": "Fière",
"restrained": "Restreinte", "refined": "Raffinée",
"scheming": "Intrigante", "restrained": "Modérée",
"reserved": "Réservée",
"righteous": "Intègre",
"scheming": "Fourbe",
"serene": "Sereine", "serene": "Sereine",
"serious": "Sérieuse", "serious": "Sérieuse",
"shrewd": "Astucieuse", "shrewd": "Rusée",
"sinister": "Sinistre",
"sociable": "Affable",
"starved": "Famélique",
"stoic": "Stoïque",
"stubborn": "Têtue", "stubborn": "Têtue",
"suspicious": "Soupçonneuse", "suspicious": "Suspicieuse",
"teasing": "Taquine", "teasing": "Moqueuse",
"territorial": "Territoriale", "territorial": "Territoriale",
"uncertain": "Incertaine", "uncertain": "Peu sûre de soi",
"unenthused": "Peu enthousiaste", "unenthused": "Amorphe",
"vain": "Vaine", "vain": "Orgueilleuse",
"wary": "Méfiante" "vengeful": "Vengeuse",
"vindictive": "Vindicative",
"wary": "Méfiante",
"watchful": "Attentif",
"wrathful": "Furieuse",
"zealous": "Zélée"
}, },
"compendium": { "compendium": {
"filter_rank": "Aff. Rangs", "filter_rank": "Aff. Rangs",
@@ -769,7 +793,8 @@
"filter": { "filter": {
"rank": "Rang", "rank": "Rang",
"rarity": "Rareté", "rarity": "Rareté",
"ring": "Anneau" "ring": "Anneau",
"clear": "Suppr. les Filtres"
} }
}, },
"source_reference": { "source_reference": {
@@ -799,6 +824,170 @@
"the_scroll_or_the_blade": "Le Parchemin ou le Sabre", "the_scroll_or_the_blade": "Le Parchemin ou le Sabre",
"legacies_of_war": "Les Flambeaux de la Guerre", "legacies_of_war": "Les Flambeaux de la Guerre",
"children_of_the_five_winds": "Les Enfants des Cinq Vents" "children_of_the_five_winds": "Les Enfants des Cinq Vents"
},
"tactical_grid": {
"settings": {
"title": "Plan Tactique",
"label": "Paramètres du Plan Tactique",
"hint": "Configure les Niveaux de Portée (GM uniquement), ainsi que les différentes couleurs et transparence (tous les utilisateurs).",
"cells": "cases",
"world": {
"enabled": "Activer le Plan Tactique",
"enabled_hint": "Active ou désactive le plan tactique pour tout le monde",
"start": "Début"
},
"client": {
"color": "Couleur",
"alpha": "Alpha"
},
"range": "Portée {index}",
"validate": {
"start-too-small": "Doit être supérieur à la Portée {previousRangeIndex} ({previousStart})",
"start-too-large": "Doit être inférieur à la Portée {nextRangeIndex} ({nextStart})"
},
"reset": "Réinitialiser les paramètres par défaut",
"submit": "Enregistrer"
},
"range_band": "Portée {band}",
"range_abbreviation": "NP {range}"
}
},
"chiaroscuro": {
"skill_ranks": {
"0": "—",
"initie": "Initié",
"expert": "Expert",
"maitre": "Maître",
"parangon1": "Parangon I",
"parangon2": "Parangon II",
"parangon3": "Parangon III"
},
"difficulties": {
"simple": "Simple (7)",
"moyenne": "Moyenne (10)",
"assez_difficile": "Assez difficile (13)",
"difficile": "Difficile (16)",
"tres_difficile": "Très difficile (22)",
"heroique": "Héroïque (28)",
"improbable": "Improbable (32)"
},
"aspects": {
"solar": "Aspect Solaire",
"lunar": "Aspect Lunaire",
"gauge": "Jauge d'Aspect",
"desequilibre_solaire": "Déséquilibre Solaire",
"desequilibre_lunaire": "Déséquilibre Lunaire"
},
"danger": {
"simple": "Simple",
"moyenne": "Moyenne",
"assez_difficile": "Assez Difficile",
"difficile": "Difficile"
},
"arcane": {
"title": "Arcanes",
"label": "Arcane",
"arcane_type": "Type",
"application": "Compétences",
"bonus": "Bonus",
"progression": "Progression",
"xp_cost": "Coût XP"
},
"etat": {
"title": "États",
"label": "État",
"application": "Application",
"mod": "Modificateur",
"effect": "Effet",
"elimination": "Condition d'élimination"
},
"mystere": {
"title": "Mystères",
"label": "Mystère",
"mystere_type": "Type",
"mineur": "Mineur",
"majeur": "Majeur",
"prerequisite_skill": "Compétence prérequis",
"prerequisite_condition": "Condition prérequis"
},
"character": {
"is_samurai": "Samouraï",
"title": "Titre",
"quick_info": "Info rapide",
"default_ring": "Anneau par défaut",
"region": "Région",
"education": "Éducation",
"past_problems": "Passé problématique",
"koku": "Koku",
"bu": "Bu",
"zeni": "Zeni"
},
"weapon": {
"bonus": "Bonus",
"categories": {
"arbalete": "Arbalète",
"arc": "Arc",
"contondante": "Arme Contondante",
"poing": "Arme de Poing",
"hast": "Arme Hast",
"improvisee": "Arme Improvisée",
"shinobi": "Arme Shinobi",
"specialisee": "Arme Spécialisée",
"bouclier": "Bouclier",
"hache": "Hache",
"naturel": "Naturel",
"sabre": "Sabre",
"nemuranai": "Nemuranai"
}
},
"armor": {
"categories": {
"vetement": "Vêtement",
"leger": "Léger",
"moyen": "Moyen",
"lourd": "Lourd",
"nemuranai": "Nemuranai"
}
},
"item": {
"types": {
"ordinaire": "Ordinaire",
"shinobi": "Shinobi",
"interdit": "Interdit",
"gaijin": "Gaijin",
"nemuranai": "Nemuranai"
}
},
"technique": {
"mot_invocation": "Mot d'Invocation",
"invocation_type": "Type d'invocation",
"invocation_types": {
"general": "Général",
"neutre": "Neutre",
"precis": "Précis"
},
"mode_invocation": "Mode d'Invocation"
},
"tabs": {
"invocations": "Invocations",
"identity": "Identité",
"identity_text1": "Apparence",
"identity_text2": "Biographie"
},
"dice": {
"title": "Jet Chiaroscuro",
"difficulty_label": "Difficulté",
"modifier_label": "Modificateur",
"options": "Options",
"aspect_point": "Point d'Aspect",
"assistance": "Assistance",
"total_dice": "Dés à lancer",
"bonus": "Bonus rang",
"roll": "Lancer les dés",
"dice_result": "Somme des dés",
"adjusted": "Ajusté (Parangon)",
"success": "Réussite",
"failure": "Échec"
} }
} }
} }

View File

@@ -1,804 +0,0 @@
{
"I18N": {
"Language": "Italiano",
"Maintainers": ["eldritchTranslator"]
},
"SETTINGS": {
"None": "Niente",
"ReverseTokenBars": {
"Title": "Reverse tokens bar",
"Hint": "Change the order in which the bars under the tokens are filled in",
"None": "None",
"Fatigue": "Fatigue only",
"Strife": "Strife",
"Both": "Both Fatigue and Strife"
},
"RollNKeep": {
"DeleteOldMessage": "Il Tira e Tieni cancella il messaggio in chat precedente",
"DeleteOldMessageHint": "Scegli se mantenere o eliminare il messaggio precedente in una serie di Tira e Tieni"
},
"Initiative": {
"SetTn1OnTypeChange": "Fissa la TN a 1 quando si cambia il conflitto",
"SetTn1OnTypeChangeHint": "Fissa la TN a 1 quando si seleziona il tipo di conflitto (Intrigo, Duello, Schermaglia or Battaglia campale)"
},
"ShowAllStatusEffects": {
"Title": "Show all StatusEffects",
"Hint": "If uncheck (default), only L5R conditions are shown."
},
"CustomTechniques": {
"Title": "Usa tecniche custom",
"Hint": "Aggiunge il tipo 'Speciale' come termine generale."
},
"CustomCompendiumName": {
"Title": "Custom Compendium Name",
"Hint": "For advanced users that want to change the name of the custom compendiums (Used to disables the embedded ones).",
"Notification": "Unable set Custom Compendium: '{name}'. Is it activated and registered with Babele?"
},
"CustomItemsHeight": {
"Title": "Default items windows height",
"Hint": "Set the default height for 'Items' windows types (techniques, weapons...), in pixels"
},
"Compendium": {
"HideDisabledSources": {
"Title": "[Compendium] Hide sources filter without reference",
"Hint": "Hide empty source with no elements in source filter."
},
"HideEmptySourcesFromPlayers": {
"Title": "[Compendium] Hide elements with empty reference",
"Hint": "Basically require a reference to be set in order for players to view the content in compendiums"
},
"AllowedOfficialSources": {
"Title": "[Compendium] Available official resources",
"Hint": "Useful if you as a GM want to limit the available official content to only books you own"
},
"AllowedUnofficialSources": {
"Title": "[Compendium] Available unofficial resources",
"Hint": "Useful if you have compendiums with custom items mixed with player facing items."
}
}
},
"TYPES": {
"Actor": {
"character": "Personaggio Giocante",
"npc": "Personaggio Non Giocante",
"army": "Esercito"
},
"Item": {
"item": "Oggetto",
"armor": "Armatura",
"weapon": "Arma",
"technique": "Tecnica",
"property": "Proprietà",
"peculiarity": "Peculiarità",
"advancement": "Avanzamento",
"title": "Titolo",
"bond": "Legame",
"signature_scroll": "Signature Scroll",
"item_pattern": "Item Pattern",
"army_fortification": "Fortezza",
"army_cohort": "Coorte"
},
"Journal": {
"journal": "Diario"
}
},
"l5r5e": {
"title": "Legend of the five Rings",
"conditions": {
"afflicted": "Afflicted",
"bleeding": "Bleeding",
"burning": "Burning",
"centered": "Centered",
"compromised": "Compromised",
"dazed": "Dazed",
"disoriented": "Disoriented",
"dying": "Dying",
"emboldened": "Emboldened",
"enraged": "Enraged",
"exhausted": "Exhausted",
"immobilized": "Immobilized",
"illness_coughing_illness": "Illness: Coughing Illness",
"illness_fire_rash": "Illness: Fire Rash",
"illness_gut_sickness": "Illness: Gut Sickness",
"illness_oozing_sore_disease": "Illness: Oozing Sore Disease",
"illness_unsteady_illness": "Illness: Unsteady Illness",
"incapacitated": "Incapacitated",
"intoxicated": "Intoxicated",
"possessed": "Possessed",
"prone": "Prone",
"silenced": "Silenced",
"unconscious": "Unconscious",
"lightly_wounded_fire": "Lightly Wounded (Fire)",
"lightly_wounded_water": "Lightly Wounded (Water)",
"lightly_wounded_air": "Lightly Wounded (Air)",
"lightly_wounded_earth": "Lightly Wounded (Earth)",
"lightly_wounded_void": "Lightly Wounded (Void)",
"severely_wounded_fire": "Severely Wounded (Fire)",
"severely_wounded_water": "Severely Wounded (Water)",
"severely_wounded_air": "Severely Wounded (Air)",
"severely_wounded_earth": "Severely Wounded (Earth)",
"severely_wounded_void": "Severely Wounded (Void)"
},
"global": {
"edge_translation_disclaimer": "",
"add": "Aggiungi",
"edit": "Modifica",
"delete_confirm": "Sei sicuro di voler eliminare '{name}' ?",
"drop_here": "Trascina qui",
"send_to_chat": "Chat",
"locked": "Bloccato",
"unlocked": "Sbloccato",
"random": "Casuale"
},
"multiselect": {
"empty_tag": "<blank>",
"placeholder": "Filter Sources",
"player_filter_label": "Player filter",
"player_filter_tooltip": "Apply player filter",
"already_in_filter": "Already in filter",
"sources_categories": {
"rules": "Rules",
"adventures": "Adventures",
"supplements": "Supplements",
"others": "Others"
}
},
"logo": {
"title": "Bisogno di aiuto?",
"src": "systems/l5r5e/assets/l5r-logo.webp",
"alt": "Aiuto online",
"content": "Segui la guida:",
"edge": {
"title": "Va' al sito di Edge-Studio",
"info": "Il tuo browser aprirà il sito di EDGE STUDIO (EN)",
"link": "https://edge-studio.net/"
},
"drivethrurpg": {
"title": "Compra un PDF del gioco...",
"info": "Il tuo browser aprirà il sito DriveThruRpg di Edge Studio (EN)",
"link": "https://www.drivethrurpg.com/browse/pub/17946/EDGE-Studio"
},
"discord": {
"title": "Discord Ufficiale di FoundryVTT",
"info": "Il tuo browser aprirà il Discord ufficiale di Foundry",
"link": "https://discordapp.com/invite/DDBZUDf"
},
"notes": {
"title": "Changelog",
"link": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/CHANGELOG.md"
},
"issues": {
"title": "Issues",
"link": "https://gitlab.com/teaml5r/l5r5e/-/issues"
},
"custom-compendiums": {
"title": "Compendiums",
"link": "https://gitlab.com/teaml5r/l5r5e/-/wikis/users/custom-compendiums.md"
},
"wiki": {
"title": "Wiki",
"link": "https://gitlab.com/teaml5r/l5r5e/-/wikis/home"
}
},
"rings": {
"title": "Anelli",
"label": "Anello",
"earth": "Terra",
"air": "Aria",
"water": "Acqua",
"fire": "Fuoco",
"void": "Vuoto"
},
"sheets": {
"narrative": "Narrativa",
"experience": "Esperienza",
"family": "Famiglia",
"region": "Regione",
"upbringing": "Educazione",
"school": "Scuola",
"description": "Descrizione",
"bought_at_rank": "Comprato a grado",
"types": "Tipi",
"source_reference": {
"reference": "Fonte",
"page_abbreviation": "p."
},
"value": "Valore",
"rarity": "Rarità",
"quantity": "Quantità",
"weight": "Peso",
"properties": "Proprietà",
"linked_property": "Proprietà collegata",
"removed_properties": "Annulla",
"notes": "Note",
"inventory": "Inventario",
"equipment": "Equipaggiamento",
"rank": "Grado",
"name": "Nome"
},
"dice": {
"chat": {
"successes": "Successi",
"explosives": "Esplosioni",
"opportunities": "Opportunità",
"strife": "Turbamento",
"difficulty": "TN",
"difficulty_hidden": "???",
"void_point_used": "Punto Vuoto usato",
"assistance_used": "Aiuto per Abilità usato",
"roll_n_keep": "Tira e Tieni",
"initiative_roll": "Tiro Iniziativa",
"success_text": "Successo!",
"bonus_text": "successi bonus",
"fail_text": "Fallimento!",
"unknown_target": "Unknown target"
},
"dicepicker": {
"title": "Selezione dadi",
"difficulty_title": "Difficoltà",
"difficulty_hidden_label": "Nascondi TN",
"use_void_point_label": "Spendi un",
"void_point_tooltip": "Punto Vuoto",
"skill_assistance_label": "Aiuto",
"roll_label": "Tira",
"bt_add_macro": "Aggiungi una macro",
"gm_request_dp_to_players": "Roll request sent to players"
},
"roll_n_keep": {
"title": "Tira e Tieni",
"discard_drop_here": "Lascia",
"reroll_drop_here": "Rilancia",
"swap_drop_here": "Scambia",
"keep_drop_here": "Tieni",
"max": "Max",
"bt_validate": "Conferma",
"bt_strife": "Aggiungi Turbamento",
"undo": "[GM] Annulla l'ultima scelta"
}
},
"gm": {
"toolbox": {
"title": "Attrezzi del GM",
"difficulty_hidden": "Cambia la visibilità della TN",
"difficulty": "Cambia difficoltà (click Sinistro: aggiungi, Destro: togli, centro: TN 2)",
"sleep": "Riposo tranquillo per tutti i personaggi (rimuove Stanchezza pari a Acqua x2. Click Sinistro: solo personaggi selezionati. Destro: tutti gli attori)",
"sleep_info": "I personaggi hanno avuto una notte di riposo tranquillo.",
"scene_end": "Fine della scena (Stanchezza e Turbamento si resettano a metà per tutti i personaggi. Click Sinistro: solo personaggi selezionati. Destro: tutti gli attori)",
"scene_end_info": "La tensione della scena finalmente cala.",
"reset_void": "Inizio del gioco: Resetta i punti Vuoto dei personaggi (Click Sinistro: solo personaggi selezionati. Destro: tutti gli attori)",
"reset_void_info": "I punti Vuoto sono stati distribuiti."
},
"monitor": {
"title": "Schermo del GM",
"switch_view": "Cambia vista",
"add_selected_tokens": "Add selected tokens",
"honor_glory_status": "O/G/S",
"focus_vigilance": "Foc./Vig.",
"mouse_control": "Click Sinistro +1, Destro: -1, centrale: resetta a 0"
}
},
"weapons": {
"title": "Armi",
"damage": "Danni",
"range": "Raggio",
"stats": "Statistiche",
"sheathed": "Equipaggiata / Infoderata",
"readied": "Pronta",
"category": "Categoria",
"deadliness": "Letalità",
"grips": "Impugnatura",
"1hand": "1 mano",
"2hand": "2 mani"
},
"armors": {
"title": "Armature",
"type": "Resistenza",
"physical": "fisica",
"supernatural": "sovrannaturale",
"equipped": "Equipaggiata"
},
"items": {
"title": "Oggetti"
},
"techniques": {
"title": "Tecniche",
"not_allowed": "Il tuo personaggio non può usare questo tipo di tecnica.",
"only_one": "Il tuo personaggio può avere solo una di questo tipo di tecniche.",
"type": "Tecniche permesse",
"kata": "Kata",
"kiho": "Kihō",
"inversion": "Inversione",
"invocation": "Invocazione",
"ritual": "Rituale",
"shuji": "Shuji",
"maho": "Mahō",
"ninjutsu": "Ninjutsu",
"mantra": "Mantra",
"school_ability": "Abilità di scuola",
"mastery_ability": "Abilità di maestria",
"title_ability": "Abilità di titolo",
"specificity": "Specificità"
},
"peculiarities": {
"types": {
"distinction": "Distinzioni",
"passion": "Passioni",
"adversity": "Avversità",
"anxiety": "Ansietà"
}
},
"money": {
"title": "Soldi",
"koku": "Koku",
"bu": "Bu",
"zeni": "Zeni"
},
"social": {
"title": "Status sociale",
"honor": "Onore",
"glory": "Gloria",
"status": "Status",
"ninjo": "Ninjo",
"giri": "Giri",
"past": "Passato",
"bushido_tenets": {
"title": "Codice del Bushido",
"paramount": "Vitale",
"less_significant": "Meno importante"
},
"titles": "Titoli",
"attitude": "Archetipo:",
"advantages": "Distinzioni e Passioni",
"disadvantages": "Avversità e Ansietà",
"bonds": "Legami",
"npc": {
"advantages": "Vantaggi",
"disadvantages": "Svantaggi",
"combat": "Combattimento",
"intrigue": "Intrigo"
},
"age": "Età",
"children": "Bambini",
"marital_status": {
"title": "Stato coniugale",
"partner": "Partner",
"married": "Sposato",
"betrothed": "Promesso",
"unmarried": "Non sposato",
"widowed": "Vedovo"
},
"gender": {
"title": "Genere",
"male": "Maschile",
"female": "Femminile"
}
},
"skills": {
"title": "Abilità",
"label": "Abilità",
"artisan": {
"title": "Artigiane",
"aesthetics": "Estetica",
"composition": "Composizione",
"design": "Moda",
"smithing": "Forgia",
"air": "Affinare",
"earth": "Ripristinare",
"fire": "Inventare",
"water": "Adattare",
"void": "Armonizzare"
},
"martial": {
"title": "Marziali",
"fitness": "Allenamento",
"melee": "Arti Marziali [Mischia]",
"ranged": "Arti Marziali [Distanza]",
"unarmed": "Arti Marziali [Senza Armi]",
"meditation": "Meditazione",
"tactics": "Tattica",
"air": "Fintare",
"earth": "Contrastare",
"fire": "Sopraffare",
"water": "Deviare",
"void": "Sacrificare"
},
"scholar": {
"title": "Intellettuali",
"culture": "Cultura",
"government": "Governo",
"medicine": "Medicina",
"sentiment": "Sensibilità",
"theology": "Teologia",
"air": "Analizzare",
"earth": "Ricordare",
"fire": "Teorizzare",
"water": "Esaminare",
"void": "Presentire"
},
"social": {
"title": "Sociali",
"command": "Comando",
"courtesy": "Cortesia",
"games": "Giochi",
"performance": "Esibizione",
"air": "Ingannare",
"earth": "Ragionare",
"fire": "Incitare",
"water": "Affascinare",
"void": "Illuminare"
},
"trade": {
"title": "Mestieriali",
"commerce": "Commercio",
"labor": "Lavori Pesanti",
"seafaring": "Navigazione",
"skulduggery": "Criminalità",
"survival": "Sopravvivenza",
"air": "Raggirare",
"earth": "Produrre",
"fire": "Innovare",
"water": "Scambiare",
"void": "Sussistere"
}
},
"attributes": {
"title": "Attributi",
"endurance": "Tenacia",
"endurancetip": "(Terra + Fuoco) x2",
"composure": "Compostezza",
"composuretip": "(Terra + Acqua) x2",
"focus": "Conc.",
"focustip": "Aria + Fuoco",
"vigilance": "Vigil.",
"vigilancetip": "(Aria + Acqua) /2",
"voidpoints": "Punti Vuoto",
"fatigue": "Stanchezza",
"strife": "Turbamento"
},
"conflict": {
"title": "Conflitto",
"stance": "Forma",
"stances": {
"airtip": "+1 al TN di prove di Attacco o Complotto che bersagliano il personaggio (+2 a grado 4+).",
"earthtip": "Altri individui non possono spendere Opportunità per infliggere colpi critici o condizioni sul personaggio.",
"firetip": "Se il personaggio ha successo, +1 successo bonus per ogni risultato Turbamento.",
"watertip": "Il personaggio effettua nel turno una seconda azione che non richieda prove o condivida il tipo con la prima azione.",
"voidtip": "Il personaggio non riceve turbamento dai simboli Turbamento nelle prove."
},
"initiative": {
"title": "Iniziativa",
"intrigue": "Intrigo",
"duel": "Duello",
"skirmish": "Schermaglia",
"mass_battle": "Battaglia Campale",
"prepared_true": "Preparato",
"prepared_false": "Sorpreso",
"prepared_actor": "Definito nella scheda del personaggio (default)",
"already_set": "La tua Iniziativa è già stata determinata."
}
},
"advancements": {
"title": "Avanzamento",
"school_rank": "Grado della Scuola",
"school_rank_0": "Grado 0",
"total": "Totale",
"cost": "Costo",
"spent": "Usati",
"saved": "Tenuti",
"total_xp_spent": "Exp spesi",
"total_xp_curriculum": "Exp spesi nel curriculum",
"curriculum": "In curriculum",
"curriculum_validate": "Completa questo grado",
"rarity_modifier": "Modificatore rarità",
"item_pattern": "Item Patterns",
"signature_scroll": "Signature Scrolls",
"school_curriculum_journal": "Trascina il diario del curriculum sulla scheda per collegarlo"
},
"character_types": {
"character": "Personaggio giocante",
"adversary": "Avversario",
"minion": "Gregario"
},
"army": {
"warlord": "Signore della guerra",
"allies_backers": "Alleati e finanziatori",
"purpose_mustering": "Scopo di adunata",
"battle_readiness": {
"title": "Preparazione alla battaglia",
"strength": "Forza",
"casualties": "Vittime",
"discipline": "Disciplina",
"panic": "Panico"
},
"commander": "Comandante",
"commander_abilities": "Capacità rilevanti del comandante",
"army_abilities": "Capacità delle Armate",
"commander_standing": "Posizione del comandante",
"supplies_logistics": "Rifornimenti e logistica",
"past_battles": "Battaglie passate",
"cohort": {
"tab": "Drappelli",
"title": "Drappello",
"leader": "Condottiero",
"abilities": "Capacità"
},
"fortification": {
"tab": "Fortificazioni",
"title": "Fortificazioni possedute",
"difficulty": "Difficoltà",
"attrition_reduction": "Riduzione dell'attrito"
}
},
"twenty_questions": {
"title": "Venti domande",
"bt_abrev": "20D",
"bt_next": "Prossimo",
"increase_ring1": "Incremento di anello (1)",
"increase_ring2": "Incremento di anello (2)",
"increase_skill1": "Incremento di abilità (1)",
"increase_skill2": "Incremento di abilità (2)",
"increase_skill3": "Incremento di abilità (3-5)",
"choose_one_ring": "Scegli uno",
"choose_one_skill": "Scegli uno",
"or": "O",
"and": "E",
"error": "Oops, sembra ci sia un errore:",
"part0": {
"intro": "Puoi usare questa scheda per rispondere alle domande del Gioco delle Venti Domande, e per prendere appunti per dopo!",
"section": "La Leggenda dei Cinque Anelli, Manuale Base, Capitolo 2: Creare un Personaggio, pp. 41-95",
"section_pow": "La Leggenda dei Cinque Anelli Sentiero delle Onde, Capitolo 2: Creare un Personaggio, pp. 3082",
"type": "Seleziona il template delle 20D che vuoi usare",
"type_core": "Samurai (Manuale Base)",
"type_pow": "Ronin (Sentiero delle Onde)"
},
"part1": {
"title": "Parte I: Identità Generale (Clan e Famiglia)",
"title_pow": "Parte I: Identità Generale (Regione e Educazione)",
"q1": "1. A quale clan appartiene il personaggio? (p. 41)",
"q1_pow": "1. Da quale regione arriva il tuo personaggio? (p. 31)",
"status": "Status",
"q2": "2. A quale famiglia appartiene il personaggio? (p. 49)",
"q2_pow": "2. Qual è stata l'educazione del tuo personaggio? (p. 43)",
"money": "Denao iniziale in Koku",
"glory": "Gloria"
},
"part2": {
"title": "Parte II: Ruolo e Scuola",
"q3": "3. Qual è la scuola del personaggio e in quali ruoli ricade quella scuola? (p. 56)",
"q3_pow": "3. Qual è la scuola del personaggio e in quali ruoli ricade quella scuola? (p. 46)",
"school": "Scuola",
"role": "Ruolo",
"honor": "Onore",
"access": "Tecniche Disponibili",
"school_ability": "Abilità di Scuola",
"starting_techniques": "Tecniche di Partenza (2-6)",
"outfit": "Dotazione di Partenza",
"q4": "4. Come si distingue il personaggio allinterno della sua scuola? (p. 88)",
"q4_pow": "4. Che cosa mette nei guai il personaggio, e che cosa lo tira fuori dai guai? (p. 60)"
},
"part3": {
"title": "Parte III: Onore e Gloria",
"title_pow": "Parte III: Il Passato, il Futuro, e come interagiscono",
"q5": "5. Chi è il suo signore e quali doveri ha il personaggio nei suoi confronti? (p. 88)",
"q5_pow": "5. Qual è il passato del tuo personaggio, e come lo ha segnato? (p. 60)",
"choose_giri": "Scegli il giri",
"choose_past": "Scegli il passato",
"q6": "6. Cosa desidera ardentemente il personaggio e come ciò potrebbe ostacolare il suo dovere? (p. 90)",
"q6_pow": "6. Cosa desidera ardentemente il personaggio, e il suo passato come potrebbe ostacolare il suo ninjō? (p. 62)",
"choose_ninjo": "Scegli ninjō",
"q7": "7. Qual è il rapporto del personaggio con il suo clan? (p. 91)",
"q7_pow": "7. Per cosa è conosciuto il tuo personaggio? (p. 61)",
"increase_glory": "Aumento di Gloria",
"q8": "8. Cosa pensa il personaggio del Bushidō? (p. 91)",
"q8_pow": "8. Cosa pensa il personaggio del Bushidō? (p. 62)",
"increase_honor": "Aumento di Onore",
"tenets": "Scegli un principio del Bushidō come il più importante e uno come meno importante (vedi Come i clan vedono il Bushidō, p. 301 del Manuale Base):",
"object": "Oggetto (Rarità 5 o minore)"
},
"part4": {
"title": "Parte IV: Punti di Forza e Punti Deboli",
"q9": "9. Qual è il traguardo più grande raggiunto dal personaggio finora? (p. 92)",
"q9_pow": "9. Qual è il traguardo più grande raggiunto dal personaggio finora? (p. 64)",
"distinction": "Distinzione (1)",
"q10": "10. Cosa è di maggiore ostacolo al personaggio nella vita? (p. 92)",
"q10_pow": "Cosa è di maggiore ostacolo al personaggio nella vita? (p. 64)",
"adversity": "Avversità (1)",
"q11": "11. Quale attività fa sentire in pace il personaggio? (p. 93)",
"q11_pow": "11. Quale attività fa sentire in pace il personaggio? (p. 65)",
"passion": "Passione (1)",
"q12": "12. Quale dubbio, paura o debolezza preoccupa di più il personaggio? (p. 93)",
"q12_pow": "12. Quale dubbio, paura o debolezza preoccupa di più il personaggio? (p. 65)",
"anxiety": "Ansietà (1)",
"q13": "13. Da chi ha imparato maggiormente il personaggio nel corso della sua vita? (p. 93)",
"q13_pow": "13. Da chi ha imparato maggiormente il personaggio nel corso della sua vita? (p. 65)",
"disadvantage": "Svantaggio (1)",
"advantage": "Vantaggio (1)"
},
"part5": {
"title": "Parte V: Personalità e Comportamento",
"q14": "14. Che cosa notano prima le persone che incontrano il personaggio? (p. 93)",
"q14_pow": "14. Qual è l'oggetto più importante per il personaggio? (p. 66)",
"accoutrement": "Tocco personale",
"q15": "15. Come reagisce il personaggio alle situazioni stressanti? (p. 94)",
"q15_pow": "15. Come reagisce il personaggio alle situazioni stressanti? (p. 66)",
"q16": "16. Quali sono le precedenti relazioni del personaggio con gli altri clan, famiglie, organizzazioni e tradizioni? (p. 94)",
"q16_pow": "16. Che relazioni hai con la tua famiglia, i clan, i popolani, e gli altri? (p. 66)",
"object": "Oggetto (Rarità 7 o minore)"
},
"part6": {
"title": "Parte VI: Antenati e Famiglia",
"title_pow": "Parte VI: Antenati e Legami",
"q17": "17. Come descriverebbero il personaggio i suoi genitori? (p. 95)",
"q17_pow": "17. Che genere di storia condividi con il tuo gruppo? (p. 66)",
"bond": "Determina un legame appropriato per la vostra relazione",
"q18": "18. Chi si intende onorare tramite il nome che è stato scelto per il personaggio? (p. 95)",
"q18_pow": "18. Chi ti ha allevato? (p. 67)",
"d10r1": "Risultato d10 (1/2)",
"d10r1_choice": "Primo effetto del d10",
"d10r2": "Risultato d10 (2/2)",
"d10r2_choice": "Secondo effetto del d10",
"d10r2_drop_items": "O una tecnica, un vantaggio, un oggetto...",
"q19": "19. Qual è il nome proprio del personaggio? (p. 95)",
"q19_pow": "19. Qual è il nome del personaggio? (p. 68)"
},
"part7": {
"title": "Parte VII: Morte",
"q20": "20. Come dovrebbe morire il personaggio? (p. 95)",
"q20_pow": "20. Come dovrebbe morire il personaggio? (p. 68)",
"summary": "Sintesi",
"generchar": "Generare il personaggio",
"generchar_disclaimer": "Attenzione, questo sovrascriverà tutti i dati del personaggio!",
"generchar_errors": "Correggi gli errori prima di continuare!"
}
},
"char_generator": {
"title": "Generatore del personaggio",
"head_bt_title": "Gen. Personaggio",
"generate": "Crea",
"average_value": "Valore medio",
"identity": "Clan, genere, età, stato civile",
"attributes": "Status sociale, Anelli, Attributi e Abilità",
"demeanor": "Atteggiamento & Affinità di anelli",
"peculiarities": "Vantaggi e Svantaggi",
"items": "Armature, Armi, e Oggetti",
"narrative": "Narrativa (Descrizione)"
},
"roles": {
"title": "Ruolo",
"artisan": "Artigiano",
"bushi": "Bushi",
"courtier": "Cortigiano",
"monk": "Monaco",
"sage": "Saggio",
"shinobi": "Shinobi",
"shugenja": "Shugenja"
},
"clans": {
"title": "I Clan",
"label": "Clan",
"imperial": "Imperiale",
"crab": "Granchio",
"crane": "Gru",
"dragon": "Drago",
"lion": "Leone",
"phoenix": "Fenice",
"scorpion": "Scorpione",
"unicorn": "Unicorno",
"mantis": "Mantide",
"ronin": "Ronin",
"badger": "Tasso",
"bat": "Pipistrello",
"boar": "Cinghiale",
"dragonfly": "Libellula",
"firefly": "Lucciola",
"fox": "Fox",
"hare": "Lepre",
"monkey": "Scimmia",
"oriole": "Oriolo",
"ox": "Bue",
"sparrow": "Passero",
"tortoise": "Tartaruga",
"ivory_kingdoms": "Regni d'Avorio",
"qamarist": "Qamarista",
"ujik": "Ujik"
},
"demeanor": {
"adaptable": "Flessibile",
"aggressive": "Aggressivo",
"ambitious": "Ambizioso",
"amiable": "Affabile",
"analytical": "Analitico",
"angry": "Iracondo",
"arrogant": "Arrogante",
"assertive": "Risoluto",
"beguiling": "Ammaliante",
"bitter": "Amaro",
"bold": "Ardito",
"calculating": "Calcolatore",
"calm": "Calmo",
"capricious": "Capriccioso",
"cautious": "Cauto",
"clever": "Furbo",
"compassionate": "Compassionate",
"confused": "Confuso",
"courageous": "Coraggioso",
"cowardly": "Codardo",
"curious": "Curioso",
"dependable": "Affidabile",
"detached": "Distaccato",
"disheartened": "Sconfortato",
"enraged": "Infuriato",
"feral": "Selvaggio",
"fickle": "Volubile",
"fierce": "Agguerrito",
"flighty": "Volubile",
"flippant": "Irriverente",
"friendly": "Amichevole",
"gruff": "Burbero",
"hungry": "Affamato",
"intense": "Intenso",
"intimidating": "Intimidatorio",
"irritable": "Irritabile",
"loyal": "Leale",
"mischievous": "Malandrino",
"morose": "Cupo",
"nurturing": "Materno",
"obstinate": "Ostinato",
"opportunistic": "Opportunista",
"passionate": "Appassionato",
"playful": "Giocoso",
"power_hungry": "Affamato di potere",
"proud": "Orgoglioso",
"restrained": "Contenuto",
"scheming": "Cospiratore",
"serene": "Sereno",
"serious": "Serio",
"shrewd": "Scaltro",
"stubborn": "Testardo",
"suspicious": "Sospettoso",
"teasing": "Stuzzicante",
"territorial": "Territoriale",
"uncertain": "Incerto",
"unenthused": "Non entusiasta",
"vain": "Vanesio",
"wary": "Diffidente"
},
"compendium": {
"filter_rank": "Show Rank",
"not_for_players": "Not shown to players",
"filter": {
"rank": "Rank",
"rarity": "Rarity",
"ring": "Ring"
}
},
"source_reference": {
"core_rulebook": "Core Rulebook",
"emerald_empire": "Emerald Empire",
"shadowlands": "Shadowlands",
"court_of_stones": "Court of Stones",
"path_of_waves": "Path of Waves",
"celestial_realms": "Celestial Realms",
"fields_of_victory": "Fields of Victory",
"writ_of_the_wild": "Writ of the Wild",
"gm_kit": "Game Master's Kit",
"beginner_game": "Beginner Game",
"the_mantis_clan": "The Mantis Clan",
"mask_of_the_oni": "Mask of the Oni",
"winters_embrace": "Winter's Embrace",
"sins_of_regret": "Sins of Regret",
"wheel_of_judgment": "Wheel of Judgment",
"blood_of_the_lioness": "Blood of the Lioness",
"imperfect_land": "Imperfect Land",
"in_the_palace_of_the_emerald_champion": "In the Palace of the Emerald Champion",
"the_highwayman": "The Highwayman",
"wedding_at_kyotei_castle": "Wedding at Kyotei Castle",
"the_knotted_tails": "The Knotted Tails",
"cresting_waves": "Cresting Waves",
"deathly_turns": "Deathly Turns",
"the_scroll_or_the_blade": "The Scroll or the Blade",
"legacies_of_war": "Legacies of War",
"children_of_the_five_winds": "Children of the Five Winds"
}
}
}

View File

@@ -30,7 +30,7 @@
{"_id":"L5RCoreIte000030","name":"Tent (Yurt)","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"2","rarity":"5","zeni":"10 koku","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"245"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]} {"_id":"L5RCoreIte000030","name":"Tent (Yurt)","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"2","rarity":"5","zeni":"10 koku","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"245"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000031","name":"Scroll satchel","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"3","zeni":"1 bu","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"60"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]} {"_id":"L5RCoreIte000031","name":"Scroll satchel","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"3","zeni":"1 bu","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"60"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000032","name":"Traveling pack","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"1","zeni":"10 koku","properties":[{"id":"L5RCorePro000012","name":"Mundane"}],"description":"","source_reference":{"source":"core_rulebook","page":"245"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]} {"_id":"L5RCoreIte000032","name":"Traveling pack","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"1","zeni":"10 koku","properties":[{"id":"L5RCorePro000012","name":"Mundane"}],"description":"","source_reference":{"source":"core_rulebook","page":"245"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000033","name":"Journal of observations","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"3","zeni":"1 bu","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"67"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]} {"_id":"L5RCoreIte000033","name":"Journal of Observations","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"3","zeni":"1 bu","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"67"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000034","name":"Omamori (Boon of Jurojin)","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"5 bu","properties":[],"description":"","source_reference":{"source":"celestial_realms","page":"97"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]} {"_id":"L5RCoreIte000034","name":"Omamori (Boon of Jurojin)","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"5 bu","properties":[],"description":"","source_reference":{"source":"celestial_realms","page":"97"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000035","name":"Omamori (Boon of Kisshoten)","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"5 bu","properties":[],"description":"","source_reference":{"source":"celestial_realms","page":"97"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]} {"_id":"L5RCoreIte000035","name":"Omamori (Boon of Kisshoten)","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"5 bu","properties":[],"description":"","source_reference":{"source":"celestial_realms","page":"97"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000036","name":"Omamori (Boon of Hotei)","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"5 bu","properties":[],"description":"","source_reference":{"source":"celestial_realms","page":"97"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]} {"_id":"L5RCoreIte000036","name":"Omamori (Boon of Hotei)","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"5 bu","properties":[],"description":"","source_reference":{"source":"celestial_realms","page":"97"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
@@ -119,3 +119,27 @@
{"_id":"L5RCoreIte000121","name":"Word of the Prophet","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"9","zeni":"15 Koku","properties":[],"description":"","source_reference":{"source":"children_of_the_five_winds","page":"103"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]} {"_id":"L5RCoreIte000121","name":"Word of the Prophet","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"9","zeni":"15 Koku","properties":[],"description":"","source_reference":{"source":"children_of_the_five_winds","page":"103"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000122","name":"Talisman of the Sun [Blessed Treasure]","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"10","zeni":"0","properties":[],"description":"","source_reference":{"source":"children_of_the_five_winds","page":"104"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]} {"_id":"L5RCoreIte000122","name":"Talisman of the Sun [Blessed Treasure]","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"10","zeni":"0","properties":[],"description":"","source_reference":{"source":"children_of_the_five_winds","page":"104"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000123","name":"Fox Pipe [Blessed Treasure]","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"10","zeni":"0","properties":[],"description":"","source_reference":{"source":"children_of_the_five_winds","page":"105"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]} {"_id":"L5RCoreIte000123","name":"Fox Pipe [Blessed Treasure]","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"10","zeni":"0","properties":[],"description":"","source_reference":{"source":"children_of_the_five_winds","page":"105"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000124","name":"Glass Ornament (Dragonfly)","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"6","zeni":"1 koku","properties":[],"description":"","source_reference":{"source":"writ_of_the_wild","page":"83"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000125","name":"Arrows: Armor-Piercing","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"0","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"236"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000126","name":"Arrows: Flesh-Cutter","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"0","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"236"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000127","name":"Arrows: Humming-Bulb","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"0","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"236"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000128","name":"Journal","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"1","zeni":"0","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"66"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000129","name":"Smithing hammer","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"1","zeni":"0","properties":[],"description":"","source_reference":{"source":"shadowlands","page":"89"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000130","name":"Sumai Garb","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"1","zeni":"0","properties":[],"description":"","source_reference":{"source":"fields_of_victory","page":"89"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000131","name":"Drafting Paper","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"1","zeni":"0","properties":[],"description":"","source_reference":{"source":"celestial_realms","page":"84"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000132","name":"Fine set of Chisels","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"1","zeni":"0","properties":[],"description":"","source_reference":{"source":"celestial_realms","page":"84"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000133","name":"Omamori (Boon of Fukurokujin)","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"5 bu","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"243"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000134","name":"Omamori (Boon of Bishamon)","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"5 bu","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"243"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000135","name":"Omamori (Boon of Benten)","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"5 bu","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"243"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000136","name":"Poison - Noxious Poison (One Vial)","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"5","zeni":"30 zeni","properties":[{"id":"L5RCorePro000009","name":"Forbidden"}],"description":"","source_reference":{"source":"core_rulebook","page":"244"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000137","name":"Poison - Fire Biter (One Vial)","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"5","zeni":"30 zeni","properties":[{"id":"L5RCorePro000009","name":"Forbidden"}],"description":"","source_reference":{"source":"core_rulebook","page":"244"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000138","name":"Poison - Night Milk (One Vial)","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"5","zeni":"30 zeni","properties":[{"id":"L5RCorePro000009","name":"Forbidden"}],"description":"","source_reference":{"source":"core_rulebook","page":"244"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000139","name":"Blanket","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"0","zeni":"1 zeni","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"245"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000140","name":"Bowl","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"0","zeni":"1 zeni","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"245"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000141","name":"Flint and Tinder","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"0","zeni":"1 zeni","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"245"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000142","name":"Furoshiki","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"0","zeni":"1 zeni","properties":[],"description":"","source_reference":{"source":"core_rulebook","page":"245"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000143","name":"The Obsidian Journal","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"10","zeni":"0","properties":[{"id":"L5RCorePro000009","name":"Forbidden"},{"id":"L5RCorePro000008","name":"Unholy"}],"description":"","source_reference":{"source":"core_rulebook","page":"127"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000144","name":"Pouch of Insence","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"0","properties":[],"description":"","source_reference":{"source":"celestial_realms","page":"85"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000145","name":"Religious texts","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"0","properties":[],"description":"","source_reference":{"source":"celestial_realms","page":"86"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000146","name":"Small Sachel of Ingredients","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"10 bu","properties":[],"description":"","source_reference":{"source":"celestial_realms","page":"80"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}
{"_id":"L5RCoreIte000147","name":"Blessed Glass vial","permission":{"default":0},"type":"item","data":{"equipped":false,"quantity":1,"weight":"0","rarity":"2","zeni":"0","properties":[],"description":"","source_reference":{"source":"celestial_realms","page":"80"}},"sort":100001,"flags":{},"img":"systems/l5r5e/assets/icons/items/item.svg","effects":[]}

View File

@@ -624,6 +624,36 @@ export class BaseCharacterSheetL5r5e extends BaseSheetL5r5e {
}); });
break; break;
case "honor":
await this.actor.update({
system: {
social: {
honor: Math.max(0, this.actor.system.social.honor + mod),
},
},
});
break;
case "glory":
await this.actor.update({
system: {
social: {
glory: Math.max(0, this.actor.system.social.glory + mod),
},
},
});
break;
case "status":
await this.actor.update({
system: {
social: {
status: Math.max(0, this.actor.system.social.status + mod),
},
},
});
break;
default: default:
console.warn("L5R5E | BCS | Unsupported type", type); console.warn("L5R5E | BCS | Unsupported type", type);
break; break;

View File

@@ -320,7 +320,7 @@ export class CharacterGenerator {
} }
// Img (only if system defaults) // Img (only if system defaults)
const folder = "systems/l5r5e/assets/icons/actors"; const folder = "systems/l5rx-chiaroscuro/assets/icons/actors";
const newImg = [ const newImg = [
`${folder}/npc.svg`, `${folder}/npc.svg`,
`${folder}/traditional-japanese-man.svg`, `${folder}/traditional-japanese-man.svg`,

View File

@@ -47,8 +47,12 @@ export class CharacterSheetL5r5e extends BaseCharacterSheetL5r5e {
// Min rank = 1 // Min rank = 1
this.actor.system.identity.school_rank = Math.max(1, this.actor.system.identity.school_rank); this.actor.system.identity.school_rank = Math.max(1, this.actor.system.identity.school_rank);
// Split Money // Money — read separate fields directly (koku/bu/zeni stored independently)
sheetData.data.system.money = this._zeniToMoney(this.actor.system.zeni); sheetData.data.system.money = {
koku: this.actor.system.koku ?? 0,
bu: this.actor.system.bu ?? 0,
zeni: this.actor.system.zeni ?? 0,
};
// Split school advancements by rank, and calculate xp spent and add it to total // Split school advancements by rank, and calculate xp spent and add it to total
this._prepareSchoolAdvancement(sheetData); this._prepareSchoolAdvancement(sheetData);
@@ -56,11 +60,63 @@ export class CharacterSheetL5r5e extends BaseCharacterSheetL5r5e {
// Split Others advancements, and calculate xp spent and add it to total // Split Others advancements, and calculate xp spent and add it to total
this._prepareOthersAdvancement(sheetData); this._prepareOthersAdvancement(sheetData);
// Update spent_xp to actor
this.actor.system.xp_spent = sheetData.data.system.xp_spent;
// Total // Total
sheetData.data.system.xp_saved = Math.floor( sheetData.data.system.xp_saved = Math.floor(
parseInt(sheetData.data.system.xp_total) - parseInt(sheetData.data.system.xp_spent) parseInt(sheetData.data.system.xp_total) - parseInt(sheetData.data.system.xp_spent)
); );
// Chiaroscuro: Skill ranks list for <select>
sheetData.data.skillRanksList = Object.keys(CONFIG.l5r5e.skillRanks).map((id) => ({
id,
label: game.i18n.localize(`chiaroscuro.skill_ranks.${id}`),
}));
// Chiaroscuro: Normalize skill values 0 (number) → "0" (string) for selectOptions matching
for (const category of Object.values(sheetData.data.system.skills)) {
for (const [key, value] of Object.entries(category)) {
if (value === 0) category[key] = "0";
}
}
// Chiaroscuro: Aspects gauge data
const aspectsData = sheetData.data.system.aspects?.aspects ?? {};
const gauge = aspectsData.gauge ?? 0;
sheetData.data.aspectsData = {
solar: aspectsData.solar ?? 0,
lunar: aspectsData.lunar ?? 0,
gauge,
gaugePercent: ((gauge + 10) / 20) * 100,
gaugeColor: gauge > 0 ? "#d4a855" : gauge < 0 ? "#5588aa" : "#888888",
};
// Chiaroscuro: État items active on the character
sheetData.data.etatItems = sheetData.items.filter((i) => i.type === "etat");
// Chiaroscuro: Invocations split by type (from splitTechniquesList)
const invocations = sheetData.data.splitTechniquesList["mot_invocation"] ?? [];
sheetData.data.splitInvocationsList = {
general: invocations.filter((t) => !t.system.invocation_type || t.system.invocation_type === "general"),
neutre: invocations.filter((t) => t.system.invocation_type === "neutre"),
precis: invocations.filter((t) => t.system.invocation_type === "precis"),
};
// Chiaroscuro: Arcane items
sheetData.data.arcaneItems = sheetData.items.filter((i) => i.type === "arcane");
// Chiaroscuro: Mystere items
sheetData.data.mystereItems = sheetData.items.filter((i) => i.type === "mystere");
// Chiaroscuro: Identity tabs enriched HTML
sheetData.data.enrichedHtml.identity_text1 = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
this.actor.system.identity_text1 ?? "", { async: true }
);
sheetData.data.enrichedHtml.identity_text2 = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
this.actor.system.identity_text2 ?? "", { async: true }
);
return sheetData; return sheetData;
} }
@@ -114,6 +170,17 @@ export class CharacterSheetL5r5e extends BaseCharacterSheetL5r5e {
// Money +/- // Money +/-
html.find(".money-control").on("click", this._modifyMoney.bind(this)); html.find(".money-control").on("click", this._modifyMoney.bind(this));
// XP +/-
html.find(".xp-control").on("click", this._modifyXP.bind(this));
// Chiaroscuro: set default ring on ring-name click
html.find(".ring-set-default").on("click", (event) => {
event.preventDefault();
const ring = $(event.currentTarget).data("ring");
this.actor.update({ "system.default_ring": ring });
});
// Advancements Tab to current rank onload // Advancements Tab to current rank onload
// TODO class "Active" Bug on load, dunno why :/ // TODO class "Active" Bug on load, dunno why :/
this._tabs this._tabs
@@ -121,6 +188,18 @@ export class CharacterSheetL5r5e extends BaseCharacterSheetL5r5e {
.activate("advancement_rank_" + (this.actor.system.identity.school_rank || 0)); .activate("advancement_rank_" + (this.actor.system.identity.school_rank || 0));
} }
/**
* Override base dice picker to open Chiaroscuro d6 dialog.
* @param {Event} event
*/
_openDicePickerForSkill(event) {
event.preventDefault();
const el = $(event.currentTarget);
const skillId = el.data("skill");
const ringId = el.data("ring") || this.actor.system?.default_ring || "void";
new game.l5r5e.ChiaroscuroDiceDialog({ actor: this.actor, ringId, skillId }).render(true);
}
/** /**
* Split the school advancement, calculate the total xp spent and the current total xp spent by rank * Split the school advancement, calculate the total xp spent and the current total xp spent by rank
*/ */
@@ -149,6 +228,12 @@ export class CharacterSheetL5r5e extends BaseCharacterSheetL5r5e {
adv[rank].spent.total += xp_used_total; adv[rank].spent.total += xp_used_total;
adv[rank].spent.curriculum += xp_used; adv[rank].spent.curriculum += xp_used;
}); });
// If we finished the rank but haven't added anything to the next rank we should show an empty tab
// note: adv is index from 1, not 0 because of rank starting at 1
if(adv.length -1 < sheetData.data.system.identity.school_rank) {
adv.push({list: [], rank: sheetData.data.system.identity.school_rank, spent: { total: 0, curriculum: 0}});
}
sheetData.data.advancementsListByRank = adv; sheetData.data.advancementsListByRank = adv;
} }
@@ -193,19 +278,29 @@ export class CharacterSheetL5r5e extends BaseCharacterSheetL5r5e {
); );
} }
// Store money in Zeni // Store money as separate fields with auto-conversion (10 zeni = 1 bu, 10 bu = 1 koku)
if (formData["system.money.koku"] || formData["system.money.bu"] || formData["system.money.zeni"]) { if (formData["system.money.koku"] !== undefined || formData["system.money.bu"] !== undefined || formData["system.money.zeni"] !== undefined) {
formData["system.zeni"] = this._moneyToZeni( let koku = parseInt(formData["system.money.koku"] ?? 0) || 0;
formData["system.money.koku"] || 0, let bu = parseInt(formData["system.money.bu"] ?? 0) || 0;
formData["system.money.bu"] || 0, let zeni = parseInt(formData["system.money.zeni"] ?? 0) || 0;
formData["system.money.zeni"] || 0 // Auto-convert
); if (zeni >= 10) { bu += Math.floor(zeni / 10); zeni = zeni % 10; }
// Remove fake money object if (bu >= 10) { koku += Math.floor(bu / 10); bu = bu % 10; }
formData["system.koku"] = koku;
formData["system.bu"] = bu;
formData["system.zeni"] = zeni;
delete formData["system.money.koku"]; delete formData["system.money.koku"];
delete formData["system.money.bu"]; delete formData["system.money.bu"];
delete formData["system.money.zeni"]; delete formData["system.money.zeni"];
} }
// Chiaroscuro: convert skill rank "0" (string from <select>) back to 0 (number)
for (const [key, value] of Object.entries(formData)) {
if (key.startsWith("system.skills.") && value === "0") {
formData[key] = 0;
}
}
// Save computed values // Save computed values
const currentData = this.object.system; const currentData = this.object.system;
formData["system.focus"] = currentData.focus; formData["system.focus"] = currentData.focus;
@@ -267,21 +362,55 @@ export class CharacterSheetL5r5e extends BaseCharacterSheetL5r5e {
const elmt = $(event.currentTarget); const elmt = $(event.currentTarget);
const type = elmt.data("type"); const type = elmt.data("type");
const mod = parseInt(elmt.data("value")) || 0;
if (!mod || !type) return;
let koku = parseInt(this.actor.system.koku) || 0;
let bu = parseInt(this.actor.system.bu) || 0;
let zeni = parseInt(this.actor.system.zeni) || 0;
if (type === "koku") koku += mod;
else if (type === "bu") bu += mod;
else zeni += mod;
// Auto-convert
if (zeni >= 10) { bu += Math.floor(zeni / 10); zeni = zeni % 10; }
if (bu >= 10) { koku += Math.floor(bu / 10); bu = bu % 10; }
// Clamp negatives
if (zeni < 0) { bu += Math.ceil(zeni / 10); zeni = ((zeni % 10) + 10) % 10; }
if (bu < 0) { koku += Math.ceil(bu / 10); bu = ((bu % 10) + 10) % 10; }
koku = Math.max(0, koku);
this.actor.update({ system: { koku, bu, zeni } });
this.render(false);
}
/**
* Add or Subtract XP (+/- buttons)
* @param {Event} event
* @private
*/
async _modifyXP(event) {
event.preventDefault();
event.stopPropagation();
const elmt = $(event.currentTarget);
let mod = elmt.data("value"); let mod = elmt.data("value");
if (!mod || !type) { if (!mod) {
return; return;
} }
if (type !== "zeni") { const new_xp_total = Math.max(0, this.actor.system.xp_total + mod);
mod = Math.floor(mod * CONFIG.l5r5e.money[type === "koku" ? 0 : 1]);
}
this.actor.system.zeni = +this.actor.system.zeni + mod;
this.actor.update({ this.actor.update({
system: { system: {
zeni: this.actor.system.zeni, xp_total: new_xp_total,
}, },
}); });
if(this.actor.system.xp_spent > new_xp_total) {
ui.notifications.warn("l5r5e.advancements.warning.total_less_then_spent", { localize: true })
}
this.render(false); this.render(false);
} }

View File

@@ -50,6 +50,21 @@ export class NpcSheetL5r5e extends BaseCharacterSheetL5r5e {
label: game.i18n.localize("l5r5e.character_types." + e), label: game.i18n.localize("l5r5e.character_types." + e),
})); }));
// Danger levels for martial/social danger selects
const dangerLevels = ["simple", "moyenne", "assez_difficile", "difficile"];
sheetData.data.dangerList = dangerLevels.map((id) => ({
id,
label: game.i18n.localize(`chiaroscuro.danger.${id}`),
}));
// Invocations list (mot_invocation techniques, split by type like character sheet)
const invocations = sheetData.data.splitTechniquesList?.["mot_invocation"] ?? [];
sheetData.data.splitInvocationsList = {
general: invocations.filter((t) => !t.system.invocation_type || t.system.invocation_type === "general"),
neutre: invocations.filter((t) => t.system.invocation_type === "neutre"),
precis: invocations.filter((t) => t.system.invocation_type === "precis"),
};
return sheetData; return sheetData;
} }
@@ -101,4 +116,16 @@ export class NpcSheetL5r5e extends BaseCharacterSheetL5r5e {
return super._updateObject(event, formData); return super._updateObject(event, formData);
} }
/**
* Override base dice picker to open Chiaroscuro d6 dialog.
* @param {Event} event
*/
_openDicePickerForSkill(event) {
event.preventDefault();
const el = $(event.currentTarget);
const skillId = el.data("skill");
const ringId = el.data("ring") || this.actor.system?.default_ring || "void";
new game.l5r5e.ChiaroscuroDiceDialog({ actor: this.actor, ringId, skillId }).render(true);
}
} }

View File

@@ -0,0 +1,11 @@
const { CompendiumDirectory } = foundry.applications.sidebar.tabs;
export class CompendiumDirectoryL5r5e extends CompendiumDirectory {
/** @inheritdoc */
async _prepareContext(options) {
const context = await super._prepareContext(options);
context.sidebarIcon = foundry.applications.sidebar.Sidebar.TABS.compendium.icon;
return context;
}
}

View File

@@ -0,0 +1,497 @@
import { L5r5eHtmlMultiSelectElement } from "../misc/l5r5e-multiselect.js";
const { Compendium } = foundry.applications.sidebar.apps;
/**
* Extended Compendium application for L5R5e.
* Adds source/rank/ring/rarity filters to Item compendiums
* @extends {Compendium}
*/
export class ItemCompendiumL5r5e extends Compendium {
/** @override */
static DEFAULT_OPTIONS = {
actions: {
applyPlayerView: ItemCompendiumL5r5e.#onApplyPlayerView,
},
window: {
resizable: true
}
};
/**
* Our own entry partial which mirrors Foundry's index-partial.hbs structure
* and appends ring/rarity/rank badges using data from _prepareDirectoryContext.
*
* NOTE: We intentionally duplicate Foundry's <li> structure here rather than
* trying to include their partial, because their partial renders a complete <li>
* element which cannot be nested or extended from outside. If Foundry ever
* changes their index-partial.hbs, this file will need updating to match.
* @override
*/
static _entryPartial = "systems/l5rx-chiaroscuro/templates/" + "compendium/l5r5e-index-partial.html";
/**
* Sources present in this specific compendium, populated during _prepareContext.
* @type {Set<string>}
*/
#sourcesInThisCompendium = new Set();
/**
* Sources unavailable to players based on permission settings.
* @type {Set<string>}
*/
#unavailableSourceForPlayersSet = new Set();
/**
* Whether to hide entries with empty sources from players.
* @type {boolean}
*/
#hideEmptySourcesFromPlayers = false;
/**
* Which filter UI controls are worth showing.
* Determined during _prepareContext by checking whether at least two
* distinct values exist for each filterable property.
* @type {{ rank: boolean, rarity: boolean, source: boolean, ring: boolean }|null}
*/
#filtersToShow = null;
/**
* Cached active filter values, read from the DOM once at the start of
* each filter pass in #reapplyFilters and held for _onMatchSearchEntry
* to consume per-entry without re-querying the DOM.
* @type {{ userFilter: string[], rankFilter: string[], ringFilter: string[], rarityFilter: string[] }}
*/
#activeFilters = {
userFilter: [],
rankFilter: [],
ringFilter: [],
rarityFilter: [],
};
/**
* Insert the filter part between header and directory by composing with
* the parent parts rather than replacing them, so future Foundry changes
* to Compendium.PARTS are picked up automatically.
* @override
*/
_configureRenderParts(options) {
const parts = super._configureRenderParts(options);
const ordered = {};
for (const [key, value] of Object.entries(parts)) {
ordered[key] = value;
if (key === "header") {
ordered.filter = {
template: `${CONFIG.l5r5e.paths.templates}compendium/filter-bar.html`,
};
}
}
return ordered;
}
/**
* @override
*/
async _prepareContext(options) {
const context = await super._prepareContext(options);
this.#sourcesInThisCompendium = new Set();
this.#resolvePermissions();
this.#filtersToShow = this.#computeFilterVisibility();
return context;
}
/* -------------------------------------------- */
/**
* @override
*/
async _preparePartContext(partId, context, options) {
context = await super._preparePartContext(partId, context, options);
if (partId === "filter") {
const ns = CONFIG.l5r5e.namespace;
const allCompendiumReferencesSet = game.settings.get(ns, "all-compendium-references");
const hideDisabledOptions = game.settings.get(ns, "compendium-hide-disabled-sources");
context.filtersToShow = this.#filtersToShow;
context.ranks = [1, 2, 3, 4, 5];
context.rarities = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
context.rings = ["fire", "water", "earth", "air", "void"];
context.hideDisabledOptions = hideDisabledOptions;
context.showPlayerView = game.user.isGM && this.#unavailableSourceForPlayersSet.size > 0;
// Source multiselect options — plain data for {{selectOptions}} in the template.
context.sources = [...allCompendiumReferencesSet].map((reference) => ({
value: reference,
label: CONFIG.l5r5e.sourceReference[reference]?.label ?? reference,
translate: true,
group:
CONFIG.l5r5e.sourceReference[reference]?.type.split(",")[0] ??
"l5r5e.multiselect.sources_categories.others",
disabled:
!this.#sourcesInThisCompendium.has(reference) ||
(!game.user.isGM && this.#unavailableSourceForPlayersSet.has(reference)),
}));
}
if (partId === "directory") {
context.entryFilterData = Object.fromEntries(
[...this.collection.index.values()].map((entry) => [
entry._id,
{
rank: entry.system?.rank,
ring: entry.system?.ring,
rarity: entry.system?.rarity,
},
])
);
}
return context;
}
/**
* @override
*/
async _onRender(context, options) {
await super._onRender(context, options);
if (options.parts.includes("filter")) {
this.#bindButtonFilter(".rank-filter");
this.#bindButtonFilter(".rarity-filter");
this.#bindButtonFilter(".ring-filter");
this.#bindSourceFilter();
}
// Reapply filters whenever the filter controls or the entry list changes.
if (options.parts.some((p) => p === "filter" || p === "directory")) {
this.#reapplyFilters();
}
}
/* -------------------------------------------- */
/**
* @override
*/
_preSyncPartState(partId, newElement, priorElement, state) {
super._preSyncPartState(partId, newElement, priorElement, state);
if (partId === "filter") {
state.selectedRanks = [...priorElement.querySelectorAll(".rank-filter .selected")].map((element) => element.dataset.rank);
state.selectedRarities = [...priorElement.querySelectorAll(".rarity-filter .selected")].map((element) => element.dataset.rarity);
state.selectedRings = [...priorElement.querySelectorAll(".ring-filter .selected")].map((element) => element.dataset.ring);
state.sourceValue = priorElement.querySelector("l5r5e-multi-select")?.value;
}
}
/**
* Restore filter selections after the filter part has been re-rendered.
* The [data-clear] button visibility is derived from whether any values
* were restored — no extra state needed.
* @override
*/
_syncPartState(partId, newElement, priorElement, state) {
super._syncPartState(partId, newElement, priorElement, state);
if (partId === "filter") {
for (const rank of state.selectedRanks ?? []) {
newElement.querySelector(`.rank-filter [data-rank="${rank}"]`)?.classList.add("selected");
}
const rankClear = newElement.querySelector(".rank-filter [data-clear]");
if (rankClear) {
rankClear.style.display = state.selectedRanks?.length ? "" : "none";
}
for (const rarity of state.selectedRarities ?? []) {
newElement.querySelector(`.rarity-filter [data-rarity="${rarity}"]`)?.classList.add("selected");
}
const rarityClear = newElement.querySelector(".rarity-filter [data-clear]");
if (rarityClear) {
rarityClear.style.display = state.selectedRarities?.length ? "" : "none";
}
for (const ring of state.selectedRings ?? []) {
newElement.querySelector(`.ring-filter [data-ring="${ring}"]`)?.classList.add("selected");
}
const ringClear = newElement.querySelector(".ring-filter [data-clear]");
if (ringClear) {
ringClear.style.display = state.selectedRings?.length ? "" : "none";
}
if (state.sourceValue) {
const multiSelect = newElement.querySelector("l5r5e-multi-select");
if (multiSelect) {
multiSelect.value = state.sourceValue;
}
}
}
}
/**
* @override
*/
_onMatchSearchEntry(query, entryIds, entry, options) {
super._onMatchSearchEntry(query, entryIds, entry, options);
if (entry.style.display === "none") {
return;
}
this.#applyEntryFilter(entry);
}
/**
* Snapshot active filter state then re-run the search filter (or walk entries directly as fallback).
* @private
*/
#reapplyFilters() {
this.#refreshActiveFilters();
const searchFilter = this._searchFilters?.[0];
if (searchFilter) {
searchFilter.filter(null, searchFilter.query);
return;
}
// Fallback
for (const entry of this.element.querySelectorAll(".directory-item")) {
this.#applyEntryFilter(entry);
}
}
/**
* Read current filter selections from the DOM and cache them in #activeFilters.
* @private
*/
#refreshActiveFilters() {
const filterElement = this.element.querySelector("[data-application-part=\"filter\"]");
const multiSelect = filterElement?.querySelector("l5r5e-multi-select");
const collectSelected = (containerSelector, dataKey) =>
[...(filterElement?.querySelectorAll(`${containerSelector} .selected`) ?? [])]
.map((element) => element.dataset[dataKey])
.filter(Boolean);
this.#activeFilters = {
userFilter: multiSelect?.value ?? [],
rankFilter: collectSelected(".rank-filter", "rank"),
ringFilter: collectSelected(".ring-filter", "ring"),
rarityFilter: collectSelected(".rarity-filter", "rarity"),
};
}
/**
* Apply all active filters to a single directory entry, showing or hiding it accordingly.
* @param {HTMLElement} entry
* @private
*/
#applyEntryFilter(entry) {
const indexEntry = this.collection.index.get(entry.dataset.entryId);
if (!indexEntry) {
return;
}
const system = indexEntry.system;
const lineSource = system?.source_reference?.source ?? null;
const { userFilter, rankFilter, ringFilter, rarityFilter } = this.#activeFilters;
let shouldShow = true;
const sourceUnavailable =
(lineSource && this.#unavailableSourceForPlayersSet.has(lineSource)) ||
(lineSource === "" && this.#hideEmptySourcesFromPlayers);
if (sourceUnavailable) {
if (game.user.isGM) {
entry.classList.add("not-for-players");
entry.dataset.tooltip = game.i18n.localize("l5r5e.compendium.not_for_players");
} else {
shouldShow = false;
}
}
if (rankFilter.length) {
shouldShow &&= rankFilter.includes(String(system?.rank));
}
if (rarityFilter.length) {
shouldShow &&= rarityFilter.includes(String(system?.rarity));
}
if (ringFilter.length) {
shouldShow &&= ringFilter.includes(system?.ring);
}
if (userFilter.length) {
shouldShow &&= userFilter.includes(lineSource);
}
entry.style.display = shouldShow ? "" : "none";
}
/**
* Iterate the compendium index to:
* 1. Populate #sourcesInThisCompendium for source filter options
* 2. Determine which filter controls have enough distinct values to show
* @returns {{ rank: boolean, rarity: boolean, source: boolean, ring: boolean }}
* @private
*/
#computeFilterVisibility() {
const filtersToShow = { rank: false, rarity: false, source: true, ring: false };
const firstSeen = { rank: null, rarity: null, ring: null };
const markIfDistinct = (prop, value) => {
if (filtersToShow[prop] || value === undefined || value === null) {
return;
}
if (firstSeen[prop] === null) {
firstSeen[prop] = value;
} else if (firstSeen[prop] !== value) {
filtersToShow[prop] = true;
}
};
for (const entry of this.collection.index.values()) {
const sys = entry.system;
if (!sys) {
continue;
}
if (sys.rank !== undefined) {
markIfDistinct("rank", sys.rank);
}
if (sys.ring !== undefined) {
markIfDistinct("ring", sys.ring);
}
if (sys.rarity !== undefined) {
markIfDistinct("rarity", sys.rarity);
}
if (sys.source_reference?.source !== undefined) {
this.#sourcesInThisCompendium.add(sys.source_reference.source);
}
}
return filtersToShow;
}
/**
* Resolve which sources are restricted from players and cache the result
* in instance-level sets for use by #applyEntryFilter.
* @private
*/
#resolvePermissions() {
const ns = CONFIG.l5r5e.namespace;
const officialSet = game.settings.get(ns, "compendium-official-content-for-players");
const unofficialSet = game.settings.get(ns, "compendium-unofficial-content-for-players");
const allRefsSet = game.settings.get(ns, "all-compendium-references");
this.#hideEmptySourcesFromPlayers = game.settings.get(ns, "compendium-hide-empty-sources-from-players");
this.#unavailableSourceForPlayersSet = new Set(
[...allRefsSet].filter((ref) => {
if (CONFIG.l5r5e.sourceReference[ref]) {
return officialSet.size > 0 ? !officialSet.has(ref) : false;
}
return unofficialSet.size > 0 ? !unofficialSet.has(ref) : false;
})
);
}
/**
* Bind toggle-selection click handlers to all children of a button filter container.
* A [data-clear] element at the end of the container acts as an inline reset:
* - It is hidden (display:none in the template) when no values are selected.
* - It becomes visible as soon as any value is selected.
* - Clicking it deselects all values and hides itself again.
* @param {string} containerSelector
* @private
*/
#bindButtonFilter(containerSelector) {
const container = this.element.querySelector(containerSelector);
if (!container) {
return;
}
const clearButton = container.querySelector("[data-clear]");
const updateClearButton = () => {
if (!clearButton) {
return;
}
const anySelected = [...container.children].some(
(element) => element.dataset.clear === undefined && element.classList.contains("selected")
);
clearButton.style.display = anySelected ? "" : "none";
};
for (const child of container.children) {
child.addEventListener("click", (event) => {
const target = event.currentTarget;
if (target.dataset.clear !== undefined) {
// Clicked the clear button — deselect all value elements
for (const element of container.children) {
element.classList.remove("selected");
}
} else {
// Clicked a value element — toggle it
target.classList.toggle("selected");
}
updateClearButton();
this.#reapplyFilters();
});
}
}
/**
* Wire up the change listener on the already-rendered multiselect element.
* The element and its options are fully declared in filter-bar.html via
* {{selectOptions}} — no imperative construction needed here.
* @private
*/
#bindSourceFilter() {
const multiSelect = this.element.querySelector("l5r5e-multi-select[name=\"filter-sources\"]");
if (!multiSelect) {
return;
}
multiSelect.addEventListener("change", () => this.#reapplyFilters());
}
/**
* Handle the GM player-view button, selecting only the sources that are
* both visible to players and present in this specific compendium.
* @this {ItemCompendiumL5r5e}
* @private
*/
static #onApplyPlayerView() {
const ns = CONFIG.l5r5e.namespace;
const allRefsSet = game.settings.get(ns, "all-compendium-references");
const availableForPlayers = [...allRefsSet]
.filter((ref) => !this.#unavailableSourceForPlayersSet.has(ref))
.filter((ref) => this.#sourcesInThisCompendium.has(ref));
const multiSelect = this.element.querySelector("l5r5e-multi-select[name=\"filter-sources\"]");
if (!multiSelect) {
return;
}
multiSelect.value = availableForPlayers;
this.#reapplyFilters();
}
/**
* Register this compendium class and extend the index fields for all Item packs.
*/
static applyToPacks() {
CONFIG.Item.compendiumIndexFields = [
...(CONFIG.Item.compendiumIndexFields ?? []),
"system.rank",
"system.ring",
"system.rarity",
"system.source_reference.source",
];
for (const pack of game.packs.filter((p) => p.metadata.type === "Item")) {
pack.applicationClass = ItemCompendiumL5r5e;
pack.getIndex(); // rebuild index with new fields — no need to await since this happens before anyone have a chance to act
}
}
}

View File

@@ -1,8 +1,8 @@
export const L5R5E = { export const L5R5E = {
namespace: "l5r5e", namespace: "l5r5e",
paths: { paths: {
assets: "systems/l5r5e/assets/", assets: "systems/l5rx-chiaroscuro/assets/",
templates: "systems/l5r5e/templates/", templates: "systems/l5rx-chiaroscuro/templates/",
}, },
money: [50, 10], money: [50, 10],
stances: ["earth", "air", "water", "fire", "void"], stances: ["earth", "air", "water", "fire", "void"],
@@ -14,172 +14,226 @@ export const L5R5E = {
skillCostMultiplier: 2, skillCostMultiplier: 2,
techniqueCost: 3, techniqueCost: 3,
}, },
// --- Chiaroscuro additions ---
/** Skill rank enum values and associated flat bonus */
skillRanks: {
0: { bonus: 0 },
initie: { bonus: 1 },
expert: { bonus: 2 },
maitre: { bonus: 3 },
parangon1: { bonus: 3, passive: 1 }, // dice results of 1 count as 2
parangon2: { bonus: 3, passive: 2 }, // dice results of 1-2 count as 3
parangon3: { bonus: 3, passive: 3 }, // dice results of 1-3 count as 4
},
/** Difficulty thresholds (Chiaroscuro scale) */
difficulties: {
simple: 7,
moyenne: 10,
assez_difficile: 13,
difficile: 16,
tres_difficile: 22,
heroique: 28,
improbable: 32,
},
/** Ring colors for Chiaroscuro visual style */
ringColors: {
air: "rgb(145, 120, 150)",
water: "rgb(95, 145, 155)",
fire: "rgb(155, 115, 80)",
earth: "rgb(105, 150, 120)",
void: "rgb(75, 70, 65)",
},
/** Aspect gauge configuration */
aspects: {
solarConditionId: "desequilibre_lunaire",
lunarConditionId: "desequilibre_solaire",
imbalanceThreshold: 5,
resetThreshold: 10,
},
// --- End Chiaroscuro additions ---
// For rings wound to be aligned, add them first // For rings wound to be aligned, add them first
conditions: [{ conditions: [{
id: "lightly_wounded_fire", id: "lightly_wounded_fire",
name: "l5r5e.conditions.lightly_wounded_fire", name: "l5r5e.conditions.lightly_wounded_fire",
img: "systems/l5r5e/assets/icons/conditions/lightly_wounded_fire.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/lightly_wounded_fire.webp",
system: { id: "L5RCoreCon000016" } system: { id: "L5RCoreCon000016" }
},{ },{
id: "lightly_wounded_water", id: "lightly_wounded_water",
name: "l5r5e.conditions.lightly_wounded_water", name: "l5r5e.conditions.lightly_wounded_water",
img: "systems/l5r5e/assets/icons/conditions/lightly_wounded_water.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/lightly_wounded_water.webp",
system: { id: "L5RCoreCon000016" } system: { id: "L5RCoreCon000016" }
},{ },{
id: "lightly_wounded_air", id: "lightly_wounded_air",
name: "l5r5e.conditions.lightly_wounded_air", name: "l5r5e.conditions.lightly_wounded_air",
img: "systems/l5r5e/assets/icons/conditions/lightly_wounded_air.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/lightly_wounded_air.webp",
system: { id: "L5RCoreCon000016" } system: { id: "L5RCoreCon000016" }
},{ },{
id: "lightly_wounded_earth", id: "lightly_wounded_earth",
name: "l5r5e.conditions.lightly_wounded_earth", name: "l5r5e.conditions.lightly_wounded_earth",
img: "systems/l5r5e/assets/icons/conditions/lightly_wounded_earth.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/lightly_wounded_earth.webp",
system: { id: "L5RCoreCon000016" } system: { id: "L5RCoreCon000016" }
},{ },{
id: "lightly_wounded_void", id: "lightly_wounded_void",
name: "l5r5e.conditions.lightly_wounded_void", name: "l5r5e.conditions.lightly_wounded_void",
img: "systems/l5r5e/assets/icons/conditions/lightly_wounded_void.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/lightly_wounded_void.webp",
system: { id: "L5RCoreCon000016" } system: { id: "L5RCoreCon000016" }
},{ },{
id: "severely_wounded_fire", id: "severely_wounded_fire",
name: "l5r5e.conditions.severely_wounded_fire", name: "l5r5e.conditions.severely_wounded_fire",
img: "systems/l5r5e/assets/icons/conditions/heavily_wounded_fire.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/heavily_wounded_fire.webp",
system: { id: "L5RCoreCon000016" } system: { id: "L5RCoreCon000016" }
},{ },{
id: "severely_wounded_water", id: "severely_wounded_water",
name: "l5r5e.conditions.severely_wounded_water", name: "l5r5e.conditions.severely_wounded_water",
img: "systems/l5r5e/assets/icons/conditions/heavily_wounded_water.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/heavily_wounded_water.webp",
system: { id: "L5RCoreCon000016" } system: { id: "L5RCoreCon000016" }
},{ },{
id: "severely_wounded_air", id: "severely_wounded_air",
name: "l5r5e.conditions.severely_wounded_air", name: "l5r5e.conditions.severely_wounded_air",
img: "systems/l5r5e/assets/icons/conditions/heavily_wounded_air.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/heavily_wounded_air.webp",
system: { id: "L5RCoreCon000016" } system: { id: "L5RCoreCon000016" }
},{ },{
id: "severely_wounded_earth", id: "severely_wounded_earth",
name: "l5r5e.conditions.severely_wounded_earth", name: "l5r5e.conditions.severely_wounded_earth",
img: "systems/l5r5e/assets/icons/conditions/heavily_wounded_earth.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/heavily_wounded_earth.webp",
system: { id: "L5RCoreCon000016" } system: { id: "L5RCoreCon000016" }
},{ },{
id: "severely_wounded_void", id: "severely_wounded_void",
name: "l5r5e.conditions.severely_wounded_void", name: "l5r5e.conditions.severely_wounded_void",
img: "systems/l5r5e/assets/icons/conditions/heavily_wounded_void.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/heavily_wounded_void.webp",
system: { id: "L5RCoreCon000016" } system: { id: "L5RCoreCon000016" }
},{ },{
id: "afflicted", id: "afflicted",
name: "l5r5e.conditions.afflicted", name: "l5r5e.conditions.afflicted",
img: "systems/l5r5e/assets/icons/conditions/afflicted.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/afflicted.webp",
system: { id: "L5RCoreCon000001" } system: { id: "L5RCoreCon000001" }
},{ },{
id: "bleeding", id: "bleeding",
name: "l5r5e.conditions.bleeding", name: "l5r5e.conditions.bleeding",
img: "systems/l5r5e/assets/icons/conditions/bleeding.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/bleeding.webp",
system: { id: "L5RCoreCon000002" } system: { id: "L5RCoreCon000002" }
},{ },{
id: "burning", id: "burning",
name: "l5r5e.conditions.burning", name: "l5r5e.conditions.burning",
img: "systems/l5r5e/assets/icons/conditions/burning.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/burning.webp",
system: { id: "L5RCoreCon000003" } system: { id: "L5RCoreCon000003" }
},{ },{
id: "centered", id: "centered",
name: "l5r5e.conditions.centered", name: "l5r5e.conditions.centered",
img: "systems/l5r5e/assets/icons/conditions/centered.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/centered.webp",
system: { id: "L5RCoreCon000022" } system: { id: "L5RCoreCon000022" }
},{ },{
id: "compromised", id: "compromised",
name: "l5r5e.conditions.compromised", name: "l5r5e.conditions.compromised",
img: "systems/l5r5e/assets/icons/conditions/compromised.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/compromised.webp",
system: { id: "L5RCoreCon000004" } system: { id: "L5RCoreCon000004" }
},{ },{
id: "dazed", id: "dazed",
name: "l5r5e.conditions.dazed", name: "l5r5e.conditions.dazed",
img: "systems/l5r5e/assets/icons/conditions/dazed.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/dazed.webp",
system: { id: "L5RCoreCon000005" } system: { id: "L5RCoreCon000005" }
},{ },{
id: "disoriented", id: "disoriented",
name: "l5r5e.conditions.disoriented", name: "l5r5e.conditions.disoriented",
img: "systems/l5r5e/assets/icons/conditions/disoriented.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/disoriented.webp",
system: { id: "L5RCoreCon000006" } system: { id: "L5RCoreCon000006" }
},{ },{
id: "dying", id: "dying",
name: "l5r5e.conditions.dying", name: "l5r5e.conditions.dying",
img: "systems/l5r5e/assets/icons/conditions/dying_1.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/dying_1.webp",
system: { id: "L5RCoreCon000007" } system: { id: "L5RCoreCon000007" }
},{ },{
id: "emboldened", id: "emboldened",
name: "l5r5e.conditions.emboldened", name: "l5r5e.conditions.emboldened",
img: "systems/l5r5e/assets/icons/conditions/emboldened.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/emboldened.webp",
system: { id: "L5RCoreCon000023" } system: { id: "L5RCoreCon000023" }
},{ },{
id: "enraged", id: "enraged",
name: "l5r5e.conditions.enraged", name: "l5r5e.conditions.enraged",
img: "systems/l5r5e/assets/icons/conditions/enraged.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/enraged.webp",
system: { id: "L5RCoreCon000008" } system: { id: "L5RCoreCon000008" }
},{ },{
id: "exhausted", id: "exhausted",
name: "l5r5e.conditions.exhausted", name: "l5r5e.conditions.exhausted",
img: "systems/l5r5e/assets/icons/conditions/exhausted.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/exhausted.webp",
system: { id: "L5RCoreCon000009" } system: { id: "L5RCoreCon000009" }
},{ },{
id: "illness_coughing_illness", id: "illness_coughing_illness",
name: "l5r5e.conditions.illness_coughing_illness", name: "l5r5e.conditions.illness_coughing_illness",
img: "systems/l5r5e/assets/icons/conditions/illness_coughing_illness.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/illness_coughing_illness.webp",
system: { id: "L5RCoreCon000019" } system: { id: "L5RCoreCon000019" }
},{ },{
id: "illness_fire_rash", id: "illness_fire_rash",
name: "l5r5e.conditions.illness_fire_rash", name: "l5r5e.conditions.illness_fire_rash",
img: "systems/l5r5e/assets/icons/conditions/illness_fire_rash.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/illness_fire_rash.webp",
system: { id: "L5RCoreCon000021" } system: { id: "L5RCoreCon000021" }
},{ },{
id: "illness_gut_sickness", id: "illness_gut_sickness",
name: "l5r5e.conditions.illness_gut_sickness", name: "l5r5e.conditions.illness_gut_sickness",
img: "systems/l5r5e/assets/icons/conditions/illness_gut_sickness.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/illness_gut_sickness.webp",
system: { id: "L5RCoreCon000018" } system: { id: "L5RCoreCon000018" }
},{ },{
id: "illness_oozing_sore_disease", id: "illness_oozing_sore_disease",
name: "l5r5e.conditions.illness_oozing_sore_disease", name: "l5r5e.conditions.illness_oozing_sore_disease",
img: "systems/l5r5e/assets/icons/conditions/illness_oozing_sore_disease.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/illness_oozing_sore_disease.webp",
system: { id: "L5RCoreCon000017" } system: { id: "L5RCoreCon000017" }
},{ },{
id: "illness_unsteady_illness", id: "illness_unsteady_illness",
name: "l5r5e.conditions.illness_unsteady_illness", name: "l5r5e.conditions.illness_unsteady_illness",
img: "systems/l5r5e/assets/icons/conditions/illness_unsteady_illness.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/illness_unsteady_illness.webp",
system: { id: "L5RCoreCon000020" } system: { id: "L5RCoreCon000020" }
},{ },{
id: "immobilized", id: "immobilized",
name: "l5r5e.conditions.immobilized", name: "l5r5e.conditions.immobilized",
img: "systems/l5r5e/assets/icons/conditions/immobilized.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/immobilized.webp",
system: { id: "L5RCoreCon000010" } system: { id: "L5RCoreCon000010" }
},{ },{
id: "incapacitated", id: "incapacitated",
name: "l5r5e.conditions.incapacitated", name: "l5r5e.conditions.incapacitated",
img: "systems/l5r5e/assets/icons/conditions/incapacitated.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/incapacitated.webp",
system: { id: "L5RCoreCon000011" } system: { id: "L5RCoreCon000011" }
},{ },{
id: "intoxicated", id: "intoxicated",
name: "l5r5e.conditions.intoxicated", name: "l5r5e.conditions.intoxicated",
img: "systems/l5r5e/assets/icons/conditions/intoxicated.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/intoxicated.webp",
system: { id: "L5RCoreCon000012" } system: { id: "L5RCoreCon000012" }
},{ },{
id: "possessed", id: "possessed",
name: "l5r5e.conditions.possessed", name: "l5r5e.conditions.possessed",
img: "systems/l5r5e/assets/icons/conditions/possesed.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/possesed.webp",
system: { id: "L5RCoreCon000024" } system: { id: "L5RCoreCon000024" }
},{ },{
id: "prone", id: "prone",
name: "l5r5e.conditions.prone", name: "l5r5e.conditions.prone",
img: "systems/l5r5e/assets/icons/conditions/prone.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/prone.webp",
system: { id: "L5RCoreCon000013" } system: { id: "L5RCoreCon000013" }
},{ },{
id: "silenced", id: "silenced",
name: "l5r5e.conditions.silenced", name: "l5r5e.conditions.silenced",
img: "systems/l5r5e/assets/icons/conditions/silenced.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/silenced.webp",
system: { id: "L5RCoreCon000014" } system: { id: "L5RCoreCon000014" }
},{ },{
id: "unconscious", id: "unconscious",
name: "l5r5e.conditions.unconscious", name: "l5r5e.conditions.unconscious",
img: "systems/l5r5e/assets/icons/conditions/unconscious.webp", img: "systems/l5rx-chiaroscuro/assets/icons/conditions/unconscious.webp",
system: { id: "L5RCoreCon000015" } system: { id: "L5RCoreCon000015" }
},{
id: "desequilibre_solaire",
name: "chiaroscuro.aspects.desequilibre_solaire",
img: "systems/l5rx-chiaroscuro/assets/icons/conditions/desequilibre_solaire.webp",
system: { id: "ChiaCon000001" }
},{
id: "desequilibre_lunaire",
name: "chiaroscuro.aspects.desequilibre_lunaire",
img: "systems/l5rx-chiaroscuro/assets/icons/conditions/desequilibre_lunaire.webp",
system: { id: "ChiaCon000002" }
}], }],
regex: { regex: {
techniqueDifficulty: /^@([TS]):([^|]+?)(?:\|(min|max)(?:\(([^)]+?)\))?)?$/, techniqueDifficulty: /^@([TS]):([^|]+?)(?:\|(min|max)(?:\(([^)]+?)\))?)?$/,
@@ -190,7 +244,7 @@ export const L5R5E = {
skirmish: "tactics", skirmish: "tactics",
mass_battle: "command", mass_battle: "command",
}, },
noHonorSkillsList: ["commerce", "skulduggery", "medicine", "seafaring", "survival", "labor"], noHonorSkillsList: ["commerce", "urban", "medicine", "seafaring", "survival", "labor"],
sourceReference: { sourceReference: {
"core_rulebook": { "core_rulebook": {
value: "core_rulebook", value: "core_rulebook",
@@ -344,37 +398,40 @@ L5R5E.techniques.set("mastery_ability", { type: "school", displayInTypes: false
L5R5E.techniques.set("title_ability", { type: "title", displayInTypes: false }); L5R5E.techniques.set("title_ability", { type: "title", displayInTypes: false });
// Custom // Custom
L5R5E.techniques.set("specificity", { type: "custom", displayInTypes: false }); L5R5E.techniques.set("specificity", { type: "custom", displayInTypes: false });
// Chiaroscuro
L5R5E.techniques.set("mot_invocation", { type: "chiaroscuro", displayInTypes: true });
// *** SkillId - CategoryId *** // *** SkillId - CategoryId ***
L5R5E.skills = new Map(); L5R5E.skills = new Map();
L5R5E.skills.set("aesthetics", "artisan"); L5R5E.skills.set("art", "artisan");
L5R5E.skills.set("composition", "artisan"); L5R5E.skills.set("composition", "artisan");
L5R5E.skills.set("design", "artisan"); L5R5E.skills.set("design", "artisan");
L5R5E.skills.set("smithing", "artisan"); L5R5E.skills.set("smithing", "artisan");
L5R5E.skills.set("labor", "artisan");
L5R5E.skills.set("archery", "martial");
L5R5E.skills.set("fitness", "martial"); L5R5E.skills.set("fitness", "martial");
L5R5E.skills.set("melee", "martial"); L5R5E.skills.set("melee", "martial");
L5R5E.skills.set("ranged", "martial");
L5R5E.skills.set("unarmed", "martial"); L5R5E.skills.set("unarmed", "martial");
L5R5E.skills.set("meditation", "martial"); L5R5E.skills.set("meditation", "martial");
L5R5E.skills.set("tactics", "martial");
L5R5E.skills.set("culture", "scholar"); L5R5E.skills.set("culture", "scholar");
L5R5E.skills.set("government", "scholar");
L5R5E.skills.set("medicine", "scholar"); L5R5E.skills.set("medicine", "scholar");
L5R5E.skills.set("sentiment", "scholar"); L5R5E.skills.set("sentiment", "scholar");
L5R5E.skills.set("tactics", "scholar");
L5R5E.skills.set("theology", "scholar"); L5R5E.skills.set("theology", "scholar");
L5R5E.skills.set("command", "social"); L5R5E.skills.set("command", "social");
L5R5E.skills.set("courtesy", "social"); L5R5E.skills.set("courtesy", "social");
L5R5E.skills.set("invocation", "social");
L5R5E.skills.set("games", "social"); L5R5E.skills.set("games", "social");
L5R5E.skills.set("performance", "social"); L5R5E.skills.set("performance", "social");
L5R5E.skills.set("animal", "trade");
L5R5E.skills.set("commerce", "trade"); L5R5E.skills.set("commerce", "trade");
L5R5E.skills.set("labor", "trade");
L5R5E.skills.set("seafaring", "trade"); L5R5E.skills.set("seafaring", "trade");
L5R5E.skills.set("skulduggery", "trade");
L5R5E.skills.set("survival", "trade"); L5R5E.skills.set("survival", "trade");
L5R5E.skills.set("urban", "trade");
// *** Symbols *** // *** Symbols ***
L5R5E.symbols = new Map(); L5R5E.symbols = new Map();
@@ -456,6 +513,7 @@ L5R5E.demeanors = [
{ id: "adaptable", mod: { water: 2, earth: -2 } }, { id: "adaptable", mod: { water: 2, earth: -2 } },
{ id: "aggressive", mod: { fire: 2, air: -2 } }, { id: "aggressive", mod: { fire: 2, air: -2 } },
{ id: "aggressive", mod: { fire: 2, water: -2 } }, { id: "aggressive", mod: { fire: 2, water: -2 } },
{ id: "alluring", mod: { air: 2, earth: -1, fire: -1 } },
{ id: "ambitious", mod: { fire: 2, water: -2 } }, { id: "ambitious", mod: { fire: 2, water: -2 } },
{ id: "amiable", mod: { air: 2, earth: -2 } }, { id: "amiable", mod: { air: 2, earth: -2 } },
{ id: "analytical", mod: { fire: 2, air: -2 } }, { id: "analytical", mod: { fire: 2, air: -2 } },
@@ -466,23 +524,38 @@ L5R5E.demeanors = [
{ id: "beguiling", mod: { air: 2, earth: -2 } }, { id: "beguiling", mod: { air: 2, earth: -2 } },
{ id: "beguiling", mod: { fire: 2, earth: -2 } }, { id: "beguiling", mod: { fire: 2, earth: -2 } },
{ id: "bitter", mod: { fire: 2, air: -2 } }, { id: "bitter", mod: { fire: 2, air: -2 } },
{ id: "bloodthirsty", mod: { fire: 2, water: -2 } },
{ id: "bold", mod: { fire: 1, earth: -1 } }, { id: "bold", mod: { fire: 1, earth: -1 } },
{ id: "calculating", mod: { air: 2, fire: -2 } }, { id: "calculating", mod: { air: 2, fire: -2 } },
{ id: "calm", mod: { fire: 2, air: -2 } }, { id: "calm", mod: { fire: 2, air: -2 } },
{ id: "capricious", mod: { air: 2, earth: -2 } }, { id: "capricious", mod: { air: 2, earth: -2 } },
{ id: "cautious", mod: { air: 2, earth: -2 } }, { id: "cautious", mod: { air: 2, earth: -2 } },
{ id: "cautious", mod: { water: 1, void: -1 } },
{ id: "clever", mod: { air: 2, earth: -2 } }, { id: "clever", mod: { air: 2, earth: -2 } },
{ id: "compassionate", mod: { fire: 2, air: -1, water: -1}}, { id: "compassionate", mod: { fire: 2, air: -1, water: -1}},
{ id: "compassionate", mod: { water: 2, fire: -2 } },
{ id: "compassionate", mod: { water: 2, void: -2 } },
{ id: "confused", mod: { fire: 1, void: 1, air: -2 } }, { id: "confused", mod: { fire: 1, void: 1, air: -2 } },
{ id: "courageous", mod: { air: 2, earth: -2 } }, { id: "courageous", mod: { air: 2, earth: -2 } },
{ id: "cowardly", mod: { earth: 2, fire: -2 } }, { id: "cowardly", mod: { earth: 2, fire: -2 } },
{ id: "crestfallen", mod: { void: 2, fire: -2 } },
{ id: "curious", mod: { earth: 1, void: -2 } }, { id: "curious", mod: { earth: 1, void: -2 } },
{ id: "curious", mod: { fire: 1, void: 1, air: -2 } }, { id: "curious", mod: { fire: 1, void: 1, air: -2 } },
{ id: "defensive", mod: { fire: 2, air: -2 } },
{ id: "dependable", mod: { fire: 1, water: 1, earth: -2 } }, { id: "dependable", mod: { fire: 1, water: 1, earth: -2 } },
{ id: "detached", mod: { earth: 1, fire: 1, void: -2 } }, { id: "detached", mod: { earth: 1, fire: 1, void: -2 } },
{ id: "determined", mod: { earth: 2, air: -2 } },
{ id: "devoted", mod: { fire: 2, earth: -2 } },
{ id: "direct", mod: { air: 2, fire: -1, water: -1 } },
{ id: "disheartened", mod: { fire: 1, earth: -1 } }, { id: "disheartened", mod: { fire: 1, earth: -1 } },
{ id: "dour", mod: { earth: 1, water: 1, air: -1 } },
{ id: "duplicitous", mod: { water: 2, fire: -2 } },
{ id: "effusive", mod: { air: 2, earth: -2 } },
{ id: "enraged", mod: { air: 1, fire: -2 } }, { id: "enraged", mod: { air: 1, fire: -2 } },
{ id: "fanatical", mod: { earth: 1, air: 1, fire: -2 } },
{ id: "feral", mod: { air: 2, fire: -2 } }, { id: "feral", mod: { air: 2, fire: -2 } },
{ id: "fervent", mod: { fire: 2, earth: -2 } },
{ id: "fervent", mod: { air: 1, water: 1, fire: -1, void: -1 } },
{ id: "fickle", mod: { fire: 2, air: -2 } }, { id: "fickle", mod: { fire: 2, air: -2 } },
{ id: "fierce", mod: { fire: 2, earth: -2 } }, { id: "fierce", mod: { fire: 2, earth: -2 } },
{ id: "flighty", mod: { air: 2, fire: -2 } }, { id: "flighty", mod: { air: 2, fire: -2 } },
@@ -490,32 +563,55 @@ L5R5E.demeanors = [
{ id: "flippant", mod: { fire: 2, air: -2 } }, { id: "flippant", mod: { fire: 2, air: -2 } },
{ id: "friendly", mod: { fire: 1, earth: -2, water: -2 } }, { id: "friendly", mod: { fire: 1, earth: -2, water: -2 } },
{ id: "gruff", mod: { water: 2, earth: -2 } }, { id: "gruff", mod: { water: 2, earth: -2 } },
{ id: "honorable", mod: { fire: 2, earth: -2 } },
{ id: "hubristic", mod: { earth: 2, air: -2 } },
{ id: "hungry", mod: { fire: 2, air: -2 } }, { id: "hungry", mod: { fire: 2, air: -2 } },
{ id: "idealistic", mod: { water: 2, earth: -2 } },
{ id: "idealistic", mod: { earth: 1, water: -1 } },
{ id: "imposing", mod: { fire: 2, water: -2 } },
{ id: "inquisitive", mod: { earth: 2, water: -2 } },
{ id: "intense", mod: { air: 2, water: -2 } }, { id: "intense", mod: { air: 2, water: -2 } },
{ id: "intense", mod: { fire: 2, water: -2 } }, { id: "intense", mod: { fire: 2, water: -2 } },
{ id: "intimidating", mod: { fire: 2, air: -2 } }, { id: "intimidating", mod: { fire: 2, air: -2 } },
{ id: "irritable", mod: { fire: 2, air: -1, water: -1 } }, { id: "irritable", mod: { fire: 2, air: -1, water: -1 } },
{ id: "loyal", mod: { air: 1, earth: -2, fire: -2 } }, { id: "loyal", mod: { air: 1, earth: -2, fire: -2 } },
{ id: "loyal", mod: { water: 2, fire: -2 } }, { id: "loyal", mod: { water: 2, fire: -2 } },
{ id: "methodical", mod: { earth: 2, fire: -2 } },
{ id: "meticulous", mod: { fire: 1, water: 1, air: -1, earth: -1 } },
{ id: "meticulous", mod: { fire: 1, water: 1, earth: -2 } },
{ id: "mischievous", mod: { fire: 2, air: -2 } }, { id: "mischievous", mod: { fire: 2, air: -2 } },
{ id: "mischievous", mod: { air: 2, earth: -2 } }, { id: "mischievous", mod: { air: 2, earth: -2 } },
{ id: "mischievous", mod: { earth: 2, fire: -2 } }, { id: "mischievous", mod: { earth: 2, fire: -2 } },
{ id: "moon_blessed", mod: { water: 2, fire: -2 } },
{ id: "morose", mod: { water: 2, fire: -2 } }, { id: "morose", mod: { water: 2, fire: -2 } },
{ id: "near_feral", mod: { air: 1, fire: -1 } },
{ id: "nurturing", mod: { earth: 2, fire: -2 } }, { id: "nurturing", mod: { earth: 2, fire: -2 } },
{ id: "obsessed", mod: { earth: 2, air: -2 } },
{ id: "obstinate", mod: { earth: 2, air: -2 } }, { id: "obstinate", mod: { earth: 2, air: -2 } },
{ id: "obstinate", mod: { water: 2, air: -2 } }, { id: "obstinate", mod: { water: 2, air: -2 } },
{ id: "otherworldly", mod: { water: 1, void: -1 } },
{ id: "outgoing", mod: { air: 2, earth: -2 } },
{ id: "opportunistic", mod: { water: 2, fire: -2 } }, { id: "opportunistic", mod: { water: 2, fire: -2 } },
{ id: "passionate", mod: { earth: 2, air: -2 } }, { id: "passionate", mod: { earth: 2, air: -2 } },
{ id: "patient", mod: { fire: 1, water: 1, air: -1, void: -1 } },
{ id: "personable", mod: { fire: 2, air: 1, void: -2 } },
{ id: "playful", mod: { earth: 2, water: -2 } }, { id: "playful", mod: { earth: 2, water: -2 } },
{ id: "playful", mod: { fire: 1, air: 1, void: -2 } }, { id: "playful", mod: { fire: 1, air: 1, void: -2 } },
{ id: "power_hungry", mod: { fire: 2, earth: -2 } }, { id: "power_hungry", mod: { fire: 2, earth: -2 } },
{ id: "proud", mod: { fire: 2, earth: -2 } }, { id: "proud", mod: { fire: 2, earth: -2 } },
{ id: "refined", mod: { earth: 1, water: 1, air: -1, fire: -1 } },
{ id: "reserved", mod: { earth: 2, water: -2 } },
{ id: "restrained", mod: { earth: 2, air: -2 } }, { id: "restrained", mod: { earth: 2, air: -2 } },
{ id: "righteous", mod: { water: 2, fire: -1, void: -1 } },
{ id: "scheming", mod: { air: 2, void: -2 } }, { id: "scheming", mod: { air: 2, void: -2 } },
{ id: "serene", mod: { fire: 2, void: -2 } }, { id: "serene", mod: { fire: 2, void: -2 } },
{ id: "serene", mod: { void: 2, fire: -2 } }, { id: "serene", mod: { void: 2, fire: -2 } },
{ id: "serious", mod: { fire: 2, earth: -2 } }, { id: "serious", mod: { fire: 2, earth: -2 } },
{ id: "shrewd", mod: { air: 2, fire: -2 } }, { id: "shrewd", mod: { air: 2, fire: -2 } },
{ id: "sinister", mod: { fire: 2, air: -2 } },
{ id: "sociable", mod: { air: 1, earth: 1, fire: -1, water: -1 } },
{ id: "starved", mod: { water: 2, fire: -2 } },
{ id: "stoic", mod: { earth: 2, fire: -2 } },
{ id: "stubborn", mod: { earth: 2, water: -2 } }, { id: "stubborn", mod: { earth: 2, water: -2 } },
{ id: "suspicious", mod: { air: 2, earth: -2 } }, { id: "suspicious", mod: { air: 2, earth: -2 } },
{ id: "teasing", mod: { air: 2, earth: -2 } }, { id: "teasing", mod: { air: 2, earth: -2 } },
@@ -523,5 +619,10 @@ L5R5E.demeanors = [
{ id: "uncertain", mod: { air: 2, fire: -2 } }, { id: "uncertain", mod: { air: 2, fire: -2 } },
{ id: "unenthused", mod: { earth: 2, fire: -2 } }, { id: "unenthused", mod: { earth: 2, fire: -2 } },
{ id: "vain", mod: { earth: 2, air: -2 } }, { id: "vain", mod: { earth: 2, air: -2 } },
{ id: "vengeful", mod: { fire: 2, void: -2 } },
{ id: "vindictive", mod: { fire: 2, water: -2 } },
{ id: "wary", mod: { earth: 2, fire: -2 } }, { id: "wary", mod: { earth: 2, fire: -2 } },
{ id: "watchful", mod: { fire: 2, earth: -1, void: -1 } },
{ id: "wrathful", mod: { fire: 2, earth: -2 } },
{ id: "zealous", mod: { earth: 2, fire: -2 } },
]; ];

View File

@@ -1,47 +1,110 @@
import { L5r5eHtmlMultiSelectElement } from "../misc/l5r5e-multiselect.js"; import { L5r5eHtmlMultiSelectElement } from "../misc/l5r5e-multiselect.js";
/** /**
* A subclass of [ArrayField]{@link ArrayField} which supports a set of contained elements. * A Foundry `SetField` that renders as an {@link L5r5eHtmlMultiSelectElement} chip-input.
* Elements in this set are treated as fungible and may be represented in any order or discarded if invalid. *
* Use this in a DataModel schema whenever a field stores an unordered collection of
* string values drawn from a fixed option list. On form submission the element returns a
* comma-separated string; `clean()` splits it back into an Array before Foundry processes
* it, and `initialize()` wraps the result in a `Set` for use in the model.
*
* @example
* // In a DataModel schema:
* skills: new L5r5eSetField({
* options: [
* { value: "athletics", label: "Athletics" },
* { value: "meditation", label: "Meditation", disabled: true, tooltip: "Requires rank 3" },
* ]
* })
*
* // Renders automatically via {{formGroup}} in a Handlebars template:
* // {{formGroup fields.skills name="skills" value=data.skills localize=true}}
*
* @param {object} options
* @param {{ value: string, label: string, disabled?: boolean, tooltip?: string }[]} options.options
* Flat list of selectable items. Passed directly to {@link L5r5eHtmlMultiSelectElement.create}.
* @param {object[]} [options.groups]
* Optional optgroup definitions, forwarded to the element factory unchanged.
* @param {boolean} [options.hideDisabledOptions=false]
* When true, disabled options are hidden from the dropdown instead of greyed out.
*/ */
export class L5r5eSetField extends foundry.data.fields.SetField { export class L5r5eSetField extends foundry.data.fields.SetField {
/**
// We don't get the options we expect when we convert this to input, * Saved constructor options, used to reconstruct the multiselect input on form render.
// So store them here * @type {object}
*/
#savedOptions; #savedOptions;
constructor(options={}, context={}) { /**
super(new foundry.data.fields.StringField({ * @param {object} options
choices: options.options.map((option) => option.value) * @param {object} context
}), options, context); */
constructor(options = {}, context = {}) {
super(
new foundry.data.fields.StringField({
choices: options.options?.map((option) => option.value) ?? [],
}),
options,
context
);
this.#savedOptions = options; this.#savedOptions = options;
} }
/** @override */ /**
initialize(value, model, options={}) { * @param {*} value
if ( !value ) return value; * @param {object} model
return new Set(super.initialize(value, model, options)); * @param {object} options
* @return {Set}
* @override
*/
initialize(value, model, options = {}) {
if (!value || (Array.isArray(value) && value.length === 0)) {
return new Set();
} }
/** @override */ return new Set(super.initialize(value, model, options).filter(Boolean));
}
/**
* @param {Set} value
* @return {*[]|*}
* @override
*/
toObject(value) { toObject(value) {
if ( !value ) return value; if (!value) {
return Array.from(value).map(v => this.element.toObject(v)); return value;
}
return Array.from(value).map((v) => this.element.toObject(v));
} }
/* -------------------------------------------- */ /**
/* Form Field Integration */ * @param {string|Array} value
/* -------------------------------------------- */ * @param {object} options
* @return {Array}
* @override
*/
clean(value, options) {
// Settings forms submit comma-separated strings; split before normal cleaning.
if (typeof value === "string") {
value = value.length ? value.split(",").filter(Boolean) : [];
}
return super.clean(value, options);
}
/** @override */ /**
* @param {object} config
* @return {L5r5eHtmlMultiSelectElement}
* @override
*/
_toInput(config) { _toInput(config) {
const e = this.element;
return L5r5eHtmlMultiSelectElement.create({ return L5r5eHtmlMultiSelectElement.create({
name: config.name, name: config.name,
options: this.#savedOptions.options, options: this.#savedOptions.options,
groups: this.#savedOptions.groups, groups: this.#savedOptions.groups,
value: config.value, value: config.value,
localize: config.localize localize: config.localize,
hideDisabledOptions: this.#savedOptions.hideDisabledOptions,
}); });
} }
} }

View File

@@ -0,0 +1,334 @@
/**
* Chiaroscuro Dice Dialog
*
* d6 pool system: ring value × multiplier d6, sum vs difficulty.
* Multiplier: ×1 base, ×2 if aspect or assistance, ×3 if both.
* Parangon passives adjust individual die results before summing.
*/
export class ChiaroscuroDiceDialog extends FormApplication {
/**
* Current Actor
* @type {ActorL5r5e}
* @private
*/
_actor = null;
/**
* Payload Object
*/
object = {
ring: { id: "void", value: 1 },
skill: { id: "", name: "", bonus: 0, rank: "0" },
difficulty: { id: "moyenne", value: 10 },
modifier: 0,
useAspectPoint: false,
aspectType: "solar",
useAssistance: false,
};
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
id: "l5r5e-chiaroscuro-dice-dialog",
classes: ["l5r5e", "chiaroscuro-dice-dialog"],
template: CONFIG.l5r5e.paths.templates + "dice/chiaroscuro-dice-dialog.html",
title: game.i18n.localize("chiaroscuro.dice.title"),
width: 440,
height: "auto",
});
}
get id() {
return `l5r5e-chiaroscuro-dice-dialog-${this._actor?.id ?? "no-actor"}`;
}
get title() {
return game.i18n.localize("chiaroscuro.dice.title") + (this._actor ? " — " + this._actor.name : "");
}
/**
* Total dice to roll (ring value × multiplier)
* @return {number}
*/
get totalDice() {
const base = this.object.ring.value;
const both = this.object.useAspectPoint && this.object.useAssistance;
const either = this.object.useAspectPoint || this.object.useAssistance;
return base * (both ? 3 : either ? 2 : 1);
}
/**
* @param options actor, actorId, ringId, skillId
*/
constructor(options = {}) {
super({}, options);
// Resolve actor
[
options?.actor,
game.actors.get(options?.actorId),
canvas.tokens.controlled[0]?.actor,
game.user.character,
].forEach((actor) => {
if (!this._actor && actor instanceof Actor && actor.isOwner) {
this._actor = actor;
}
});
// Default ring: options > actor default_ring > void
const ringId = options.ringId ?? this._actor?.system?.default_ring ?? "void";
this.ringId = ringId;
// Skill
if (options.skillId) {
this.skillId = options.skillId;
}
}
/**
* Set ring (id + value from actor)
* @param {string} ringId
*/
set ringId(ringId) {
this.object.ring.id = CONFIG.l5r5e.stances.includes(ringId) ? ringId : "void";
this.object.ring.value = this._actor?.system?.rings?.[this.object.ring.id] || 1;
// Auto-derive aspect type from ring (fire/earth → solar, air/water → lunar; void = manual)
if (this.object.ring.id !== "void") {
this.object.aspectType = ["fire", "earth"].includes(this.object.ring.id) ? "solar" : "lunar";
}
}
/**
* Set skill (id, name, rank, bonus)
* @param {string} skillId
*/
set skillId(skillId) {
if (!skillId) return;
const catId = CONFIG.l5r5e.skills.get(skillId.toLowerCase().trim());
const rank = this._actor?.system?.skills?.[catId]?.[skillId] ?? "0";
this.object.skill = {
...this.object.skill,
id: skillId,
name: catId ? game.i18n.localize(`l5r5e.skills.${catId}.${skillId}`) : skillId,
rank,
bonus: CONFIG.l5r5e.skillRanks?.[rank]?.bonus ?? 0,
};
}
async getData(options = null) {
const difficultiesList = Object.entries(CONFIG.l5r5e.difficulties).map(([id, value]) => ({
id,
label: game.i18n.localize(`chiaroscuro.difficulties.${id}`),
value,
}));
const aspectsList = [
{ id: "solar", label: game.i18n.localize("chiaroscuro.aspects.solar") },
{ id: "lunar", label: game.i18n.localize("chiaroscuro.aspects.lunar") },
];
return {
...(await super.getData(options)),
actor: this._actor,
data: this.object,
totalDice: this.totalDice,
ringsList: game.l5r5e.HelpersL5r5e.getRingsList(this._actor),
difficultiesList,
aspectsList,
isVoidRing: this.object.ring.id === "void",
quickInfo: this._actor?.system?.quick_info ?? "",
};
}
activateListeners(html) {
super.activateListeners(html);
// Ring selector
html.find(".ring-selection-chi").on("click", async (event) => {
event.preventDefault();
event.stopPropagation();
this.ringId = event.currentTarget.dataset.ringid;
this.render(false);
});
// Difficulty select
html.find("select[name='difficulty.id']").on("change", (event) => {
this.object.difficulty.id = event.target.value;
this.object.difficulty.value = CONFIG.l5r5e.difficulties[this.object.difficulty.id];
this.render(false);
});
// Flat modifier
html.find("input[name='modifier']").on("change", (event) => {
this.object.modifier = parseInt(event.target.value) || 0;
});
// Aspect point checkbox
html.find("#use_aspect_point").on("change", (event) => {
this.object.useAspectPoint = event.target.checked;
this.render(false);
});
// Aspect type select (solar / lunar)
html.find("select[name='aspectType']").on("change", (event) => {
this.object.aspectType = event.target.value;
});
// Assistance checkbox
html.find("#use_assistance").on("change", (event) => {
this.object.useAssistance = event.target.checked;
this.render(false);
});
// Roll button — explicit submit trigger
html.find("button[name='roll']").on("click", (event) => {
event.preventDefault();
this._onSubmit(event);
});
}
async _updateObject(event, formData) {
const nbDice = this.totalDice;
const skillRank = this.object.skill.rank;
const skillBonus = this.object.skill.bonus;
const flatModifier = this.object.modifier;
const difficultyObj = this.object.difficulty;
const difficultyValue = difficultyObj.value;
// Roll the dice using FoundryVTT Roll API
const roll = await new Roll(`${nbDice}d6`).evaluate();
const rawResults = roll.dice[0].results.map((r) => r.result);
// Apply parangon passive adjustments
const adjustedResults = rawResults.map((r) => this._applyParangon(r, skillRank));
const diceAdjustedFlags = rawResults.map((r, i) => adjustedResults[i] !== r);
const wasAdjusted = diceAdjustedFlags.some(Boolean);
// Compute total
const rawSum = adjustedResults.reduce((a, b) => a + b, 0);
const total = rawSum + skillBonus + flatModifier;
const success = total >= difficultyValue;
const bonus = success ? total - difficultyValue : 0;
// Update aspect gauge after roll
if (this._actor && this.object.useAspectPoint) {
await this._updateAspectGauge();
}
// Post chat message
await this._sendChatMessage({
nbDice,
rawResults,
adjustedResults,
diceAdjustedFlags,
wasAdjusted,
rawSum,
total,
skillBonus,
flatModifier,
difficulty: difficultyObj,
success,
bonus,
});
return this.close();
}
/**
* Apply parangon rank passive: replace low die results with higher value.
* parangon1: 1 → 2
* parangon2: 12 → 3
* parangon3: 13 → 4
* @param {number} result
* @param {string} rank
* @return {number}
*/
_applyParangon(result, rank) {
if (rank === "parangon3" && result <= 3) return 4;
if (rank === "parangon2" && result <= 2) return 3;
if (rank === "parangon1" && result <= 1) return 2;
return result;
}
/**
* Update the aspect gauge on the actor after an aspect point roll.
* Gauge positive = solar side, negative = lunar side.
* ±5 → apply Déséquilibre. ±10 → full reset.
*/
async _updateAspectGauge() {
// Support both single-nested (system.aspects) and double-nested (system.aspects.aspects)
const aspectsPath = this._actor.system.aspects?.aspects !== undefined
? "system.aspects.aspects"
: "system.aspects";
const aspects = foundry.utils.getProperty(this._actor, aspectsPath) ?? {};
const gaugeDirection = this.object.aspectType === "solar" ? 1 : -1;
const newGauge = (aspects.gauge ?? 0) + gaugeDirection;
if (Math.abs(newGauge) >= 10) {
// Full reset
await this._actor.update({
[`${aspectsPath}.gauge`]: 0,
[`${aspectsPath}.solar`]: 0,
[`${aspectsPath}.lunar`]: 0,
});
// Remove all desequilibre conditions
const toRemove = this._actor.items
.filter((i) => i.type === "etat" && ["desequilibre_solaire", "desequilibre_lunaire"].includes(i.system?.condition_type))
.map((i) => i.id);
if (toRemove.length) {
await this._actor.deleteEmbeddedDocuments("Item", toRemove);
}
} else {
await this._actor.update({ [`${aspectsPath}.gauge`]: newGauge });
if (Math.abs(newGauge) >= 5) {
// Apply opposing desequilibre
const condType = this.object.aspectType === "solar" ? "desequilibre_lunaire" : "desequilibre_solaire";
const existing = this._actor.items.find(
(i) => i.type === "etat" && i.system?.condition_type === condType
);
if (!existing) {
await this._actor.createEmbeddedDocuments("Item", [
{
type: "etat",
name: game.i18n.localize(`chiaroscuro.aspects.${condType}`),
system: { condition_type: condType },
},
]);
}
}
}
}
/**
* Create and send the chat message.
*/
async _sendChatMessage(rollData) {
const content = await foundry.applications.handlebars.renderTemplate(
CONFIG.l5r5e.paths.templates + "dice/chiaroscuro-chat-roll.html",
{
actor: this._actor,
profileImg: this._actor?.img ?? "icons/svg/mystery-man.svg",
ring: this.object.ring,
skill: this.object.skill,
difficulty: this.object.difficulty,
useAspectPoint: this.object.useAspectPoint,
aspectType: this.object.aspectType,
useAssistance: this.object.useAssistance,
modifier: this.object.modifier,
quickInfo: this._actor?.system?.quick_info ?? "",
...rollData,
}
);
return ChatMessage.implementation.create({
user: game.user.id,
speaker: {
actor: this._actor?.id ?? null,
alias: this._actor?.name ?? null,
},
content,
sound: CONFIG.sounds.dice,
});
}
}

View File

@@ -513,6 +513,9 @@ export class DicePickerDialog extends FormApplication {
this._updateVoidPointUsage(); this._updateVoidPointUsage();
this.render(false); this.render(false);
}); });
// Open journal on effect name
html.find(".effect-name").on("click", this._openEffectJournal.bind(this));
} }
/** /**
@@ -687,7 +690,7 @@ export class DicePickerDialog extends FormApplication {
type: "script", type: "script",
scope: "actor", scope: "actor",
command, command,
img: this._actor?.img || "systems/l5r5e/assets/dices/default/ring_et.svg", img: this._actor?.img || "systems/l5rx-chiaroscuro/assets/dices/default/ring_et.svg",
}); });
} }
@@ -864,4 +867,34 @@ export class DicePickerDialog extends FormApplication {
return array; return array;
} }
/**
* Open the core linked journal effect if exist
* @param {Event} event
* @private
*/
async _openEffectJournal(event) {
event.preventDefault();
event.stopPropagation();
const effectId = $(event.currentTarget).data("effect-id");
if (!effectId) {
return;
}
const effect = this._actor?.effects?.get(effectId);
if (!effect?.system?.id && !effect?.system?.uuid) {
return;
}
const journal = await game.l5r5e.HelpersL5r5e.getObjectGameOrPack({
id: effect.system.id,
uuid: effect.system.uuid,
type: "JournalEntry",
});
if (journal) {
// Open on the "rules" section. If non exists then it will open the first page
journal.sheet.render(true, {pageIndex: 2});
}
}
} }

View File

@@ -268,6 +268,9 @@ export class RollnKeepDialog extends FormApplication {
], { jQuery: false }); ], { jQuery: false });
} }
// Open journal on effect name
html.find(".effect-name").on("click", this._openEffectJournal.bind(this));
// *** Everything below here is only needed if the sheet is editable *** // *** Everything below here is only needed if the sheet is editable ***
if (!this.isEditable) { if (!this.isEditable) {
return; return;
@@ -802,4 +805,34 @@ export class RollnKeepDialog extends FormApplication {
// Re-enable the button // Re-enable the button
button.attr("disabled", false); button.attr("disabled", false);
} }
/**
* Open the core linked journal effect if exist
* @param {Event} event
* @private
*/
async _openEffectJournal(event) {
event.preventDefault();
event.stopPropagation();
const effectId = $(event.currentTarget).data("effect-id");
if (!effectId) {
return;
}
const effect = this.roll.l5r5e?.actor?.effects?.get(effectId);
if (!effect?.system?.id && !effect?.system?.uuid) {
return;
}
const journal = await game.l5r5e.HelpersL5r5e.getObjectGameOrPack({
id: effect.system.id,
uuid: effect.system.uuid,
type: "JournalEntry",
});
if (journal) {
// Open on the "rules" section. If non exists then it will open the first page
journal.sheet.render(true, {pageIndex: 2});
}
}
} }

View File

@@ -73,11 +73,11 @@ export class GmMonitor extends HandlebarsApplicationMixin(ApplicationV2) {
}, },
character: { character: {
id: "character", id: "character",
template: "systems/l5r5e/templates/" + "gm/monitor/character-view.html" template: "systems/l5rx-chiaroscuro/templates/" + "gm/monitor/character-view.html"
}, },
army: { army: {
if: "army", if: "army",
template: "systems/l5r5e/templates/" + "gm/monitor/army-view.html" template: "systems/l5rx-chiaroscuro/templates/" + "gm/monitor/army-view.html"
} }
}; };
@@ -166,6 +166,15 @@ export class GmMonitor extends HandlebarsApplicationMixin(ApplicationV2) {
} }
} }
); );
// Apply global interface theme if it is set
if (!this.options.classes.includes("themed")) {
this.element.classList.remove("theme-light", "theme-dark");
const {colorScheme} = game.settings.get("core", "uiConfig");
if (colorScheme.interface) {
this.element.classList.add("themed", `theme-${colorScheme.interface}`);
}
}
} }
/** @override ApplicationV2 */ /** @override ApplicationV2 */

View File

@@ -5,10 +5,11 @@ export class GmToolbox extends HandlebarsApplicationMixin(ApplicationV2) {
/** @override ApplicationV2 */ /** @override ApplicationV2 */
static get DEFAULT_OPTIONS() { return { static get DEFAULT_OPTIONS() { return {
id: "l5r5e-gm-toolbox", id: "l5r5e-gm-toolbox",
classes: ["faded-ui"],
window: { window: {
contentClasses: ["l5r5e", "gm-toolbox", "faded-ui"], contentClasses: ["l5r5e", "gm-toolbox"],
title: "l5r5e.gm.toolbox.title", title: "l5r5e.gm.toolbox.title",
minimizable: true, minimizable: false,
}, },
position: { position: {
width: "auto", width: "auto",
@@ -43,7 +44,7 @@ export class GmToolbox extends HandlebarsApplicationMixin(ApplicationV2) {
static PARTS = { static PARTS = {
main: { main: {
id: "gm-tool-content", id: "gm-tool-content",
template: "systems/l5r5e/templates/" + "gm/gm-toolbox.html" template: "systems/l5rx-chiaroscuro/templates/" + "gm/gm-toolbox.html"
} }
}; };
@@ -89,6 +90,19 @@ export class GmToolbox extends HandlebarsApplicationMixin(ApplicationV2) {
options.position.left = 220; //x - 630; options.position.left = 220; //x - 630;
} }
async _onRender(context, options) {
await super._onRender(context, options);
if (this.options.classes.includes("themed")) {
return;
}
this.element.classList.remove("theme-light", "theme-dark");
const {colorScheme} = game.settings.get("core", "uiConfig");
if (colorScheme.interface) {
this.element.classList.add("themed", `theme-${colorScheme.interface}`);
}
}
/** /**
* The GM Toolbox should not be removed when toggling the main menu with the esc key etc. * The GM Toolbox should not be removed when toggling the main menu with the esc key etc.
* @override ApplicationV2 * @override ApplicationV2

View File

@@ -64,6 +64,11 @@ export const RegisterHandlebars = function () {
return objects.join(""); return objects.join("");
}); });
// Chiaroscuro: return the flat bonus for a given skill rank id
Handlebars.registerHelper("skillRankBonus", (rankId) => {
return CONFIG.l5r5e.skillRanks?.[rankId]?.bonus ?? 0;
});
// Add a setter // Add a setter
Handlebars.registerHelper("setVar", function (varName, varValue, options) { Handlebars.registerHelper("setVar", function (varName, varValue, options) {
options.data.root[varName] = varValue; options.data.root[varName] = varValue;

View File

@@ -1,4 +1,4 @@
import { L5r5eHtmlMultiSelectElement } from "./misc/l5r5e-multiselect.js"; import { ItemCompendiumL5r5e } from "./compendium/l5r5e-item-compendium.js"
export default class HooksL5r5e { export default class HooksL5r5e {
/** /**
@@ -26,6 +26,8 @@ export default class HooksL5r5e {
) { ) {
game.babele.setSystemTranslationsDir("babele"); // Since Babele v2.0.7 game.babele.setSystemTranslationsDir("babele"); // Since Babele v2.0.7
} }
ItemCompendiumL5r5e.applyToPacks();
} }
/** /**
@@ -245,236 +247,6 @@ export default class HooksL5r5e {
}); });
} }
/**
* Compendium display (Add filters)
*/
static async renderCompendium(app, html, data) {
html = $(html); // basic patch for v13
if (app.collection.documentName === "Item") {
const content = await app.collection.getDocuments();
const sourcesInThisCompendium = new Set([]);
const filtersToShow = {
rank: false,
rarity: false,
source: false,
ring: false,
};
// Used to auto hide same values for a full compendium
const previousValue = {
rank: null,
rarity: null,
source: null,
ring: null,
};
// Cache
const header = html.find(".directory-header");
const entries = html.find(".directory-item");
// Add additional data to the entries to make it faster to lookup.
// Add Ring/rank/rarity information
for (const document of content) {
const entry = entries.filter(`[data-entry-id="${document.id}"]`);
// Hide filter if only one value of this type is found in the compendium
const autoDisplayFilter = (props, documentData = null) => {
documentData ??= document.system[props];
if (filtersToShow[props] || previousValue[props] === documentData) {
return;
}
filtersToShow[props] = previousValue[props] !== null && previousValue[props] !== documentData;
previousValue[props] = documentData;
};
if (document.system?.rank) {
autoDisplayFilter('rank');
entry.data("rank", document.system.rank);
}
if (document.system?.source_reference.source) {
autoDisplayFilter('source', document.system.source_reference.source);
sourcesInThisCompendium.add(document.system.source_reference.source);
entry.data("source", document.system.source_reference);
}
if (document.system?.ring) {
autoDisplayFilter('ring');
entry.data("ring", document.system.ring);
}
if (document.system?.rarity) {
autoDisplayFilter('rarity');
entry.data("rarity", document.system.rarity);
}
// Add ring/rank/rarity information on the item in the compendium view
if (document.system?.ring || document.system?.rarity || document.system?.rank) {
const ringRarityRank = await foundry.applications.handlebars.renderTemplate(`${CONFIG.l5r5e.paths.templates}compendium/ring-rarity-rank.html`, document.system);
entry.append(ringRarityRank);
}
}
// Setup filters
const officialContentSet = game.settings.get(CONFIG.l5r5e.namespace, "compendium-official-content-for-players");
const unofficialContentSet = game.settings.get(CONFIG.l5r5e.namespace, "compendium-unofficial-content-for-players");
const allCompendiumReferencesSet = game.settings.get(CONFIG.l5r5e.namespace, "all-compendium-references")
const hideEmptySourcesFromPlayers = game.settings.get(CONFIG.l5r5e.namespace, "compendium-hide-empty-sources-from-players");
const unavailableSourceForPlayersSet = new Set([...allCompendiumReferencesSet].filter((element) => {
if (CONFIG.l5r5e.sourceReference[element]) {
return officialContentSet.size > 0 ? !officialContentSet.has(element) : false;
}
return unofficialContentSet.size > 0 ? !unofficialContentSet.has(element) : false;
}));
// Create filter function
const applyCompendiumFilter = () => {
const userFilter = header.find("l5r5e-multi-select").val();
const rankFilter = header.find(".rank-filter .selected").data("rank");
const ringFilter = header.find(".ring-filter .selected").data("ring");
const rarityFilter = header.find(".rarity-filter .selected").data("rarity");
entries.each(function () {
const lineSource = $(this).data("source")?.source;
// We might have stuff in the compendium view that does not have a source (folders etc.) Ignore those.
if (lineSource === null || lineSource === undefined) {
return;
}
let shouldShow = true;
// Handle unavailable sources
if (unavailableSourceForPlayersSet.has(lineSource)) {
if (game.user.isGM) {
shouldShow &= true;
$(this)
.addClass("not-for-players")
.attr("data-tooltip", game.i18n.localize("l5r5e.compendium.not_for_players"));
} else {
shouldShow &= false;
}
}
// Handle empty sources
if (lineSource === "" && hideEmptySourcesFromPlayers) {
if (game.user.isGM) {
shouldShow &= true;
$(this)
.addClass("not-for-players")
.attr("data-tooltip", game.i18n.localize("l5r5e.compendium.not_for_players"));
} else {
shouldShow &= false;
}
}
// Apply filters
if (rankFilter) {
shouldShow &= $(this).data("rank") == rankFilter;
}
if (userFilter?.length) {
shouldShow &= userFilter.includes(lineSource);
}
if (ringFilter) {
shouldShow &= $(this).data("ring") == ringFilter;
}
if (rarityFilter >= 0) {
shouldShow &= $(this).data("rarity") == rarityFilter;
}
// Show or hide this entry based on the result
shouldShow ? $(this).show() : $(this).hide();
});
};
// Filter setup
const addFilter = async (filterType, templateFile, templateData) => {
if (!filtersToShow[filterType]) {
return;
}
const filterTemplate = await foundry.applications.handlebars.renderTemplate(
`${CONFIG.l5r5e.paths.templates}compendium/${templateFile}.html`,
templateData
);
header.append(filterTemplate);
header.find(`.${filterType}-filter`).children().each(function () {
$(this).on("click", (event) => {
const selected = $(event.target).hasClass("selected");
header.find(`.${filterType}-filter`).children().removeClass("selected");
$(event.target).toggleClass("selected", !selected);
applyCompendiumFilter();
});
});
};
// Add Rank, Rarity, Ring Filters
await Promise.all([
addFilter('rank' , 'rank-filter', { type: "rank", number: [1, 2, 3, 4, 5] }),
addFilter('rarity', 'rank-filter', { type: "rarity", number: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }),
addFilter('ring' , 'ring-filter', {}),
]);
if (filtersToShow.source) {
// Build the source select
const selectableSourcesArray = [...allCompendiumReferencesSet].map((reference) => ({
value: reference,
label: CONFIG.l5r5e.sourceReference[reference]?.label ?? reference,
translate: true,
group: CONFIG.l5r5e.sourceReference[reference]?.type.split(",")[0] ?? "l5r5e.multiselect.sources_categories.others",
disabled: !sourcesInThisCompendium.has(reference) || (!game.user.isGM && unavailableSourceForPlayersSet.has(reference))
}));
const filterSourcesBox = L5r5eHtmlMultiSelectElement.create({
name: "filter-sources",
options: selectableSourcesArray,
localize: true,
});
header.append(filterSourcesBox.outerHTML);
$("l5r5e-multi-select").on("change", applyCompendiumFilter);
// If gm add an extra button to easily filter the content to see the same stuff as a player
if (game.user.isGM && unavailableSourceForPlayersSet.size > 0) {
const buttonHTML = `<button type="button" class="gm" data-tooltip="${game.i18n.localize('l5r5e.multiselect.player_filter_tooltip')}">`
+ game.i18n.localize('l5r5e.multiselect.player_filter_label')
+ '</button>'
const filterPlayerViewArray = [...allCompendiumReferencesSet]
.filter((item) => !unavailableSourceForPlayersSet.has(item))
.filter((item) => sourcesInThisCompendium.has(item));
$(buttonHTML).appendTo($(header).find("l5r5e-multi-select")).click(function() {
header.find("l5r5e-multi-select")[0].value = filterPlayerViewArray;
});
}
}
// TODO: This delay is a workaround and should be addressed in another way.
// This is ugly but if we hide the content too early then it won't be hidden for some reason.
// Current guess is that the foundry search filter is doing something.
// Adding a delay here so that we hide the content. This will fail on slow computers/network...
setTimeout(() => {
applyCompendiumFilter();
}, 250);
return false;
}
}
static updateCompendium(pack, documents, options, userId) {
documents.forEach((document) => {
const inc_reference = document?.system?.source_reference?.source?.trim();
if (!!inc_reference) {
const references = game.settings.get(CONFIG.l5r5e.namespace, "all-compendium-references");
if (!references.includes(inc_reference)) {
references.push(inc_reference);
game.settings.set(CONFIG.l5r5e.namespace, "all-compendium-references", references);
}
}
});
}
/** /**
* DiceSoNice - Add L5R DicePresets * DiceSoNice - Add L5R DicePresets
*/ */

View File

@@ -90,12 +90,12 @@ export class AdvancementSheetL5r5e extends ItemSheetL5r5e {
// Modify image to reflect choice // Modify image to reflect choice
if (newChoice.ring) { if (newChoice.ring) {
name = game.i18n.localize(`l5r5e.rings.${newChoice.ring}`) + "+1"; name = game.i18n.localize(`l5r5e.rings.${newChoice.ring}`) + "+1";
img = `systems/l5r5e/assets/icons/rings/${newChoice.ring}.svg`; img = `systems/l5rx-chiaroscuro/assets/icons/rings/${newChoice.ring}.svg`;
} else if (newChoice.skill) { } else if (newChoice.skill) {
name = name =
game.i18n.localize(`l5r5e.skills.${CONFIG.l5r5e.skills.get(newChoice.skill)}.${newChoice.skill}`) + game.i18n.localize(`l5r5e.skills.${CONFIG.l5r5e.skills.get(newChoice.skill)}.${newChoice.skill}`) +
"+1"; "+1";
img = `systems/l5r5e/assets/dices/default/skill_blank.svg`; img = `systems/l5rx-chiaroscuro/assets/dices/default/skill_blank.svg`;
} }
// Object embed in actor ? // Object embed in actor ?
@@ -149,5 +149,8 @@ export class AdvancementSheetL5r5e extends ItemSheetL5r5e {
xp_used: xp_used, xp_used: xp_used,
}, },
}); });
// Re-render sheet
this.render(true);
} }
} }

View File

@@ -0,0 +1,44 @@
import { BaseItemSheetL5r5e } from "./base-item-sheet.js";
/**
* Sheet for Arcane items (Chiaroscuro).
* @extends {BaseItemSheetL5r5e}
*/
export class ArcaneSheetL5r5e extends BaseItemSheetL5r5e {
/** @override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["l5r5e", "sheet", "arcane"],
template: CONFIG.l5r5e.paths.templates + "items/arcane/arcane-sheet.html",
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "attributes" }],
});
}
/** @override */
async getData(options = {}) {
const sheetData = await super.getData(options);
// Convert application array to comma-separated string for display
const app = sheetData.data.system.application;
sheetData.data.system.applicationDisplay = Array.isArray(app) ? app.join(", ") : (app ?? "");
sheetData.data.enrichedHtml = {
description: await foundry.applications.ux.TextEditor.implementation.enrichHTML(
sheetData.data.system.description ?? "",
{ async: true }
),
};
return sheetData;
}
/** @override */
async _updateObject(event, formData) {
// Convert comma-separated application string back to array
const raw = formData["system.applicationDisplay"] ?? "";
formData["system.application"] = raw.split(",").map((s) => s.trim()).filter(Boolean);
delete formData["system.applicationDisplay"];
return super._updateObject(event, formData);
}
}

View File

@@ -11,4 +11,16 @@ export class ArmorSheetL5r5e extends ItemSheetL5r5e {
template: CONFIG.l5r5e.paths.templates + "items/armor/armor-sheet.html", template: CONFIG.l5r5e.paths.templates + "items/armor/armor-sheet.html",
}); });
} }
/** @override */
async getData(options = {}) {
const sheetData = await super.getData(options);
const catObj = game.l5r5e.HelpersL5r5e.getLocalizedRawObject("chiaroscuro.armor.categories") ?? {};
sheetData.data.armorCategories = Object.entries(catObj)
.filter(([k]) => k !== "label")
.map(([id, label]) => ({ id, label }));
return sheetData;
}
} }

View File

@@ -0,0 +1,30 @@
import { BaseItemSheetL5r5e } from "./base-item-sheet.js";
/**
* Sheet for État items (Chiaroscuro).
* @extends {BaseItemSheetL5r5e}
*/
export class EtatSheetL5r5e extends BaseItemSheetL5r5e {
/** @override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["l5r5e", "sheet", "etat"],
template: CONFIG.l5r5e.paths.templates + "items/etat/etat-sheet.html",
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "attributes" }],
});
}
/** @override */
async getData(options = {}) {
const sheetData = await super.getData(options);
sheetData.data.enrichedHtml = {
description: await foundry.applications.ux.TextEditor.implementation.enrichHTML(
sheetData.data.system.description ?? "",
{ async: true }
),
};
return sheetData;
}
}

View File

@@ -50,7 +50,7 @@ export class ItemSheetL5r5e extends BaseItemSheetL5r5e {
id: property.id, id: property.id,
name: property.name, name: property.name,
type: "property", type: "property",
img: "systems/l5r5e/assets/icons/items/property.svg", img: "systems/l5rx-chiaroscuro/assets/icons/items/property.svg",
removed: true, removed: true,
}; };
})); }));

View File

@@ -0,0 +1,35 @@
import { BaseItemSheetL5r5e } from "./base-item-sheet.js";
/**
* Sheet for Mystère items (Chiaroscuro).
* @extends {BaseItemSheetL5r5e}
*/
export class MystereSheetL5r5e extends BaseItemSheetL5r5e {
/** @override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["l5r5e", "sheet", "mystere"],
template: CONFIG.l5r5e.paths.templates + "items/mystere/mystere-sheet.html",
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "attributes" }],
});
}
/** @override */
async getData(options = {}) {
const sheetData = await super.getData(options);
sheetData.data.mystereTypes = [
{ id: "mineur", label: game.i18n.localize("chiaroscuro.mystere.mineur") },
{ id: "majeur", label: game.i18n.localize("chiaroscuro.mystere.majeur") },
];
sheetData.data.enrichedHtml = {
description: await foundry.applications.ux.TextEditor.implementation.enrichHTML(
sheetData.data.system.description ?? "",
{ async: true }
),
};
return sheetData;
}
}

View File

@@ -17,12 +17,27 @@ export class TechniqueSheetL5r5e extends ItemSheetL5r5e {
const sheetData = await super.getData(options); const sheetData = await super.getData(options);
// List all available techniques type // List all available techniques type
const types = ["core", "school", "title"]; const types = ["core", "school", "title", "chiaroscuro"];
if (game.settings.get(CONFIG.l5r5e.namespace, "techniques-customs")) { if (game.settings.get(CONFIG.l5r5e.namespace, "techniques-customs")) {
types.push("custom"); types.push("custom");
} }
sheetData.data.techniquesList = game.l5r5e.HelpersL5r5e.getTechniquesList({ types }); sheetData.data.techniquesList = game.l5r5e.HelpersL5r5e.getTechniquesList({ types });
// Invocation sub-type fields (visible only for mot_invocation)
sheetData.data.isMotInvocation = sheetData.data.system.technique_type === "mot_invocation";
sheetData.data.invocationTypes = [
{ id: "general", label: game.i18n.localize("chiaroscuro.technique.invocation_types.general") },
{ id: "neutre", label: game.i18n.localize("chiaroscuro.technique.invocation_types.neutre") },
{ id: "precis", label: game.i18n.localize("chiaroscuro.technique.invocation_types.precis") },
];
sheetData.data.modeInvocationValues = [
{ id: "-3", label: "-3" },
{ id: "0", label: "0" },
{ id: "3", label: "+3" },
];
// Convert mode_invocation to string for selectOptions matching
sheetData.data.system.mode_invocation_str = String(sheetData.data.system.mode_invocation ?? 0);
// Sanitize Difficulty and Skill list // Sanitize Difficulty and Skill list
sheetData.data.system.difficulty = TechniqueSheetL5r5e.formatDifficulty(sheetData.data.system.difficulty); sheetData.data.system.difficulty = TechniqueSheetL5r5e.formatDifficulty(sheetData.data.system.difficulty);
sheetData.data.system.skill = TechniqueSheetL5r5e.translateSkillsList( sheetData.data.system.skill = TechniqueSheetL5r5e.translateSkillsList(
@@ -55,6 +70,12 @@ export class TechniqueSheetL5r5e extends ItemSheetL5r5e {
TechniqueSheetL5r5e.translateSkillsList(formData["system.skill"].split(","), true) TechniqueSheetL5r5e.translateSkillsList(formData["system.skill"].split(","), true)
).join(","); ).join(",");
// Convert mode_invocation_str back to number
if ("system.mode_invocation_str" in formData) {
formData["system.mode_invocation"] = parseInt(formData["system.mode_invocation_str"] ?? "0", 10);
delete formData["system.mode_invocation_str"];
}
return super._updateObject(event, formData); return super._updateObject(event, formData);
} }

View File

@@ -23,6 +23,12 @@ export class WeaponSheetL5r5e extends ItemSheetL5r5e {
label: "l5r5e.skills." + cat.toLowerCase() + "." + id.toLowerCase(), label: "l5r5e.skills." + cat.toLowerCase() + "." + id.toLowerCase(),
})); }));
// Weapon categories (Chiaroscuro)
const catObj = game.l5r5e.HelpersL5r5e.getLocalizedRawObject("chiaroscuro.weapon.categories") ?? {};
sheetData.data.weaponCategories = [{ id: "", label: "—" }].concat(
Object.entries(catObj).map(([id, label]) => ({ id, label }))
);
return sheetData; return sheetData;
} }
} }

View File

@@ -11,6 +11,7 @@ import { ActorL5r5e } from "./actor.js";
import { CharacterSheetL5r5e } from "./actors/character-sheet.js"; import { CharacterSheetL5r5e } from "./actors/character-sheet.js";
import { NpcSheetL5r5e } from "./actors/npc-sheet.js"; import { NpcSheetL5r5e } from "./actors/npc-sheet.js";
import { ArmySheetL5r5e } from "./actors/army-sheet.js"; import { ArmySheetL5r5e } from "./actors/army-sheet.js";
import { RulerL5r5e, TokenRulerL5r5e } from "./tatical-grid-rulers.js";
// Dice and rolls // Dice and rolls
import { L5rBaseDie } from "./dice/dietype/l5r-base-die.js"; import { L5rBaseDie } from "./dice/dietype/l5r-base-die.js";
import { AbilityDie } from "./dice/dietype/ability-die.js"; import { AbilityDie } from "./dice/dietype/ability-die.js";
@@ -18,6 +19,7 @@ import { RingDie } from "./dice/dietype/ring-die.js";
import { RollL5r5e } from "./dice/roll.js"; import { RollL5r5e } from "./dice/roll.js";
import { DicePickerDialog } from "./dice/dice-picker-dialog.js"; import { DicePickerDialog } from "./dice/dice-picker-dialog.js";
import { RollnKeepDialog } from "./dice/roll-n-keep-dialog.js"; import { RollnKeepDialog } from "./dice/roll-n-keep-dialog.js";
import { ChiaroscuroDiceDialog } from "./dice/chiaroscuro-dice-dialog.js";
import { CombatL5r5e } from "./combat.js"; import { CombatL5r5e } from "./combat.js";
// Items // Items
import { ItemL5r5e } from "./item.js"; import { ItemL5r5e } from "./item.js";
@@ -32,11 +34,16 @@ import { TitleSheetL5r5e } from "./items/title-sheet.js";
import { BondSheetL5r5e } from "./items/bond-sheet.js"; import { BondSheetL5r5e } from "./items/bond-sheet.js";
import { SignatureScrollSheetL5r5e } from "./items/signature-scroll-sheet.js"; import { SignatureScrollSheetL5r5e } from "./items/signature-scroll-sheet.js";
import { ItemPatternSheetL5r5e } from "./items/item-pattern-sheet.js"; import { ItemPatternSheetL5r5e } from "./items/item-pattern-sheet.js";
import { ArcaneSheetL5r5e } from "./items/arcane-sheet.js";
import { EtatSheetL5r5e } from "./items/etat-sheet.js";
import { MystereSheetL5r5e } from "./items/mystere-sheet.js";
import { ArmyCohortSheetL5r5e } from "./items/army-cohort-sheet.js"; import { ArmyCohortSheetL5r5e } from "./items/army-cohort-sheet.js";
import { ArmyFortificationSheetL5r5e } from "./items/army-fortification-sheet.js"; import { ArmyFortificationSheetL5r5e } from "./items/army-fortification-sheet.js";
// JournalEntry // JournalEntry
import { JournalL5r5e } from "./journal.js"; import { JournalL5r5e } from "./journal.js";
import { BaseJournalSheetL5r5e } from "./journals/base-journal-sheet.js"; import { BaseJournalSheetL5r5e } from "./journals/base-journal-sheet.js";
// Compendium
import { CompendiumDirectoryL5r5e } from "./compendium/l5r5e-compendium-directory.js";
// Specific // Specific
import { MigrationL5r5e } from "./migration.js"; import { MigrationL5r5e } from "./migration.js";
import { GmToolbox } from "./gm/gm-toolbox.js"; import { GmToolbox } from "./gm/gm-toolbox.js";
@@ -44,8 +51,10 @@ import { GmMonitor } from "./gm/gm-monitor.js";
import { Storage } from "./storage.js"; import { Storage } from "./storage.js";
// Misc // Misc
import { L5r5eHtmlMultiSelectElement } from "./misc/l5r5e-multiselect.js"; import { L5r5eHtmlMultiSelectElement } from "./misc/l5r5e-multiselect.js";
import { L5R5eHtmlComboBoxElement } from "./misc/l5r5e-combo-box.js";
window.customElements.define(L5r5eHtmlMultiSelectElement.tagName, L5r5eHtmlMultiSelectElement); window.customElements.define(L5r5eHtmlMultiSelectElement.tagName, L5r5eHtmlMultiSelectElement);
window.customElements.define(L5R5eHtmlComboBoxElement.tagName, L5R5eHtmlComboBoxElement);
/* ------------------------------------ */ /* ------------------------------------ */
/* Initialize system */ /* Initialize system */
@@ -65,6 +74,23 @@ Hooks.once("init", async () => {
// Global access to L5R Config // Global access to L5R Config
CONFIG.l5r5e = L5R5E; CONFIG.l5r5e = L5R5E;
// Setting up sidebar icons
CONFIG.ChatMessage.sidebarIcon = "l5r5e chatIcon";
CONFIG.Combat.sidebarIcon = "l5r5e combatIcon";
CONFIG.Scene.sidebarIcon = "l5r5e sceneIcon";
CONFIG.Actor.sidebarIcon = "l5r5e actorIcon";
CONFIG.Item.sidebarIcon = "l5r5e itemIcon";
CONFIG.JournalEntry.sidebarIcon = "l5r5e journalIcon";
CONFIG.RollTable.sidebarIcon = "l5r5e rolltableIcon";
CONFIG.Playlist.sidebarIcon = "l5r5e playlistIcon";
// Note: We don't have any custom icons here so just append l5r5e and type
CONFIG.Cards.sidebarIcon += " l5r5e cardsIcon";
CONFIG.Macro.sidebarIcon += " l5r5e macroIcon";
// The compendium and the settings menu is registered a little different.
foundry.applications.sidebar.Sidebar.TABS.compendium.icon = "l5r5e compendiumIcon";
foundry.applications.sidebar.Sidebar.TABS.settings.icon = "l5r5e settingsIcon";
// Assign custom classes and constants here // Assign custom classes and constants here
CONFIG.Combat.documentClass = CombatL5r5e; CONFIG.Combat.documentClass = CombatL5r5e;
CONFIG.Actor.documentClass = ActorL5r5e; CONFIG.Actor.documentClass = ActorL5r5e;
@@ -72,6 +98,10 @@ Hooks.once("init", async () => {
CONFIG.Item.documentClass = ItemL5r5e; CONFIG.Item.documentClass = ItemL5r5e;
CONFIG.JournalEntry.documentClass = JournalL5r5e; CONFIG.JournalEntry.documentClass = JournalL5r5e;
CONFIG.JournalEntry.sheetClass = BaseJournalSheetL5r5e; CONFIG.JournalEntry.sheetClass = BaseJournalSheetL5r5e;
CONFIG.Token.rulerClass = TokenRulerL5r5e;
CONFIG.Canvas.rulerClass = RulerL5r5e;
CONFIG.ui.compendium = CompendiumDirectoryL5r5e;
// Define custom Roll class // Define custom Roll class
CONFIG.Dice.rolls.unshift(RollL5r5e); CONFIG.Dice.rolls.unshift(RollL5r5e);
@@ -92,6 +122,7 @@ Hooks.once("init", async () => {
ActorL5r5e, ActorL5r5e,
DicePickerDialog, DicePickerDialog,
RollnKeepDialog, RollnKeepDialog,
ChiaroscuroDiceDialog,
GmToolbox, GmToolbox,
GmMonitor, GmMonitor,
storage: new Storage(), storage: new Storage(),
@@ -197,6 +228,21 @@ Hooks.once("init", async () => {
label: "TYPES.Item.army_fortification", label: "TYPES.Item.army_fortification",
makeDefault: true, makeDefault: true,
}); });
fdc.Items.registerSheet(L5R5E.namespace, ArcaneSheetL5r5e, {
types: ["arcane"],
label: "TYPES.Item.arcane",
makeDefault: true,
});
fdc.Items.registerSheet(L5R5E.namespace, EtatSheetL5r5e, {
types: ["etat"],
label: "TYPES.Item.etat",
makeDefault: true,
});
fdc.Items.registerSheet(L5R5E.namespace, MystereSheetL5r5e, {
types: ["mystere"],
label: "TYPES.Item.mystere",
makeDefault: true,
});
// Journal // Journal
fdc.Journal.unregisterSheet("core", fav1s.JournalSheet); fdc.Journal.unregisterSheet("core", fav1s.JournalSheet);
@@ -262,6 +308,4 @@ Hooks.on("renderSidebarTab", (app, html, data) => HooksL5r5e.renderSidebarTab(ap
Hooks.on("activateSettings", async (app)=> HooksL5r5e.activateSettings(app)); Hooks.on("activateSettings", async (app)=> HooksL5r5e.activateSettings(app));
Hooks.on("renderChatMessageHTML", (message, html, data) => HooksL5r5e.renderChatMessage(message, html, data)); Hooks.on("renderChatMessageHTML", (message, html, data) => HooksL5r5e.renderChatMessage(message, html, data));
Hooks.on("renderCombatTracker", (app, html, data) => HooksL5r5e.renderCombatTracker(app, html, data)); Hooks.on("renderCombatTracker", (app, html, data) => HooksL5r5e.renderCombatTracker(app, html, data));
Hooks.on("renderCompendium", async (app, html, data) => HooksL5r5e.renderCompendium(app, html, data));
Hooks.on("diceSoNiceRollStart", (messageId, context) => HooksL5r5e.diceSoNiceRollStart(messageId, context)); Hooks.on("diceSoNiceRollStart", (messageId, context) => HooksL5r5e.diceSoNiceRollStart(messageId, context));
Hooks.on("updateCompendium", (pack, documents, options, userId) => HooksL5r5e.updateCompendium(pack, documents, options, userId));

View File

@@ -309,6 +309,29 @@ export class MigrationL5r5e {
} }
// ***** End of 1.3.0 ***** // ***** End of 1.3.0 *****
// ***** Start of 2.0.0 (Chiaroscuro) *****
if (options?.force || MigrationL5r5e.needUpdate("2.0.0")) {
// Migrate character skill ranks from numeric (1-5) to Chiaroscuro string enum.
// Rank 0 (unranked) stays as the number 0 — this is intentional: the template
// defaults to 0 (number) and JS coerces it correctly when keying into skillRanks.
if (actor.type === "character" && system.skills) {
const rankMap = { 1: "initie", 2: "expert", 3: "maitre", 4: "parangon1", 5: "parangon2" };
const groups = ["artisan", "martial", "scholar", "social", "trade"];
for (const group of groups) {
const groupSkills = system.skills[group];
if (!groupSkills) continue;
for (const [skillName, rank] of Object.entries(groupSkills)) {
const numRank = Number(rank);
// Only migrate non-zero numeric ranks; 0 is already valid as-is
if (numRank > 0 && rankMap[numRank]) {
updateData[`system.skills.${group}.${skillName}`] = rankMap[numRank];
}
}
}
}
}
// ***** End of 2.0.0 (Chiaroscuro) *****
return updateData; return updateData;
} }

View File

@@ -0,0 +1,257 @@
import { DropdownMixin } from "./l5r5e-dropdown-mixin.js";
const { AbstractFormInputElement } = foundry.applications.elements;
/**
* A custom `<l5r5e-combo-box>` combining a free-text input with a filterable option dropdown.
*
* Stores a **single string value** — either a predefined option's `value` attribute, or
* whatever the user typed freely. Use this when a field holds exactly one value, whether
* chosen from a list or entered manually (e.g. a weapon name, a title, a custom skill).
* For storing multiple values from a list, use {@link L5r5eHtmlMultiSelectElement} instead.
*
* Picking a predefined option stores its `value` attribute while displaying its human-readable
* label. Free-typing stores the typed string as both value and label. Fires `input` on every
* keystroke and `change` only on commit (blur or Enter) to avoid triggering sheet re-renders
* mid-typing. Picking from the dropdown fires both `input` and `change` immediately.
*
* Use `{{selectOptions}}` without `selected=` to render the available options, and set the
* current value via the `value` attribute on the element directly.
*
* @example
* ```hbs
* {{!-- Pass current value via the element's `value` attribute, not selectOptions selected= --}}
* <l5r5e-combo-box name="weapon" value="{{data.weapon}}">
* {{selectOptions choices localize=true}}
* </l5r5e-combo-box>
* ```
*
* @example
* // Programmatic update — query the element by its name attribute, then set value directly.
* // The visible input label updates automatically to match the selected option's label.
* const el = document.querySelector("l5r5e-combo-box[name='weapon']");
* el.value = "axe"; // input shows "Battleaxe", el.value returns "axe"
*
* // Free-text entry (no matching option) — value and label are both set to the typed string:
* el.value = "naginata"; // input shows "naginata", el.value returns "naginata"
*/
export class L5R5eHtmlComboBoxElement extends DropdownMixin(
AbstractFormInputElement,
{ multiSelect: false, debounceMs: 150, clearOnClose: false }
) {
/**
* The label currently shown in the text input. Differs from `_value` when a predefined
* option is selected (value = option's value attribute, label = option's display text).
* @type {string}
*/
_label = "";
/** @override */
static tagName = "l5r5e-combo-box";
/** @override */
static observedAttributes = ["disabled", "placeholder", "value"];
/**
* Flat descriptor list built once in _initialize(), mirrors the light-DOM options.
* @type {{ value: string, label: string, group: string|null }[]}
*/
#options = [];
/**
* Value snapshot taken when the input receives focus.
* Used by the blur handler to decide whether to fire a change event.
* @type {string}
*/
#valueAtFocus = "";
/* -------------------------------------------- */
/* Accessors */
/* -------------------------------------------- */
/** @override */
get value() {
return this._value ?? "";
}
set value(value) {
const match = this.#options.find(option => option.value === String(value ?? ""));
if (match) {
this._value = match.value;
this._label = match.label;
}
else {
this._value = String(value ?? "");
this._label = this._value;
}
this._internals.setFormValue(this._value);
if (this._dropdownInput) {
this._dropdownInput.value = this._label;
}
this.dispatchEvent(new Event("input", { bubbles: true, cancelable: true }));
this.dispatchEvent(new Event("change", { bubbles: true, cancelable: true }));
}
/**
* AbstractFormInputElement does not have an _initialize() hook, so we override
* connectedCallback to snapshot options from the light DOM before _buildElements()
* is called by super.connectedCallback().
*
* We keep this minimal: just build the flat #options list so _getDropdownOptions()
* and the value setter can look options up by value.
* @override
*/
connectedCallback() {
this.#snapshotOptions();
this.#resolveInitialValue();
super.connectedCallback();
}
#snapshotOptions() {
const makeOption = (option, group = null) => ({
value: option.value,
label: option.innerText,
group,
});
this.#options = [...this.children].flatMap(child => {
if (child instanceof HTMLOptGroupElement) {
return [...child.querySelectorAll("option")]
.filter(option => option.value)
.map(option => makeOption(option, child.label));
}
if (child instanceof HTMLOptionElement && child.value) {
return makeOption(child);
}
return [];
});
}
#resolveInitialValue() {
// Honour a `value` attribute if set, otherwise find a selected option.
const attrValue = this.getAttribute("value");
const initial = attrValue ?? this.#options.find(option => option.selected)?.value ?? "";
const match = this.#options.find(option => option.value === initial);
if (match) {
this._value = match.value;
this._label = match.label;
} else {
this._value = initial;
this._label = initial;
}
}
/* -------------------------------------------- */
/* Element Lifecycle */
/* -------------------------------------------- */
/** @override */
_buildElements() {
const wrapper = this._buildDropdownElements({
placeholder: this.getAttribute("placeholder") ?? "",
});
this._dropdownInput.value = this._label || this._value || "";
this._primaryInput = this._dropdownInput;
return [wrapper];
}
/** @override */
_activateListeners() {
const signal = this.abortSignal;
this._activateDropdownListeners();
// Prevent the inner <input>'s own native change from reaching Foundry's form handler.
// We dispatch our own change at commit time only (see below).
this._dropdownInput.addEventListener("change", (e) => e.stopPropagation(), { signal });
// Free typing: update value and fire `input` immediately.
// Do NOT fire `change` here — Foundry's form handler re-renders the sheet on
// every `change` event, which would destroy the element mid-typing.
// `change` is fired at commit time: on blur (if value changed) or Enter.
this._dropdownInput.addEventListener("input", () => {
const typed = this._dropdownInput.value;
this._label = typed;
this._value = typed;
this._internals.setFormValue(typed);
this.dispatchEvent(new Event("input", { bubbles: true, cancelable: true }));
// DropdownMixin's #onInput fires the debounced dropdown re-render.
}, { signal });
// Commit on blur if the value has changed since the element was focused.
this._dropdownInput.addEventListener("focus", () => {
this.#valueAtFocus = this._value;
}, { signal });
this._dropdownInput.addEventListener("blur", () => {
if (this._value !== this.#valueAtFocus) {
this.dispatchEvent(new Event("change", { bubbles: true, cancelable: true }));
}
}, { signal });
// Commit on Enter for free-text values (not picked from the dropdown).
this._dropdownInput.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
e.preventDefault();
this._dropdownInput.blur();
}
}, { signal });
}
/** @override */
_toggleDisabled(disabled) {
this._toggleDropdownDisabled(disabled);
// Add/remove .disabled on the wrapper so CSS can dim the whole control.
const wrapper = this.querySelector(".wrapper");
if (wrapper) {
wrapper.classList.toggle("disabled", disabled);
}
}
/** @override */
attributeChangedCallback(attrName, oldValue, newValue) {
super.attributeChangedCallback(attrName, oldValue, newValue);
if (attrName === "disabled") {
this._toggleDropdownDisabled(newValue !== null);
}
}
/** @override */
_refresh() {
if (!this._dropdownInput)
return;
this._dropdownInput.value = this._label ?? "";
this._internals.setFormValue(this._value ?? "");
this._dropdownRefresh();
}
/* -------------------------------------------- */
/* DropdownMixin Contract */
/* -------------------------------------------- */
/** @override */
_getDropdownOptions() {
return this.#options;
}
/** @override */
_isOptionSelected(value) {
return this._value === value;
}
/**
* Commit the picked option as the current value and close the dropdown.
* @override
*/
_onDropdownPick(option) {
this._value = option.value;
this._label = option.label;
this._dropdownInput.value = option.label;
this._internals.setFormValue(option.value);
this._dropdownInput.blur();
this.dispatchEvent(new Event("input", { bubbles: true, cancelable: true }));
this.dispatchEvent(new Event("change", { bubbles: true, cancelable: true }));
}
}

View File

@@ -0,0 +1,492 @@
/**
* @typedef {Object} DropdownMixinConfig
* @property {boolean} [multiSelect=false]
* When true the dropdown toggles selection and stays open after a pick.
* When false a pick commits the value and closes (combo-box mode).
* @property {number} [debounceMs=150]
* Trailing-debounce delay in milliseconds for dropdown re-renders while typing.
*/
/**
* DropdownMixin
*
* Adds a fully custom `<ul role="listbox">` dropdown to any AbstractFormInputElement
* subclass. Handles UI only — building, opening, closing, rendering options, and keyboard
* navigation. Has no opinion about how options are stored or how values are managed.
*
* ### Contract: three methods the host must implement
*
* - `_getDropdownOptions()`
* Return `{ value, label, group, disabled, tooltip }[]` — the full unfiltered list.
*
* - `_isOptionSelected(value)` → boolean
* Return whether a given value is currently selected.
*
* - `_onDropdownPick(option)` → void
* Called when the user picks an option. The mixin handles post-pick behaviour
* (close in single mode, re-render in multi mode) after this returns.
*
* ### Host responsibilities
* - Call `this._buildDropdownElements({ placeholder })` inside `_buildElements()`
* and include the returned wrapper in the returned array.
* - Call `this._activateDropdownListeners()` inside `_activateListeners()`.
* - Call `this._toggleDropdownDisabled(disabled)` inside `_toggleDisabled()`.
* - Call `this._dropdownRefresh()` inside `_refresh()` to keep checkmarks in sync.
*
* @param {typeof AbstractFormInputElement} Base
* @param {DropdownMixinConfig} [mixinConfig={}]
* @return {typeof Base}
*/
export function DropdownMixin(Base, mixinConfig = {}) {
const {
multiSelect = false,
debounceMs = 150,
/**
* When true, closing the dropdown clears the search input text.
* Use true for multi-select (search is transient) and false for
* combo-box (the input IS the value and must persist after close).
*/
clearOnClose = true,
} = mixinConfig;
return class DropdownMixinElement extends Base {
/* --------------------------------------------------------- */
/* Private Fields */
/* --------------------------------------------------------- */
/** @type {HTMLInputElement} */
#searchInput;
/** @type {HTMLUListElement} */
#list;
/** @type {boolean} */
#open = false;
/**
* Snapshot of #open at the moment a focus event fires.
* Lets us distinguish a fresh focus (should open) from a click
* on an already-focused input (should toggle closed).
* @type {boolean}
*/
#wasOpenOnFocus = false;
/** @type {number} */
#activeIndex = -1;
/** @type {HTMLLIElement[]} — flat list of pickable <li>s, excludes group headers */
#optionElements = [];
/** @type {Function} */
#debouncedOpen;
/**
* Per-instance key so multiple elements on the same page never share a timer.
* @type {string}
*/
#debounceId = `l5r5e-dropdown-${foundry.utils.randomID()}`;
/**
* The search input element. The host should assign this to `this._primaryInput`.
* @return {HTMLInputElement}
*/
get _dropdownInput() {
return this.#searchInput;
}
/**
* Build the search `<input>` + `<ul>` dropdown inside a positioned wrapper div.
* Include the returned element in the array returned from `_buildElements()`.
*
* @param {object} [opts]
* @param {string} [opts.placeholder=""]
* @return {HTMLDivElement}
*/
_buildDropdownElements({ placeholder = "" } = {}) {
const wrapper = document.createElement("div");
wrapper.classList.add("wrapper");
this.#searchInput = document.createElement("input");
this.#searchInput.type = "text";
this.#searchInput.classList.add("input");
this.#searchInput.setAttribute("autocomplete", "off");
this.#searchInput.setAttribute("role", "combobox");
this.#searchInput.setAttribute("aria-autocomplete", "list");
this.#searchInput.setAttribute("aria-expanded", "false");
this.#searchInput.setAttribute("aria-haspopup", "listbox");
if (placeholder) {
this.#searchInput.setAttribute("placeholder", placeholder);
}
this.#list = document.createElement("ul");
this.#list.classList.add("dropdown");
this.#list.setAttribute("role", "listbox");
if (multiSelect) {
this.#list.setAttribute("aria-multiselectable", "true");
}
this.#list.hidden = true;
this.#syncOffset();
wrapper.append(this.#searchInput, this.#list);
return wrapper;
}
/** Attach dropdown event listeners. Call inside `_activateListeners()`. */
_activateDropdownListeners() {
const signal = this.abortSignal;
this.#debouncedOpen = game.l5r5e.HelpersL5r5e.debounce(
this.#debounceId,
(query) => this.#openDropdown(query),
debounceMs,
false // trailing — fires after the user pauses
);
this.#searchInput.addEventListener("mousedown", this.#onMouseDown.bind(this), { signal });
this.#searchInput.addEventListener("focus", this.#onFocus.bind(this), { signal });
this.#searchInput.addEventListener("input", this.#onInput.bind(this), { signal });
this.#searchInput.addEventListener("keydown", this.#onKeydown.bind(this), { signal });
this.#searchInput.addEventListener("blur", this.#onBlur.bind(this), { signal });
}
/**
* Enable or disable the search input. Call inside `_toggleDisabled()`.
* @param {boolean} disabled
*/
_toggleDropdownDisabled(disabled) {
if (this.#searchInput) {
this.#searchInput.disabled = disabled;
}
}
/* --------------------------------------------------------- */
/* Refresh */
/* --------------------------------------------------------- */
/**
* Re-render the open dropdown in place so checkmarks and disabled states
* stay in sync with the current value. Call inside `_refresh()`.
*/
_dropdownRefresh() {
if (this.#open) {
this.#renderOptions(this.#filter(this.#searchInput?.value ?? ""));
}
}
/**
* @abstract
* @return {{ value: string, label: string, group: string|null, disabled?: boolean, tooltip?: string }[]}
*/
_getDropdownOptions() {
throw new Error(`${this.constructor.name} must implement _getDropdownOptions()`);
}
/**
* @abstract
* @param {string} value
* @return {boolean}
*/
_isOptionSelected(value) {
throw new Error(`${this.constructor.name} must implement _isOptionSelected()`);
}
/**
* @abstract
* @param {{ value: string, label: string }} option
*/
_onDropdownPick(option) {
throw new Error(`${this.constructor.name} must implement _onDropdownPick()`);
}
/**
* Case-insensitive label filter over `_getDropdownOptions()`.
* Returns all options when query is empty.
* @param {string} query
* @return {object[]}
*/
#filter(query) {
const all = this._getDropdownOptions();
if (!query) {
return all;
}
const lower = query.toLowerCase();
return all.filter(option => option.label.toLowerCase().includes(lower));
}
#openDropdown(query = "") {
this.#renderOptions(this.#filter(query));
this.#list.hidden = false;
this.#searchInput.setAttribute("aria-expanded", "true");
this.#open = true;
this.#activeIndex = -1;
this._onDropdownOpened();
}
/**
* Called when the dropdown opens. Override in host classes to snapshot
* the current value so _onDropdownClosed can compare against it.
* Default is a no-op.
* @protected
*/
_onDropdownOpened() {}
#closeDropdown() {
this.#list.hidden = true;
this.#searchInput.setAttribute("aria-expanded", "false");
this.#open = false;
this.#wasOpenOnFocus = false;
this.#activeIndex = -1;
this.#optionElements = [];
// In combo-box mode the input IS the value, so we leave it intact.
// In multi-select mode the search text is transient and should reset.
if (clearOnClose && this.#searchInput) {
this.#searchInput.value = "";
}
// Notify the host that the dropdown has closed. Hosts can override this
// to fire a single change event after a multi-pick session.
this._onDropdownClosed();
}
/**
* Called when the dropdown closes. Override in host classes to fire a
* consolidated change event after a multi-pick session.
* Default is a no-op.
* @protected
*/
_onDropdownClosed() {}
#renderOptions(options) {
this.#list.innerHTML = "";
this.#optionElements = [];
// hideDisabledOptions is a host-level attribute, read via the DOM.
const visible = this.hasAttribute("hidedisabledoptions")
? options.filter(o => !o.disabled)
: options;
if (!visible.length) {
const empty = document.createElement("li");
empty.classList.add("no-results");
empty.textContent = game.i18n.localize("l5r5e.multiselect.no_results") ?? "No matches";
empty.setAttribute("aria-disabled", "true");
this.#list.append(empty);
return;
}
// Bucket into groups, preserving insertion order.
const groups = new Map();
const ungrouped = [];
for (const option of visible) {
if (option.group) {
if (!groups.has(option.group)) groups.set(option.group, []);
groups.get(option.group).push(option);
} else {
ungrouped.push(option);
}
}
for (const [label, options] of groups) {
const header = document.createElement("li");
header.classList.add("group");
header.setAttribute("role", "presentation");
header.textContent = label;
this.#list.append(header);
for (const option of options) {
this.#list.append(this.#buildOptionEl(option));
}
}
for (const option of ungrouped){
this.#list.append(this.#buildOptionEl(option));
}
}
#buildOptionEl(option) {
const selected = this._isOptionSelected(option.value);
const disabled = !!option.disabled;
const li = document.createElement("li");
li.classList.add("option");
if (selected) {
li.classList.add("selected");
}
if (disabled) {
li.classList.add("disabled");
}
li.setAttribute("role", "option");
li.setAttribute("aria-selected", String(selected));
li.setAttribute("aria-disabled", String(disabled));
li.dataset.value = option.value;
if (multiSelect) {
const check = document.createElement("span");
check.classList.add("checkmark");
check.setAttribute("aria-hidden", "true");
li.append(check);
}
const labelEl = document.createElement("span");
labelEl.classList.add("label");
labelEl.textContent = option.label;
li.append(labelEl);
if (selected && multiSelect) {
li.title = game.i18n.localize("l5r5e.multiselect.already_in_filter");
} else if (disabled && option.tooltip) {
li.title = option.tooltip;
}
if (!disabled) {
li.addEventListener("mouseenter", () => {
for (const element of this.#optionElements) {
element.classList.remove("active");
}
this.#activeIndex = this.#optionElements.indexOf(li);
li.classList.add("active");
});
li.addEventListener("mouseleave", () => {
li.classList.remove("active");
this.#activeIndex = -1;
});
li.addEventListener("mousedown", (event) => {
event.preventDefault(); // keep focus on the search input
this.#pick(option);
});
}
this.#optionElements.push(li);
return li;
}
#pick(option) {
this._onDropdownPick(option);
if (multiSelect) {
// Stay open — re-render so checkmarks reflect the new state.
this.#renderOptions(this.#filter(this.#searchInput.value));
} else {
this.#closeDropdown();
}
}
#moveHighlight(direction) {
if (!this.#optionElements.length) {
return;
}
const prev = this.#optionElements[this.#activeIndex];
if (prev) {
prev.classList.remove("active");
}
this.#activeIndex = Math.max(
-1,
Math.min(this.#optionElements.length - 1, this.#activeIndex + direction)
);
const next = this.#optionElements[this.#activeIndex];
if (next) {
next.classList.add("active");
next.scrollIntoView({ block: "nearest" });
}
}
#syncOffset() {
if (!this.#searchInput || !this.#list) {
return;
}
const offset = this.#searchInput.offsetLeft;
this.#list.style.left = `${offset}px`;
this.#list.style.right = `-${offset}px`;
}
/**
* Handles click-to-toggle behaviour.
*
* Three cases:
* 1. Dropdown is open → close it. preventDefault stops blur firing, which
* would otherwise trigger a second close via #onBlur.
* 2. Dropdown is closed AND input is already focused → open immediately.
* In this case focus will NOT fire again (input never blurred after the
* previous preventDefault), so we must open here rather than in #onFocus.
* 3. Dropdown is closed AND input is not yet focused → do nothing; the
* browser will fire focus naturally and #onFocus will open the dropdown.
*/
#onMouseDown(event) {
this.#wasOpenOnFocus = this.#open;
if (this.#open) {
event.preventDefault();
this.#closeDropdown();
} else if (document.activeElement === this.#searchInput) {
// Case 2: already focused, focus won't re-fire — open directly.
this.#openDropdown(this.#searchInput.value);
}
}
#onFocus(event) {
// Only open if mousedown didn't already handle it (cases 1 & 2 above).
if (!this.#wasOpenOnFocus && document.activeElement === this.#searchInput) {
this.#openDropdown(this.#searchInput.value);
}
}
#onInput(event) {
this.#debouncedOpen(this.#searchInput.value);
}
/**
* Close the dropdown when focus genuinely leaves the component.
*
* event.relatedTarget is the element that is RECEIVING focus. If it is
* inside our host element (e.g. the clear button, a chip remove span that
* managed to steal focus) we leave the dropdown open. Only when focus moves
* completely outside do we close — and we do so synchronously, so that
* _onDropdownClosed fires its change event BEFORE the browser hands control
* to whatever the user clicked. This eliminates the 100 ms race where Foundry
* could read stale FormData between the blur and a deferred close.
*/
#onBlur(event) {
if (this.contains(event.relatedTarget)) {
return;
}
this.#closeDropdown();
}
#onKeydown(event) {
if (!this.#open) {
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
event.preventDefault();
this.#openDropdown(this.#searchInput.value);
}
return;
}
switch (event.key) {
case "ArrowDown": {
event.preventDefault();
this.#moveHighlight(1);
} break;
case "ArrowUp": {
event.preventDefault();
this.#moveHighlight(-1);
}break;
case "Enter": {
event.preventDefault();
if (this.#activeIndex >= 0) {
const li = this.#optionElements[this.#activeIndex];
const option = this._getDropdownOptions().find(option => option.value === li.dataset.value);
if (option) {
this.#pick(option);
}
} else {
this.#closeDropdown();
}
} break;
case "Escape": {
event.preventDefault();
this.#closeDropdown();
} break;
case "Tab": {
this.#closeDropdown();
} break;
}
}
};
}

View File

@@ -1,301 +1,424 @@
import { DropdownMixin } from "./l5r5e-dropdown-mixin.js";
const { AbstractMultiSelectElement } = foundry.applications.elements; const { AbstractMultiSelectElement } = foundry.applications.elements;
/** /**
* Provide a multi-select workflow using a select element as the input mechanism. * A custom `<l5r5e-multi-select>` form element providing Select2-style chip multi-selection.
* It is a expanded copy of the HTMLMultiselect with support for disabling options
* and a clear all button. Also have support for hover-over information using titlea
* *
* @example Multi-Select HTML Markup * Stores **multiple string values** from a fixed option list, shown as removable chips inside
* ```html * the input box. A live-search input filters the dropdown as the user types. Use this when a
* <l5r5e-multi-select name="select-many-things"> * field holds an unordered collection of values (e.g. a set of skills, tags, or abilities).
* <optgroup label="Basic Options"> * For storing a single value — predefined or free-text — use {@link L5R5eHtmlComboBoxElement} instead.
* <option value="foo">Foo</option> *
* <option value="bar">Bar</option> * The element's `value` getter returns a comma-separated string (e.g. `"fire,water"`),
* <option value="baz">Baz</option> * which is what `FormData` will read on submission. `_getValue()` returns a plain Array,
* </optgroup> * which is what `FormDataExtended` will use.
* <optgroup label="Advanced Options"> *
* <option value="fizz">Fizz</option> * Pre-selection on render is handled via the `value` attribute on the element — NOT via
* <option value="buzz">Buzz</option> * `{{selectOptions selected=...}}`, which cannot handle comma-separated strings. Use
* </optgroup> * `{{selectOptions}}` without `selected` purely to render the available options, and let
* the `value` attribute drive pre-selection. Since `getAttribute()` always returns a string,
* passing a `Set` or `Array` via Handlebars will not work correctly — always pass a
* comma-separated string to `value=`.
*
* Prefer {@link L5r5eSetField} + `{{formGroup}}` when wiring this into a DataModel — the
* field handles the full round-trip automatically.
*
* @example
* ```hbs
* {{!-- Use value= (comma-separated string) for pre-selection, not selectOptions selected= --}}
* <l5r5e-multi-select name="elements" value="{{data.elements}}">
* {{selectOptions choices localize=true}}
* </l5r5e-multi-select> * </l5r5e-multi-select>
* ``` * ```
*
* @example
* // Static factory — use only when building outside of Foundry's field/template system:
* const el = L5r5eHtmlMultiSelectElement.create({
* name: "elements",
* options: [{ value: "fire", label: "Fire" }, { value: "water", label: "Water" }],
* value: "fire,water", // comma-separated pre-selection
* });
* form.appendChild(el);
*
* // Reading the value back:
* el.value; // "fire,water" — comma-separated string, compatible with FormData
* el._getValue(); // ["fire","water"] — array, compatible with FormDataExtended
*/ */
export class L5r5eHtmlMultiSelectElement extends AbstractMultiSelectElement { export class L5r5eHtmlMultiSelectElement extends DropdownMixin(
AbstractMultiSelectElement,
constructor() { { multiSelect: true, debounceMs: 150 }
super(); ) {
this.#setup();
}
/** @override */ /** @override */
static tagName = "l5r5e-multi-select"; static tagName = "l5r5e-multi-select";
/** /** @type {HTMLDivElement} — outer box containing chips, input, clear button */
* A select element used to choose options. #selectionBox;
* @type {HTMLSelectElement}
*/ /** @type {HTMLDivElement} — chips are injected here */
#select; #chipList;
/** @type {HTMLSpanElement} — auto-sizing wrapper around the search input */
#inputSizer;
/** @type {HTMLButtonElement} — trailing clear-all button */
#clearButton;
/** @type {Set<string>} */
#disabledValues = new Set();
/** @type {Map<string, string>} */
#tooltips = new Map();
/** /**
* A display element which lists the chosen options. * Returns a comma-separated string
* @type {HTMLDivElement} * FormData reads this via field.value.
* @override
*/ */
#tags; get value() {
return Array.from(this._value).join(",");
}
/** @override */
set value(val) {
this._value.clear();
const values = Array.isArray(val) ? val : String(val).split(",").filter(Boolean);
for (const v of values) {
this._value.add(v);
}
this._internals.setFormValue(this.value);
this._refresh();
}
/** /**
* A button element which clear all the options. * Return an array so FormDataExtended.object[name] matches Foundry's own
* @type {HTMLButtonElement} * HTMLMultiSelectElement — both field.value (string) and .object (array) are correct.
* @override
* @protected
*/ */
#clearAll; _getValue() {
return Array.from(this._value);
}
/** /**
* A Set containing the values that should always be disabled. * Accept either an array or comma-separated string when Foundry calls _setValue().
* @type {Set} * @override
* @protected
*/ */
#disabledValues; _setValue(val) {
const values = Array.isArray(val) ? val : String(val).split(",").filter(Boolean);
if (values.some(v => v && !(v in this._choices))) {
throw new Error("The values assigned to a multi-select element must all be valid options.");
}
this._value.clear();
for (const v of values) {
this._value.add(v);
}
}
/** @override */
_initialize() {
super._initialize(); // fills this._choices, this._value, this._options
for (const option of this.querySelectorAll("option")) {
if (option.disabled)
this.#disabledValues.add(option.value);
if (option.title)
this.#tooltips.set(option.value, option.title);
}
if (this.hasAttribute("value")) {
this._setValue(this.getAttribute("value"));
}
}
/* -------------------------------------------- */ /* -------------------------------------------- */
/* Element Lifecycle */
// We will call initialize twice (one in the parent constructor) then one in #setup /* -------------------------------------------- */
// required since when we want to build the elements we should to an initialize first
// and we cannot override _initialize since we don't have access to #disabledValues there
#setup() {
super._initialize();
this.#disabledValues = new Set();
for (const option of this.querySelectorAll("option")) {
if (option.value === "") {
option.label = game.i18n.localize("l5r5e.multiselect.empty_tag");
this._choices[option.value] = game.i18n.localize("l5r5e.multiselect.empty_tag");
}
if (option.disabled) {
this.#disabledValues.add(option.value);
}
}
}
/** @override */ /** @override */
_buildElements() { _buildElements() {
this.#setup(); // Ask mixin to build <input> + <ul>, then re-home them into our structure.
const mixinWrapper = this._buildDropdownElements({
// Create select element placeholder: this.getAttribute("placeholder")
this.#select = this._primaryInput = document.createElement("select"); ?? game.i18n.localize("l5r5e.multiselect.placeholder"),
this.#select.insertAdjacentHTML("afterbegin", `<option id="l5r5e-multiselect-placeholder" value="" disabled selected hidden>${game.i18n.localize("l5r5e.multiselect.placeholder")}</option>`);
this.#select.append(...this._options);
this.#select.disabled = !this.editable;
// Create a div element for display
this.#tags = document.createElement("div");
this.#tags.className = "tags input-element-tags";
// Create a clear all button
this.#clearAll = document.createElement("button");
this.#clearAll.textContent = "X";
return [this.#select, this.#clearAll, this.#tags];
}
/* -------------------------------------------- */
/** @override */
_refresh() {
// Update the displayed tags
const tags = Array.from(this._value).map(id => {
return foundry.applications.elements.HTMLStringTagsElement.renderTag(id, this._choices[id], this.editable);
}); });
this.#tags.replaceChildren(...tags); const searchInput = mixinWrapper.querySelector("input.input");
const dropdownList = mixinWrapper.querySelector("ul.dropdown");
// Figure out if we are overflowing the tag div. // Selection box
if($(this.#tags).css("max-height")) { this.#selectionBox = document.createElement("div");
const numericMaxHeight = parseInt($(this.#tags).css("max-height"), 10); this.#selectionBox.classList.add("selection-box");
if(numericMaxHeight) {
if($(this.#tags).prop("scrollHeight") > numericMaxHeight) {
this.#tags.classList.add("overflowing");
}
else {
this.#tags.classList.remove("overflowing");
}
}
}
// Disable selected options // Chip list
const hideDisabled = game.settings.get(CONFIG.l5r5e.namespace, "compendium-hide-disabled-sources"); this.#chipList = document.createElement("div");
for (const option of this.#select) { this.#chipList.classList.add("chip-list");
if (this._value.has(option.value)) {
option.disabled = true;
option.title = game.i18n.localize("l5r5e.multiselect.already_in_filter");
continue;
}
if (this.#disabledValues.has(option.value)) {
option.disabled = true;
option.hidden = hideDisabled;
continue;
}
option.disabled = false;
option.removeAttribute("title");
}
}
/* -------------------------------------------- */ // Auto-sizing sizer — CSS grid trick: ::after mirrors data-value, input shares the cell
this.#inputSizer = document.createElement("span");
this.#inputSizer.classList.add("input-sizer");
this.#inputSizer.dataset.value = "";
this.#inputSizer.append(searchInput);
// Clear-all button
this.#clearButton = document.createElement("button");
this.#clearButton.type = "button";
this.#clearButton.classList.add("clear-btn");
this.#clearButton.setAttribute("aria-label",
game.i18n.localize("l5r5e.multiselect.clear_all") ?? "Clear all");
this.#clearButton.textContent = "×";
this.#clearButton.hidden = true;
this.#selectionBox.append(this.#chipList, this.#inputSizer, this.#clearButton);
// Container: selection box + dropdown must share the same positioned ancestor.
const container = document.createElement("div");
container.classList.add("multi-select-container");
container.append(this.#selectionBox, dropdownList);
this._primaryInput = searchInput;
return [container];
}
/** @override */ /** @override */
_activateListeners() { _activateListeners() {
this.#select.addEventListener("change", this.#onChangeSelect.bind(this)); this._activateDropdownListeners();
this.#clearAll.addEventListener("click", this.#onClickClearAll.bind(this)); const signal = this.abortSignal;
this.#tags.addEventListener("click", this.#onClickTag.bind(this));
this.#tags.addEventListener("mouseleave", this.#onMouseLeave.bind(this)); this.#selectionBox.addEventListener("mousedown", this.#onBoxMouseDown.bind(this), { signal });
this.#chipList.addEventListener("click", this.#onChipClick.bind(this), { signal });
this.#clearButton.addEventListener("click", this.#onClearAll.bind(this), { signal });
// stop the clear button from opening the selection box when pressing it
this.#clearButton.addEventListener("mousedown", (event) => {event.preventDefault(); event.stopPropagation();}, {signal});
this._dropdownInput.addEventListener("input", () => this.#updateInputSizer(), { signal });
} }
#onMouseLeave(event) {
// Figure out if we are overflowing the tag div.
if($(this.#tags).css("max-height")) {
const numericMaxHeight = parseInt($(this.#tags).css("max-height"), 10);
if($(this.#tags).prop("scrollHeight") > numericMaxHeight) {
this.#tags.classList.add("overflowing");
}
else {
this.#tags.classList.remove("overflowing");
}
}
}
/* -------------------------------------------- */
/**
* Handle changes to the Select input, marking the selected option as a chosen value.
* @param {Event} event The change event on the select element
*/
#onChangeSelect(event) {
event.preventDefault();
event.stopImmediatePropagation();
const select = event.currentTarget;
if (select.valueIndex === 0)
return; // Ignore placeholder
this.select(select.value);
select.value = "";
}
/* -------------------------------------------- */
/**
* Handle click events on a tagged value, removing it from the chosen set.
* @param {PointerEvent} event The originating click event on a chosen tag
*/
#onClickTag(event) {
event.preventDefault();
if (!event.target.classList.contains("remove"))
return;
if (!this.editable)
return;
const tag = event.target.closest(".tag");
this.unselect(tag.dataset.key);
}
/* -------------------------------------------- */
/**
* Handle clickling the clear all button
* @param {Event} event The originating click event on the clear all button
*/
#onClickClearAll(event) {
event.preventDefault();
var _this = this;
$(this.#tags).children().each(function () {
_this.unselect($(this).data("key"));
})
}
/* -------------------------------------------- */
/** @override */ /** @override */
_toggleDisabled(disabled) { _toggleDisabled(disabled) {
this.#select.toggleAttribute("disabled", disabled); this._toggleDropdownDisabled(disabled);
if (this.#selectionBox) {
this.#selectionBox.classList.toggle("disabled", disabled);
}
if (this.#chipList) {
this._refresh(); // re-render chips so × appears/disappears
}
}
/** @override */
_refresh() {
const values = Array.from(this._value);
this._internals.setFormValue(values.length ? values.join(",") : "");
this.#renderChips(values);
// Clear button: only visible when editable and something is selected.
if (this.#clearButton) {
this.#clearButton.hidden = (!this.editable || values.length === 0);
}
this.#updateInputSizer();
this._dropdownRefresh();
}
/** @param {string[]} values */
#renderChips(values) {
if (!this.#chipList){
return
}
this.#chipList.replaceChildren(...values.map(id => this.#buildChip(id)));
}
/** @param {string} id */
#buildChip(id) {
const chip = document.createElement("span");
chip.classList.add("chip");
chip.dataset.key = id;
const label = document.createElement("span");
label.classList.add("chip-label");
label.textContent = this._choices[id] ?? id;
chip.append(label);
// Only add × when the element is editable (not disabled, not readonly).
if (this.editable) {
const remove = document.createElement("span");
remove.classList.add("chip-remove");
remove.setAttribute("aria-label", `Remove ${this._choices[id] ?? id}`);
remove.setAttribute("aria-hidden", "true");
remove.textContent = "×";
chip.append(remove);
}
return chip;
}
/** Mirror typed text into the sizer span so CSS sizes the input correctly. */
#updateInputSizer() {
if (!this.#inputSizer || !this._dropdownInput)
return;
const input = this._dropdownInput;
const text = input.value || input.placeholder || "";
this.#inputSizer.dataset.value = text;
}
/** @override */
_getDropdownOptions() {
const makeOption = (option, group = null) => ({
value: option.value,
label: this._choices[option.value] ?? option.innerText,
group,
disabled: this.#disabledValues.has(option.value),
tooltip: this.#tooltips.get(option.value) ?? "",
});
return this._options.flatMap(child => {
if (child instanceof HTMLOptGroupElement) {
return [...child.querySelectorAll("option")]
.filter(option => option.value)
.map(option => makeOption(option, child.label));
}
if (child instanceof HTMLOptionElement && child.value) {
return makeOption(child);
}
return [];
});
}
/** @override */
_isOptionSelected(value) {
return this._value.has(value);
}
/** @override */
_onDropdownPick(option) {
const inValue = this._value.has(option.value);
const inChoices = option.value in this._choices;
if(!(inValue || inChoices))
return;
if (inValue) {
this._value.delete(option.value);
}
else if(inChoices) {
this._value.add(option.value);
}
this._internals.setFormValue(this.value);
this._refresh();
this.dispatchEvent(new Event("change", { bubbles: true, cancelable: true }));
}
#onBoxMouseDown(event) {
// Fully block interaction when not editable.
if (!this.editable) {
event.preventDefault();
return;
}
if (event.target.classList.contains("chip-remove"))
return;
if (event.target === this._dropdownInput)
return;
event.preventDefault();
this._dropdownInput?.focus();
}
#onChipClick(event) {
if (!event.target.classList.contains("chip-remove") || !this.editable)
return;
const chip = event.target.closest(".chip");
if (!chip)
return;
this._value.delete(chip.dataset.key);
this._internals.setFormValue(this.value);
this._refresh();
this.dispatchEvent(new Event("change", { bubbles: true, cancelable: true }));
this._dropdownInput?.focus();
}
#onClearAll(event) {
event.preventDefault();
if (!this.editable)
return;
this._value.clear();
this._internals.setFormValue("");
this._refresh();
this.dispatchEvent(new Event("change", { bubbles: true, cancelable: true }));
} }
/* -------------------------------------------- */
/* Static Factory */
/* -------------------------------------------- */ /* -------------------------------------------- */
/**
* Create a HTML_l5r5e_MultiSelectElement using provided configuration data.
* @param {FormInputConfig<string[]> & Omit<SelectInputConfig, "blank">} config
* @returns {L5r5eHtmlMultiSelectElement}
*/
static create(config) { static create(config) {
// Foundry creates either a select with tag multi-select or multi-checkboxes. We want a l5r5e-multi-select
// Copied the implementation from foundry.applications.fields.createMultiSelectInput with our required changes.
const groups = prepareSelectOptionGroups(config); const groups = prepareSelectOptionGroups(config);
const element = document.createElement(L5r5eHtmlMultiSelectElement.tagName);
element.name = config.name;
foundry.applications.fields.setInputAttributes(element, config);
if (config.hideDisabledOptions) {
element.toggleAttribute("hidedisabledoptions", true);
}
//Setup the HTML for (const groupEntry of groups) {
const select = document.createElement(L5r5eHtmlMultiSelectElement.tagName); let parent = element;
select.name = config.name; if (groupEntry.group) {
foundry.applications.fields.setInputAttributes(select, config); parent = _appendOptgroup(groupEntry.group, element);
for (const group_entry of groups) {
let parent = select;
if (group_entry.group) {
parent = _appendOptgroupHtml(group_entry.group, select);
} }
for (const option_entry of group_entry.options) { for (const groupOption of groupEntry.options){
_appendOptionHtml(option_entry, parent); _appendOption(groupOption, parent);
} }
} }
return select; return element;
} }
} }
/** Stolen from foundry.applications.fields.prepareSelectOptionGroups: Needed to add support for tooltips /* -------------------------------------------- */
* /* Module Helpers */
*/ /* -------------------------------------------- */
function prepareSelectOptionGroups(config) { function prepareSelectOptionGroups(config) {
const result = foundry.applications.fields.prepareSelectOptionGroups(config); const result = foundry.applications.fields.prepareSelectOptionGroups(config);
config.options.filter(option => option?.disabled || option?.tooltip).forEach(special => {
// Disable options based on input result.forEach(group => {
config.options.filter((option) => option?.disabled || option?.tooltip).forEach((SpecialOption) => { group.options.forEach(groupOption => {
result.forEach((group) => { if (groupOption.value === special.value) {
group.options.forEach((option) => { groupOption.disabled = special.disabled;
if (SpecialOption.value === option.value) { groupOption.tooltip = special.tooltip;
option.disabled = SpecialOption.disabled;
option.tooltip = SpecialOption?.tooltip;
} }
}) });
}) });
}) });
return result; return result;
} }
/** Stolen from foundry.applications.fields function _appendOptgroup(label, parent) {
* Create and append an optgroup element to a parent select. const element = document.createElement("optgroup");
* @param {string} label element.label = label;
* @param {HTMLSelectElement} parent parent.appendChild(element);
* @returns {HTMLOptGroupElement}
* @internal return element;
*/
function _appendOptgroupHtml(label, parent) {
const optgroup = document.createElement("optgroup");
optgroup.label = label;
parent.appendChild(optgroup);
return optgroup;
} }
/** Stolen from foundry.applications.fields function _appendOption(option, parent) {
* Create and append an option element to a parent select or optgroup.
* @param {FormSelectOption} option
* @param {HTMLSelectElement|HTMLOptGroupElement} parent
* @internal
*/
function _appendOptionHtml(option, parent) {
const { value, label, selected, disabled, rule, tooltip } = option; const { value, label, selected, disabled, rule, tooltip } = option;
if ((value !== undefined) && (label !== undefined)) { if (value !== undefined && label !== undefined) {
const option_html = document.createElement("option"); const element = document.createElement("option");
option_html.value = value; element.value = value;
option_html.innerText = label; element.innerText = label;
if (selected) { if (selected) {
option_html.toggleAttribute("selected", true); element.toggleAttribute("selected", true);
} }
if (disabled) { if (disabled) {
option_html.toggleAttribute("disabled", true); element.toggleAttribute("disabled", true);
} }
if (tooltip) { if (tooltip) {
option_html.setAttribute("title", tooltip); element.setAttribute("title", tooltip);
} }
parent.appendChild(option_html); parent.appendChild(element);
} }
if (rule) { if (rule) {
parent.insertAdjacentHTML("beforeend", "<hr>"); parent.insertAdjacentHTML("beforeend", "<hr>");

View File

@@ -1,16 +1,19 @@
export const PreloadTemplates = async function () { export const PreloadTemplates = async function () {
const tpl = CONFIG.l5r5e.paths.templates; const tpl = CONFIG.l5r5e.paths.templates;
return foundry.applications.handlebars.loadTemplates([ return foundry.applications.handlebars.loadTemplates([
// Add paths to "systems/l5r5e/templates" // Add paths to "systems/l5rx-chiaroscuro/templates"
// *** Actors : PC *** // *** Actors : PC ***
`${tpl}actors/character/advancement-school.html`, `${tpl}actors/character/advancement-school.html`,
`${tpl}actors/character/advancement-others.html`, `${tpl}actors/character/advancement-others.html`,
`${tpl}actors/character/aspects.html`,
`${tpl}actors/character/attributes.html`, `${tpl}actors/character/attributes.html`,
`${tpl}actors/character/category.html`, `${tpl}actors/character/category.html`,
`${tpl}actors/character/conflict.html`, `${tpl}actors/character/conflict.html`,
`${tpl}actors/character/experience.html`, `${tpl}actors/character/experience.html`,
`${tpl}actors/character/identity.html`, `${tpl}actors/character/identity.html`,
`${tpl}actors/character/identity-text.html`,
`${tpl}actors/character/inventory.html`, `${tpl}actors/character/inventory.html`,
`${tpl}actors/character/invocations.html`,
`${tpl}actors/character/narrative.html`, `${tpl}actors/character/narrative.html`,
`${tpl}actors/character/rings.html`, `${tpl}actors/character/rings.html`,
`${tpl}actors/character/effects.html`, `${tpl}actors/character/effects.html`,
@@ -74,5 +77,6 @@ export const PreloadTemplates = async function () {
`${tpl}items/weapon/weapon-sheet.html`, `${tpl}items/weapon/weapon-sheet.html`,
`${tpl}items/army-cohort/army-cohort-entry.html`, `${tpl}items/army-cohort/army-cohort-entry.html`,
`${tpl}items/army-fortification/army-fortification-entry.html`, `${tpl}items/army-fortification/army-fortification-entry.html`,
`${tpl}dice/chiaroscuro-chat-roll.html`,
]); ]);
}; };

View File

@@ -1,4 +1,5 @@
import { L5r5eSetField } from "./data/l5r5e-setfield.js"; import { L5r5eSetField } from "./data/l5r5e-setfield.js";
import { TacticalGridSettingsL5R5E } from "./settings/tactical-grid-settings.js"
/** /**
* Custom system settings register * Custom system settings register
@@ -236,4 +237,28 @@ export const RegisterSettings = function () {
default: [], default: [],
onChange: () => game.l5r5e.HelpersL5r5e.refreshLocalAndSocket("l5r5e-gm-monitor"), onChange: () => game.l5r5e.HelpersL5r5e.refreshLocalAndSocket("l5r5e-gm-monitor"),
}); });
/* -------------------------------------- */
/* Grid Settings (GM only) */
/* -------------------------------------- */
// UI Configuration
game.settings.register(CONFIG.l5r5e.namespace, "tactical-grid-settings-world", {
scope: "world",
config: false,
type: TacticalGridSettingsL5R5E.worldSchema,
});
game.settings.register(CONFIG.l5r5e.namespace, "tactical-grid-settings-client", {
scope: "client",
config: false,
type: TacticalGridSettingsL5R5E.clientSchema,
});
game.settings.registerMenu(CONFIG.l5r5e.namespace, "tactical-grid-settings", {
name: "l5r5e.tactical_grid.settings.title",
label: "l5r5e.tactical_grid.settings.label",
hint: "l5r5e.tactical_grid.settings.hint",
icon: "fa-solid fa-table-layout",
type: TacticalGridSettingsL5R5E
});
}; };

View File

@@ -0,0 +1,351 @@
const HandlebarsApplicationMixin = foundry.applications.api.HandlebarsApplicationMixin;
const ApplicationV2 = foundry.applications.api.ApplicationV2;
const fields = foundry.data.fields;
/**
*
* @typedef {Object} RangeBand
* @property {number} start
*
* @typedef {Object} ClientRangeBand
* @property {string} color
* @property {number} alpha
*
* @typedef {Object} WorldSettings
* @property {boolean} enabled
* @property {Record<number, RangeBand>} ranges - Indexed 0-6
*
* @typedef {Object} ClientSettings
* @property {Record<number, ClientRangeBand>} ranges - Indexed 0-6
*/
export class TacticalGridSettingsL5R5E extends HandlebarsApplicationMixin(ApplicationV2) {
/** @inheritDoc */
static DEFAULT_OPTIONS = {
id: "tactical-grid-settings",
tag: "form",
classes: [""], // We could add l5r here but that would add styling that is not matching the default settings menu
window: {
title: "l5r5e.tactical_grid.settings.title",
contentClasses: ["standard-form"]
},
form: {
closeOnSubmit: true,
handler: TacticalGridSettingsL5R5E.#onSubmit
},
position: { width: 540 },
actions: {
reset: TacticalGridSettingsL5R5E.#onReset
}
};
/** @override */
static PARTS = {
form: {
template: "systems/l5rx-chiaroscuro/templates/" + "settings/tactical-grid-settings.html",
scrollable: [""],
},
footer: {
template: "templates/generic/form-footer.hbs"
}
};
/**
* Creates a SchemaField defining a world range band.
* @param {{start: number}} initial - Initial range values.
* `start` must be ≥ 0.
* * @returns {SchemaField} A schema field containing a 'start' field
*
* @private
*/
static #createWorldRangeBandSchema(initial) {
return new fields.SchemaField({
start: new fields.NumberField({ initial: initial.start, label: "l5r5e.tactical_grid.settings.world.start", min: 0, max:Infinity, nullable: false, required: true, gmOnly: true})
});
}
/**
* Creates a SchemaField defining a client range band.
* @param {{color: string, alpha: number}} initial - Initial range band values.
* `color` should be a valid CSS color string and `alpha` a valid alpha value.
* @returns {SchemaField} A schema field containing `color` and `alpha` fields.
*
* @private
*/
static #createClientRangeBandSchema(initial) {
return new fields.SchemaField({
color: new fields.ColorField({initial: initial.color, label: "l5r5e.tactical_grid.settings.client.color", required: true}),
alpha: new fields.AlphaField({initial: initial.alpha, label: "l5r5e.tactical_grid.settings.client.alpha", required: true}),
});
}
/**
* Combined Foundry VTT settings schema representing both:
* - **World (GM-controlled)** configuration
* - **Client (per-user)** visual configuration
*
* This variable serves as a single source-of-truth definition for the modules
* tactical grid settings structure, including field types, defaults, labels, and
* validation rules for world ranges.
* @private
*/
static #schema = {
world: new fields.SchemaField({
enabled: new fields.BooleanField({ initial: true, label: "l5r5e.tactical_grid.settings.world.enabled", hint: "l5r5e.tactical_grid.settings.world.enabled_hint"}),
ranges: new fields.SchemaField({
0: TacticalGridSettingsL5R5E.#createWorldRangeBandSchema({ start: 0}),
1: TacticalGridSettingsL5R5E.#createWorldRangeBandSchema({ start: 1}),
2: TacticalGridSettingsL5R5E.#createWorldRangeBandSchema({ start: 2}),
3: TacticalGridSettingsL5R5E.#createWorldRangeBandSchema({ start: 3}),
4: TacticalGridSettingsL5R5E.#createWorldRangeBandSchema({ start: 6}),
5: TacticalGridSettingsL5R5E.#createWorldRangeBandSchema({ start: 10}),
6: TacticalGridSettingsL5R5E.#createWorldRangeBandSchema({ start: 15})
})
}, {
validate: TacticalGridSettingsL5R5E.#validateWorldRangeConfiguration
}),
client: new fields.SchemaField({
ranges: new fields.SchemaField({
0: TacticalGridSettingsL5R5E.#createClientRangeBandSchema({color: "#00FFFF", alpha: 0.5}),
1: TacticalGridSettingsL5R5E.#createClientRangeBandSchema({color: "#FF00FF", alpha: 0.5}),
2: TacticalGridSettingsL5R5E.#createClientRangeBandSchema({color: "#FFFF00", alpha: 0.5}),
3: TacticalGridSettingsL5R5E.#createClientRangeBandSchema({color: "#0000FF", alpha: 0.5}),
4: TacticalGridSettingsL5R5E.#createClientRangeBandSchema({color: "#7FFF00", alpha: 0.5}),
5: TacticalGridSettingsL5R5E.#createClientRangeBandSchema({color: "#4B0082", alpha: 0.5}),
6: TacticalGridSettingsL5R5E.#createClientRangeBandSchema({color: "#FF8800", alpha: 0.5})
})
})
};
/**
* Exposes the **world (GM-controlled)** portion of the tactical grid settings schema.
* @return {SchemaField}
*/
static get worldSchema() {
return TacticalGridSettingsL5R5E.#schema.world;
}
/**
* Exposes the **client (per-user visual)** portion of the tactical grid settings schema.
* @return {SchemaField}
*/
static get clientSchema() {
return TacticalGridSettingsL5R5E.#schema.client;
}
/** Holds a mutable copy of the tactical grid settings so the form can operate on current values without altering the schema. */
static #setting = null;
/** @override ApplicationV2 */
async _prepareContext(options) {
if (options.isFirstRender) {
const client = game.settings.get(CONFIG.l5r5e.namespace, "tactical-grid-settings-client");
const world = game.settings.get(CONFIG.l5r5e.namespace, "tactical-grid-settings-world");
TacticalGridSettingsL5R5E.#setting = foundry.utils.deepClone({client: client, world: world});
}
// Pre-process range bands for easier template access
const rangeBands = Object.entries(this.constructor.worldSchema.fields.ranges.fields).map(([index, field]) => ({
index: Number(index),
worldField: field,
clientFields: this.constructor.clientSchema.fields.ranges.fields[index],
worldValue: TacticalGridSettingsL5R5E.#setting.world.ranges[index],
clientValue: TacticalGridSettingsL5R5E.#setting.client.ranges[index]
}));
return {
isGm: game.user.isGM,
tactical_grid_enabled: {
field: this.constructor.worldSchema.fields.enabled,
value: TacticalGridSettingsL5R5E.#setting.world.enabled,
},
rangeBands,
buttons: [
{ type: "reset", label: "l5r5e.tactical_grid.settings.reset", icon: "fa-solid fa-arrow-rotate-left", action: "reset" },
{ type: "submit", label: "l5r5e.tactical_grid.settings.submit", icon: "fa-solid fa-floppy-disk" }
]
};
}
/** @override ApplicationV2 */
_onChangeForm(formConfig, event) {
const formData = new foundry.applications.ux.FormDataExtended(this.form, { readonly: true });
const {
cleaned: cleanedWorldSettings,
failure: validationFailures
} = TacticalGridSettingsL5R5E.#validateAndCleanWorldSettings(formData, event);
TacticalGridSettingsL5R5E.#applyValidationState(validationFailures);
TacticalGridSettingsL5R5E.#setting.world = cleanedWorldSettings
TacticalGridSettingsL5R5E.#setting.client = foundry.utils.expandObject(formData.object).l5r5e["tactical-grid-settings-client"];
}
/**
* Validates world schema ensuring range bands are properly ordered and connected.
* Note: internal field validation takes precedence, and will result in this validation potentially not running
* Checks that:
* - Sequential range bands connect properly (range[n].start < range[n+1].start)
* @param {*} value - The world settings object to validate
* @param {DataFieldValidationOptions} options - Validation options including lastElementChange
* @returns {boolean|foundry.data.validation.DataModelValidationFailure} True if valid, otherwise validation failure object
*/
static #validateWorldRangeConfiguration(value, options) {
if(!value.enabled) // don't validate if tactical_grids are disabled
return true;
let previousStart = -1;
let previousRangeIndex = null;
const failure = new foundry.data.validation.DataModelValidationFailure({ unresolved: true });
const changedElementName = options?.element?.name;
for (const [rangeIndex, range] of Object.entries(value.ranges)) {
if (range.start <= previousStart) {
let errorKey = TacticalGridSettingsL5R5E.worldSchema.fields.ranges.fields[rangeIndex].fields.start.fieldPath;
const previousErrorKey = errorKey.replace(/\.(\d+)\./, `.${previousRangeIndex}.`);
let isErrorOnPrevious = false;
// If the previous field was changed, show error there instead
if (changedElementName === previousErrorKey) {
errorKey = previousErrorKey;
isErrorOnPrevious = true;
}
failure.fields[errorKey] = new foundry.data.validation.DataModelValidationFailure({
invalidValue: isErrorOnPrevious ? previousStart : range.start,
unresolved: true,
message: game.i18n.format(
isErrorOnPrevious
? "l5r5e.tactical_grid.settings.validate.start-too-large"
: "l5r5e.tactical_grid.settings.validate.start-too-small",
isErrorOnPrevious
? { nextRangeIndex: Number(rangeIndex), nextStart: range.start }
: { previousRangeIndex: Number(previousRangeIndex), previousStart: previousStart }
)
});
}
previousStart = range.start;
previousRangeIndex = rangeIndex;
}
return Object.keys(failure.fields).length > 0 ? failure : true;
}
/**
* Validates and cleans the world portion of the tactical grid settings.
*
* Expands raw form data, validates it against the schema, updates form input
* error states and tooltips, and returns a cleaned object ready to save.
*
* @param {foundry.applications.ux.FormDataExtended} formData - The submitted form data.
* @param {Event} [event] - Optional event for determining which field changed.
* @returns {WorldSettings} A cleaned and validated copy of the world settings.
* @private
*/
static #validateAndCleanWorldSettings(formData, event) {
const expanded = foundry.utils.expandObject(formData.object).l5r5e["tactical-grid-settings-world"];
const validate = TacticalGridSettingsL5R5E.#schema.world.validate(expanded, { element: event.target});
// validation from Number etc. itself has the error key just as "ranges.0.start"
// so fixing that here so that we can directly reference they html elements
const prefix = "l5r5e.tactical-grid-settings-world.";
const failures = Object.fromEntries(
Object.entries(validate?.asError()?.getAllFailures() ?? {}).map(([key, value]) => [
key.startsWith(prefix) ? key : `${prefix}${key}`,
value
])
);
// Return cleaned schema so that we have something that is somewhat correct we can save
return {
cleaned: TacticalGridSettingsL5R5E.#schema.world.clean(expanded),
failure: failures
}
}
/**
* Applies a validation message to a form element.
*
* @param {HTMLElement} element - The element to apply validation to
* @param {string|null} message - The validation message, or null to clear
* @private
*/
static #applyValidationMessage(element, message) {
if (message) {
element.setCustomValidity(message);
element.dataset.tooltip = message;
element.ariaLabel = game.i18n.localize(element.dataset.tooltip);
game.tooltip.activate(element, {
direction: foundry.CONFIG.ux.TooltipManager.TOOLTIP_DIRECTIONS.RIGHT,
locked: true
});
}
else {
element?.setCustomValidity("");
delete element?.dataset?.tooltip
}
}
/**
* Applies validation state to all range band start fields.
*
* @param {Object} failures - Validation failures keyed by field name
* @private
*/
static #applyValidationState(failures) {
for (let i = 0; i < 7; i++) {
const name = `l5r5e.tactical-grid-settings-world.ranges.${i}.start`;
this.#applyValidationMessage(
document.getElementsByName(name)[0],
failures?.[name]?.message || null
);
}
}
/**
* Handles form submission.
*
* @param {Event} event - The submission event
* @param {HTMLFormElement} form - The form element
* @param {foundry.applications.ux.FormDataExtended} formData - The submitted form data
* @returns {Promise<void>}
* @private
*/
static async #onSubmit(event, form, formData) {
const {
cleaned: cleanedWorldSettings,
failure: validationFailures
} = TacticalGridSettingsL5R5E.#validateAndCleanWorldSettings(formData, event);
TacticalGridSettingsL5R5E.#applyValidationState(validationFailures);
TacticalGridSettingsL5R5E.#setting.world = cleanedWorldSettings;
TacticalGridSettingsL5R5E.#setting.client = foundry.utils.expandObject(formData.object).l5r5e["tactical-grid-settings-client"];
const promises = [];
promises.push(game.settings.set(CONFIG.l5r5e.namespace, "tactical-grid-settings-world", TacticalGridSettingsL5R5E.#setting.world));
promises.push(game.settings.set(CONFIG.l5r5e.namespace, "tactical-grid-settings-client", TacticalGridSettingsL5R5E.#setting.client));
await Promise.all(promises);
}
/**
* Handles reset action to restore default settings.
*
* @param {Event} event - The reset event
* @returns {Promise<void>}
* @private
*/
static async #onReset(event) {
const client = TacticalGridSettingsL5R5E.clientSchema.clean();
const world = TacticalGridSettingsL5R5E.worldSchema.clean();
TacticalGridSettingsL5R5E.#setting = foundry.utils.deepClone({client: client, world: world});
await this.render({ force: false });
}
}

View File

@@ -0,0 +1,81 @@
function getRangeband(gridSettings, distance) {
const entries = Object.entries(gridSettings.ranges);
for (let i = entries.length - 1; i >= 0; i--) {
const [range, { start }] = entries[i];
if (distance >= start) {
return Number(range);
}
}
return NaN;
}
export class RulerL5r5e extends foundry.canvas.interaction.Ruler {
static WAYPOINT_LABEL_TEMPLATE = "systems/l5rx-chiaroscuro/templates/" + "hud/tactical-grid-ruler.html"
/** @override */
_getWaypointLabelContext(waypoint, state) {
const context = super._getWaypointLabelContext(waypoint, state);
if (!context)
return;
const gridSettings = game.settings.get(CONFIG.l5r5e.namespace, "tactical-grid-settings-world");
if(gridSettings.enabled) {
const diagonalCost = game.canvas.grid.distance * waypoint.measurement.diagonals;
context.distance.total = waypoint.measurement.distance.toNearest(0.1) + diagonalCost; //Diagonals count twice
context.additional = {
label: game.i18n.format("l5r5e.tactical_grid.range_abbreviation", {range: getRangeband(gridSettings, waypoint.measurement.distance)})
};
}
return context;
}
/** @override */
_getSegmentStyle(waypoint) {
const context = super._getSegmentStyle(waypoint);
const client = game.settings.get(CONFIG.l5r5e.namespace, "tactical-grid-settings-client");
const gridSettings = game.settings.get(CONFIG.l5r5e.namespace, "tactical-grid-settings-world");
if(gridSettings.enabled) {
const rangeband = getRangeband(gridSettings, waypoint.measurement.distance);
context.color = client.ranges[rangeband].color;
}
return context;
}
}
export class TokenRulerL5r5e extends foundry.canvas.placeables.tokens.TokenRuler {
static WAYPOINT_LABEL_TEMPLATE = "systems/l5rx-chiaroscuro/templates/" + "hud/tactical-grid-ruler.html"
/** @override */
_getWaypointLabelContext(waypoint, state) {
const context = super._getWaypointLabelContext(waypoint, state);
if (!context)
return;
if (!this.token.actor)
return context;
const gridSettings = game.settings.get(CONFIG.l5r5e.namespace, "tactical-grid-settings-world");
if(gridSettings.enabled) {
const diagonalCost = game.canvas.grid.distance * waypoint.measurement.diagonals;
context.cost.total = waypoint.measurement.cost.toNearest(0.1) + diagonalCost; //Diagonals count twice
context.additional = {
label: game.i18n.format("l5r5e.tactical_grid.range_abbreviation", {range: getRangeband(gridSettings, waypoint.measurement.distance)})
};
}
return context;
}
/** @override */
_getGridHighlightStyle(waypoint, offset) {
const context = super._getGridHighlightStyle(waypoint, offset);
const client = game.settings.get(CONFIG.l5r5e.namespace, "tactical-grid-settings-client");
const gridSettings = game.settings.get(CONFIG.l5r5e.namespace, "tactical-grid-settings-world");
if(gridSettings.enabled) {
const rangeband = getRangeband(gridSettings, waypoint.measurement.distance);
context.color = client.ranges[rangeband].color;
context.alpha = client.ranges[rangeband].alpha;
}
return context;
}
}

View File

@@ -20,5 +20,7 @@
@import "../scss/skills"; @import "../scss/skills";
@import "../scss/items"; @import "../scss/items";
@import "../scss/twenty-questions"; @import "../scss/twenty-questions";
@import "../scss/tactical-grid";
@import "../scss/chiaroscuro";
} }
} }

File diff suppressed because one or more lines are too long

View File

@@ -10,8 +10,6 @@
.readiness { .readiness {
flex: 0 0 100%; flex: 0 0 100%;
display: flex;
flex-wrap: wrap;
ul { ul {
display: flex; display: flex;
@@ -21,15 +19,20 @@
li { li {
flex: 25%; flex: 25%;
display: inline-grid; display: flex;
flex-direction: column;
align-items: center;
position: relative; position: relative;
.attributes-buttons { .increment-control {
position: relative; position: absolute;
line-height: 13px; right: -0.70rem;
top: 0.3rem; top: 15%;
right: 1.2rem;
width: 12px; display: flex;
flex-direction: column;
gap:0.1rem;
line-height: 1;
} }
strong { strong {
@@ -40,14 +43,19 @@
} }
label { label {
flex: 100%; position: relative;
display: flex;
align-items: center;
justify-content: center;
} }
input { input {
background: transparent; background: transparent;
border: 0 none; border: 0 none;
text-align: center; text-align: center;
margin: 0.3rem 1.6rem 0 1.5rem; margin: 0;
padding: 0;
width: 2rem;
} }
&:after { &:after {
@@ -55,8 +63,6 @@
width: 2rem; width: 2rem;
height: 2rem; height: 2rem;
position: absolute; position: absolute;
right: calc(50% - 0.9rem);
top: 0.1rem;
background: transparent url("../assets/icons/circle.svg") no-repeat 0 0; background: transparent url("../assets/icons/circle.svg") no-repeat 0 0;
background-size: contain; background-size: contain;
opacity: 0.25; opacity: 0.25;
@@ -64,9 +70,6 @@
} }
&:nth-child(1) { &:nth-child(1) {
input {
margin: 0.3rem 1rem 0 1.5rem;
}
&:after { &:after {
transform: rotate(0deg); transform: rotate(0deg);
} }
@@ -79,9 +82,6 @@
} }
&:nth-child(3) { &:nth-child(3) {
input {
margin: 0.3rem 1rem 0 1.5rem;
}
&:after { &:after {
transform: rotate(180deg); transform: rotate(180deg);
} }

View File

@@ -0,0 +1,376 @@
// ── Chiaroscuro UI Styles ──────────────────────────────────────────────────
// ── Aspects (header block on character sheet) ─────────────────────────────
.aspects-section {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.25rem 0.5rem;
padding: 0.25rem 0.5rem;
border: 1px solid rgba($chi-title, 0.3);
border-radius: 0.25rem;
font-size: 0.85rem;
.aspect-fields {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.25rem;
flex: 1;
.attribute-label {
display: flex;
align-items: center;
gap: 0.25rem;
&:nth-child(1) { color: $chi-solar; } // solar
&:nth-child(2) { color: $chi-lunar; } // lunar
input[type="number"] {
width: 3rem;
text-align: center;
}
}
.gauge-bar-wrapper {
flex: 0 0 100%;
height: 0.4rem;
background: linear-gradient(to right, $chi-lunar, rgba(128,128,128,0.3) 50%, $chi-solar);
border-radius: 0.25rem;
position: relative;
overflow: hidden;
.gauge-bar {
position: absolute;
top: 0;
height: 100%;
border-radius: 0.25rem;
opacity: 0.8;
}
}
}
}
// ── État badges (character sheet header) ─────────────────────────────────
.etat-summary {
flex: 0 0 100%;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.2rem;
padding: 0.1rem 0;
font-size: 0.8rem;
.etat-summary-label {
color: $l5r5e-label;
font-style: italic;
margin-right: 0.2rem;
}
.etat-badge {
display: inline-flex;
align-items: center;
gap: 0.2rem;
padding: 0.1rem 0.35rem;
border-radius: 0.2rem;
background: rgba($chi-title, 0.18);
border: 1px solid rgba($chi-title, 0.4);
color: $chi-title;
cursor: default;
&:hover { background: rgba($chi-title, 0.32); }
}
}
// ── NPC Danger levels (identity.html) ────────────────────────────────────
.danger-row {
display: flex;
align-items: center;
gap: 0.4rem;
margin: 0.2rem 0;
}
.danger-wrapper {
display: flex;
align-items: center;
gap: 0.3rem;
.danger-select {
font-size: 0.85rem;
background: $l5r5e-white;
border: 0 none;
color: $l5r5e-bold;
font-family: $font-primary;
}
}
.danger-icons {
display: flex;
gap: 0.15rem;
.danger-icon {
font-size: 0.9rem;
&.fa-skull { color: $l5r5e-red; }
&.fa-star { color: $l5r5e-shuji; }
}
}
// ── Chiaroscuro Dice Dialog ───────────────────────────────────────────────
&.chiaroscuro-dice-dialog {
// Header: portrait + actor name
.chi-dice-header {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem;
border-bottom: 1px solid rgba($chi-title, 0.3);
.profile-img {
width: 3rem;
height: 3rem;
object-fit: cover;
border-radius: 50%;
border: 2px solid rgba($chi-title, 0.5);
}
.chi-dice-actor-info {
display: flex;
flex-direction: column;
strong { font-family: $font-secondary; font-size: 1.1rem; color: $chi-title; }
.chi-dice-quick-info { font-size: 0.8rem; color: $l5r5e-label; font-style: italic; }
}
}
// Section fieldsets
.chi-dice-section {
flex: 0 0 100%;
border: 1px solid rgba($chi-subtitle, 0.35);
border-radius: 0.25rem;
margin: 0.35rem 0.5rem 0;
padding: 0.25rem 0.5rem 0.4rem;
legend {
font-family: $font-tertiary;
font-size: 0.8rem;
color: $chi-subtitle;
padding: 0 0.25rem;
}
}
// Ring selector
.chi-rings {
display: flex;
flex-wrap: wrap;
gap: 0.2rem;
list-style: none;
padding: 0;
margin: 0;
li { flex: 1; }
.ring-selection-chi {
display: flex;
flex-direction: column;
align-items: center;
padding: 0.2rem;
border-radius: 0.2rem;
border: 1px solid rgba($l5r5e-title, 0.2);
cursor: pointer;
font-size: 0.75rem;
&:hover { border-color: rgba($chi-title, 0.6); background: rgba($chi-title, 0.08); }
&.ring-selected {
border-color: $chi-title;
background: rgba($chi-title, 0.15);
strong { text-decoration: underline; }
}
i { font-size: 1.5rem; }
.ring-value { font-weight: bold; font-size: 0.9rem; }
}
.earth.ring-selection-chi { color: $l5r5e-earth; }
.air.ring-selection-chi { color: $l5r5e-air; }
.water.ring-selection-chi { color: $l5r5e-water; }
.fire.ring-selection-chi { color: $l5r5e-fire; }
.void.ring-selection-chi { color: $l5r5e-void-light; }
}
// Skill info row
.chi-skill-row {
display: flex;
align-items: baseline;
gap: 0.4rem;
.chi-skill-name { font-weight: bold; flex: 1; }
.chi-skill-rank { font-size: 0.8rem; color: $l5r5e-label; }
.chi-skill-bonus { font-size: 0.85rem; color: $chi-solar; font-weight: bold; }
}
// Difficulty + modifier row
.chi-difficulty-row {
display: flex;
align-items: center;
gap: 0.5rem;
select { flex: 1; }
.chi-modifier-label {
display: flex;
align-items: center;
gap: 0.25rem;
font-size: 0.85rem;
white-space: nowrap;
}
}
// Options checkboxes
.chi-options-row {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.15rem 0;
label {
display: flex;
align-items: center;
gap: 0.35rem;
font-size: 0.9rem;
}
.chi-auto-aspect { font-size: 0.8rem; color: $l5r5e-label; }
}
// Dice total summary
.chi-dice-total-summary {
flex: 0 0 100%;
text-align: center;
padding: 0.4rem;
font-size: 0.9rem;
.chi-total-dice { font-size: 1.3rem; color: $chi-title; margin: 0 0.2rem; }
}
// Submit button
.chi-dice-submit {
flex: 0 0 100%;
padding: 0.4rem 0.5rem;
button[type="submit"] {
width: 100%;
background: rgba($chi-title, 0.85);
border: 1px solid $chi-title;
color: $white;
font-family: $font-tertiary;
font-size: 1rem;
padding: 0.4rem;
cursor: pointer;
border-radius: 0.2rem;
&:hover { background: $chi-title; }
}
}
}
// ── Chiaroscuro Chat Roll ─────────────────────────────────────────────────
.chiaroscuro-chat-roll {
padding: 0.35rem;
font-size: 0.9rem;
// Header: portrait + actor + badges
.chi-chat-header {
display: flex;
align-items: center;
gap: 0.4rem;
margin-bottom: 0.3rem;
.profile-img {
width: 2.5rem;
height: 2.5rem;
object-fit: cover;
border-radius: 50%;
border: 2px solid rgba($chi-title, 0.5);
}
.chi-chat-actor {
flex: 1;
strong { font-family: $font-secondary; color: $chi-title; }
.chi-chat-quick-info { font-size: 0.75rem; color: $l5r5e-label; font-style: italic; }
}
.chi-chat-badges {
display: flex;
gap: 0.2rem;
align-items: center;
.chi-aspect-badge {
font-size: 1rem;
&.solar { color: $chi-solar; }
&.lunar { color: $chi-lunar; }
}
.chi-assistance-badge { color: $l5r5e-label; font-size: 1rem; }
}
}
// Description line
.chi-chat-desc {
display: flex;
align-items: center;
gap: 0.3rem;
margin-bottom: 0.3rem;
font-size: 0.85rem;
.chi-chat-skill { font-weight: bold; color: $chi-title; }
.chi-chat-vs { color: $l5r5e-label; }
.chi-chat-diff { color: $chi-subtitle; font-style: italic; }
}
// Dice pool
.chi-chat-dice-pool {
display: flex;
flex-wrap: wrap;
gap: 0.25rem;
margin-bottom: 0.35rem;
.chi-die {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.8rem;
height: 1.8rem;
border-radius: 0.25rem;
font-weight: bold;
font-size: 1rem;
background: rgba($l5r5e-black, 0.35);
border: 1px solid rgba($l5r5e-title, 0.4);
position: relative;
&.die-low { color: $l5r5e-red; border-color: rgba($l5r5e-red, 0.5); }
&.die-high { color: $chi-solar; border-color: rgba($chi-solar, 0.5); }
.die-adj-icon {
position: absolute;
top: -0.3rem;
right: -0.2rem;
font-size: 0.6rem;
color: $chi-solar;
}
}
}
// Breakdown
.chi-chat-breakdown {
font-size: 0.85rem;
margin-bottom: 0.25rem;
color: $l5r5e-label;
strong { color: $white; }
}
// Result banner
.chi-chat-result {
display: flex;
align-items: center;
gap: 0.3rem;
font-family: $font-tertiary;
font-size: 1rem;
padding: 0.25rem 0.5rem;
border-radius: 0.2rem;
&.chi-success {
background: rgba($chi-subtitle, 0.25);
border: 1px solid rgba($chi-subtitle, 0.5);
color: $chi-subtitle;
}
&.chi-failure {
background: rgba($l5r5e-red, 0.12);
border: 1px solid rgba($l5r5e-red, 0.35);
color: $l5r5e-red;
}
.chi-bonus-successes {
font-size: 0.85rem;
opacity: 0.85;
}
}
}
// ── Skill rank: bonus display ──────────────────────────────────────────────
.skill-bonus {
color: $chi-solar;
font-size: 0.8rem;
font-weight: bold;
margin-left: 0.2rem;
}
// ── Default ring indicator ────────────────────────────────────────────────
.rings .default-ring {
text-decoration: underline 2px $chi-title;
text-underline-offset: 2px;
cursor: pointer;
}

View File

@@ -53,7 +53,23 @@ $l5r5e-chat-color-roll: rgba(225, 215, 200, 0.75);
$l5r5e-chat-color-blind: transparent; $l5r5e-chat-color-blind: transparent;
$l5r5e-chat-color-whisper: rgba(225, 200, 225, 0.75); $l5r5e-chat-color-whisper: rgba(225, 200, 225, 0.75);
// -- Rings // Misc
$l5r5e-selection-circle-color: #8a1a00;
// -- Chiaroscuro Colors
// Title (was: rgba(186, 187, 177, 0.5) → spec: rgb(158, 65, 76))
$chi-title: rgb(158, 65, 76);
// Subtitle (spec: rgb(103, 128, 119))
$chi-subtitle: rgb(103, 128, 119);
// Solar aspect (spec: rgb(150, 119, 116))
$chi-solar: rgb(150, 119, 116);
// Lunar aspect (spec: rgb(100, 147, 137))
$chi-lunar: rgb(100, 147, 137);
// Active tab accent
$chi-tab-active: rgb(158, 65, 76);
// Tab hover accent
$chi-tab-hover: rgb(103, 128, 119);
// Earth // Earth
$l5r5e-earth: rgb(105, 150, 120); $l5r5e-earth: rgb(105, 150, 120);
@@ -65,6 +81,7 @@ $l5r5e-water: rgb(95, 145, 155);
$l5r5e-fire: rgb(155, 115, 80); $l5r5e-fire: rgb(155, 115, 80);
// Void // Void
$l5r5e-void: rgb(75, 70, 65); $l5r5e-void: rgb(75, 70, 65);
$l5r5e-void-light: rgba(207,207,207,.8);
// -- Clans // -- Clans

View File

@@ -5,9 +5,55 @@
cursor: url("../assets/cursors/pointer.webp"), pointer; cursor: url("../assets/cursors/pointer.webp"), pointer;
} }
// define a mixin
@mixin roll-effects-base {
clear: both;
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 2px 4px;
.effect-container {
border: 1px solid #5a6e5a;
border-radius: 4px;
background-color: rgba(0, 0, 0, 0.4);
padding: 3px;
display: flex;
}
.effect-delete {
width: 16px;
height: 16px;
background-repeat: no-repeat;
background-size: contain;
text-align: end;
cursor: url("../assets/cursors/pointer.webp"), pointer;
}
.effect-icon {
width: 16px;
height: 16px;
background-repeat: no-repeat;
background-size: contain;
}
.effect-name {
vertical-align: top;
white-space: nowrap;
color: $white;
margin-left: 4px;
font-size: 14px;
line-height: 16px;
}
}
// Dice Picker // Dice Picker
.dice-picker-dialog { .dice-picker-dialog {
min-width: 35rem; .effects {
@include roll-effects-base();
}
width: 35rem;
min-height: auto; min-height: auto;
// Utility // Utility
* { * {
@@ -206,6 +252,12 @@
.profil { .profil {
border-bottom: 1px solid rgba(0, 0, 0, 0.1); border-bottom: 1px solid rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column; // stack profile ul and effects ul vertically
.effects {
@include roll-effects-base();
}
} }
.dropbox { .dropbox {

View File

@@ -1,5 +1,5 @@
.application { .application {
color: var(--color-text-dark-primary); color: var(--color-text-primary);
.scrollable { .scrollable {
--scroll-margin: 0; --scroll-margin: 0;
@@ -48,10 +48,69 @@
} }
} }
// Handle Sidebar here. Starting with custom icons
$l5r5e-custom-icons: (
chatIcon: "../assets/ui/sidebar/chat.svg",
combatIcon: "../assets/ui/sidebar/combat-tracker.svg",
sceneIcon: "../assets/ui/sidebar/scenes.svg",
actorIcon: "../assets/ui/sidebar/actors.svg",
itemIcon: "../assets/ui/sidebar/object.svg",
journalIcon: "../assets/ui/sidebar/journal.svg",
rolltableIcon: "../assets/ui/sidebar/rolltable.svg",
playlistIcon: "../assets/ui/sidebar/playlist.svg",
compendiumIcon: "../assets/ui/sidebar/compendium.svg",
settingsIcon: "../assets/ui/sidebar/settings.svg"
);
$selectors: (
"#sidebar-tabs button.l5r5e",
"#sidebar-content .create-button.l5r5e",
"#sidebar-content i.l5r5e"
);
@each $selector in $selectors {
#{$selector} {
position: relative;
display: flex;
justify-content: center;
align-items: center;
@if str-index($selector, "i.") {
width: 2em;
height: 2em;
color: currentColor;
}
@if str-index($selector, "create-button") {
filter: drop-shadow(0 0 3px var(--color-dark-1));
}
// Apply masks for each icon
@each $name, $url in $l5r5e-custom-icons {
&.#{$name}::before {
content: "";
position: absolute;
width: 95%;
height: 95%;
background-color: currentColor;
mask: url($url) no-repeat center / contain;
-webkit-mask: url($url) no-repeat center / contain;
z-index: 0;
}
}
// Generic plus icon badge
&.icon-plus::after {
z-index: 2;
}
}
}
#sidebar-tabs > menu { #sidebar-tabs > menu {
gap: 4px; // halve the distance between menu icons gap: 4px; // halve the distance between menu icons
} }
#sidebar-content.expanded { #sidebar-content.expanded {
background: url("../assets/ui/bgSidebar.webp") no-repeat; background: url("../assets/ui/bgSidebar.webp") no-repeat;
border-image: url("../assets/ui/macro-button.webp") 10 repeat; border-image: url("../assets/ui/macro-button.webp") 10 repeat;

View File

@@ -28,7 +28,7 @@ nav {
.item { .item {
flex: 1; flex: 1;
&:hover { &:hover {
background-color: $l5r5e-label; background-color: $chi-tab-hover;
color: $white-light; color: $white-light;
text-shadow: none; text-shadow: none;
clip-path: polygon( clip-path: polygon(
@@ -44,7 +44,7 @@ nav {
} }
} }
.item.active { .item.active {
background-color: rgba(73, 12, 11, 0.85); background-color: $chi-tab-active;
color: rgba(255, 255, 255, 1); color: rgba(255, 255, 255, 1);
clip-path: polygon( clip-path: polygon(
0% var(--notchSize), 0% var(--notchSize),
@@ -58,7 +58,7 @@ nav {
); );
&:hover { &:hover {
background-color: rgba(73, 12, 11, 0.85); background-color: $chi-tab-active;
cursor: default; cursor: default;
} }
} }

View File

@@ -1,18 +1,33 @@
/** Rings **/ /** Rings — disposition en pentagone **/
.rings { .rings {
display: flex; position: relative;
flex-wrap: wrap; min-height: 260px;
color: $white-light; color: $white-light;
// All list-style: none;
padding: 0;
margin: 0;
// — Common rules for all ring items —
#earth, #earth,
#air, #air,
#water, #water,
#fire, #fire,
#void { #void {
position: absolute;
label {
position: relative; position: relative;
flex: 1 1 50%; display: block;
text-align: center; text-align: center;
cursor: pointer;
width: 5.5rem;
line-height: normal;
&.stance-active strong {
text-decoration: underline 2px;
}
}
i.i_earth, i.i_earth,
i.i_water, i.i_water,
@@ -21,26 +36,25 @@
i.i_void { i.i_void {
font-size: 5rem; font-size: 5rem;
line-height: 4.75rem; line-height: 4.75rem;
display: block;
} }
label { strong {
position: relative; display: block;
width: 5rem; font-size: 0.78rem;
line-height: 0; line-height: 1.3;
float: right; margin-top: 0.15rem;
}
label.stance-active strong {
text-decoration: underline 2px;
} }
input { input {
position: absolute; position: absolute;
height: 2rem; height: 1.9rem;
width: 2rem; width: 1.9rem;
border-radius: 100%; border-radius: 100%;
top: 0; top: 0;
left: 0; left: 0;
text-align: center; text-align: center;
font-size: 1rem; font-size: 0.95rem;
border: 2px solid $l5r5e-title; border: 2px solid $l5r5e-title;
color: $white-light; color: $white-light;
&:hover { &:hover {
@@ -51,106 +65,71 @@
} }
} }
// Earth // — Solaire / Lunaire badges —
#earth { .ring-type {
float: right; display: block;
color: $l5r5e-earth; text-align: center;
input { font-size: 0.62rem;
top: auto; line-height: 1.2 !important;
right: 0; font-weight: bold;
bottom: -0.9rem; text-transform: uppercase;
left: auto; letter-spacing: 0.07em;
background: $l5r5e-earth; white-space: nowrap;
} margin-top: 0.1rem;
label { pointer-events: none;
strong {
position: absolute; &.solaire {
bottom: 0.75rem; color: #f5c842;
left: -1.75rem; text-shadow: 0 0 4px rgba(245, 180, 0, 0.6);
} }
&.lunaire {
color: #9ecfef;
text-shadow: 0 0 4px rgba(100, 180, 230, 0.6);
} }
} }
// Air // — Pentagone centré — rayon 4.5rem autour du centre x=50%, y≈6.875rem
#air { // (centre de l'icône à 2.375rem du haut de chaque li)
color: $l5r5e-air; // cos/sin calculés pour les 5 sommets d'un pentagone régulier (Vide au sommet)
input {
top: auto;
right: auto;
bottom: -0.9rem;
left: 0;
background: $l5r5e-air;
}
label {
float: left;
strong {
position: absolute;
bottom: 0.75rem;
right: -1rem;
}
}
}
// Water // Pentagone ancré à gauche — centre du cercle à 8rem du bord gauche
#water { // Vide — sommet (90°)
float: right;
color: $l5r5e-water;
padding-right: 2rem;
input {
top: 17%;
right: -1.25rem;
bottom: auto;
left: auto;
background: $l5r5e-water;
}
label {
strong {
position: absolute;
bottom: -0.75rem;
right: 2rem;
}
}
}
// Fire
#fire {
color: $l5r5e-fire;
padding-left: 2rem;
input {
top: 17%;
right: auto;
bottom: auto;
left: -1.25rem;
background: $l5r5e-fire;
}
label {
float: left;
strong {
position: absolute;
bottom: -0.75rem;
right: 2rem;
}
}
}
// Void
#void { #void {
top: -2rem; top: 0;
margin: 0 calc(50% - 2.5rem); left: 5.25rem;
color: $l5r5e-void; color: $l5r5e-void;
input { input { background: $l5r5e-void; }
top: -1rem;
right: auto;
bottom: auto;
left: 30%;
background: $l5r5e-void;
} }
label {
strong { // Air (Solaire) — haut gauche (162° : cos=0.951, sin=0.309)
position: absolute; #air {
bottom: -0.75rem; top: 3.1rem;
left: 1.75rem; left: 1rem;
color: $l5r5e-air;
input { background: $l5r5e-air; }
} }
// Eau (Lunaire) — haut droite (18° : cos=0.951, sin=0.309)
#water {
top: 3.1rem;
left: 9.5rem;
color: $l5r5e-water;
input { background: $l5r5e-water; }
} }
// Feu (Solaire) — bas gauche (126° : cos=0.588, sin=0.809)
#fire {
top: 8.1rem;
left: 2.6rem;
color: $l5r5e-fire;
input { background: $l5r5e-fire; }
}
// Terre (Lunaire) — bas droite (54° : cos=0.588, sin=0.809)
#earth {
top: 8.1rem;
left: 7.9rem;
color: $l5r5e-earth;
input { background: $l5r5e-earth; }
} }
} }

View File

@@ -247,6 +247,14 @@
margin: 0 0 0.25rem; margin: 0 0 0.25rem;
} }
&:nth-child(3) { &:nth-child(3) {
flex: auto;
input {
width: 2.5rem;
text-align: center;
padding: 0;
}
}
&:nth-child(4) {
flex: auto; flex: auto;
input { input {
width: 1rem; width: 1rem;
@@ -254,14 +262,14 @@
margin-right: 0; margin-right: 0;
} }
} }
&:nth-child(4), &:nth-child(5),
&:nth-child(5) { &:nth-child(6) {
flex: 60%; flex: 60%;
input { input {
font-size: 1rem; font-size: 1rem;
} }
} }
&:nth-child(5) { &:nth-child(6) {
flex: 40%; flex: 40%;
input { input {
margin-right: 0; margin-right: 0;
@@ -272,16 +280,16 @@
} }
.mid-wrapper { .mid-wrapper {
display: flex; display: flex;
} flex: 0 0 100%;
.side-col {
width: 30%;
} }
.central-col { .central-col {
width: 40%; flex: 1;
width: 100%;
} }
.rings { .rings {
padding: 0; padding: 0;
margin-top: 1rem; margin-top: 0.5rem;
width: 100%;
} }
.social-content, .social-content,
.attributes-wrapper { .attributes-wrapper {
@@ -326,7 +334,7 @@
margin: 0.25rem 0; margin: 0.25rem 0;
flex-direction: row-reverse; flex-direction: row-reverse;
strong { strong {
flex: 0 0 calc(100% - 3.5rem); flex: 0 0 calc(100% - 4.5rem);
} }
input { input {
flex: 0 0 3rem; flex: 0 0 3rem;
@@ -444,7 +452,7 @@
width: 3.5rem; width: 3.5rem;
} }
} }
.attributes-buttons { .increment-control {
line-height: 13px; line-height: 13px;
position: relative; position: relative;
top: 0.2rem; top: 0.2rem;
@@ -538,8 +546,8 @@
right: 0.85rem; right: 0.85rem;
} }
} }
li:nth-child(3), li:nth-child(4),
li:nth-child(5) { li:nth-child(6) {
.attribute-label { .attribute-label {
&:before { &:before {
height: calc(100% - 0.6rem); height: calc(100% - 0.6rem);
@@ -751,12 +759,22 @@
flex: calc(100% / 3); flex: calc(100% / 3);
padding: 0.5rem; padding: 0.5rem;
font-size: 0.85rem; font-size: 0.85rem;
align-items: center;
input { input {
margin-left: 0.5rem; margin-left: 0.5rem;
} }
} }
.xp-buttons,
.money-buttons { .money-buttons {
line-height: 13px; line-height: 13px;
padding-left: 0.3em;
}
.increment-control {
display: flex;
flex-direction: column;
align-items: center;
padding-left: 0.2rem;
flex: none;
} }
} }

View File

@@ -0,0 +1,32 @@
// Set the label for in-world measurement to be the same as normal waypoint-label
@at-root #measurement .waypoint-label-additional {
color: var(--color-text-emphatic);
font-size: var(--font-size-24);
}
@at-root #tactical-grid-settings {
input[type="number"]:invalid {
background-color: red;
}
input[type="number"]:read-only {
border: none;
outline: none;
box-shadow: none;
background: transparent;
cursor: default;
pointer-events: none; /* not clickable or focusable */
user-select: none; /* text cannot be selected */
-webkit-user-select: none; /* Safari/Chrome */
-moz-user-select: none; /* Firefox */
}
.range_band {
display: flex;
flex-flow: wrap;
fieldset {
flex: 25%;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +1,17 @@
{ {
"id": "l5r5e", "id": "l5rx-chiaroscuro",
"title": "Legend of the Five Rings (5th Edition)", "title": "Chiaroscuro - L5R",
"description": "This is an authorised multilingual game system En|Fr|Es, for Legend of the Five Rings (5th Edition) by <a href='https://edge-studio.net/'>Edge Studio</a> <p> - Join the official Discord server: <a href='https://discord.gg/foundryvtt'> Official Discord</a></p><p> - Rejoignez la communauté Francophone: <a href='https://discord.gg/pPSDNJk'>Francophone Discord</a></p>", "description": "This is an authorised multilingual game system En|Fr|Es, for Legend of the Five Rings (5th Edition) by <a href='https://edge-studio.net/'>Edge Studio</a> <p> - Join the official Discord server: <a href='https://discord.gg/foundryvtt'> Official Discord</a></p><p> - Rejoignez la communauté Francophone: <a href='https://discord.gg/pPSDNJk'>Francophone Discord</a></p>",
"url": "https://gitlab.com/teaml5r/l5r5e", "url": "https://gitlab.com/teaml5r/l5r5e",
"readme": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/README.md", "readme": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/README.md",
"changelog": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/CHANGELOG.md", "changelog": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/CHANGELOG.md",
"license": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/LICENSE.md", "license": "https://gitlab.com/teaml5r/l5r5e/-/blob/master/LICENSE.md",
"manifest": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/system/system.json", "manifest": "https://gitlab.com/teaml5r/l5r5e/-/raw/master/system/system.json",
"download": "https://gitlab.com/teaml5r/l5r5e/-/jobs/artifacts/v1.13.2/raw/l5r5e.zip?job=build", "download": "https://gitlab.com/teaml5r/l5r5e/-/jobs/artifacts/v1.13.4/raw/l5r5e.zip?job=build",
"version": "1.13.2", "version": "14.0.0",
"compatibility": { "compatibility": {
"minimum": "13", "minimum": "13",
"verified": "13", "verified": "14"
"maximum": "13"
}, },
"socket": true, "socket": true,
"authors": [ "authors": [
@@ -29,6 +28,10 @@
"name": "Carter", "name": "Carter",
"discord": "Carter#2703", "discord": "Carter#2703",
"url": "https://fr.tipeee.com/carter-foundryvtt" "url": "https://fr.tipeee.com/carter-foundryvtt"
},
{
"name": "Litasa",
"discord": "Litasa#3139"
} }
], ],
"background": "systems/l5r5e/assets/l5r-header.webp", "background": "systems/l5r5e/assets/l5r-header.webp",
@@ -334,25 +337,10 @@
} }
], ],
"languages": [ "languages": [
{
"lang": "en",
"name": "English",
"path": "lang/en-en.json"
},
{ {
"lang": "fr", "lang": "fr",
"name": "French (France)", "name": "French (France)",
"path": "lang/fr-fr.json" "path": "lang/fr-fr.json"
},
{
"lang": "es",
"name": "Spanish (Spain)",
"path": "lang/es-es.json"
},
{
"lang": "it",
"name": "Italian (Italy)",
"path": "lang/it-it.json"
} }
], ],
"media": [ "media": [

View File

@@ -1,6 +1,10 @@
{ {
"Actor": { "Actor": {
"types": ["character", "npc", "army"], "types": [
"character",
"npc",
"army"
],
"templates": { "templates": {
"softlock": { "softlock": {
"soft_locked": false "soft_locked": false
@@ -10,11 +14,14 @@
"age": "", "age": "",
"clan": "", "clan": "",
"family": "", "family": "",
"region": "",
"education": "",
"female": null, "female": null,
"marital_status": "", "marital_status": "",
"roles": "", "roles": "",
"school": "", "school": "",
"school_rank": 1, "school_rank": 1,
"title": "",
"school_curriculum_journal": {} "school_curriculum_journal": {}
} }
}, },
@@ -36,6 +43,7 @@
"status": 0, "status": 0,
"ninjo": "", "ninjo": "",
"giri": "", "giri": "",
"past_problems": "",
"bushido_tenets": { "bushido_tenets": {
"paramount": "", "paramount": "",
"less_significant": "" "less_significant": ""
@@ -45,38 +53,39 @@
"skills": { "skills": {
"skills": { "skills": {
"artisan": { "artisan": {
"aesthetics": 0, "art": 0,
"composition": 0, "composition": 0,
"design": 0, "design": 0,
"smithing": 0 "smithing": 0,
"labor": 0
}, },
"martial": { "martial": {
"archery": 0,
"fitness": 0, "fitness": 0,
"melee": 0, "melee": 0,
"ranged": 0,
"unarmed": 0, "unarmed": 0,
"meditation": 0, "meditation": 0
"tactics": 0
}, },
"scholar": { "scholar": {
"culture": 0, "culture": 0,
"government": 0,
"medicine": 0, "medicine": 0,
"sentiment": 0, "sentiment": 0,
"tactics": 0,
"theology": 0 "theology": 0
}, },
"social": { "social": {
"command": 0, "command": 0,
"courtesy": 0, "courtesy": 0,
"invocation": 0,
"games": 0, "games": 0,
"performance": 0 "performance": 0
}, },
"trade": { "trade": {
"animal": 0,
"commerce": 0, "commerce": 0,
"labor": 0,
"seafaring": 0, "seafaring": 0,
"skulduggery": 0, "survival": 0,
"survival": 0 "urban": 0
} }
} }
}, },
@@ -118,18 +127,51 @@
"mantra": false, "mantra": false,
"specificity": true "specificity": true
} }
},
"aspects": {
"aspects": {
"solar": 0,
"lunar": 0,
"gauge": 0
}
} }
}, },
"character": { "character": {
"templates": ["softlock", "identity", "rings", "social", "skills", "techniques", "conflict", "advancement"], "templates": [
"softlock",
"identity",
"rings",
"social",
"skills",
"techniques",
"conflict",
"advancement",
"aspects"
],
"template": "core", "template": "core",
"twenty_questions": {}, "is_samurai": true,
"zeni": 0 "quick_info": "",
"default_ring": "void",
"koku": 0,
"bu": 0,
"zeni": 0,
"identity_text1": "",
"identity_text2": "",
"twenty_questions": {}
}, },
"npc": { "npc": {
"templates": ["softlock", "identity", "rings", "social", "techniques", "conflict"], "templates": [
"softlock",
"identity",
"rings",
"social",
"techniques",
"conflict"
],
"type": "adversary", "type": "adversary",
"attitude": "", "attitude": "",
"martial_danger": "simple",
"social_danger": "simple",
"conflict_rank": { "conflict_rank": {
"martial": 0, "martial": 0,
"social": 0 "social": 0
@@ -150,7 +192,9 @@
} }
}, },
"army": { "army": {
"templates": ["softlock"], "templates": [
"softlock"
],
"warlord": "", "warlord": "",
"warlord_actor_id": null, "warlord_actor_id": null,
"allies_backers": "", "allies_backers": "",
@@ -194,7 +238,10 @@
"signature_scroll", "signature_scroll",
"item_pattern", "item_pattern",
"army_cohort", "army_cohort",
"army_fortification" "army_fortification",
"arcane",
"etat",
"mystere"
], ],
"templates": { "templates": {
"basics": { "basics": {
@@ -224,18 +271,30 @@
} }
}, },
"item": { "item": {
"templates": ["basics", "item"] "templates": [
"basics",
"item"
],
"item_type": ""
}, },
"armor": { "armor": {
"templates": ["basics", "item"], "templates": [
"basics",
"item"
],
"armor_category": "",
"armor": { "armor": {
"physical": 0, "physical": 0,
"supernatural": 0 "supernatural": 0
} }
}, },
"weapon": { "weapon": {
"templates": ["basics", "item"], "templates": [
"basics",
"item"
],
"category": "", "category": "",
"bonus": 0,
"skill": "melee", "skill": "melee",
"readied": false, "readied": false,
"range": "0", "range": "0",
@@ -245,44 +304,71 @@
"grip_2": "" "grip_2": ""
}, },
"technique": { "technique": {
"templates": ["basics", "advancement"], "templates": [
"basics",
"advancement"
],
"skill": "", "skill": "",
"difficulty": "", "difficulty": "",
"technique_type": "kata" "technique_type": "kata",
"invocation_type": "",
"mode_invocation": 0
}, },
"property": { "property": {
"templates": ["basics"], "templates": [
"basics"
],
"properties": [] "properties": []
}, },
"peculiarity": { "peculiarity": {
"templates": ["basics", "advancement"], "templates": [
"basics",
"advancement"
],
"peculiarity_type": "distinction", "peculiarity_type": "distinction",
"types": "" "types": ""
}, },
"advancement": { "advancement": {
"templates": ["basics", "advancement"], "templates": [
"basics",
"advancement"
],
"advancement_type": "skill", "advancement_type": "skill",
"skill": "" "skill": ""
}, },
"title": { "title": {
"templates": ["basics", "advancement"], "templates": [
"basics",
"advancement"
],
"advancements": [], "advancements": [],
"xp_used_total": 0 "xp_used_total": 0
}, },
"bond": { "bond": {
"templates": ["basics", "advancement"], "templates": [
"basics",
"advancement"
],
"bond_type": "" "bond_type": ""
}, },
"item_pattern": { "item_pattern": {
"templates": ["basics", "advancement"], "templates": [
"basics",
"advancement"
],
"linked_property_id": null, "linked_property_id": null,
"rarity_modifier": "" "rarity_modifier": ""
}, },
"signature_scroll": { "signature_scroll": {
"templates": ["basics", "advancement"] "templates": [
"basics",
"advancement"
]
}, },
"army_cohort": { "army_cohort": {
"templates": ["basics"], "templates": [
"basics"
],
"leader": "", "leader": "",
"leader_actor_id": null, "leader_actor_id": null,
"equipment": "", "equipment": "",
@@ -299,10 +385,39 @@
} }
}, },
"army_fortification": { "army_fortification": {
"templates": ["basics"], "templates": [
"basics"
],
"difficulty": 0, "difficulty": 0,
"attrition_reduction": 0, "attrition_reduction": 0,
"notes": "" "notes": ""
},
"arcane": {
"templates": [
"basics"
],
"arcane_type": "",
"application": [],
"bonus": 2,
"progression": "",
"xp_cost": 1
},
"etat": {
"templates": [
"basics"
],
"application": "",
"mod": 0,
"effect": "",
"elimination": ""
},
"mystere": {
"templates": [
"basics"
],
"mystere_type": "mineur",
"prerequisite_skill": "",
"prerequisite_condition": ""
} }
} }
} }

View File

@@ -70,9 +70,9 @@
{{#each list as |technique|}} {{#each list as |technique|}}
<li> <li>
{{#ifCond techName '==' 'title_ability'}} {{#ifCond techName '==' 'title_ability'}}
{{> 'systems/l5r5e/templates/items/title/title-text.html' data=technique editable=../../options.editable}} {{> 'systems/l5rx-chiaroscuro/templates/items/title/title-text.html' data=technique editable=../../options.editable}}
{{else}} {{else}}
{{> 'systems/l5r5e/templates/items/technique/technique-text.html' data=technique editable=../../options.editable}} {{> 'systems/l5rx-chiaroscuro/templates/items/technique/technique-text.html' data=technique editable=../../options.editable}}
{{/ifCond}} {{/ifCond}}
</li> </li>
{{/each}} {{/each}}
@@ -86,7 +86,7 @@
<ul> <ul>
{{#each actor.items as |scroll|}} {{#each actor.items as |scroll|}}
{{#ifCond scroll.type '==' 'signature_scroll'}} {{#ifCond scroll.type '==' 'signature_scroll'}}
<li>{{> 'systems/l5r5e/templates/items/signature-scroll/signature-scroll-text.html' data=scroll editable=../options.editable}}</li> <li>{{> 'systems/l5rx-chiaroscuro/templates/items/signature-scroll/signature-scroll-text.html' data=scroll editable=../options.editable}}</li>
{{/ifCond}} {{/ifCond}}
{{/each}} {{/each}}
</ul> </ul>
@@ -97,7 +97,7 @@
<ul> <ul>
{{#each data.items as |item|}} {{#each data.items as |item|}}
{{#ifCond '["distinction","passion"]' 'includes' item.system.peculiarity_type}} {{#ifCond '["distinction","passion"]' 'includes' item.system.peculiarity_type}}
<li>{{> 'systems/l5r5e/templates/items/peculiarity/peculiarity-text.html' data=item editable=../options.editable}}</li> <li>{{> 'systems/l5rx-chiaroscuro/templates/items/peculiarity/peculiarity-text.html' data=item editable=../options.editable}}</li>
{{/ifCond}} {{/ifCond}}
{{/each}} {{/each}}
</ul> </ul>
@@ -107,7 +107,7 @@
<ul> <ul>
{{#each data.items as |item|}} {{#each data.items as |item|}}
{{#ifCond '["adversity","anxiety"]' 'includes' item.system.peculiarity_type}} {{#ifCond '["adversity","anxiety"]' 'includes' item.system.peculiarity_type}}
<li>{{> 'systems/l5r5e/templates/items/peculiarity/peculiarity-text.html' data=item editable=../options.editable}}</li> <li>{{> 'systems/l5rx-chiaroscuro/templates/items/peculiarity/peculiarity-text.html' data=item editable=../options.editable}}</li>
{{/ifCond}} {{/ifCond}}
{{/each}} {{/each}}
</ul> </ul>
@@ -117,7 +117,7 @@
<ul> <ul>
{{#each data.items as |bond|}} {{#each data.items as |bond|}}
{{#ifCond bond.type '==' 'bond'}} {{#ifCond bond.type '==' 'bond'}}
<li>{{> 'systems/l5r5e/templates/items/bond/bond-text.html' data=bond editable=../options.editable}}</li> <li>{{> 'systems/l5rx-chiaroscuro/templates/items/bond/bond-text.html' data=bond editable=../options.editable}}</li>
{{/ifCond}} {{/ifCond}}
{{/each}} {{/each}}
</ul> </ul>
@@ -133,7 +133,7 @@
<strong>{{localize (localize 'l5r5e.{type}s.title' type=type)}} ({{cat.length}})</strong> <strong>{{localize (localize 'l5r5e.{type}s.title' type=type)}} ({{cat.length}})</strong>
<ul> <ul>
{{#each cat as |item|}} {{#each cat as |item|}}
<li>{{> 'systems/l5r5e/templates/items/item/item-text.html' data=item editable=../../options.editable}}</li> <li>{{> 'systems/l5rx-chiaroscuro/templates/items/item/item-text.html' data=item editable=../../options.editable}}</li>
{{/each}} {{/each}}
</ul> </ul>
</li> </li>
@@ -145,7 +145,7 @@
<ul> <ul>
{{#each actor.items as |pattern|}} {{#each actor.items as |pattern|}}
{{#ifCond pattern.type '==' 'item_pattern'}} {{#ifCond pattern.type '==' 'item_pattern'}}
<li>{{> 'systems/l5r5e/templates/items/item-pattern/item-pattern-text.html' data=pattern editable=../options.editable}}</li> <li>{{> 'systems/l5rx-chiaroscuro/templates/items/item-pattern/item-pattern-text.html' data=pattern editable=../options.editable}}</li>
{{/ifCond}} {{/ifCond}}
{{/each}} {{/each}}
</ul> </ul>

View File

@@ -13,9 +13,9 @@
<div class="readiness"> <div class="readiness">
<ul> <ul>
<li> <li>
<label class="attribute-label-casualties"> <label class="attribute-label casualties">
<input name="system.battle_readiness.casualties_strength.value" type="number" value="{{data.system.battle_readiness.casualties_strength.value}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input name="system.battle_readiness.casualties_strength.value" type="number" value="{{data.system.battle_readiness.casualties_strength.value}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
<span class="attributes-buttons"> <span class="increment-control casualties">
<i class="addsub-control pointer-choice fa fa-plus-square" data-type="casualties" data-value="1"></i> <i class="addsub-control pointer-choice fa fa-plus-square" data-type="casualties" data-value="1"></i>
<i class="addsub-control pointer-choice fa fa-minus-square" data-type="casualties" data-value="-1"></i> <i class="addsub-control pointer-choice fa fa-minus-square" data-type="casualties" data-value="-1"></i>
</span> </span>
@@ -23,15 +23,15 @@
<strong>{{localize 'l5r5e.army.battle_readiness.casualties'}}</strong> <strong>{{localize 'l5r5e.army.battle_readiness.casualties'}}</strong>
</li> </li>
<li> <li>
<label class="attribute-label-strength"> <label class="attribute-label strength">
<input name="system.battle_readiness.casualties_strength.max" type="number" value="{{data.system.battle_readiness.casualties_strength.max}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input name="system.battle_readiness.casualties_strength.max" type="number" value="{{data.system.battle_readiness.casualties_strength.max}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
<strong>{{localize 'l5r5e.army.battle_readiness.strength'}}</strong> <strong>{{localize 'l5r5e.army.battle_readiness.strength'}}</strong>
</li> </li>
<li> <li>
<label class="attribute-label-panic"> <label class="attribute-label panic">
<input name="system.battle_readiness.panic_discipline.value" type="number" value="{{data.system.battle_readiness.panic_discipline.value}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input name="system.battle_readiness.panic_discipline.value" type="number" value="{{data.system.battle_readiness.panic_discipline.value}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
<span class="attributes-buttons"> <span class="increment-control panic">
<i class="addsub-control pointer-choice fa fa-plus-square" data-type="panic" data-value="1"></i> <i class="addsub-control pointer-choice fa fa-plus-square" data-type="panic" data-value="1"></i>
<i class="addsub-control pointer-choice fa fa-minus-square" data-type="panic" data-value="-1"></i> <i class="addsub-control pointer-choice fa fa-minus-square" data-type="panic" data-value="-1"></i>
</span> </span>
@@ -39,7 +39,7 @@
<strong>{{localize 'l5r5e.army.battle_readiness.panic'}}</strong> <strong>{{localize 'l5r5e.army.battle_readiness.panic'}}</strong>
</li> </li>
<li> <li>
<label class="attribute-label-discipline"> <label class="attribute-label discipline">
<input name="system.battle_readiness.panic_discipline.max" type="number" value="{{data.system.battle_readiness.panic_discipline.max}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input name="system.battle_readiness.panic_discipline.max" type="number" value="{{data.system.battle_readiness.panic_discipline.max}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
<strong>{{localize 'l5r5e.army.battle_readiness.discipline'}}</strong> <strong>{{localize 'l5r5e.army.battle_readiness.discipline'}}</strong>
@@ -60,22 +60,22 @@
{{!-- Army Tab --}} {{!-- Army Tab --}}
<article class="tab army" data-group="primary" data-tab="army"> <article class="tab army" data-group="primary" data-tab="army">
{{> 'systems/l5r5e/templates/actors/army/army.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/army/army.html'}}
</article> </article>
{{!-- Cohort Tab --}} {{!-- Cohort Tab --}}
<article class="tab cohort" data-group="primary" data-tab="cohort"> <article class="tab cohort" data-group="primary" data-tab="cohort">
{{> 'systems/l5r5e/templates/actors/army/cohort.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/army/cohort.html'}}
</article> </article>
{{!-- Fortification Tab --}} {{!-- Fortification Tab --}}
<article class="tab fortification" data-group="primary" data-tab="fortification"> <article class="tab fortification" data-group="primary" data-tab="fortification">
{{> 'systems/l5r5e/templates/actors/army/fortification.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/army/fortification.html'}}
</article> </article>
{{!-- Others Tab --}} {{!-- Others Tab --}}
<article class="tab others" data-group="primary" data-tab="others"> <article class="tab others" data-group="primary" data-tab="others">
{{> 'systems/l5r5e/templates/actors/army/others.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/army/others.html'}}
</article> </article>
</section> </section>
</form> </form>

View File

@@ -7,7 +7,7 @@
</legend> </legend>
<ul class="item-list"> <ul class="item-list">
{{#each data.splitItemsList.army_cohort as |item|}} {{#each data.splitItemsList.army_cohort as |item|}}
{{> 'systems/l5r5e/templates/items/army-cohort/army-cohort-entry.html' cohort=item editable=../data.editable_not_soft_locked}} {{> 'systems/l5rx-chiaroscuro/templates/items/army-cohort/army-cohort-entry.html' cohort=item editable=../data.editable_not_soft_locked}}
{{/each}} {{/each}}
</ul> </ul>
</fieldset> </fieldset>

View File

@@ -7,7 +7,7 @@
</legend> </legend>
<ul class="item-list"> <ul class="item-list">
{{#each data.splitItemsList.army_fortification as |item|}} {{#each data.splitItemsList.army_fortification as |item|}}
{{> 'systems/l5r5e/templates/items/army-fortification/army-fortification-entry.html' fortification=item editable=../data.editable_not_soft_locked}} {{> 'systems/l5rx-chiaroscuro/templates/items/army-fortification/army-fortification-entry.html' fortification=item editable=../data.editable_not_soft_locked}}
{{/each}} {{/each}}
</ul> </ul>
</fieldset> </fieldset>

View File

@@ -15,62 +15,69 @@
<input name="name" type="text" value="{{data.name}}" placeholder="Name" {{^if <input name="name" type="text" value="{{data.name}}" placeholder="Name" {{^if
data.editable_not_soft_locked}}disabled{{/if}} /> data.editable_not_soft_locked}}disabled{{/if}} />
</h1> </h1>
{{> 'systems/l5r5e/templates/actors/character/identity.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/identity.html'}}
</div> </div>
<div class="header-fields mid-wrapper"> <div class="header-fields mid-wrapper">
<div class="side-col"> <div class="central-col">{{> 'systems/l5rx-chiaroscuro/templates/actors/character/rings.html'}}</div>
<h2>{{localize 'l5r5e.social.title'}}</h2>
{{> 'systems/l5r5e/templates/actors/character/social.html'}}
</div>
<div class="central-col">{{> 'systems/l5r5e/templates/actors/character/rings.html'}}</div>
<div class="side-col">
<h2 class="right">{{localize 'l5r5e.attributes.title'}}</h2>
{{> 'systems/l5r5e/templates/actors/character/attributes.html'}}
</div> </div>
<div class="header-fields chiaroscuro-aspects-wrapper">
{{> 'systems/l5rx-chiaroscuro/templates/actors/character/aspects.html'}}
</div> </div>
</header> </header>
{{!-- Sheet Body --}} {{!-- Sheet Body --}}
<section class="sheet-body"> <section class="sheet-body">
{{!-- Active effects --}} {{!-- Active effects --}}
{{> 'systems/l5r5e/templates/actors/character/effects.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/effects.html'}}
{{!-- Sheet Tab Navigation --}} {{!-- Sheet Tab Navigation --}}
<nav class="sheet-tabs tabs" data-group="primary"> <nav class="sheet-tabs tabs" data-group="primary">
<a class="item" data-tab="skills">{{localize 'l5r5e.skills.title'}}</a> <a class="item" data-tab="skills">{{localize 'l5r5e.skills.title'}}</a>
<a class="item" data-tab="narrative">{{localize 'l5r5e.sheets.narrative'}}</a> <a class="item" data-tab="narrative">{{localize 'l5r5e.sheets.narrative'}}</a>
<a class="item" data-tab="invocations">{{localize 'chiaroscuro.tabs.invocations'}}</a>
<a class="item" data-tab="conflict">{{localize 'l5r5e.conflict.title'}}</a> <a class="item" data-tab="conflict">{{localize 'l5r5e.conflict.title'}}</a>
<a class="item" data-tab="inventory">{{localize 'l5r5e.sheets.inventory'}}</a> <a class="item" data-tab="inventory">{{localize 'l5r5e.sheets.inventory'}}</a>
<a class="item" data-tab="experience">{{localize 'l5r5e.sheets.experience'}}</a> <a class="item" data-tab="experience">{{localize 'l5r5e.sheets.experience'}}</a>
<a class="item" data-tab="identity">{{localize 'chiaroscuro.tabs.identity'}}</a>
</nav> </nav>
{{!-- Skills Tab --}} {{!-- Skills Tab --}}
<article class="tab skills" data-group="primary" data-tab="skills"> <article class="tab skills" data-group="primary" data-tab="skills">
<ul class="skills-wrapper"> <ul class="skills-wrapper">
{{#each data.system.skills as |category id|}} {{> {{#each data.system.skills as |category id|}} {{>
'systems/l5r5e/templates/actors/character/category.html' category=category categoryId=id data=../data}} 'systems/l5rx-chiaroscuro/templates/actors/character/category.html' category=category categoryId=id data=../data}}
{{/each}} {{/each}}
</ul> </ul>
{{> 'systems/l5r5e/templates/actors/character/techniques.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/techniques.html'}}
</article> </article>
{{!-- Narrative Tab --}} {{!-- Narrative Tab --}}
<article class="tab narrative" data-group="primary" data-tab="narrative"> <article class="tab narrative" data-group="primary" data-tab="narrative">
{{> 'systems/l5r5e/templates/actors/character/narrative.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/narrative.html'}}
</article> </article>
{{!-- Conflict Tab --}} {{!-- Conflict Tab --}}
<article class="tab conflict" data-group="primary" data-tab="conflict"> <article class="tab conflict" data-group="primary" data-tab="conflict">
{{> 'systems/l5r5e/templates/actors/character/conflict.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/conflict.html'}}
</article> </article>
{{!-- Inventory Tab --}} {{!-- Inventory Tab --}}
<article class="tab inventory" data-group="primary" data-tab="inventory"> <article class="tab inventory" data-group="primary" data-tab="inventory">
{{> 'systems/l5r5e/templates/actors/character/inventory.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/inventory.html'}}
</article> </article>
{{!-- Experience Tab --}} {{!-- Experience Tab --}}
<article class="tab experience" data-group="primary" data-tab="experience"> <article class="tab experience" data-group="primary" data-tab="experience">
{{> 'systems/l5r5e/templates/actors/character/experience.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/experience.html'}}
</article>
{{!-- Invocations Tab --}}
<article class="tab invocations" data-group="primary" data-tab="invocations">
{{> 'systems/l5rx-chiaroscuro/templates/actors/character/invocations.html'}}
</article>
{{!-- Identity Tab --}}
<article class="tab identity" data-group="primary" data-tab="identity">
{{> 'systems/l5rx-chiaroscuro/templates/actors/character/identity-text.html'}}
</article> </article>
</section> </section>
</form> </form>

View File

@@ -0,0 +1,30 @@
<div class="aspects-section">
<div class="aspect-fields">
<label class="attribute-label">
{{localize 'chiaroscuro.aspects.solar'}}
<input type="number" name="system.aspects.aspects.solar" value="{{data.system.aspects.aspects.solar}}" class="select-on-focus" data-dtype="Number" min="0" max="100" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label>
<label class="attribute-label">
{{localize 'chiaroscuro.aspects.lunar'}}
<input type="number" name="system.aspects.aspects.lunar" value="{{data.system.aspects.aspects.lunar}}" class="select-on-focus" data-dtype="Number" min="0" max="100" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label>
<label class="attribute-label">
{{localize 'chiaroscuro.aspects.gauge'}}
<input type="number" name="system.aspects.aspects.gauge" value="{{data.system.aspects.aspects.gauge}}" class="select-on-focus" data-dtype="Number" min="-10" max="10" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label>
<div class="gauge-bar-wrapper">
<div class="gauge-bar" style="width: {{data.aspectsData.gaugePercent}}%; background-color: {{data.aspectsData.gaugeColor}};"></div>
</div>
</div>
{{#if data.etatItems.length}}
<div class="etat-summary">
<span class="etat-summary-label">{{localize 'chiaroscuro.etat.title'}}</span>
{{#each data.etatItems as |etat|}}
<span class="etat-badge l5r5e-tooltip" title="{{etat.system.effect}}">
<img src="{{etat.img}}" width="16" height="16" />
{{etat.name}}
</span>
{{/each}}
</div>
{{/if}}
</div>

View File

@@ -7,7 +7,7 @@
<label class="attribute-label"> <label class="attribute-label">
<strong>{{localize 'l5r5e.attributes.fatigue'}}</strong> <strong>{{localize 'l5r5e.attributes.fatigue'}}</strong>
<input class="centered-input select-on-focus" type="number" name="system.fatigue.value" value="{{data.system.fatigue.value}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input class="centered-input select-on-focus" type="number" name="system.fatigue.value" value="{{data.system.fatigue.value}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
<span class="attributes-buttons"> <span class="increment-control fatigue">
<i class="addsub-control pointer-choice fa fa-plus-square" data-type="fatigue" data-value="1"></i> <i class="addsub-control pointer-choice fa fa-plus-square" data-type="fatigue" data-value="1"></i>
<i class="addsub-control pointer-choice fa fa-minus-square" data-type="fatigue" data-value="-1"></i> <i class="addsub-control pointer-choice fa fa-minus-square" data-type="fatigue" data-value="-1"></i>
</span> </span>
@@ -22,7 +22,7 @@
<label class="attribute-label"> <label class="attribute-label">
<strong>{{localize 'l5r5e.attributes.strife'}}</strong> <strong>{{localize 'l5r5e.attributes.strife'}}</strong>
<input class="centered-input select-on-focus" type="number" name="system.strife.value" value="{{data.system.strife.value}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input class="centered-input select-on-focus" type="number" name="system.strife.value" value="{{data.system.strife.value}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
<span class="attributes-buttons"> <span class="increment-control strife">
<i class="addsub-control pointer-choice fa fa-plus-square" data-type="strife" data-value="1"></i> <i class="addsub-control pointer-choice fa fa-plus-square" data-type="strife" data-value="1"></i>
<i class="addsub-control pointer-choice fa fa-minus-square" data-type="strife" data-value="-1"></i> <i class="addsub-control pointer-choice fa fa-minus-square" data-type="strife" data-value="-1"></i>
</span> </span>

View File

@@ -2,7 +2,7 @@
<h4 class="section-header toggle-on-click" data-toggle="toggle-skill-category-{{categoryId}}">{{localizeSkill categoryId 'title'}}</h4> <h4 class="section-header toggle-on-click" data-toggle="toggle-skill-category-{{categoryId}}">{{localizeSkill categoryId 'title'}}</h4>
<ul class="skill-category-skills-list toggle-skill-category-{{categoryId}} {{#ifCond data.storeInfos 'includes' (concat 'toggle-skill-category-' categoryId)}}toggle-hidden{{/ifCond}}"> <ul class="skill-category-skills-list toggle-skill-category-{{categoryId}} {{#ifCond data.storeInfos 'includes' (concat 'toggle-skill-category-' categoryId)}}toggle-hidden{{/ifCond}}">
{{#each category as |skill id|}} {{#each category as |skill id|}}
{{> 'systems/l5r5e/templates/actors/character/skill.html' categoryId=../categoryId skill=skill skillId=id data=../data}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/skill.html' categoryId=../categoryId skill=skill skillId=id data=../data}}
{{/each}} {{/each}}
</ul> </ul>
<ul class="skill-category-ring-actions toggle-skill-category-{{categoryId}} {{#ifCond data.storeInfos 'includes' (concat 'toggle-skill-category-' categoryId)}}toggle-hidden{{/ifCond}}"> <ul class="skill-category-ring-actions toggle-skill-category-{{categoryId}} {{#ifCond data.storeInfos 'includes' (concat 'toggle-skill-category-' categoryId)}}toggle-hidden{{/ifCond}}">

View File

@@ -14,9 +14,8 @@
<legend class="section-header">{{localize 'l5r5e.conflict.stance'}}</legend> <legend class="section-header">{{localize 'l5r5e.conflict.stance'}}</legend>
<ul class="item-list"> <ul class="item-list">
{{#each data.system.rings as |ringValue ringId|}} {{#each data.system.rings as |ringValue ringId|}}
{{> 'systems/l5r5e/templates/actors/character/stance.html' stance=../data.system.stance ringId=ringId}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/stance.html' stance=../data.system.stance ringId=ringId}}
{{/each}} {{/each}}
</ul> </ul>
</fieldset> </fieldset>
{{> 'systems/l5r5e/templates/items/weapon/weapons.html' }}
{{> 'systems/l5r5e/templates/items/armor/armors.html' }}

View File

@@ -3,6 +3,10 @@
<label class="attribute-label"> <label class="attribute-label">
{{localize 'l5r5e.advancements.total'}} {{localize 'l5r5e.advancements.total'}}
<input class="centered-input select-on-focus" type="number" name="system.xp_total" value="{{data.system.xp_total}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input class="centered-input select-on-focus" type="number" name="system.xp_total" value="{{data.system.xp_total}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
<span class="increment-control xp">
<i class="xp-control pointer-choice fa fa-plus-square" data-type="xp" data-value="1"></i>
<i class="xp-control pointer-choice fa fa-minus-square" data-type="xp" data-value="-1"></i>
</span>
</label> </label>
<label class="attribute-label"> <label class="attribute-label">
{{localize 'l5r5e.advancements.spent'}} {{localize 'l5r5e.advancements.spent'}}
@@ -48,7 +52,7 @@
<tbody class="flex"> <tbody class="flex">
{{#each data.advancementsListByRank as |rankObject|}} {{#each data.advancementsListByRank as |rankObject|}}
{{#each rankObject.list as |advancement advancementId|}} {{#each rankObject.list as |advancement advancementId|}}
{{> 'systems/l5r5e/templates/actors/character/advancement-school.html' advancement=advancement rank=rankObject.rank editable=../../data.editable_not_soft_locked}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/advancement-school.html' advancement=advancement rank=rankObject.rank editable=../../data.editable_not_soft_locked}}
{{/each}} {{/each}}
{{#ifCond rankObject.rank '>' 0}} {{#ifCond rankObject.rank '>' 0}}
<tr class="tfoot flexrow row tab" data-group="advancements" data-tab="advancement_rank_{{rankObject.rank}}"> <tr class="tfoot flexrow row tab" data-group="advancements" data-tab="advancement_rank_{{rankObject.rank}}">
@@ -94,7 +98,7 @@
</thead> </thead>
<tbody class="flex"> <tbody class="flex">
{{#each data.advancementsOthers as |advancement advancementId|}} {{#each data.advancementsOthers as |advancement advancementId|}}
{{> 'systems/l5r5e/templates/actors/character/advancement-others.html' advancement=advancement show_curriculum_toggle=false editable=../data.editable_not_soft_locked}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/advancement-others.html' advancement=advancement show_curriculum_toggle=false editable=../data.editable_not_soft_locked}}
{{/each}} {{/each}}
</tbody> </tbody>
<tfoot class="flex"> <tfoot class="flex">

View File

@@ -0,0 +1,10 @@
<div class="identity-text-wrapper flexrow">
<fieldset class="identity-text-block">
<legend class="text-block-header">{{localize 'chiaroscuro.tabs.identity_text1'}}</legend>
{{editor data.enrichedHtml.identity_text1 target="system.identity_text1" button=true editable=options.editable engine="prosemirror" collaborate=false}}
</fieldset>
<fieldset class="identity-text-block">
<legend class="text-block-header">{{localize 'chiaroscuro.tabs.identity_text2'}}</legend>
{{editor data.enrichedHtml.identity_text2 target="system.identity_text2" button=true editable=options.editable engine="prosemirror" collaborate=false}}
</fieldset>
</div>

View File

@@ -1,28 +1,44 @@
<ul class="identity-content"> <ul class="identity-content">
<li> <li>
<label class="attribute-label"> <label class="attribute-label">
{{#ifCond data.system.template '==' 'pow'}} {{#if data.system.is_samurai}}
{{localize 'l5r5e.sheets.region'}}
{{else}}
{{localize 'l5r5e.clans.label'}} {{localize 'l5r5e.clans.label'}}
{{/ifCond}} {{else}}
{{localize 'chiaroscuro.character.region'}}
{{/if}}
<input type="text" name="system.identity.clan" value="{{data.system.identity.clan}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input type="text" name="system.identity.clan" value="{{data.system.identity.clan}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
</li> </li>
<li> <li>
<label class="attribute-label"> <label class="attribute-label">
{{#ifCond data.system.template '==' 'pow'}} {{#if data.system.is_samurai}}
{{localize 'l5r5e.sheets.upbringing'}}
{{else}}
{{localize 'l5r5e.sheets.family'}} {{localize 'l5r5e.sheets.family'}}
{{/ifCond}} {{else}}
{{localize 'chiaroscuro.character.education'}}
{{/if}}
<input type="text" name="system.identity.family" value="{{data.system.identity.family}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input type="text" name="system.identity.family" value="{{data.system.identity.family}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
</li> </li>
<li> <li>
<label class="attribute-label"> <label class="attribute-label">
{{localize 'l5r5e.sheets.rank'}} {{localize 'l5r5e.social.status'}}
<input type="number" name="system.identity.school_rank" value="{{data.system.identity.school_rank}}" class="select-on-focus" data-dtype="Number" min="0" placeholder="1" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <span class="increment-control status">
<i class="addsub-control pointer-choice fa fa-plus-square" data-type="status" data-value="1"></i>
<i class="addsub-control pointer-choice fa fa-minus-square" data-type="status" data-value="-1"></i>
</span>
<input class="select-on-focus" type="number" name="system.social.status" value="{{data.system.social.status}}" data-dtype="Number" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label>
</li>
<li>
<label class="attribute-label is-samurai-label">
{{localize 'chiaroscuro.character.is_samurai'}}
<input type="checkbox" name="system.is_samurai" {{checked data.system.is_samurai}} {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label>
</li>
<li>
<label class="attribute-label">
{{localize 'chiaroscuro.character.title'}}
<input type="text" name="system.identity.title" value="{{data.system.identity.title}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
</li> </li>
<li> <li>
@@ -37,4 +53,10 @@
<input type="text" name="system.identity.roles" value="{{data.system.identity.roles}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input type="text" name="system.identity.roles" value="{{data.system.identity.roles}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
</li> </li>
<li>
<label class="attribute-label quick-info-label">
{{localize 'chiaroscuro.character.quick_info'}}
<input type="text" name="system.quick_info" value="{{data.system.quick_info}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label>
</li>
</ul> </ul>

View File

@@ -1,25 +1,25 @@
<fieldset class="money money-wrapper"> <fieldset class="money money-wrapper">
<legend class="section-header">{{localize 'l5r5e.money.title'}}</legend> <legend class="section-header">{{localize 'l5r5e.money.title'}}</legend>
<label> <label class="attribute-label money">
{{localize 'l5r5e.money.koku'}} {{localize 'l5r5e.money.koku'}}
<input name="system.money.koku" type="number" value="{{data.system.money.koku}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input name="system.money.koku" type="number" value="{{data.system.money.koku}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
<span class="money-buttons"> <span class="increment-control money">
<i class="money-control pointer-choice fa fa-plus-square" data-type="koku" data-value="1"></i> <i class="money-control pointer-choice fa fa-plus-square" data-type="koku" data-value="1"></i>
<i class="money-control pointer-choice fa fa-minus-square" data-type="koku" data-value="-1"></i> <i class="money-control pointer-choice fa fa-minus-square" data-type="koku" data-value="-1"></i>
</span> </span>
</label> </label>
<label> <label class="attribute-label money">
{{localize 'l5r5e.money.bu'}} {{localize 'l5r5e.money.bu'}}
<input name="system.money.bu" type="number" value="{{data.system.money.bu}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input name="system.money.bu" type="number" value="{{data.system.money.bu}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
<span class="money-buttons"> <span class="increment-control money">
<i class="money-control pointer-choice fa fa-plus-square" data-type="bu" data-value="1"></i> <i class="money-control pointer-choice fa fa-plus-square" data-type="bu" data-value="1"></i>
<i class="money-control pointer-choice fa fa-minus-square" data-type="bu" data-value="-1"></i> <i class="money-control pointer-choice fa fa-minus-square" data-type="bu" data-value="-1"></i>
</span> </span>
</label> </label>
<label> <label class="attribute-label money">
{{localize 'l5r5e.money.zeni'}} {{localize 'l5r5e.money.zeni'}}
<input name="system.money.zeni" type="number" value="{{data.system.money.zeni}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input name="system.money.zeni" type="number" value="{{data.system.money.zeni}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
<span class="money-buttons"> <span class="increment-control money">
<i class="money-control pointer-choice fa fa-plus-square" data-type="zeni" data-value="1"></i> <i class="money-control pointer-choice fa fa-plus-square" data-type="zeni" data-value="1"></i>
<i class="money-control pointer-choice fa fa-minus-square" data-type="zeni" data-value="-1"></i> <i class="money-control pointer-choice fa fa-minus-square" data-type="zeni" data-value="-1"></i>
</span> </span>
@@ -28,7 +28,7 @@
{{!-- items list --}} {{!-- items list --}}
<fieldset class="items-wrapper"> <fieldset class="items-wrapper">
<legend>{{localize 'l5r5e.sheets.equipment'}}</legend> <legend>{{localize 'l5r5e.sheets.equipment'}}</legend>
{{> 'systems/l5r5e/templates/items/item/items.html'}} {{> 'systems/l5rx-chiaroscuro/templates/items/item/items.html'}}
</fieldset> </fieldset>
{{!-- item patterns list --}} {{!-- item patterns list --}}
<fieldset> <fieldset>
@@ -41,7 +41,7 @@
<ul class="item-list"> <ul class="item-list">
{{#each actor.items as |pattern id|}} {{#each actor.items as |pattern id|}}
{{#ifCond pattern.type '==' 'item_pattern'}} {{#ifCond pattern.type '==' 'item_pattern'}}
{{> 'systems/l5r5e/templates/items/item-pattern/item-pattern-entry.html' pattern=pattern id=id editable=../data.editable_not_soft_locked}} {{> 'systems/l5rx-chiaroscuro/templates/items/item-pattern/item-pattern-entry.html' pattern=pattern id=id editable=../data.editable_not_soft_locked}}
{{/ifCond}} {{/ifCond}}
{{/each}} {{/each}}
</ul> </ul>

View File

@@ -0,0 +1,17 @@
<div class="invocations-wrapper">
{{#each data.splitInvocationsList as |list type|}}
<fieldset class="section-header flexrow">
<legend class="technique-controls">
<span>{{localize (concat 'chiaroscuro.technique.invocation_types.' type)}}</span>
{{#if ../data.editable_not_soft_locked}}
<a data-item-type="technique" class="technique-control item-add" data-tech-type="mot_invocation" title="{{localize 'l5r5e.global.add'}}"><i class="fas fa-plus"></i></a>
{{/if}}
</legend>
<ul class="item-list">
{{#each list as |item|}}
{{> 'systems/l5rx-chiaroscuro/templates/items/technique/technique-entry.html' technique=item editable=../../data.editable_not_soft_locked}}
{{/each}}
</ul>
</fieldset>
{{/each}}
</div>

View File

@@ -7,12 +7,16 @@
<textarea type="text" name="system.social.ninjo" {{^if data.editable_not_soft_locked}}disabled{{/if}}>{{data.system.social.ninjo}}</textarea> <textarea type="text" name="system.social.ninjo" {{^if data.editable_not_soft_locked}}disabled{{/if}}>{{data.system.social.ninjo}}</textarea>
</label> </label>
<label class="attribute-label"> <label class="attribute-label">
{{#ifCond data.system.template '==' 'pow'}} {{#if data.system.is_samurai}}
{{localize 'l5r5e.social.past'}}
{{else}}
{{localize 'l5r5e.social.giri'}} {{localize 'l5r5e.social.giri'}}
{{/ifCond}} {{else}}
{{localize 'chiaroscuro.character.past_problems'}}
{{/if}}
{{#if data.system.is_samurai}}
<textarea type="text" name="system.social.giri" {{^if data.editable_not_soft_locked}}disabled{{/if}}>{{data.system.social.giri}}</textarea> <textarea type="text" name="system.social.giri" {{^if data.editable_not_soft_locked}}disabled{{/if}}>{{data.system.social.giri}}</textarea>
{{else}}
<textarea type="text" name="system.social.past_problems" {{^if data.editable_not_soft_locked}}disabled{{/if}}>{{data.system.social.past_problems}}</textarea>
{{/if}}
</label> </label>
</fieldset> </fieldset>
{{!-- Bushido Tenets --}} {{!-- Bushido Tenets --}}
@@ -40,7 +44,7 @@
<ul class="item-list"> <ul class="item-list">
{{#each actor.items as |item id|}} {{#each actor.items as |item id|}}
{{#ifCond '["distinction","passion"]' 'includes' item.system.peculiarity_type}} {{#ifCond '["distinction","passion"]' 'includes' item.system.peculiarity_type}}
{{> 'systems/l5r5e/templates/items/peculiarity/peculiarity-entry.html' peculiarity=item id=id editable=../data.editable_not_soft_locked}} {{> 'systems/l5rx-chiaroscuro/templates/items/peculiarity/peculiarity-entry.html' peculiarity=item id=id editable=../data.editable_not_soft_locked}}
{{/ifCond}} {{/ifCond}}
{{/each}} {{/each}}
</ul> </ul>
@@ -56,7 +60,7 @@
<ul class="item-list"> <ul class="item-list">
{{#each actor.items as |item id|}} {{#each actor.items as |item id|}}
{{#ifCond '["adversity","anxiety"]' 'includes' item.system.peculiarity_type}} {{#ifCond '["adversity","anxiety"]' 'includes' item.system.peculiarity_type}}
{{> 'systems/l5r5e/templates/items/peculiarity/peculiarity-entry.html' peculiarity=item id=id editable=../data.editable_not_soft_locked}} {{> 'systems/l5rx-chiaroscuro/templates/items/peculiarity/peculiarity-entry.html' peculiarity=item id=id editable=../data.editable_not_soft_locked}}
{{/ifCond}} {{/ifCond}}
{{/each}} {{/each}}
</ul> </ul>
@@ -72,7 +76,7 @@
<ul class="item-list"> <ul class="item-list">
{{#each actor.items as |bond id|}} {{#each actor.items as |bond id|}}
{{#ifCond bond.type '==' 'bond'}} {{#ifCond bond.type '==' 'bond'}}
{{> 'systems/l5r5e/templates/items/bond/bond-entry.html' bond=bond id=id editable=../data.editable_not_soft_locked}} {{> 'systems/l5rx-chiaroscuro/templates/items/bond/bond-entry.html' bond=bond id=id editable=../data.editable_not_soft_locked}}
{{/ifCond}} {{/ifCond}}
{{/each}} {{/each}}
</ul> </ul>

View File

@@ -1,36 +1,40 @@
<ul class="rings"> <ul class="rings">
<li id="earth">
<label class="earth {{#ifCond 'earth' '==' data.system.stance}}stance-active{{/ifCond}}">
<i class="i_earth dice-picker rollable" data-ring="earth"></i>
<strong>{{localizeRing 'earth'}}</strong>
<input class="centered-input select-on-focus" type="number" name="system.rings.earth" value="{{data.system.rings.earth}}" data-dtype="Number" min="1" max="9" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label>
</li>
<li id="air"> <li id="air">
<label class="air {{#ifCond 'air' '==' data.system.stance}}stance-active{{/ifCond}}"> <label class="air {{#ifCond 'air' '==' data.system.stance}}stance-active{{/ifCond}}">
<i class="i_air dice-picker rollable" data-ring="air"></i> <i class="i_air dice-picker rollable" data-ring="air"></i>
<strong>{{localizeRing 'air'}}</strong> <strong class="ring-set-default {{#ifCond 'air' '==' data.system.default_ring}}default-ring{{/ifCond}}" data-ring="air" title="{{localize 'chiaroscuro.character.default_ring'}}">{{localizeRing 'air'}}</strong>
<span class="ring-type solaire">☀ Solaire</span>
<input class="centered-input select-on-focus" type="number" name="system.rings.air" value="{{data.system.rings.air}}" data-dtype="Number" min="1" max="9" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input class="centered-input select-on-focus" type="number" name="system.rings.air" value="{{data.system.rings.air}}" data-dtype="Number" min="1" max="9" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
</li> </li>
<li id="water"> <li id="water">
<label class="water {{#ifCond 'water' '==' data.system.stance}}stance-active{{/ifCond}}"> <label class="water {{#ifCond 'water' '==' data.system.stance}}stance-active{{/ifCond}}">
<i class="i_water dice-picker rollable" data-ring="water"></i> <i class="i_water dice-picker rollable" data-ring="water"></i>
<strong>{{localizeRing 'water'}}</strong> <strong class="ring-set-default {{#ifCond 'water' '==' data.system.default_ring}}default-ring{{/ifCond}}" data-ring="water" title="{{localize 'chiaroscuro.character.default_ring'}}">{{localizeRing 'water'}}</strong>
<span class="ring-type lunaire">☽ Lunaire</span>
<input class="centered-input select-on-focus" type="number" name="system.rings.water" value="{{data.system.rings.water}}" data-dtype="Number" min="1" max="9" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input class="centered-input select-on-focus" type="number" name="system.rings.water" value="{{data.system.rings.water}}" data-dtype="Number" min="1" max="9" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
</li> </li>
<li id="fire"> <li id="fire">
<label class="fire {{#ifCond 'fire' '==' data.system.stance}}stance-active{{/ifCond}}"> <label class="fire {{#ifCond 'fire' '==' data.system.stance}}stance-active{{/ifCond}}">
<i class="i_fire dice-picker rollable" data-ring="fire"></i> <i class="i_fire dice-picker rollable" data-ring="fire"></i>
<strong>{{localizeRing 'fire'}}</strong> <strong class="ring-set-default {{#ifCond 'fire' '==' data.system.default_ring}}default-ring{{/ifCond}}" data-ring="fire" title="{{localize 'chiaroscuro.character.default_ring'}}">{{localizeRing 'fire'}}</strong>
<span class="ring-type solaire">☀ Solaire</span>
<input class="centered-input select-on-focus" type="number" name="system.rings.fire" value="{{data.system.rings.fire}}" data-dtype="Number" min="1" max="9" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input class="centered-input select-on-focus" type="number" name="system.rings.fire" value="{{data.system.rings.fire}}" data-dtype="Number" min="1" max="9" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
</li> </li>
<li id="earth">
<label class="earth {{#ifCond 'earth' '==' data.system.stance}}stance-active{{/ifCond}}">
<i class="i_earth dice-picker rollable" data-ring="earth"></i>
<strong class="ring-set-default {{#ifCond 'earth' '==' data.system.default_ring}}default-ring{{/ifCond}}" data-ring="earth" title="{{localize 'chiaroscuro.character.default_ring'}}">{{localizeRing 'earth'}}</strong>
<span class="ring-type lunaire">☽ Lunaire</span>
<input class="centered-input select-on-focus" type="number" name="system.rings.earth" value="{{data.system.rings.earth}}" data-dtype="Number" min="1" max="9" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label>
</li>
<li id="void"> <li id="void">
<label class="void {{#ifCond 'void' '==' data.system.stance}}stance-active{{/ifCond}}"> <label class="void {{#ifCond 'void' '==' data.system.stance}}stance-active{{/ifCond}}">
<i class="i_void dice-picker rollable" data-ring="void"></i> <i class="i_void dice-picker rollable" data-ring="void"></i>
<strong>{{localizeRing 'void'}}</strong> <strong class="ring-set-default {{#ifCond 'void' '==' data.system.default_ring}}default-ring{{/ifCond}}" data-ring="void" title="{{localize 'chiaroscuro.character.default_ring'}}">{{localizeRing 'void'}}</strong>
<input class="centered-input select-on-focus" type="number" name="system.rings.void" value="{{data.system.rings.void}}" data-dtype="Number" min="1" max="9" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input class="centered-input select-on-focus" type="number" name="system.rings.void" value="{{data.system.rings.void}}" data-dtype="Number" min="1" max="9" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
</li> </li>

View File

@@ -1,16 +1,9 @@
<li class="skill skill-wrapper"> <li class="skill skill-wrapper">
<label class="skill-content"> <label class="skill-content">
<span class="dice-picker attribute-label rollable" data-skill="{{skillId}}">{{localizeSkill categoryId skillId}}</span> <span class="dice-picker attribute-label rollable" data-skill="{{skillId}}">{{localizeSkill categoryId skillId}}</span>
<input <select name="system.skills.{{categoryId}}.{{skillId}}" {{^if data.editable_not_soft_locked}}disabled{{/if}}>
class="centered-input select-on-focus" {{selectOptions data.skillRanksList selected=skill valueAttr='id' labelAttr='label'}}
type="number" </select>
name="system.skills.{{categoryId}}.{{skillId}}" {{#ifCond skill '!=' '0'}}<span class="skill-bonus">+{{skillRankBonus skill}}</span>{{/ifCond}}
value="{{skill}}"
data-dtype="Number"
min="0"
max="9"
placeholder="0"
{{^if data.editable_not_soft_locked}}disabled{{/if}}
/>
</label> </label>
</li> </li>

View File

@@ -2,18 +2,30 @@
<li> <li>
<label class="attribute-label centered-input"> <label class="attribute-label centered-input">
<strong>{{localize 'l5r5e.social.honor'}}</strong> <strong>{{localize 'l5r5e.social.honor'}}</strong>
<span class="increment-control honor">
<i class="addsub-control pointer-choice fa fa-plus-square" data-type="honor" data-value="1"></i>
<i class="addsub-control pointer-choice fa fa-minus-square" data-type="honor" data-value="-1"></i>
</span>
<input class="centered-input select-on-focus" type="number" name="system.social.honor" value="{{data.system.social.honor}}" data-dtype="Number" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input class="centered-input select-on-focus" type="number" name="system.social.honor" value="{{data.system.social.honor}}" data-dtype="Number" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
</li> </li>
<li> <li>
<label class="attribute-label centered-input"> <label class="attribute-label centered-input">
<strong>{{localize 'l5r5e.social.glory'}}</strong> <strong>{{localize 'l5r5e.social.glory'}}</strong>
<span class="increment-control glory">
<i class="addsub-control pointer-choice fa fa-plus-square" data-type="glory" data-value="1"></i>
<i class="addsub-control pointer-choice fa fa-minus-square" data-type="glory" data-value="-1"></i>
</span>
<input class="centered-input select-on-focus" type="number" name="system.social.glory" value="{{data.system.social.glory}}" data-dtype="Number" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input class="centered-input select-on-focus" type="number" name="system.social.glory" value="{{data.system.social.glory}}" data-dtype="Number" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
</li> </li>
<li> <li>
<label class="attribute-label centered-input"> <label class="attribute-label centered-input">
<strong>{{localize 'l5r5e.social.status'}}</strong> <strong>{{localize 'l5r5e.social.status'}}</strong>
<span class="increment-control status">
<i class="addsub-control pointer-choice fa fa-plus-square" data-type="status" data-value="1"></i>
<i class="addsub-control pointer-choice fa fa-minus-square" data-type="status" data-value="-1"></i>
</span>
<input class="centered-input select-on-focus" type="number" name="system.social.status" value="{{data.system.social.status}}" data-dtype="Number" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input class="centered-input select-on-focus" type="number" name="system.social.status" value="{{data.system.social.status}}" data-dtype="Number" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
</li> </li>

View File

@@ -1,48 +1,52 @@
<div class="techniques-wrapper"> <div class="techniques-wrapper">
{{!-- technique types --}} {{!-- Arcane items list --}}
<div class="checklist">
<i>{{localize 'l5r5e.techniques.type'}}</i>
{{#each data.techniquesList as |technique|}}
{{#ifCond ../data.editable_not_soft_locked '||' (lookup ../data.system.techniques technique.id)}}
<label>
<input type="checkbox" name="system.techniques.{{technique.id}}" {{checked (lookup ../data.system.techniques technique.id)}} {{^if ../data.editable_not_soft_locked}}disabled{{/if}} />
{{technique.label}}
</label>
{{/ifCond}}
{{/each}}
</div>
{{!-- technique list --}}
{{#each data.splitTechniquesList as |list technique|}}
<fieldset class="section-header flexrow">
<legend class="technique-controls">
<span class="technique-controls toggle-on-click" data-toggle="toggle-technique-category-{{technique}}">
{{localize (localize 'l5r5e.techniques.{technique}' technique=technique)}}
</span>
{{#ifCond ../data.editable_not_soft_locked '&&' (lookup ../data.system.techniques technique)}}
<a data-item-type="technique" class="technique-control item-add" data-tech-type="{{technique}}" title="{{localize 'l5r5e.global.add'}}"><i class="fas fa-plus"></i></a>
{{/ifCond}}
</legend>
<ul class="item-list toggle-technique-category-{{technique}} {{#ifCond ../data.storeInfos 'includes' (concat 'toggle-technique-category-' technique)}}toggle-hidden{{/ifCond}}">
{{#each list as |item id|}}
{{> 'systems/l5r5e/templates/items/technique/technique-entry.html' technique=item editable=../../data.editable_not_soft_locked}}
{{/each}}
</ul>
</fieldset>
{{/each}}
{{!-- signature scroll list --}}
<fieldset class="section-header flexrow"> <fieldset class="section-header flexrow">
<legend class="text-block-header"> <legend class="text-block-header">
{{localize 'l5r5e.advancements.signature_scroll' }} {{localize 'chiaroscuro.arcane.title'}}
{{#if data.editable_not_soft_locked}} {{#if data.editable_not_soft_locked}}
<a data-item-type="signature_scroll" class="signature-scroll-control item-add" title="{{localize 'l5r5e.global.add'}}"><i class="fas fa-plus"></i></a> <a data-item-type="arcane" class="arcane-control item-add" title="{{localize 'l5r5e.global.add'}}"><i class="fas fa-plus"></i></a>
{{/if}} {{/if}}
</legend> </legend>
<ul class="item-list"> <ul class="item-list">
{{#each actor.items as |scroll id|}} {{#each data.arcaneItems as |item|}}
{{#ifCond scroll.type '==' 'signature_scroll'}} <li class="item technique flexcol" data-item-id="{{item._id}}">
{{> 'systems/l5r5e/templates/items/signature-scroll/signature-scroll-entry.html' scroll=scroll id=id editable=../data.editable_not_soft_locked}} <ul class="item-header technique-controls">
{{/ifCond}} <li class="item-img"><img src="{{item.img}}" title="{{item.name}}" width="32px" height="32px"/></li>
<li class="item-name dice-picker l5r5e-tooltip" data-item-id="{{item._id}}">{{item.name}}</li>
{{#if ../data.editable_not_soft_locked}}
<li data-item-id="{{item._id}}" class="item-control item-edit" title="{{localize 'l5r5e.global.edit'}}"><i class="fas fa-edit"></i></li>
<li data-item-id="{{item._id}}" class="item-control item-delete" title="{{localize 'Delete'}}"><i class="fas fa-trash"></i></li>
{{/if}}
</ul>
</li>
{{/each}} {{/each}}
</ul> </ul>
</fieldset> </fieldset>
{{!-- Mystere items list --}}
<fieldset class="section-header flexrow">
<legend class="text-block-header">
{{localize 'chiaroscuro.mystere.title'}}
{{#if data.editable_not_soft_locked}}
<a data-item-type="mystere" class="mystere-control item-add" title="{{localize 'l5r5e.global.add'}}"><i class="fas fa-plus"></i></a>
{{/if}}
</legend>
<ul class="item-list">
{{#each data.mystereItems as |item|}}
<li class="item technique flexcol" data-item-id="{{item._id}}">
<ul class="item-header technique-controls">
<li class="item-img"><img src="{{item.img}}" title="{{item.name}}" width="32px" height="32px"/></li>
<li class="item-name l5r5e-tooltip" data-item-id="{{item._id}}">{{item.name}}</li>
{{#if ../data.editable_not_soft_locked}}
<li data-item-id="{{item._id}}" class="item-control item-edit" title="{{localize 'l5r5e.global.edit'}}"><i class="fas fa-edit"></i></li>
<li data-item-id="{{item._id}}" class="item-control item-delete" title="{{localize 'Delete'}}"><i class="fas fa-trash"></i></li>
{{/if}}
</ul>
</li>
{{/each}}
</ul>
</fieldset>
{{!-- Equipped weapons list --}}
{{> 'systems/l5rx-chiaroscuro/templates/items/weapon/weapons.html' }}
{{!-- Equipped armors list --}}
{{> 'systems/l5rx-chiaroscuro/templates/items/armor/armors.html' }}
</div> </div>

View File

@@ -1,7 +1,7 @@
<fieldset data-step="{{stepName}}" class="tq-drag-n-drop"> <fieldset data-step="{{stepName}}" class="tq-drag-n-drop">
<ul class="item-list"> <ul class="item-list">
{{#each itemsList as |item id|}} {{#each itemsList as |item id|}}
{{> 'systems/l5r5e/templates/items/property/property-entry.html' property=item id=id editable=../options.editable}} {{> 'systems/l5rx-chiaroscuro/templates/items/property/property-entry.html' property=item id=id editable=../options.editable}}
{{/each}} {{/each}}
</ul> </ul>
</fieldset> </fieldset>

View File

@@ -15,56 +15,62 @@
<input name="name" type="text" value="{{data.name}}" placeholder="Name" {{^if <input name="name" type="text" value="{{data.name}}" placeholder="Name" {{^if
data.editable_not_soft_locked}}disabled{{/if}} /> data.editable_not_soft_locked}}disabled{{/if}} />
</h1> </h1>
{{> 'systems/l5r5e/templates/actors/npc/identity.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/npc/identity.html'}}
</div> </div>
<div class="header-fields mid-wrapper"> <div class="header-fields mid-wrapper">
<div class="side-col"> <div class="side-col">
<h2>{{localize 'l5r5e.social.title'}}</h2> <h2>{{localize 'l5r5e.social.title'}}</h2>
{{> 'systems/l5r5e/templates/actors/npc/social.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/npc/social.html'}}
</div> </div>
<div class="central-col">{{> 'systems/l5r5e/templates/actors/npc/rings.html'}}</div> <div class="central-col">{{> 'systems/l5rx-chiaroscuro/templates/actors/npc/rings.html'}}</div>
<div class="side-col"> <div class="side-col">
<h2 class="right">{{localize 'l5r5e.attributes.title'}}</h2> <h2 class="right">{{localize 'l5r5e.attributes.title'}}</h2>
{{> 'systems/l5r5e/templates/actors/npc/attributes.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/npc/attributes.html'}}
</div> </div>
</div> </div>
</header> </header>
{{!-- Sheet Body --}} {{!-- Sheet Body --}}
<section class="sheet-body"> <section class="sheet-body">
{{!-- Active effects --}} {{!-- Active effects --}}
{{> 'systems/l5r5e/templates/actors/npc/effects.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/npc/effects.html'}}
{{!-- Skills No Tab --}} {{!-- Skills No Tab --}}
{{> 'systems/l5r5e/templates/actors/npc/skill.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/npc/skill.html'}}
{{!-- Sheet Tab Navigation --}} {{!-- Sheet Tab Navigation --}}
<nav class="sheet-tabs tabs" data-group="primary"> <nav class="sheet-tabs tabs" data-group="primary">
<a class="item" data-tab="skills">{{localize 'l5r5e.skills.title'}}</a> <a class="item" data-tab="skills">{{localize 'l5r5e.skills.title'}}</a>
<a class="item" data-tab="narrative">{{localize 'l5r5e.sheets.narrative'}}</a> <a class="item" data-tab="narrative">{{localize 'l5r5e.sheets.narrative'}}</a>
<a class="item" data-tab="invocations">{{localize 'chiaroscuro.tabs.invocations'}}</a>
<a class="item" data-tab="conflict">{{localize 'l5r5e.conflict.title'}}</a> <a class="item" data-tab="conflict">{{localize 'l5r5e.conflict.title'}}</a>
<a class="item" data-tab="inventory">{{localize 'l5r5e.sheets.inventory'}}</a> <a class="item" data-tab="inventory">{{localize 'l5r5e.sheets.inventory'}}</a>
</nav> </nav>
{{!-- Techniques Tab --}} {{!-- Techniques Tab --}}
<article class="tab skills" data-group="primary" data-tab="skills"> <article class="tab skills" data-group="primary" data-tab="skills">
{{> 'systems/l5r5e/templates/actors/npc/techniques.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/npc/techniques.html'}}
</article> </article>
{{!-- Narrative Tab --}} {{!-- Narrative Tab --}}
<article class="tab narrative" data-group="primary" data-tab="narrative"> <article class="tab narrative" data-group="primary" data-tab="narrative">
{{> 'systems/l5r5e/templates/actors/npc/narrative.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/npc/narrative.html'}}
</article>
{{!-- Invocations Tab --}}
<article class="tab invocations" data-group="primary" data-tab="invocations">
{{> 'systems/l5rx-chiaroscuro/templates/actors/character/invocations.html'}}
</article> </article>
{{!-- Conflict Tab --}} {{!-- Conflict Tab --}}
<article class="tab conflict" data-group="primary" data-tab="conflict"> <article class="tab conflict" data-group="primary" data-tab="conflict">
{{> 'systems/l5r5e/templates/actors/npc/conflict.html'}} {{> {{> 'systems/l5rx-chiaroscuro/templates/actors/npc/conflict.html'}} {{>
'systems/l5r5e/templates/items/weapon/weapons.html'}} {{> 'systems/l5rx-chiaroscuro/templates/items/weapon/weapons.html'}} {{>
'systems/l5r5e/templates/items/armor/armors.html'}} 'systems/l5rx-chiaroscuro/templates/items/armor/armors.html'}}
</article> </article>
{{!-- Inventory Tab --}} {{!-- Inventory Tab --}}
<article class="tab inventory" data-group="primary" data-tab="inventory"> <article class="tab inventory" data-group="primary" data-tab="inventory">
{{> 'systems/l5r5e/templates/actors/npc/inventory.html'}} {{> 'systems/l5rx-chiaroscuro/templates/actors/npc/inventory.html'}}
</article> </article>
</section> </section>
</form> </form>

View File

@@ -7,7 +7,7 @@
<label class="attribute-label"> <label class="attribute-label">
<strong>{{localize 'l5r5e.attributes.fatigue'}}</strong> <strong>{{localize 'l5r5e.attributes.fatigue'}}</strong>
<input class="centered-input select-on-focus" type="number" name="system.fatigue.value" value="{{data.system.fatigue.value}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input class="centered-input select-on-focus" type="number" name="system.fatigue.value" value="{{data.system.fatigue.value}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
<span class="attributes-buttons"> <span class="increment-control fatigue">
<i class="addsub-control pointer-choice fa fa-plus-square" data-type="fatigue" data-value="1"></i> <i class="addsub-control pointer-choice fa fa-plus-square" data-type="fatigue" data-value="1"></i>
<i class="addsub-control pointer-choice fa fa-minus-square" data-type="fatigue" data-value="-1"></i> <i class="addsub-control pointer-choice fa fa-minus-square" data-type="fatigue" data-value="-1"></i>
</span> </span>
@@ -22,7 +22,7 @@
<label class="attribute-label"> <label class="attribute-label">
<strong>{{localize 'l5r5e.attributes.strife'}}</strong> <strong>{{localize 'l5r5e.attributes.strife'}}</strong>
<input class="centered-input select-on-focus" type="number" name="system.strife.value" value="{{data.system.strife.value}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input class="centered-input select-on-focus" type="number" name="system.strife.value" value="{{data.system.strife.value}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
<span class="attributes-buttons"> <span class="increment-control strife">
<i class="addsub-control pointer-choice fa fa-plus-square" data-type="strife" data-value="1"></i> <i class="addsub-control pointer-choice fa fa-plus-square" data-type="strife" data-value="1"></i>
<i class="addsub-control pointer-choice fa fa-minus-square" data-type="strife" data-value="-1"></i> <i class="addsub-control pointer-choice fa fa-minus-square" data-type="strife" data-value="-1"></i>
</span> </span>

View File

@@ -14,7 +14,7 @@
<legend class="section-header">{{localize 'l5r5e.conflict.stance'}}</legend> <legend class="section-header">{{localize 'l5r5e.conflict.stance'}}</legend>
<ul class="item-list"> <ul class="item-list">
{{#each data.system.rings as |ringValue ringId|}} {{#each data.system.rings as |ringValue ringId|}}
{{> 'systems/l5r5e/templates/actors/character/stance.html' stance=../data.system.stance ringId=ringId}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/stance.html' stance=../data.system.stance ringId=ringId}}
{{/each}} {{/each}}
</ul> </ul>
</fieldset> </fieldset>

View File

@@ -5,14 +5,34 @@
{{selectOptions data.types selected=data.system.type valueAttr='id' labelAttr='label'}} {{selectOptions data.types selected=data.system.type valueAttr='id' labelAttr='label'}}
</select> </select>
</li> </li>
{{!-- Martial --}} {{!-- Martial Danger --}}
<li> <li class="danger-row">
<i class="i_bushi" title="{{localize 'l5r5e.social.npc.combat'}}"></i> <i class="i_bushi" title="{{localize 'l5r5e.social.npc.combat'}}"></i>
<input class="centered-input select-on-focus" type="number" name="system.conflict_rank.martial" value="{{data.system.conflict_rank.martial}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <div class="danger-wrapper">
<select name="system.martial_danger" {{^if data.editable_not_soft_locked}}disabled{{/if}}>
{{selectOptions data.dangerList selected=data.system.martial_danger valueAttr='id' labelAttr='label'}}
</select>
<div class="danger-icons">
<i class="fas fa-skull danger-icon"></i>
{{#ifCond '["moyenne","assez_difficile","difficile"]' 'includes' data.system.martial_danger}}<i class="fas fa-skull danger-icon"></i>{{/ifCond}}
{{#ifCond '["assez_difficile","difficile"]' 'includes' data.system.martial_danger}}<i class="fas fa-skull danger-icon"></i>{{/ifCond}}
{{#ifCond data.system.martial_danger '==' 'difficile'}}<i class="fas fa-skull danger-icon"></i>{{/ifCond}}
</div>
</div>
</li> </li>
{{!-- Social --}} {{!-- Social Danger --}}
<li> <li class="danger-row">
<i class="i_courtier" title="{{localize 'l5r5e.social.npc.intrigue'}}"></i> <i class="i_courtier" title="{{localize 'l5r5e.social.npc.intrigue'}}"></i>
<input class="centered-input select-on-focus" type="number" name="system.conflict_rank.social" value="{{data.system.conflict_rank.social}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <div class="danger-wrapper">
<select name="system.social_danger" {{^if data.editable_not_soft_locked}}disabled{{/if}}>
{{selectOptions data.dangerList selected=data.system.social_danger valueAttr='id' labelAttr='label'}}
</select>
<div class="danger-icons">
<i class="fas fa-star danger-icon"></i>
{{#ifCond '["moyenne","assez_difficile","difficile"]' 'includes' data.system.social_danger}}<i class="fas fa-star danger-icon"></i>{{/ifCond}}
{{#ifCond '["assez_difficile","difficile"]' 'includes' data.system.social_danger}}<i class="fas fa-star danger-icon"></i>{{/ifCond}}
{{#ifCond data.system.social_danger '==' 'difficile'}}<i class="fas fa-star danger-icon"></i>{{/ifCond}}
</div>
</div>
</li> </li>
</ul> </ul>

View File

@@ -1,6 +1,6 @@
<fieldset class="items-wrapper"> <fieldset class="items-wrapper">
<legend>{{localize 'l5r5e.sheets.equipment'}}</legend> <legend>{{localize 'l5r5e.sheets.equipment'}}</legend>
{{> 'systems/l5r5e/templates/items/item/items.html'}} {{> 'systems/l5rx-chiaroscuro/templates/items/item/items.html'}}
</fieldset> </fieldset>
{{!-- item patterns list --}} {{!-- item patterns list --}}
<fieldset> <fieldset>
@@ -13,7 +13,7 @@
<ul class="item-list"> <ul class="item-list">
{{#each actor.items as |pattern id|}} {{#each actor.items as |pattern id|}}
{{#ifCond pattern.type '==' 'item_pattern'}} {{#ifCond pattern.type '==' 'item_pattern'}}
{{> 'systems/l5r5e/templates/items/item-pattern/item-pattern-entry.html' pattern=pattern id=id editable=../data.editable_not_soft_locked}} {{> 'systems/l5rx-chiaroscuro/templates/items/item-pattern/item-pattern-entry.html' pattern=pattern id=id editable=../data.editable_not_soft_locked}}
{{/ifCond}} {{/ifCond}}
{{/each}} {{/each}}
</ul> </ul>

View File

@@ -36,7 +36,7 @@
<ul class="item-list"> <ul class="item-list">
{{#each actor.items as |item id|}} {{#each actor.items as |item id|}}
{{#ifCond '["distinction","passion"]' 'includes' item.system.peculiarity_type}} {{#ifCond '["distinction","passion"]' 'includes' item.system.peculiarity_type}}
{{> 'systems/l5r5e/templates/items/peculiarity/peculiarity-entry.html' peculiarity=item id=id editable=../data.editable_not_soft_locked}} {{> 'systems/l5rx-chiaroscuro/templates/items/peculiarity/peculiarity-entry.html' peculiarity=item id=id editable=../data.editable_not_soft_locked}}
{{/ifCond}} {{/ifCond}}
{{/each}} {{/each}}
</ul> </ul>
@@ -52,7 +52,7 @@
<ul class="item-list"> <ul class="item-list">
{{#each actor.items as |item id|}} {{#each actor.items as |item id|}}
{{#ifCond '["adversity","anxiety"]' 'includes' item.system.peculiarity_type}} {{#ifCond '["adversity","anxiety"]' 'includes' item.system.peculiarity_type}}
{{> 'systems/l5r5e/templates/items/peculiarity/peculiarity-entry.html' peculiarity=item id=id editable=../data.editable_not_soft_locked}} {{> 'systems/l5rx-chiaroscuro/templates/items/peculiarity/peculiarity-entry.html' peculiarity=item id=id editable=../data.editable_not_soft_locked}}
{{/ifCond}} {{/ifCond}}
{{/each}} {{/each}}
</ul> </ul>
@@ -68,7 +68,7 @@
<ul class="item-list"> <ul class="item-list">
{{#each actor.items as |bond id|}} {{#each actor.items as |bond id|}}
{{#ifCond bond.type '==' 'bond'}} {{#ifCond bond.type '==' 'bond'}}
{{> 'systems/l5r5e/templates/items/bond/bond-entry.html' bond=bond id=id editable=../data.editable_not_soft_locked}} {{> 'systems/l5rx-chiaroscuro/templates/items/bond/bond-entry.html' bond=bond id=id editable=../data.editable_not_soft_locked}}
{{/ifCond}} {{/ifCond}}
{{/each}} {{/each}}
</ul> </ul>

View File

@@ -2,18 +2,30 @@
<li> <li>
<label class="attribute-label centered-input"> <label class="attribute-label centered-input">
<strong>{{localize 'l5r5e.social.honor'}}</strong> <strong>{{localize 'l5r5e.social.honor'}}</strong>
<span class="increment-control honor">
<i class="addsub-control pointer-choice fa fa-plus-square" data-type="honor" data-value="1"></i>
<i class="addsub-control pointer-choice fa fa-minus-square" data-type="honor" data-value="-1"></i>
</span>
<input class="centered-input select-on-focus" type="number" name="system.social.honor" value="{{data.system.social.honor}}" data-dtype="Number" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input class="centered-input select-on-focus" type="number" name="system.social.honor" value="{{data.system.social.honor}}" data-dtype="Number" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
</li> </li>
<li> <li>
<label class="attribute-label centered-input"> <label class="attribute-label centered-input">
<strong>{{localize 'l5r5e.social.glory'}}</strong> <strong>{{localize 'l5r5e.social.glory'}}</strong>
<span class="increment-control glory">
<i class="addsub-control pointer-choice fa fa-plus-square" data-type="glory" data-value="1"></i>
<i class="addsub-control pointer-choice fa fa-minus-square" data-type="glory" data-value="-1"></i>
</span>
<input class="centered-input select-on-focus" type="number" name="system.social.glory" value="{{data.system.social.glory}}" data-dtype="Number" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input class="centered-input select-on-focus" type="number" name="system.social.glory" value="{{data.system.social.glory}}" data-dtype="Number" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
</li> </li>
<li> <li>
<label class="attribute-label centered-input"> <label class="attribute-label centered-input">
<strong>{{localize 'l5r5e.social.status'}}</strong> <strong>{{localize 'l5r5e.social.status'}}</strong>
<span class="increment-control status">
<i class="addsub-control pointer-choice fa fa-plus-square" data-type="status" data-value="1"></i>
<i class="addsub-control pointer-choice fa fa-minus-square" data-type="status" data-value="-1"></i>
</span>
<input class="centered-input select-on-focus" type="number" name="system.social.status" value="{{data.system.social.status}}" data-dtype="Number" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/> <input class="centered-input select-on-focus" type="number" name="system.social.status" value="{{data.system.social.status}}" data-dtype="Number" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
</label> </label>
</li> </li>

View File

@@ -27,7 +27,7 @@
</legend> </legend>
<ul class="item-list toggle-technique-category-{{technique}} {{#ifCond ../data.storeInfos 'includes' (concat 'toggle-technique-category-' technique)}}toggle-hidden{{/ifCond}}"> <ul class="item-list toggle-technique-category-{{technique}} {{#ifCond ../data.storeInfos 'includes' (concat 'toggle-technique-category-' technique)}}toggle-hidden{{/ifCond}}">
{{#each list as |item id|}} {{#each list as |item id|}}
{{> 'systems/l5r5e/templates/items/technique/technique-entry.html' technique=item editable=../../data.editable_not_soft_locked}} {{> 'systems/l5rx-chiaroscuro/templates/items/technique/technique-entry.html' technique=item editable=../../data.editable_not_soft_locked}}
{{/each}} {{/each}}
</ul> </ul>
</fieldset> </fieldset>
@@ -43,7 +43,7 @@
<ul class="item-list"> <ul class="item-list">
{{#each actor.items as |scroll id|}} {{#each actor.items as |scroll id|}}
{{#ifCond scroll.type '==' 'signature_scroll'}} {{#ifCond scroll.type '==' 'signature_scroll'}}
{{> 'systems/l5r5e/templates/items/signature-scroll/signature-scroll-entry.html' scroll=scroll id=id editable=../data.editable_not_soft_locked}} {{> 'systems/l5rx-chiaroscuro/templates/items/signature-scroll/signature-scroll-entry.html' scroll=scroll id=id editable=../data.editable_not_soft_locked}}
{{/ifCond}} {{/ifCond}}
{{/each}} {{/each}}
</ul> </ul>

View File

@@ -204,13 +204,13 @@
<tr> <tr>
<td class="fifty"> <td class="fifty">
{{localize 'l5r5e.twenty_questions.part2.school_ability'}} {{localize 'l5r5e.twenty_questions.part2.school_ability'}}
{{> 'systems/l5r5e/templates/actors/character/twenty-questions-item.html' itemsList=cache.step3.school_ability stepName='step3.school_ability' itemType='techniques' hideDndAt=1}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/twenty-questions-item.html' itemsList=cache.step3.school_ability stepName='step3.school_ability' itemType='techniques' hideDndAt=1}}
{{localize 'l5r5e.twenty_questions.part2.starting_techniques'}} {{localize 'l5r5e.twenty_questions.part2.starting_techniques'}}
{{> 'systems/l5r5e/templates/actors/character/twenty-questions-item.html' itemsList=cache.step3.techniques stepName='step3.techniques' itemType='techniques' hideDndAt=6}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/twenty-questions-item.html' itemsList=cache.step3.techniques stepName='step3.techniques' itemType='techniques' hideDndAt=6}}
</td> </td>
<td class="fifty"> <td class="fifty">
{{localize 'l5r5e.twenty_questions.part2.outfit'}} {{localize 'l5r5e.twenty_questions.part2.outfit'}}
{{> 'systems/l5r5e/templates/actors/character/twenty-questions-item.html' itemsList=cache.step3.equipment stepName='step3.equipment' itemType='items' hideDndAt=20}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/twenty-questions-item.html' itemsList=cache.step3.equipment stepName='step3.equipment' itemType='items' hideDndAt=20}}
</td> </td>
</tr> </tr>
</table> </table>
@@ -288,7 +288,7 @@
<tr> <tr>
<td class="" colspan="3"> <td class="" colspan="3">
{{localize 'l5r5e.twenty_questions.or'}} {{localize 'l5r5e.twenty_questions.part3.object'}} {{localize 'l5r5e.twenty_questions.or'}} {{localize 'l5r5e.twenty_questions.part3.object'}}
{{> 'systems/l5r5e/templates/actors/character/twenty-questions-item.html' itemsList=cache.step8.item stepName='step8.item' itemType='items' hideDndAt=1}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/twenty-questions-item.html' itemsList=cache.step8.item stepName='step8.item' itemType='items' hideDndAt=1}}
</td> </td>
</tr> </tr>
{{/ifCond}} {{/ifCond}}
@@ -319,25 +319,25 @@
<textarea name="step9.success">{{data.step9.success}}</textarea> <textarea name="step9.success">{{data.step9.success}}</textarea>
<label> <label>
{{localize 'l5r5e.twenty_questions.part4.distinction'}} {{localize 'l5r5e.twenty_questions.part4.distinction'}}
{{> 'systems/l5r5e/templates/actors/character/twenty-questions-item.html' itemsList=cache.step9.distinction stepName='step9.distinction' itemType='peculiarities' hideDndAt=1}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/twenty-questions-item.html' itemsList=cache.step9.distinction stepName='step9.distinction' itemType='peculiarities' hideDndAt=1}}
</label> </label>
<h3>{{localize (localize 'l5r5e.twenty_questions.part4.q10{suffix}' suffix=suffix)}}</h3> <h3>{{localize (localize 'l5r5e.twenty_questions.part4.q10{suffix}' suffix=suffix)}}</h3>
<textarea name="step10.difficulty">{{data.step10.difficulty}}</textarea> <textarea name="step10.difficulty">{{data.step10.difficulty}}</textarea>
<label> <label>
{{localize 'l5r5e.twenty_questions.part4.adversity'}} {{localize 'l5r5e.twenty_questions.part4.adversity'}}
{{> 'systems/l5r5e/templates/actors/character/twenty-questions-item.html' itemsList=cache.step10.adversity stepName='step10.adversity' itemType='peculiarities' hideDndAt=1}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/twenty-questions-item.html' itemsList=cache.step10.adversity stepName='step10.adversity' itemType='peculiarities' hideDndAt=1}}
</label> </label>
<h3>{{localize (localize 'l5r5e.twenty_questions.part4.q11{suffix}' suffix=suffix)}}</h3> <h3>{{localize (localize 'l5r5e.twenty_questions.part4.q11{suffix}' suffix=suffix)}}</h3>
<textarea name="step11.calms">{{data.step11.calms}}</textarea> <textarea name="step11.calms">{{data.step11.calms}}</textarea>
<label> <label>
{{localize 'l5r5e.twenty_questions.part4.passion'}} {{localize 'l5r5e.twenty_questions.part4.passion'}}
{{> 'systems/l5r5e/templates/actors/character/twenty-questions-item.html' itemsList=cache.step11.passion stepName='step11.passion' itemType='peculiarities' hideDndAt=1}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/twenty-questions-item.html' itemsList=cache.step11.passion stepName='step11.passion' itemType='peculiarities' hideDndAt=1}}
</label> </label>
<h3>{{localize (localize 'l5r5e.twenty_questions.part4.q12{suffix}' suffix=suffix)}}</h3> <h3>{{localize (localize 'l5r5e.twenty_questions.part4.q12{suffix}' suffix=suffix)}}</h3>
<textarea name="step12.worries">{{data.step12.worries}}</textarea> <textarea name="step12.worries">{{data.step12.worries}}</textarea>
<label> <label>
{{localize 'l5r5e.twenty_questions.part4.anxiety'}} {{localize 'l5r5e.twenty_questions.part4.anxiety'}}
{{> 'systems/l5r5e/templates/actors/character/twenty-questions-item.html' itemsList=cache.step12.anxiety stepName='step12.anxiety' itemType='peculiarities' hideDndAt=1}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/twenty-questions-item.html' itemsList=cache.step12.anxiety stepName='step12.anxiety' itemType='peculiarities' hideDndAt=1}}
</label> </label>
<h3>{{localize (localize 'l5r5e.twenty_questions.part4.q13{suffix}' suffix=suffix)}}</h3> <h3>{{localize (localize 'l5r5e.twenty_questions.part4.q13{suffix}' suffix=suffix)}}</h3>
<textarea name="step13.most_learn">{{data.step13.most_learn}}</textarea> <textarea name="step13.most_learn">{{data.step13.most_learn}}</textarea>
@@ -346,7 +346,7 @@
<td class="third"> <td class="third">
{{localize 'l5r5e.twenty_questions.part4.disadvantage'}} {{localize 'l5r5e.twenty_questions.part4.disadvantage'}}
{{#ifCond data.step13.advantage.length '==' 0}} {{#ifCond data.step13.advantage.length '==' 0}}
{{> 'systems/l5r5e/templates/actors/character/twenty-questions-item.html' itemsList=cache.step13.disadvantage stepName='step13.disadvantage' itemType='peculiarities' hideDndAt=1 }} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/twenty-questions-item.html' itemsList=cache.step13.disadvantage stepName='step13.disadvantage' itemType='peculiarities' hideDndAt=1 }}
{{/ifCond}} {{/ifCond}}
{{localize 'l5r5e.twenty_questions.and'}} {{localize 'l5r5e.twenty_questions.and'}}
{{localize 'l5r5e.twenty_questions.increase_skill1'}} {{localize 'l5r5e.twenty_questions.increase_skill1'}}
@@ -367,7 +367,7 @@
<td class=""> <td class="">
{{localize 'l5r5e.twenty_questions.part4.advantage'}} {{localize 'l5r5e.twenty_questions.part4.advantage'}}
{{#ifCond (ifCond data.step13.disadvantage.length '==' 0) '&&' (ifCond data.step13.skill '==' 'none')}} {{#ifCond (ifCond data.step13.disadvantage.length '==' 0) '&&' (ifCond data.step13.skill '==' 'none')}}
{{> 'systems/l5r5e/templates/actors/character/twenty-questions-item.html' itemsList=cache.step13.advantage stepName='step13.advantage' itemType='peculiarities' hideDndAt=1}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/twenty-questions-item.html' itemsList=cache.step13.advantage stepName='step13.advantage' itemType='peculiarities' hideDndAt=1}}
{{/ifCond}} {{/ifCond}}
</td> </td>
</tr> </tr>
@@ -380,7 +380,7 @@
<textarea name="step14.first_sight">{{data.step14.first_sight}}</textarea> <textarea name="step14.first_sight">{{data.step14.first_sight}}</textarea>
<label> <label>
{{localize 'l5r5e.twenty_questions.part5.accoutrement'}} {{localize 'l5r5e.twenty_questions.part5.accoutrement'}}
{{> 'systems/l5r5e/templates/actors/character/twenty-questions-item.html' itemsList=cache.step14.special_features stepName='step14.special_features' itemType='items' hideDndAt=1}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/twenty-questions-item.html' itemsList=cache.step14.special_features stepName='step14.special_features' itemType='items' hideDndAt=1}}
</label> </label>
<h3>{{localize (localize 'l5r5e.twenty_questions.part5.q15{suffix}' suffix=suffix)}}</h3> <h3>{{localize (localize 'l5r5e.twenty_questions.part5.q15{suffix}' suffix=suffix)}}</h3>
<textarea name="step15.stress">{{data.step15.stress}}</textarea> <textarea name="step15.stress">{{data.step15.stress}}</textarea>
@@ -389,7 +389,7 @@
<textarea name="step16.relations">{{data.step16.relations}}</textarea> <textarea name="step16.relations">{{data.step16.relations}}</textarea>
<label> <label>
{{localize 'l5r5e.twenty_questions.part5.object'}} {{localize 'l5r5e.twenty_questions.part5.object'}}
{{> 'systems/l5r5e/templates/actors/character/twenty-questions-item.html' itemsList=cache.step16.item stepName='step16.item' itemType='items' hideDndAt=1}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/twenty-questions-item.html' itemsList=cache.step16.item stepName='step16.item' itemType='items' hideDndAt=1}}
</label> </label>
{{/ifCond}} {{/ifCond}}
<button class="next" name="next" type="button">{{localize 'l5r5e.twenty_questions.bt_next'}} <i class='fas fa-arrow-right'></i></button> <button class="next" name="next" type="button">{{localize 'l5r5e.twenty_questions.bt_next'}} <i class='fas fa-arrow-right'></i></button>
@@ -401,7 +401,7 @@
<textarea name="step16.relations">{{data.step16.relations}}</textarea> <textarea name="step16.relations">{{data.step16.relations}}</textarea>
<label> <label>
{{localize 'l5r5e.twenty_questions.part5.object'}} {{localize 'l5r5e.twenty_questions.part5.object'}}
{{> 'systems/l5r5e/templates/actors/character/twenty-questions-item.html' itemsList=cache.step16.item stepName='step16.item' itemType='items' hideDndAt=1}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/twenty-questions-item.html' itemsList=cache.step16.item stepName='step16.item' itemType='items' hideDndAt=1}}
</label> </label>
{{/ifCond}} {{/ifCond}}
<h3>{{localize (localize 'l5r5e.twenty_questions.part6.q17{suffix}' suffix=suffix)}}</h3> <h3>{{localize (localize 'l5r5e.twenty_questions.part6.q17{suffix}' suffix=suffix)}}</h3>
@@ -421,7 +421,7 @@
{{else}} {{else}}
<label> <label>
{{localize 'l5r5e.twenty_questions.part6.bond'}} {{localize 'l5r5e.twenty_questions.part6.bond'}}
{{> 'systems/l5r5e/templates/actors/character/twenty-questions-item.html' itemsList=cache.step17.bond stepName='step17.bond' itemType='bonds' hideDndAt=1}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/twenty-questions-item.html' itemsList=cache.step17.bond stepName='step17.bond' itemType='bonds' hideDndAt=1}}
</label> </label>
{{/ifCond}} {{/ifCond}}
<h3>{{localize (localize 'l5r5e.twenty_questions.part6.q18{suffix}' suffix=suffix)}}</h3> <h3>{{localize (localize 'l5r5e.twenty_questions.part6.q18{suffix}' suffix=suffix)}}</h3>
@@ -474,7 +474,7 @@
{{/each}} {{/each}}
</select> </select>
{{localize 'l5r5e.twenty_questions.part6.d10r2_drop_items'}} {{localize 'l5r5e.twenty_questions.part6.d10r2_drop_items'}}
{{> 'systems/l5r5e/templates/actors/character/twenty-questions-item.html' itemsList=cache.step18.heritage_item stepName='step18.heritage_item' itemType='items' hideDndAt=1}} {{> 'systems/l5rx-chiaroscuro/templates/actors/character/twenty-questions-item.html' itemsList=cache.step18.heritage_item stepName='step18.heritage_item' itemType='items' hideDndAt=1}}
</td> </td>
</tr> </tr>
</table> </table>

View File

@@ -0,0 +1,52 @@
<div class="l5r5e filter-bar">
{{#if filtersToShow.rank}}
<div class="flexrow l5r5e rank-filter number-filter">
<label>{{localize 'l5r5e.compendium.filter.rank'}}:</label>
{{#each ranks}}
<a data-rank="{{this}}"
data-tooltip="{{localize 'l5r5e.compendium.filter.rank'}} {{this}}">{{this}}</a>
{{/each}}
<a data-clear style="display:none" data-tooltip="{{localize 'l5r5e.compendium.filter.clear'}}">×</a>
</div>
{{/if}}
{{#if filtersToShow.rarity}}
<div class="flexrow l5r5e rarity-filter number-filter">
<label>{{localize 'l5r5e.compendium.filter.rarity'}}:</label>
{{#each rarities}}
<a data-rarity="{{this}}"
data-tooltip="{{localize 'l5r5e.compendium.filter.rarity'}} {{this}}">{{this}}</a>
{{/each}}
<a data-clear style="display:none" data-tooltip="{{localize 'l5r5e.compendium.filter.clear'}}">×</a>
</div>
{{/if}}
{{#if filtersToShow.ring}}
<div class="flexrow l5r5e ring-filter">
<label>{{localize 'l5r5e.rings.label'}}:</label>
{{#each rings}}
<i data-ring="{{this}}"
data-tooltip="{{localize (concat 'l5r5e.rings.' this)}}"
class="i_{{this}}"></i>
{{/each}}
<a data-clear style="display:none" data-tooltip="{{localize 'l5r5e.compendium.filter.clear'}}">×</a>
</div>
{{/if}}
{{#if filtersToShow.source}}
<div class="flexrow l5r5e source-filter">
<l5r5e-multi-select name="filter-sources" {{#if hideDisabledOptions}}hidedisabledoptions{{/if}}>
{{selectOptions sources localize=true}}
</l5r5e-multi-select>
</div>
{{#if showPlayerView}}
<button type="button" class="gm applyPlayerFilter"
data-action="applyPlayerView"
data-tooltip="{{localize 'l5r5e.multiselect.player_filter_tooltip'}}">
{{localize 'l5r5e.multiselect.player_filter_label'}}
</button>
{{/if}}
{{/if}}
</div>

Some files were not shown because too many files have changed in this diff Show More