Compare commits
16 Commits
dev
...
dev_skills
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87fd300a22 | ||
|
|
fe2aa5dd25 | ||
|
|
6f7b00328e | ||
|
|
67b7601fa1 | ||
|
|
87096ab286 | ||
|
|
273531f522 | ||
|
|
c1bf9644f8 | ||
|
|
1b68d33bd2 | ||
|
|
a24e775001 | ||
|
|
823b883d4e | ||
|
|
12c8a70f60 | ||
|
|
1d42d2970d | ||
|
|
0b3816587b | ||
|
|
710afd9804 | ||
|
|
1ec9e65ca5 | ||
|
|
5fbb34d882 |
@@ -1,6 +1,10 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
Date format : day/month/year
|
Date format : day/month/year
|
||||||
|
|
||||||
|
## 2.0.0 - xx/xx/2024 - Skill list
|
||||||
|
- Skills are now items, this can break things update with caution. Save before upgrading !
|
||||||
|
- Added a new dialog settings to configure default skills list.
|
||||||
|
|
||||||
## 1.11.0 - 13/12/2023 - Little fixes
|
## 1.11.0 - 13/12/2023 - Little fixes
|
||||||
- 20Q :
|
- 20Q :
|
||||||
- Starting techniques now have a limit of 6 techniques instead of 5 (see Celestial Realms : `Moshi Sun Sentinel School`).
|
- Starting techniques now have a limit of 6 techniques instead of 5 (see Celestial Realms : `Moshi Sun Sentinel School`).
|
||||||
|
|||||||
26
system/assets/icons/items/skill.svg
Normal file
26
system/assets/icons/items/skill.svg
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?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" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="239.5px" height="239.5px" viewBox="0 0 239.5 239.5" style="enable-background:new 0 0 239.5 239.5;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#FFFFCC;}
|
||||||
|
</style>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M173.2,103.1c0.8-4.9,1.4-9.8,1.4-14.9c0-48.2-39.1-87.3-87.3-87.3C39.1,0.9,0,40,0,88.2s39.1,87.3,87.3,87.3
|
||||||
|
c5.7,0,11.3-0.6,16.7-1.6c0-0.1,0-0.2,0-0.3c0-7.6,1.2-14.9,3.5-21.7c-6.4,2-13.1,3.1-20.1,3.1c-36.8,0-66.7-29.9-66.7-66.7
|
||||||
|
s29.9-66.7,66.7-66.7s66.7,29.9,66.7,66.7c0,6.5-1,12.9-2.8,18.8C158.2,104.6,165.5,103.2,173.2,103.1z"/>
|
||||||
|
<path class="st0" d="M87.3,26.8c-33.8,0-61.4,27.5-61.4,61.4c0,33.8,27.5,61.4,61.4,61.4c8,0,15.7-1.6,22.7-4.4
|
||||||
|
c6.9-15.6,19.3-28.2,34.7-35.4c2.5-6.7,4-13.9,4-21.5C148.6,54.3,121.1,26.8,87.3,26.8z M110.6,101.7c0,5.4-4.4,9.8-9.8,9.8H73.7
|
||||||
|
c-5.4,0-9.8-4.4-9.8-9.8v-27c0-5.4,4.4-9.8,9.8-9.8h27.1c5.4,0,9.8,4.4,9.8,9.8V101.7z"/>
|
||||||
|
<path class="st0" d="M174.4,108.4c-0.8,0-1.6,0.1-2.4,0.1c-8.2,0.3-16,2-23.1,5.1c-1.3,0.5-2.5,1.2-3.8,1.8
|
||||||
|
c-1.4,0.7-2.8,1.5-4.2,2.3c-9.5,5.7-17.5,13.8-23.1,23.5c-0.8,1.4-1.5,2.8-2.2,4.3c-0.6,1.2-1.2,2.5-1.7,3.8
|
||||||
|
c-2.9,7.2-4.6,15-4.7,23.2c0,0.3,0,0.7,0,1c0,35.9,29.2,65.1,65.1,65.1s65.1-29.2,65.1-65.1C239.5,137.6,210.3,108.4,174.4,108.4z
|
||||||
|
M174.4,226c-28.9,0-52.4-23.5-52.4-52.4c0-1.8,0.1-3.6,0.3-5.4c2.5-24.2,21.6-43.6,45.7-46.6c2.1-0.3,4.3-0.4,6.5-0.4
|
||||||
|
c28.9,0,52.4,23.5,52.4,52.4C226.9,202.4,203.3,226,174.4,226z"/>
|
||||||
|
<path class="st0" d="M174.4,126.5c-3.2,0-6.2,0.3-9.2,0.9c-18.9,3.8-33.7,18.9-37.1,37.9c-0.5,2.7-0.8,5.4-0.8,8.2
|
||||||
|
c0,26,21.1,47.1,47.1,47.1s47.1-21.1,47.1-47.1S200.4,126.5,174.4,126.5z M192.6,184c0,4.2-3.4,7.6-7.6,7.6h-21
|
||||||
|
c-4.2,0-7.6-3.4-7.6-7.6v-21c0-4.2,3.4-7.6,7.6-7.6h21c4.2,0,7.6,3.4,7.6,7.6V184z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
153
system/babele/fr/l5r5e.core-skills.json
Normal file
153
system/babele/fr/l5r5e.core-skills.json
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
{
|
||||||
|
"label": "Compétences",
|
||||||
|
"mapping": {
|
||||||
|
"description": "system.description",
|
||||||
|
"book_reference": "system.book_reference"
|
||||||
|
},
|
||||||
|
"entries": [
|
||||||
|
{
|
||||||
|
"id": "Composition",
|
||||||
|
"name": "Composition",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.146"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Aesthetics",
|
||||||
|
"name": "Esthétique",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.146"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Smithing",
|
||||||
|
"name": "Forge",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.149"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Design",
|
||||||
|
"name": "Stylisme",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.147"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Martial Arts [Melee]",
|
||||||
|
"name": "Arts martiaux (corps à corps)",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.162"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Martial Arts [Ranged]",
|
||||||
|
"name": "Arts martiaux (distance)",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.163"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Martial Arts [Unarmed]",
|
||||||
|
"name": "Arts martiaux (mains nues)",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.164"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Fitness",
|
||||||
|
"name": "Forme",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.162"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Meditation",
|
||||||
|
"name": "Méditation",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.164"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Tactics",
|
||||||
|
"name": "Tactique",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.165"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Commerce",
|
||||||
|
"name": "Commerce",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.167"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Skulduggery",
|
||||||
|
"name": "Magouilles",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.168"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Seafaring",
|
||||||
|
"name": "Navigation",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.168"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Survival",
|
||||||
|
"name": "Survie",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.169"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Labor",
|
||||||
|
"name": "Travail manuel",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.167"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Culture",
|
||||||
|
"name": "Culture",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.156"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Government",
|
||||||
|
"name": "Gouvernement",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.156"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Medicine",
|
||||||
|
"name": "Médecine",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.157"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Sentiment",
|
||||||
|
"name": "Sentiments",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.158"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Theology",
|
||||||
|
"name": "Théologie",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.158"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Command",
|
||||||
|
"name": "Commandement",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.151"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Courtesy",
|
||||||
|
"name": "Courtoisie",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.152"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Games",
|
||||||
|
"name": "Jeux",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.153"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Performance",
|
||||||
|
"name": "Représentations",
|
||||||
|
"description": "",
|
||||||
|
"book_reference": "Livre de Règles p.154"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -22,6 +22,11 @@
|
|||||||
"Title": "Custom Compendium Name",
|
"Title": "Custom Compendium Name",
|
||||||
"Hint": "For advanced users that want to change the name of the custom compendiums (Used to disables the embedded ones).",
|
"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?"
|
"Notification": "Unable set Custom Compendium: '{name}'. Is it activated and registered with Babele?"
|
||||||
|
},
|
||||||
|
"DefaultSkillsList": {
|
||||||
|
"Title": "Skills",
|
||||||
|
"Label": "Set Default Skills",
|
||||||
|
"Hint": "Set default skills list for new characters."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"TYPES": {
|
"TYPES": {
|
||||||
@@ -31,6 +36,7 @@
|
|||||||
"army": "Army"
|
"army": "Army"
|
||||||
},
|
},
|
||||||
"Item": {
|
"Item": {
|
||||||
|
"skill": "Skill",
|
||||||
"item": "Item",
|
"item": "Item",
|
||||||
"armor": "Armor",
|
"armor": "Armor",
|
||||||
"weapon": "Weapon",
|
"weapon": "Weapon",
|
||||||
@@ -285,6 +291,7 @@
|
|||||||
"skills": {
|
"skills": {
|
||||||
"title": "Skills",
|
"title": "Skills",
|
||||||
"label": "Skill",
|
"label": "Skill",
|
||||||
|
"category": "Category",
|
||||||
"artisan": {
|
"artisan": {
|
||||||
"title": "Artisan",
|
"title": "Artisan",
|
||||||
"aesthetics": "Aesthetics",
|
"aesthetics": "Aesthetics",
|
||||||
|
|||||||
@@ -285,6 +285,7 @@
|
|||||||
"skills": {
|
"skills": {
|
||||||
"title": "Habilidades",
|
"title": "Habilidades",
|
||||||
"label": "Habilidad",
|
"label": "Habilidad",
|
||||||
|
"category": "Categoría",
|
||||||
"artisan": {
|
"artisan": {
|
||||||
"title": "Artesanales",
|
"title": "Artesanales",
|
||||||
"aesthetics": "Estética",
|
"aesthetics": "Estética",
|
||||||
|
|||||||
@@ -22,6 +22,11 @@
|
|||||||
"Title": "Nom du CustomCompendium",
|
"Title": "Nom du CustomCompendium",
|
||||||
"Hint": "Pour les utilisateurs avancés qui souhaitent modifier le nom du compendium personnalisé (utilisé pour désactiver ceux intégrés).",
|
"Hint": "Pour les utilisateurs avancés qui souhaitent modifier le nom du compendium personnalisé (utilisé pour désactiver ceux intégrés).",
|
||||||
"Notification": "Impossible de définir le compendium personnalisé : '{name}'. Est-il activé et enregistré auprès de Babele ?"
|
"Notification": "Impossible de définir le compendium personnalisé : '{name}'. Est-il activé et enregistré auprès de Babele ?"
|
||||||
|
},
|
||||||
|
"DefaultSkillsList": {
|
||||||
|
"Title": "Compétences",
|
||||||
|
"Label": "Définir les compétences par défaut",
|
||||||
|
"Hint": "Définie la liste des compétences par défaut pour les nouveaux personnages."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"TYPES": {
|
"TYPES": {
|
||||||
@@ -31,6 +36,7 @@
|
|||||||
"army": "Armée"
|
"army": "Armée"
|
||||||
},
|
},
|
||||||
"Item": {
|
"Item": {
|
||||||
|
"skill": "Compétence",
|
||||||
"item": "Objet",
|
"item": "Objet",
|
||||||
"armor": "Armure",
|
"armor": "Armure",
|
||||||
"weapon": "Arme",
|
"weapon": "Arme",
|
||||||
@@ -285,6 +291,7 @@
|
|||||||
"skills": {
|
"skills": {
|
||||||
"title": "Compétences",
|
"title": "Compétences",
|
||||||
"label": "Compétence",
|
"label": "Compétence",
|
||||||
|
"category": "Catégorie",
|
||||||
"artisan": {
|
"artisan": {
|
||||||
"title": "Artisanales",
|
"title": "Artisanales",
|
||||||
"aesthetics": "Esthétique",
|
"aesthetics": "Esthétique",
|
||||||
|
|||||||
@@ -285,6 +285,7 @@
|
|||||||
"skills": {
|
"skills": {
|
||||||
"title": "Abilità",
|
"title": "Abilità",
|
||||||
"label": "Abilità",
|
"label": "Abilità",
|
||||||
|
"category": "Categoria",
|
||||||
"artisan": {
|
"artisan": {
|
||||||
"title": "Artigiane",
|
"title": "Artigiane",
|
||||||
"aesthetics": "Estetica",
|
"aesthetics": "Estetica",
|
||||||
|
|||||||
24
system/packs/core-skills.db
Normal file
24
system/packs/core-skills.db
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{"_id":"L5RCoreSkl000001","name":"Composition","permission":{"default":0},"type":"skill","data":{"category":"artisan","description":"","book_reference":"Core Rulebook p.146","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"composition"}},"img":"icons/sundries/scrolls/scroll-symbol-circle-white.webp","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000002","name":"Aesthetics","permission":{"default":0},"type":"skill","data":{"category":"artisan","description":"","book_reference":"Core Rulebook p.146","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"aesthetics"}},"img":"systems/l5r5e/assets/icons/techs/kiho.svg","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000003","name":"Smithing","permission":{"default":0},"type":"skill","data":{"category":"artisan","description":"","book_reference":"Core Rulebook p.149","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"smithing"}},"img":"systems/l5r5e/assets/icons/items/item_pattern.svg","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000004","name":"Design","permission":{"default":0},"type":"skill","data":{"category":"artisan","description":"","book_reference":"Core Rulebook p.147","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"design"}},"img":"systems/l5r5e/assets/icons/items/keikogi.svg","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000005","name":"Martial Arts [Melee]","permission":{"default":0},"type":"skill","data":{"category":"martial","description":"","book_reference":"Core Rulebook p.162","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"melee"}},"img":"systems/l5r5e/assets/icons/weapons/katana.svg","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000006","name":"Martial Arts [Ranged]","permission":{"default":0},"type":"skill","data":{"category":"martial","description":"","book_reference":"Core Rulebook p.163","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"ranged"}},"img":"systems/l5r5e/assets/icons/weapons/crossbow.svg","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000007","name":"Martial Arts [Unarmed]","permission":{"default":0},"type":"skill","data":{"category":"martial","description":"","book_reference":"Core Rulebook p.164","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"unarmed"}},"img":"systems/l5r5e/assets/icons/weapons/unarmed.svg","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000008","name":"Fitness","permission":{"default":0},"type":"skill","data":{"category":"martial","description":"","book_reference":"Core Rulebook p.162","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"fitness"}},"img":"icons/skills/melee/maneuver-daggers-paired-orange.webp","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000009","name":"Meditation","permission":{"default":0},"type":"skill","data":{"category":"martial","description":"","book_reference":"Core Rulebook p.164","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"meditation"}},"img":"systems/l5r5e/assets/icons/techs/ritual.svg","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000010","name":"Tactics","permission":{"default":0},"type":"skill","data":{"category":"martial","description":"","book_reference":"Core Rulebook p.165","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"tactics"}},"img":"systems/l5r5e/assets/icons/items/armor.svg","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000011","name":"Commerce","permission":{"default":0},"type":"skill","data":{"category":"trade","description":"","book_reference":"Core Rulebook p.167","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"commerce"}},"img":"icons/skills/trades/baking-bread-rolls-green.webp","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000012","name":"Skulduggery","permission":{"default":0},"type":"skill","data":{"category":"trade","description":"","book_reference":"Core Rulebook p.168","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"skulduggery"}},"img":"icons/skills/social/intimidation-impressing.webp","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000013","name":"Seafaring","permission":{"default":0},"type":"skill","data":{"category":"trade","description":"","book_reference":"Core Rulebook p.168","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"seafaring"}},"img":"icons/skills/trades/profession-sailing-ship.webp","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000014","name":"Survival","permission":{"default":0},"type":"skill","data":{"category":"trade","description":"","book_reference":"Core Rulebook p.169","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"survival"}},"img":"icons/environment/wilderness/camp-improvised.webp","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000015","name":"Labor","permission":{"default":0},"type":"skill","data":{"category":"trade","description":"","book_reference":"Core Rulebook p.167","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"labor"}},"img":"icons/tools/hand/hammer-and-nail.webp","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000016","name":"Culture","permission":{"default":0},"type":"skill","data":{"category":"scholar","description":"","book_reference":"Core Rulebook p.156","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"culture"}},"img":"icons/sundries/documents/document-sealed-signatures-red.webp","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000017","name":"Government","permission":{"default":0},"type":"skill","data":{"category":"scholar","description":"","book_reference":"Core Rulebook p.156","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"government"}},"img":"systems/l5r5e/assets/icons/items/army_fortification.svg","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000018","name":"Medicine","permission":{"default":0},"type":"skill","data":{"category":"scholar","description":"","book_reference":"Core Rulebook p.157","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"medicine"}},"img":"icons/tools/laboratory/bowl-liquid-pink-yellow-green.webp","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000019","name":"Sentiment","permission":{"default":0},"type":"skill","data":{"category":"scholar","description":"","book_reference":"Core Rulebook p.158","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"sentiment"}},"img":"systems/l5r5e/assets/icons/actors/traditional-japanese-woman.svg","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000020","name":"Theology","permission":{"default":0},"type":"skill","data":{"category":"scholar","description":"","book_reference":"Core Rulebook p.158","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"theology"}},"img":"systems/l5r5e/assets/icons/items/blessed.svg","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000021","name":"Command","permission":{"default":0},"type":"skill","data":{"category":"social","description":"","book_reference":"Core Rulebook p.151","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"command"}},"img":"systems/l5r5e/assets/icons/items/army_cohort.svg","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000022","name":"Courtesy","permission":{"default":0},"type":"skill","data":{"category":"social","description":"","book_reference":"Core Rulebook p.152","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"courtesy"}},"img":"systems/l5r5e/assets/icons/social.svg","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000023","name":"Games","permission":{"default":0},"type":"skill","data":{"category":"social","description":"","book_reference":"Core Rulebook p.153","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"games"}},"img":"icons/sundries/gaming/dice-runed-tan.webp","effects":[]}
|
||||||
|
{"_id":"L5RCoreSkl000024","name":"Performance","permission":{"default":0},"type":"skill","data":{"category":"social","description":"","book_reference":"Core Rulebook p.154","rank":0,"modifier":0},"sort":100001,"flags":{"l5r5e":{"skillCoreId":"performance"}},"img":"icons/environment/people/group.webp","effects":[]}
|
||||||
@@ -16,66 +16,92 @@ export class ActorL5r5e extends Actor {
|
|||||||
docData.img = `${CONFIG.l5r5e.paths.assets}icons/actors/${docData.type}.svg`;
|
docData.img = `${CONFIG.l5r5e.paths.assets}icons/actors/${docData.type}.svg`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some tweak on actors prototypeToken
|
// Only for new actors (New actor has no items, duplicates does)
|
||||||
docData.prototypeToken = docData.prototypeToken || {};
|
if (!docData.items) {
|
||||||
switch (docData.type) {
|
// Some tweak on actors prototypeToken
|
||||||
case "character":
|
docData.prototypeToken = docData.prototypeToken || {};
|
||||||
foundry.utils.mergeObject(
|
switch (docData.type) {
|
||||||
docData.prototypeToken,
|
case "character":
|
||||||
{
|
// Load skills from core compendiums (only for pc character)
|
||||||
// vision: true,
|
docData.items = [];
|
||||||
// dimSight: 30,
|
await ActorL5r5e.addSkillsFromDefaultList(docData);
|
||||||
// brightSight: 0,
|
|
||||||
actorLink: true,
|
|
||||||
disposition: 1, // friendly
|
|
||||||
bar1: {
|
|
||||||
attribute: "fatigue",
|
|
||||||
},
|
|
||||||
bar2: {
|
|
||||||
attribute: "strife",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ overwrite: false }
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "npc":
|
// Set token properties
|
||||||
foundry.utils.mergeObject(
|
foundry.utils.mergeObject(
|
||||||
docData.prototypeToken,
|
docData.prototypeToken,
|
||||||
{
|
{
|
||||||
actorLink: true,
|
// vision: true,
|
||||||
disposition: 0, // neutral
|
// dimSight: 30,
|
||||||
bar1: {
|
// brightSight: 0,
|
||||||
attribute: "fatigue",
|
actorLink: true,
|
||||||
|
disposition: 1, // friendly
|
||||||
|
bar1: {
|
||||||
|
attribute: "fatigue",
|
||||||
|
},
|
||||||
|
bar2: {
|
||||||
|
attribute: "strife",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
bar2: {
|
{ overwrite: false }
|
||||||
attribute: "strife",
|
);
|
||||||
},
|
break;
|
||||||
},
|
|
||||||
{ overwrite: false }
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "army":
|
case "npc":
|
||||||
foundry.utils.mergeObject(
|
foundry.utils.mergeObject(
|
||||||
docData.prototypeToken,
|
docData.prototypeToken,
|
||||||
{
|
{
|
||||||
actorLink: true,
|
actorLink: true,
|
||||||
disposition: 0, // neutral
|
disposition: 0, // neutral
|
||||||
bar1: {
|
bar1: {
|
||||||
attribute: "battle_readiness.casualties_strength",
|
attribute: "fatigue",
|
||||||
|
},
|
||||||
|
bar2: {
|
||||||
|
attribute: "strife",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
bar2: {
|
{ overwrite: false }
|
||||||
attribute: "battle_readiness.panic_discipline",
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "army":
|
||||||
|
foundry.utils.mergeObject(
|
||||||
|
docData.prototypeToken,
|
||||||
|
{
|
||||||
|
actorLink: true,
|
||||||
|
disposition: 0, // neutral
|
||||||
|
bar1: {
|
||||||
|
attribute: "battle_readiness.casualties_strength",
|
||||||
|
},
|
||||||
|
bar2: {
|
||||||
|
attribute: "battle_readiness.panic_discipline",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
{ overwrite: false }
|
||||||
{ overwrite: false }
|
);
|
||||||
);
|
break;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
await super.create(docData, options);
|
await super.create(docData, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add all the skills from compendiums to "items"
|
||||||
|
*/
|
||||||
|
static async addSkillsFromDefaultList(docData) {
|
||||||
|
console.log(`L5R5E | Adding default skills to ${docData.name}`);
|
||||||
|
|
||||||
|
const skillList = await game.l5r5e.HelpersL5r5e.getSkillsItemsList();
|
||||||
|
|
||||||
|
skillList.forEach(item => {
|
||||||
|
// Get the json data and replace the object id/rank
|
||||||
|
const tmpData = item.toObject();
|
||||||
|
tmpData._id = foundry.utils.randomID();
|
||||||
|
tmpData.system.rank = 0;
|
||||||
|
docData.items.push(tmpData);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entity-specific actions that should occur when the Entity is updated
|
* Entity-specific actions that should occur when the Entity is updated
|
||||||
* @override
|
* @override
|
||||||
@@ -94,7 +120,7 @@ export class ActorL5r5e extends Actor {
|
|||||||
context.pack = this.pack;
|
context.pack = this.pack;
|
||||||
|
|
||||||
// NPC switch between types : Linked actor for Adversary, unlinked for Minion
|
// NPC switch between types : Linked actor for Adversary, unlinked for Minion
|
||||||
if (!!docData["system.type"] && this.type === "npc" && docData["system.type"] !== this.system.type) {
|
if (!!docData["system.type"] && this.isNpc && docData["system.type"] !== this.system.type) {
|
||||||
docData["prototypeToken.actorLink"] = docData["system.type"] === "adversary";
|
docData["prototypeToken.actorLink"] = docData["system.type"] === "adversary";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,38 +223,51 @@ export class ActorL5r5e extends Actor {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
async _updateActorFromAdvancement(item, isAdd) {
|
async _updateActorFromAdvancement(item, isAdd) {
|
||||||
if (item && item.type === "advancement") {
|
if (!item || item.type !== "advancement") {
|
||||||
const actor = foundry.utils.duplicate(this.system);
|
return;
|
||||||
const itemData = item.system;
|
}
|
||||||
if (itemData.advancement_type === "ring") {
|
|
||||||
// Ring
|
const actorSystem = foundry.utils.duplicate(this.system);
|
||||||
if (isAdd) {
|
const itemData = item.system;
|
||||||
actor.rings[itemData.ring] = Math.min(9, actor.rings[itemData.ring] + 1);
|
if (itemData.advancement_type === "ring") {
|
||||||
} else {
|
// Ring
|
||||||
actor.rings[itemData.ring] = Math.max(1, actor.rings[itemData.ring] - 1);
|
if (isAdd) {
|
||||||
}
|
actorSystem.rings[itemData.ring] = Math.min(9, actorSystem.rings[itemData.ring] + 1);
|
||||||
} else {
|
} else {
|
||||||
// Skill
|
actorSystem.rings[itemData.ring] = Math.max(1, actorSystem.rings[itemData.ring] - 1);
|
||||||
const skillCatId = CONFIG.l5r5e.skills.get(itemData.skill);
|
|
||||||
if (skillCatId) {
|
|
||||||
if (isAdd) {
|
|
||||||
actor.skills[skillCatId][itemData.skill] = Math.min(
|
|
||||||
9,
|
|
||||||
actor.skills[skillCatId][itemData.skill] + 1
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
actor.skills[skillCatId][itemData.skill] = Math.max(
|
|
||||||
0,
|
|
||||||
actor.skills[skillCatId][itemData.skill] - 1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Actor
|
// Update Actor
|
||||||
await this.update({
|
await this.update({
|
||||||
system: foundry.utils.diffObject(this.system, actor),
|
system: foundry.utils.diffObject(this.system, actorSystem),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Skill
|
||||||
|
let skillItem = await fromUuid(itemData.skill); // Skill itemUuid
|
||||||
|
if (!skillItem) {
|
||||||
|
console.warn("L5R5E | Unknown skill item uuid", itemData.skill);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Out of actor item ?
|
||||||
|
if (!skillItem.actor || skillItem.actor._id !== this._id) {
|
||||||
|
const checkItem = this.items.getName(skillItem.name);
|
||||||
|
if (checkItem) {
|
||||||
|
skillItem = checkItem;
|
||||||
|
} else {
|
||||||
|
throw new Error(`Unable to find "${skillItem.name}" on this actor`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const newRank = isAdd
|
||||||
|
? Math.min(9, skillItem.system.rank + 1)
|
||||||
|
: Math.max(0, skillItem.system.rank - 1);
|
||||||
|
if (skillItem.system.rank === newRank) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update Item
|
||||||
|
await skillItem.update({ "system.rank": newRank });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,12 +300,20 @@ export class ActorL5r5e extends Actor {
|
|||||||
return this.type === "character";
|
return this.type === "character";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if this actor is a NPC
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
get isNpc() {
|
||||||
|
return this.type === "npc";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if this actor is an Adversary
|
* Return true if this actor is an Adversary
|
||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
get isAdversary() {
|
get isAdversary() {
|
||||||
return this.type === "npc" && this.system.type === "adversary";
|
return this.isNpc && this.system.type === "adversary";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -274,7 +321,7 @@ export class ActorL5r5e extends Actor {
|
|||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
get isMinion() {
|
get isMinion() {
|
||||||
return this.type === "npc" && this.system.type === "minion";
|
return this.isNpc && this.system.type === "minion";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -370,7 +417,7 @@ export class ActorL5r5e extends Actor {
|
|||||||
if (!this.isCharacterType) {
|
if (!this.isCharacterType) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return this.type === "npc" ? this.system.conflict_rank.social : this.system.identity.school_rank;
|
return this.isNpc ? this.system.conflict_rank.social : this.system.identity.school_rank;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -381,6 +428,6 @@ export class ActorL5r5e extends Actor {
|
|||||||
if (!this.isCharacterType) {
|
if (!this.isCharacterType) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return this.type === "npc" ? this.system.conflict_rank.martial : this.system.identity.school_rank;
|
return this.isNpc ? this.system.conflict_rank.martial : this.system.identity.school_rank;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,141 +133,151 @@ export class BaseCharacterSheetL5r5e extends BaseSheetL5r5e {
|
|||||||
* @param {DragEvent} event
|
* @param {DragEvent} event
|
||||||
*/
|
*/
|
||||||
async _onDrop(event) {
|
async _onDrop(event) {
|
||||||
// *** Everything below here is only needed if the sheet is editable ***
|
try {
|
||||||
if (!this.isEditable || this.actor.system.soft_locked) {
|
// *** Everything below here is only needed if the sheet is editable ***
|
||||||
console.log("L5R5E | BCS | This sheet is not editable");
|
if (!this.isEditable || this.actor.system.soft_locked) {
|
||||||
return;
|
console.log("L5R5E | BCS | This sheet is not editable");
|
||||||
}
|
|
||||||
|
|
||||||
// Check item type and subtype
|
|
||||||
const item = await game.l5r5e.HelpersL5r5e.getDragnDropTargetObject(event);
|
|
||||||
if (!item || !["Item", "JournalEntry"].includes(item.documentName) || item.type === "property") {
|
|
||||||
console.log(`L5R5E | BCS | Wrong subtype ${item?.type}`, item);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Specific curriculum journal drop
|
|
||||||
if (item.documentName === "JournalEntry") {
|
|
||||||
// npc does not have this
|
|
||||||
if (!this.actor.system.identity?.school_curriculum_journal) {
|
|
||||||
console.log("L5R5E | BCS | NPC won't go to school :'(");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.actor.system.identity.school_curriculum_journal = {
|
|
||||||
id: item._id,
|
|
||||||
name: item.name,
|
|
||||||
pack: item.pack || null,
|
|
||||||
};
|
|
||||||
await this.actor.update({
|
|
||||||
system: {
|
|
||||||
identity: {
|
|
||||||
school_curriculum_journal: this.actor.system.identity.school_curriculum_journal,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dropped an item with same "id" as one owned
|
|
||||||
if (this.actor.items) {
|
|
||||||
// Exit if we already owned exactly this id (drag a personal item on our own sheet)
|
|
||||||
if (
|
|
||||||
this.actor.items.some((embedItem) => {
|
|
||||||
// Search in children
|
|
||||||
if (embedItem.items instanceof Map && embedItem.items.has(item._id)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return embedItem._id === item._id;
|
|
||||||
})
|
|
||||||
) {
|
|
||||||
console.log("L5R5E | BCS | This element has been ignored because it already exists in this actor", item.uuid);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add quantity instead if they have (id is different so use type and name)
|
// Check item type and subtype
|
||||||
if (item.system.quantity) {
|
const item = await game.l5r5e.HelpersL5r5e.getDragnDropTargetObject(event);
|
||||||
const tmpItem = this.actor.items.find(
|
if (!item || !["Item", "JournalEntry"].includes(item.documentName) || item.type === "property") {
|
||||||
(embedItem) => embedItem.name === item.name && embedItem.type === item.type
|
console.log(`L5R5E | BCS | Wrong subtype ${item?.type}`, item);
|
||||||
);
|
return;
|
||||||
if (tmpItem && this._modifyQuantity(tmpItem.id, 1)) {
|
}
|
||||||
|
|
||||||
|
// Specific curriculum journal drop
|
||||||
|
if (item.documentName === "JournalEntry") {
|
||||||
|
// npc does not have this
|
||||||
|
if (!this.actor.system.identity?.school_curriculum_journal) {
|
||||||
|
console.log("L5R5E | BCS | NPC won't go to school :'(");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
this.actor.system.identity.school_curriculum_journal = {
|
||||||
}
|
id: item._id,
|
||||||
|
name: item.name,
|
||||||
// Can add the item - Foundry override cause props
|
pack: item.pack || null,
|
||||||
const allowed = Hooks.call("dropActorSheetData", this.actor, this, item);
|
};
|
||||||
if (allowed === false) {
|
await this.actor.update({
|
||||||
return;
|
system: {
|
||||||
}
|
identity: {
|
||||||
|
school_curriculum_journal: this.actor.system.identity.school_curriculum_journal,
|
||||||
let itemData = item.toObject(true);
|
},
|
||||||
|
},
|
||||||
// Item subtype specific
|
});
|
||||||
switch (itemData.type) {
|
|
||||||
case "army_cohort":
|
|
||||||
case "army_fortification":
|
|
||||||
console.warn("L5R5E | BCS | Army items are not allowed", item?.type, item);
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case "advancement":
|
// Dropped an item with same "id" as one owned
|
||||||
// Specific advancements, remove 1 to selected ring/skill
|
if (this.actor.items) {
|
||||||
await this.actor.addBonus(item);
|
// Exit if we already owned exactly this id (drag a personal item on our own sheet)
|
||||||
break;
|
if (
|
||||||
|
this.actor.items.some((embedItem) => {
|
||||||
case "title":
|
// Search in children
|
||||||
// Generate new Ids for the embed items
|
if (embedItem.items instanceof Map && embedItem.items.has(item._id)) {
|
||||||
await item.generateNewIdsForAllEmbedItems();
|
return true;
|
||||||
|
}
|
||||||
// Add embed advancements bonus
|
return embedItem._id === item._id;
|
||||||
for (let [embedId, embedItem] of item.system.items) {
|
})
|
||||||
if (embedItem.type === "advancement") {
|
) {
|
||||||
await this.actor.addBonus(embedItem);
|
console.log("L5R5E | BCS | This element has been ignored because it already exists in this actor", item.uuid);
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// refresh data
|
// Add quantity instead if they have (id is different so use type and name)
|
||||||
itemData = item.toObject(true);
|
if (item.system.quantity) {
|
||||||
break;
|
const tmpItem = this.actor.items.find(
|
||||||
|
(embedItem) => embedItem.name === item.name && embedItem.type === item.type
|
||||||
case "technique":
|
);
|
||||||
// School_ability and mastery_ability, allow only 1 per type
|
if (tmpItem && this._modifyQuantity(tmpItem.id, 1)) {
|
||||||
if (CONFIG.l5r5e.techniques.get(itemData.system.technique_type)?.type === "school") {
|
|
||||||
if (
|
|
||||||
Array.from(this.actor.items).some((e) => {
|
|
||||||
return e.type === "technique" && e.system.technique_type === itemData.system.technique_type;
|
|
||||||
})
|
|
||||||
) {
|
|
||||||
ui.notifications.info(game.i18n.localize("l5r5e.techniques.only_one"));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No cost for schools
|
|
||||||
itemData.system.xp_cost = 0;
|
|
||||||
itemData.system.xp_used = 0;
|
|
||||||
itemData.system.in_curriculum = true;
|
|
||||||
} else {
|
|
||||||
// Check if technique is allowed for this character
|
|
||||||
// if (!game.user.isGM && !this.actor.system.techniques[itemData.system.technique_type]) {
|
|
||||||
// ui.notifications.info(game.i18n.localize("l5r5e.techniques.not_allowed"));
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Verify cost
|
|
||||||
itemData.system.xp_cost =
|
|
||||||
itemData.system.xp_cost > 0 ? itemData.system.xp_cost : CONFIG.l5r5e.xp.techniqueCost;
|
|
||||||
itemData.system.xp_used = itemData.system.xp_cost;
|
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Modify the bought at rank to the current actor rank
|
// Can add the item - Foundry override cause props
|
||||||
if (itemData.system.bought_at_rank !== undefined && this.actor.system.identity?.school_rank) {
|
const allowed = Hooks.call("dropActorSheetData", this.actor, this, item);
|
||||||
itemData.system.bought_at_rank = this.actor.system.identity.school_rank;
|
if (allowed === false) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Finally create the embed
|
let itemData = item.toObject(true);
|
||||||
return this.actor.createEmbeddedDocuments("Item", [itemData]);
|
|
||||||
|
// Item subtype specific
|
||||||
|
switch (itemData.type) {
|
||||||
|
case "army_cohort":
|
||||||
|
case "army_fortification":
|
||||||
|
console.warn("L5R5E | BCS | Army items are not allowed", item?.type, item);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case "advancement":
|
||||||
|
// Specific advancements, add x to selected ring/skill
|
||||||
|
await this.actor.addBonus(item);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "title":
|
||||||
|
// Generate new Ids for the embed items
|
||||||
|
await item.generateNewIdsForAllEmbedItems();
|
||||||
|
|
||||||
|
// Add embed advancements bonus
|
||||||
|
for (let [embedId, embedItem] of item.system.items) {
|
||||||
|
if (embedItem.type === "advancement") {
|
||||||
|
await this.actor.addBonus(embedItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// refresh data
|
||||||
|
itemData = item.toObject(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "skill":
|
||||||
|
itemData.system.rank = 0;
|
||||||
|
itemData.system.modifier = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "technique":
|
||||||
|
// School_ability and mastery_ability, allow only 1 per type
|
||||||
|
if (CONFIG.l5r5e.techniques.get(itemData.system.technique_type)?.type === "school") {
|
||||||
|
if (
|
||||||
|
Array.from(this.actor.items).some((e) => {
|
||||||
|
return e.type === "technique" && e.system.technique_type === itemData.system.technique_type;
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
ui.notifications.info(game.i18n.localize("l5r5e.techniques.only_one"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No cost for schools
|
||||||
|
itemData.system.xp_cost = 0;
|
||||||
|
itemData.system.xp_used = 0;
|
||||||
|
itemData.system.in_curriculum = true;
|
||||||
|
} else {
|
||||||
|
// Check if technique is allowed for this character
|
||||||
|
// if (!game.user.isGM && !this.actor.system.techniques[itemData.system.technique_type]) {
|
||||||
|
// ui.notifications.info(game.i18n.localize("l5r5e.techniques.not_allowed"));
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Verify cost
|
||||||
|
itemData.system.xp_cost =
|
||||||
|
itemData.system.xp_cost > 0 ? itemData.system.xp_cost : CONFIG.l5r5e.xp.techniqueCost;
|
||||||
|
itemData.system.xp_used = itemData.system.xp_cost;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify the bought at rank to the current actor rank
|
||||||
|
if (itemData.system.bought_at_rank !== undefined && this.actor.system.identity?.school_rank) {
|
||||||
|
itemData.system.bought_at_rank = this.actor.system.identity.school_rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally create the embed
|
||||||
|
return this.actor.createEmbeddedDocuments("Item", [itemData]);
|
||||||
|
|
||||||
|
} catch (ex) {
|
||||||
|
console.warn("L5R5E |", ex.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @inheritdoc */
|
/** @inheritdoc */
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ export class CharacterGeneratorDialog extends FormApplication {
|
|||||||
}));
|
}));
|
||||||
return {
|
return {
|
||||||
...(await super.getData(options)),
|
...(await super.getData(options)),
|
||||||
isNpc: this.actor.type === "npc",
|
isNpc: this.actor.isNpc,
|
||||||
clanList: [{ id: "random", label: game.i18n.localize("l5r5e.global.random") }, ...clans],
|
clanList: [{ id: "random", label: game.i18n.localize("l5r5e.global.random") }, ...clans],
|
||||||
genderList: [
|
genderList: [
|
||||||
{ id: "random", label: game.i18n.localize("l5r5e.global.random") },
|
{ id: "random", label: game.i18n.localize("l5r5e.global.random") },
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ export class CharacterGenerator {
|
|||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
const actorDatas = actor.system;
|
const actorDatas = actor.system;
|
||||||
const isNpc = actor.type === "npc";
|
const isNpc = actor.isNpc;
|
||||||
|
|
||||||
// Need to set some required values
|
// Need to set some required values
|
||||||
this.data.age = actorDatas.identity.age || CharacterGenerator.genAge(this.data.avgRingsValue);
|
this.data.age = actorDatas.identity.age || CharacterGenerator.genAge(this.data.avgRingsValue);
|
||||||
|
|||||||
@@ -47,8 +47,11 @@ 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 Skills
|
||||||
|
sheetData.data.skillCategories = game.l5r5e.HelpersL5r5e.splitSkillByCategory(sheetData.items);
|
||||||
|
|
||||||
// Split Money
|
// Split Money
|
||||||
sheetData.data.system.money = this._zeniToMoney(this.actor.system.zeni);
|
sheetData.data.money = this._zeniToMoney(this.actor.system.zeni);
|
||||||
|
|
||||||
// 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);
|
||||||
@@ -180,6 +183,12 @@ export class CharacterSheetL5r5e extends BaseCharacterSheetL5r5e {
|
|||||||
* @param formData
|
* @param formData
|
||||||
*/
|
*/
|
||||||
_updateObject(event, formData) {
|
_updateObject(event, formData) {
|
||||||
|
// Update items ranks
|
||||||
|
const formDataObj = foundry.utils.expandObject(formData);
|
||||||
|
if (formDataObj.skillsValues) {
|
||||||
|
this._updateItemsRank(foundry.utils.expandObject(formDataObj.skillsValues));
|
||||||
|
}
|
||||||
|
|
||||||
// Clan tag trim if autocomplete in school name
|
// Clan tag trim if autocomplete in school name
|
||||||
if (
|
if (
|
||||||
formData["autoCompleteListName"] === "system.identity.school" &&
|
formData["autoCompleteListName"] === "system.identity.school" &&
|
||||||
@@ -194,16 +203,12 @@ export class CharacterSheetL5r5e extends BaseCharacterSheetL5r5e {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Store money in Zeni
|
// Store money in Zeni
|
||||||
if (formData["system.money.koku"] || formData["system.money.bu"] || formData["system.money.zeni"]) {
|
if (formData["money.koku"] || formData["money.bu"] || formData["money.zeni"]) {
|
||||||
formData["system.zeni"] = this._moneyToZeni(
|
formData["system.zeni"] = this._moneyToZeni(
|
||||||
formData["system.money.koku"] || 0,
|
formData["money.koku"] || 0,
|
||||||
formData["system.money.bu"] || 0,
|
formData["money.bu"] || 0,
|
||||||
formData["system.money.zeni"] || 0
|
formData["money.zeni"] || 0
|
||||||
);
|
);
|
||||||
// Remove fake money object
|
|
||||||
delete formData["system.money.koku"];
|
|
||||||
delete formData["system.money.bu"];
|
|
||||||
delete formData["system.money.zeni"];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save computed values
|
// Save computed values
|
||||||
@@ -219,6 +224,20 @@ export class CharacterSheetL5r5e extends BaseCharacterSheetL5r5e {
|
|||||||
return super._updateObject(event, formData);
|
return super._updateObject(event, formData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update embedded items ranks
|
||||||
|
* @param {Object<String:String>} itemsValues items new values "ids: rank"
|
||||||
|
*/
|
||||||
|
_updateItemsRank(itemsValues) {
|
||||||
|
Object.entries(itemsValues).forEach(([key, rank]) => {
|
||||||
|
const item = this.actor.items.get(key);
|
||||||
|
if (!item || item.system.rank === rank) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
item.update({ "system.rank": rank });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a sum in Zeni to Zeni, Bu and Koku
|
* Convert a sum in Zeni to Zeni, Bu and Koku
|
||||||
* @param {number} zeni
|
* @param {number} zeni
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export class CombatL5r5e extends Combat {
|
|||||||
const skillId = messageOptions.skillId
|
const skillId = messageOptions.skillId
|
||||||
? messageOptions.skillId
|
? messageOptions.skillId
|
||||||
: CONFIG.l5r5e.initiativeSkills[game.settings.get(CONFIG.l5r5e.namespace, "initiative-encounter")];
|
: CONFIG.l5r5e.initiativeSkills[game.settings.get(CONFIG.l5r5e.namespace, "initiative-encounter")];
|
||||||
const skillCat = CONFIG.l5r5e.skills.get(skillId);
|
const skillCat = CONFIG.l5r5e.skills.get(skillId); // TODO refacto with skill items
|
||||||
|
|
||||||
// Get score for each combatant
|
// Get score for each combatant
|
||||||
const networkActors = [];
|
const networkActors = [];
|
||||||
@@ -199,6 +199,6 @@ export class CombatL5r5e extends Combat {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
static _getWeightByActorType(actor) {
|
static _getWeightByActorType(actor) {
|
||||||
return actor.type === "npc" ? (actor.type === "minion" ? 3 : 2) : 1;
|
return actor.isNpc ? (actor.type === "minion" ? 3 : 2) : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export const L5R5E = {
|
|||||||
money: [50, 10],
|
money: [50, 10],
|
||||||
stances: ["earth", "air", "water", "fire", "void"],
|
stances: ["earth", "air", "water", "fire", "void"],
|
||||||
roles: ["artisan", "bushi", "courtier", "monk", "sage", "shinobi", "shugenja"],
|
roles: ["artisan", "bushi", "courtier", "monk", "sage", "shinobi", "shugenja"],
|
||||||
|
skillCategories: ["artisan", "martial", "scholar", "social", "trade"],
|
||||||
xp: {
|
xp: {
|
||||||
costPerRank: [0, 20, 24, 32, 44, 60],
|
costPerRank: [0, 20, 24, 32, 44, 60],
|
||||||
bondCostPerRank: [0, 3, 4, 6, 8, 10],
|
bondCostPerRank: [0, 3, 4, 6, 8, 10],
|
||||||
@@ -46,6 +47,7 @@ L5R5E.techniques.set("title_ability", { type: "title", displayInTypes: false });
|
|||||||
L5R5E.techniques.set("specificity", { type: "custom", displayInTypes: false });
|
L5R5E.techniques.set("specificity", { type: "custom", displayInTypes: false });
|
||||||
|
|
||||||
// *** SkillId - CategoryId ***
|
// *** SkillId - CategoryId ***
|
||||||
|
// Hardcoded skills are still required for compatibility (migration & olds worlds)
|
||||||
L5R5E.skills = new Map();
|
L5R5E.skills = new Map();
|
||||||
L5R5E.skills.set("aesthetics", "artisan");
|
L5R5E.skills.set("aesthetics", "artisan");
|
||||||
L5R5E.skills.set("composition", "artisan");
|
L5R5E.skills.set("composition", "artisan");
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ export class DicePickerDialog extends FormApplication {
|
|||||||
* ex: new game.l5r5e.DicePickerDialog({skillId: 'aesthetics', ringId: 'water', actor: game.user.character}).render(true);
|
* ex: new game.l5r5e.DicePickerDialog({skillId: 'aesthetics', ringId: 'water', actor: game.user.character}).render(true);
|
||||||
*
|
*
|
||||||
* Options :
|
* Options :
|
||||||
* actor {Actor} Any `Actor` object instance. Ex : `game.user.character`, `canvas.tokens.controlled[0].actor`
|
* actor {ActorL5r5e} Any `Actor` object instance. Ex : `game.user.character`, `canvas.tokens.controlled[0].actor`
|
||||||
* actorId {string} This is the `id` not the `uuid` of an actor. Ex : "AbYgKrNwWeAxa9jT"
|
* actorId {string} This is the `id` not the `uuid` of an actor. Ex : "AbYgKrNwWeAxa9jT"
|
||||||
* actorName {string} Careful this is case-sensitive. Ex : "Isawa Aki"
|
* actorName {string} Careful this is case-sensitive. Ex : "Isawa Aki"
|
||||||
* difficulty {number} `1` to `9`
|
* difficulty {number} `1` to `9`
|
||||||
@@ -271,19 +271,21 @@ export class DicePickerDialog extends FormApplication {
|
|||||||
if (!skillsList) {
|
if (!skillsList) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.object.skill.list = this.parseSkillsList(skillsList);
|
this.parseSkillsList(skillsList).then((list) => {
|
||||||
if (this.object.skill.list.length > 0) {
|
this.object.skill.list = list;
|
||||||
// Set 1st skill
|
if (this.object.skill.list.length > 0) {
|
||||||
if (this.useCategory) {
|
// Set 1st skill
|
||||||
this.skillCatId = this.object.skill.list[0].id;
|
if (this.useCategory) {
|
||||||
} else {
|
this.skillCatId = this.object.skill.list[0].id;
|
||||||
this.skillId = this.object.skill.list[0].id;
|
} else {
|
||||||
|
this.skillId = this.object.skill.list[0].id;
|
||||||
|
}
|
||||||
|
// Remove the list if only one item
|
||||||
|
if (this.object.skill.list.length === 1) {
|
||||||
|
this.object.skill.list = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Remove the list if only one item
|
});
|
||||||
if (this.object.skill.list.length === 1) {
|
|
||||||
this.object.skill.list = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -303,7 +305,7 @@ export class DicePickerDialog extends FormApplication {
|
|||||||
name: "",
|
name: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
this.skillCatId = CONFIG.l5r5e.skills.get(skillId);
|
this.skillCatId = CONFIG.l5r5e.skills.get(skillId); // TODO refacto with skill items
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -382,7 +384,7 @@ export class DicePickerDialog extends FormApplication {
|
|||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
get useCategory() {
|
get useCategory() {
|
||||||
return !!this._actor && this._actor.type === "npc";
|
return !!this._actor && this._actor.isNpc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -830,10 +832,10 @@ export class DicePickerDialog extends FormApplication {
|
|||||||
* NPC : shrink to category names
|
* NPC : shrink to category names
|
||||||
*
|
*
|
||||||
* @param {string} skillList
|
* @param {string} skillList
|
||||||
* @return {string[]}
|
* @returns {Promise<{id: *, label: string}[]>}
|
||||||
*/
|
*/
|
||||||
parseSkillsList(skillList) {
|
async parseSkillsList(skillList) {
|
||||||
const categories = game.l5r5e.HelpersL5r5e.getCategoriesSkillsList();
|
const categories = await game.l5r5e.HelpersL5r5e.getCategoriesSkillsList();
|
||||||
|
|
||||||
// Sanitize and uniques values
|
// Sanitize and uniques values
|
||||||
const unqSkillList = new Set();
|
const unqSkillList = new Set();
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ export class GmMonitor extends FormApplication {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// If empty add pc with owner
|
// If empty add pc with owner
|
||||||
actors = game.actors.filter((actor) => actor.type === "character" && actor.hasPlayerOwnerActive);
|
actors = game.actors.filter((actor) => actor.isCharacter && actor.hasPlayerOwnerActive);
|
||||||
this._saveActorsIds();
|
this._saveActorsIds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,12 @@ export const RegisterHandlebars = function () {
|
|||||||
return objects.join("");
|
return objects.join("");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Make the sum of values
|
||||||
|
Handlebars.registerHelper('sum', function(...nb) {
|
||||||
|
nb.pop(); // remove this function call
|
||||||
|
return nb.reduce((acc, n) => acc + Number(n ?? 0), 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;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
export class HelpersL5r5e {
|
export class HelpersL5r5e {
|
||||||
/**
|
/**
|
||||||
* Get Rings/Element for List / Select
|
* Get Rings/Element for List / Select
|
||||||
* @param {Actor|null} actor
|
* @param {ActorL5r5e|null} actor
|
||||||
* @return {{id: string, label: *, value}[]}
|
* @return {{id: string, label: *, value}[]}
|
||||||
*/
|
*/
|
||||||
static getRingsList(actor = null) {
|
static getRingsList(actor = null) {
|
||||||
@@ -15,12 +15,83 @@ export class HelpersL5r5e {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the default skill list for settings
|
||||||
|
* @returns {string[]}
|
||||||
|
*/
|
||||||
|
static getDefaultSkillsUuidFromPack() {
|
||||||
|
return Array.from({length: 24}, (_, i) => "Compendium.l5r5e.core-skills.L5RCoreSkl" + ('' +(i + 1)).padStart(6, "0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the skill items list for this actor or from the default (settings)
|
||||||
|
* @param {ActorL5r5e} actor If actor provided, get the skills preferably from it
|
||||||
|
* @returns {Promise<Item[]>}
|
||||||
|
*/
|
||||||
|
static async getSkillsItemsList(actor = null) {
|
||||||
|
const skillList = [];
|
||||||
|
|
||||||
|
// If actor provided, get the skills preferably from it
|
||||||
|
if (actor instanceof Actor && actor?.isCharacter) {
|
||||||
|
actor.items
|
||||||
|
.filter(item => item.type === "skill")
|
||||||
|
.forEach(item => skillList.push(item))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the default list from settings
|
||||||
|
let defaultList = game.settings.get(CONFIG.l5r5e.namespace, "defaultSkillsList") || [];
|
||||||
|
|
||||||
|
// If empty, refill with default values
|
||||||
|
if (foundry.utils.isEmpty(defaultList)) {
|
||||||
|
defaultList = HelpersL5r5e.getDefaultSkillsUuidFromPack();
|
||||||
|
await game.settings.set(CONFIG.l5r5e.namespace, "defaultSkillsList", defaultList);
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultList = await Promise.all(defaultList.map(async uuid => await fromUuid(uuid)));
|
||||||
|
|
||||||
|
|
||||||
|
// Merge the two list by name
|
||||||
|
const namesList = skillList.map(item => item.name);
|
||||||
|
defaultList.forEach(item => {
|
||||||
|
if (item && !namesList.includes(item.name)) {
|
||||||
|
skillList.push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return skillList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split Skills item by categories, and sort them alphabetically
|
||||||
|
* @param {Item[]} itemsList
|
||||||
|
* @return {{catName: Item[]}}
|
||||||
|
*/
|
||||||
|
static splitSkillByCategory(itemsList) {
|
||||||
|
const skill = CONFIG.l5r5e.skillCategories.reduce((acc,curr) => (acc[curr] = [], acc), {});
|
||||||
|
|
||||||
|
itemsList.forEach((item) => {
|
||||||
|
if (item.type === "skill") {
|
||||||
|
const cat = item.system.category ?? "artisan";
|
||||||
|
skill[cat].push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sort Items by name
|
||||||
|
Object.values(skill).forEach(section => {
|
||||||
|
section.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
});
|
||||||
|
|
||||||
|
return skill;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Skills for List / Select with groups
|
* Get Skills for List / Select with groups
|
||||||
* @param {boolean} useGroup
|
* @param {boolean} useGroup
|
||||||
* @return {{cat: any, id: any, label: *}[]}
|
* @return {{cat: any, id: any, label: *}[]}
|
||||||
*/
|
*/
|
||||||
static getSkillsList(useGroup = false) {
|
static getSkillsList(useGroup = false) {
|
||||||
|
console.warn('@deprecated hardcoded skills - helpers.getSkillsList() - Use getSkillsItemsList() + splitSkillByCategory() instead'); // TODO @deprecated hardcoded skills
|
||||||
|
|
||||||
if (!useGroup) {
|
if (!useGroup) {
|
||||||
return Array.from(CONFIG.l5r5e.skills).map(([id, cat]) => ({
|
return Array.from(CONFIG.l5r5e.skills).map(([id, cat]) => ({
|
||||||
id: id,
|
id: id,
|
||||||
@@ -45,17 +116,25 @@ export class HelpersL5r5e {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return Categories and Skill names in it
|
* Return Categories and Skill names in it
|
||||||
* @return {Map}
|
* @param {ActorL5r5e} actor If actor provided, get the skills preferably from it
|
||||||
|
* @returns {Promise<Map>}
|
||||||
*/
|
*/
|
||||||
static getCategoriesSkillsList() {
|
static async getCategoriesSkillsList(actor = null) {
|
||||||
return Array.from(CONFIG.l5r5e.skills).reduce((acc, [id, cat]) => {
|
const skillList = await HelpersL5r5e.getSkillsItemsList(actor);
|
||||||
|
const acc = new Map();
|
||||||
|
|
||||||
|
skillList.forEach((item) => {
|
||||||
|
const id = item.name;
|
||||||
|
const cat = item.system.category;
|
||||||
|
|
||||||
if (acc.has(cat)) {
|
if (acc.has(cat)) {
|
||||||
acc.set(cat, [...acc.get(cat), id]);
|
acc.set(cat, [...acc.get(cat), id]);
|
||||||
} else {
|
} else {
|
||||||
acc.set(cat, [id]);
|
acc.set(cat, [id]);
|
||||||
}
|
}
|
||||||
return acc;
|
});
|
||||||
}, new Map());
|
|
||||||
|
return acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -297,6 +376,8 @@ export class HelpersL5r5e {
|
|||||||
static getPackNameForCoreItem(documentId) {
|
static getPackNameForCoreItem(documentId) {
|
||||||
const core = new Map();
|
const core = new Map();
|
||||||
|
|
||||||
|
core.set("Skl", "l5r5e.core-skills");
|
||||||
|
|
||||||
core.set("Arm", "l5r5e.core-armors");
|
core.set("Arm", "l5r5e.core-armors");
|
||||||
core.set("Bon", "l5r5e.core-bonds");
|
core.set("Bon", "l5r5e.core-bonds");
|
||||||
core.set("Boo", "l5r5e.core-celestial-implement-boons");
|
core.set("Boo", "l5r5e.core-celestial-implement-boons");
|
||||||
@@ -442,8 +523,8 @@ export class HelpersL5r5e {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribe to common events from the sheet.
|
* Subscribe to common events from the sheet.
|
||||||
* @param {jQuery} html HTML content of the sheet.
|
* @param {jQuery} html HTML content of the sheet.
|
||||||
* @param {Actor} actor Actor Object
|
* @param {ActorL5r5e} actor Actor Object
|
||||||
*/
|
*/
|
||||||
static commonListeners(html, actor = null) {
|
static commonListeners(html, actor = null) {
|
||||||
// Toggle
|
// Toggle
|
||||||
@@ -567,12 +648,15 @@ export class HelpersL5r5e {
|
|||||||
static async getEmbedItemByEvent(event, actor) {
|
static async getEmbedItemByEvent(event, actor) {
|
||||||
const current = $(event.currentTarget);
|
const current = $(event.currentTarget);
|
||||||
const itemId = current.data("item-id");
|
const itemId = current.data("item-id");
|
||||||
|
const itemUuid = current.data("item-uuid");
|
||||||
const propertyId = current.data("property-id");
|
const propertyId = current.data("property-id");
|
||||||
const itemParentId = current.data("item-parent-id");
|
const itemParentId = current.data("item-parent-id");
|
||||||
|
|
||||||
let item;
|
let item;
|
||||||
if (propertyId) {
|
if (propertyId) {
|
||||||
item = await HelpersL5r5e.getObjectGameOrPack({ id: propertyId, type: "Item" });
|
item = await HelpersL5r5e.getObjectGameOrPack({ id: propertyId, type: "Item" });
|
||||||
|
} else if (itemUuid) {
|
||||||
|
item = await fromUuid(itemUuid);
|
||||||
} else if (itemParentId) {
|
} else if (itemParentId) {
|
||||||
// Embed Item
|
// Embed Item
|
||||||
let parentItem;
|
let parentItem;
|
||||||
@@ -739,7 +823,7 @@ export class HelpersL5r5e {
|
|||||||
* @return {Promise<{RollTableDraw}>} The drawn results
|
* @return {Promise<{RollTableDraw}>} The drawn results
|
||||||
*/
|
*/
|
||||||
static async drawManyFromPack(pack, tableName, retrieve = 5, opt = { rollMode: "selfroll" }) {
|
static async drawManyFromPack(pack, tableName, retrieve = 5, opt = { rollMode: "selfroll" }) {
|
||||||
const comp = await game.packs.get(pack);
|
const comp = game.packs.get(pack);
|
||||||
if (!comp) {
|
if (!comp) {
|
||||||
console.log(`L5R5E | Helpers | Pack not found[${pack}]`);
|
console.log(`L5R5E | Helpers | Pack not found[${pack}]`);
|
||||||
return;
|
return;
|
||||||
@@ -754,6 +838,23 @@ export class HelpersL5r5e {
|
|||||||
return await table.drawMany(retrieve, opt);
|
return await table.drawMany(retrieve, opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load all compendium data from his id
|
||||||
|
*
|
||||||
|
* @param {String} compendium
|
||||||
|
* @param {Function} filter
|
||||||
|
* @returns {Promise<Item[]>}
|
||||||
|
*/
|
||||||
|
static async loadCompendium(compendium, filter = item => true) {
|
||||||
|
const pack = game.packs.get(compendium);
|
||||||
|
if (!pack) {
|
||||||
|
console.log(`L5R5E | Pack not found[${compendium}]`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const data = (await pack.getDocuments()) ?? [];
|
||||||
|
return data.filter(filter);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the string simplified for comparaison
|
* Return the string simplified for comparaison
|
||||||
* @param {string} str
|
* @param {string} str
|
||||||
|
|||||||
@@ -28,6 +28,14 @@ export default class HooksL5r5e {
|
|||||||
game.l5r5e.migrations.migrateWorld({ force: false }).then();
|
game.l5r5e.migrations.migrateWorld({ force: false }).then();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prepare values are sometimes null
|
||||||
|
["character", "adversary", "minion"].forEach(preparedId => {
|
||||||
|
const prepVal = game.settings.get(CONFIG.l5r5e.namespace, `initiative-prepared-${preparedId}`);
|
||||||
|
if (prepVal === null || prepVal === "null") {
|
||||||
|
game.settings.set(CONFIG.l5r5e.namespace, `initiative-prepared-${preparedId}`, "actor");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// For some reasons, not always really ready, so wait a little
|
// For some reasons, not always really ready, so wait a little
|
||||||
await new Promise((r) => setTimeout(r, 2000));
|
await new Promise((r) => setTimeout(r, 2000));
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export class ItemL5r5e extends Item {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the linked Actor instance if any (current or embed)
|
* Return the linked Actor instance if any (current or embed)
|
||||||
* @return {Actor|null}
|
* @return {ActorL5r5e|null}
|
||||||
*/
|
*/
|
||||||
get actor() {
|
get actor() {
|
||||||
return super.actor || game.actors.get(this.system.parent_id?.actor_id) || null;
|
return super.actor || game.actors.get(this.system.parent_id?.actor_id) || null;
|
||||||
@@ -58,7 +58,11 @@ export class ItemL5r5e extends Item {
|
|||||||
*/
|
*/
|
||||||
static async create(data, context = {}) {
|
static async create(data, context = {}) {
|
||||||
if (data.img === undefined) {
|
if (data.img === undefined) {
|
||||||
data.img = `${CONFIG.l5r5e.paths.assets}icons/items/${data.type}.svg`;
|
if (data.type === 'technique') {
|
||||||
|
data.img = `${CONFIG.l5r5e.paths.assets}icons/techs/kata.svg`;
|
||||||
|
} else {
|
||||||
|
data.img = `${CONFIG.l5r5e.paths.assets}icons/items/${data.type}.svg`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return super.create(data, context);
|
return super.create(data, context);
|
||||||
}
|
}
|
||||||
@@ -235,7 +239,11 @@ export class ItemL5r5e extends Item {
|
|||||||
if (addBonusToActor) {
|
if (addBonusToActor) {
|
||||||
const actor = this.actor;
|
const actor = this.actor;
|
||||||
if (item instanceof Item && actor instanceof Actor) {
|
if (item instanceof Item && actor instanceof Actor) {
|
||||||
actor.addBonus(item);
|
try {
|
||||||
|
await actor.addBonus(item);
|
||||||
|
} catch (ex) {
|
||||||
|
console.warn("L5R5E |", ex.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export class AdvancementSheetL5r5e extends ItemSheetL5r5e {
|
|||||||
const sheetData = await super.getData(options);
|
const sheetData = await super.getData(options);
|
||||||
|
|
||||||
sheetData.data.subTypesList = AdvancementSheetL5r5e.types;
|
sheetData.data.subTypesList = AdvancementSheetL5r5e.types;
|
||||||
sheetData.data.skillsList = game.l5r5e.HelpersL5r5e.getSkillsList(true);
|
sheetData.data.skillsList = game.l5r5e.HelpersL5r5e.splitSkillByCategory(await game.l5r5e.HelpersL5r5e.getSkillsItemsList(this.actor));
|
||||||
|
|
||||||
return sheetData;
|
return sheetData;
|
||||||
}
|
}
|
||||||
@@ -82,33 +82,45 @@ export class AdvancementSheetL5r5e extends ItemSheetL5r5e {
|
|||||||
let name = this.object.name;
|
let name = this.object.name;
|
||||||
let img = this.object.img;
|
let img = this.object.img;
|
||||||
|
|
||||||
|
const getLocalItemByUuid = async (uuid) => {
|
||||||
|
const item = await fromUuid(uuid);
|
||||||
|
if (!item) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (item?.actor?._id === this.actor._id) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
return this.items.getName(item.name);
|
||||||
|
}
|
||||||
|
const skillItemNew = newChoice.skill ? (await getLocalItemByUuid(newChoice.skill)) : null;
|
||||||
|
const skillItemOld = oldChoice.skill ? (await getLocalItemByUuid(oldChoice.skill)) : null;
|
||||||
|
|
||||||
// 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/l5r5e/assets/icons/rings/${newChoice.ring}.svg`;
|
||||||
} else if (newChoice.skill) {
|
|
||||||
name =
|
} else if (newChoice.skill && skillItemNew) {
|
||||||
game.i18n.localize(`l5r5e.skills.${CONFIG.l5r5e.skills.get(newChoice.skill)}.${newChoice.skill}`) +
|
name = skillItemNew.name +"+1";
|
||||||
"+1";
|
|
||||||
img = `systems/l5r5e/assets/dices/default/skill_blank.svg`;
|
img = `systems/l5r5e/assets/dices/default/skill_blank.svg`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Object embed in actor ?
|
// Object embed in actor ?
|
||||||
const actor = this.document.actor;
|
const actor = this.document.actor;
|
||||||
if (actor) {
|
if (actor) {
|
||||||
|
if (newChoice.skill && !skillItemNew.actor) {
|
||||||
|
ui.notifications.warn(`Unable to find "${skillItemNew?.name}" on this actor`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const actorData = foundry.utils.duplicate(actor.system);
|
const actorData = foundry.utils.duplicate(actor.system);
|
||||||
let skillCatId = null;
|
|
||||||
|
|
||||||
// Old choices
|
// Old choices
|
||||||
if (oldChoice.ring) {
|
if (oldChoice.ring) {
|
||||||
actorData.rings[oldChoice.ring] = Math.max(1, actorData.rings[oldChoice.ring] - 1);
|
actorData.rings[oldChoice.ring] = Math.max(1, actorData.rings[oldChoice.ring] - 1);
|
||||||
}
|
}
|
||||||
if (oldChoice.skill) {
|
if (oldChoice.skill && skillItemOld) {
|
||||||
skillCatId = CONFIG.l5r5e.skills.get(oldChoice.skill);
|
await skillItemOld.update({ "system.rank": Math.max(0, skillItemOld.system.rank - 1) });
|
||||||
actorData.skills[skillCatId][oldChoice.skill] = Math.max(
|
|
||||||
0,
|
|
||||||
actorData.skills[skillCatId][oldChoice.skill] - 1
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// new choices
|
// new choices
|
||||||
@@ -119,15 +131,11 @@ export class AdvancementSheetL5r5e extends ItemSheetL5r5e {
|
|||||||
game.i18n.localize(`l5r5e.rings.${newChoice.ring}`) +
|
game.i18n.localize(`l5r5e.rings.${newChoice.ring}`) +
|
||||||
` +1 (${actorData.rings[newChoice.ring] - 1} -> ${actorData.rings[newChoice.ring]})`;
|
` +1 (${actorData.rings[newChoice.ring] - 1} -> ${actorData.rings[newChoice.ring]})`;
|
||||||
}
|
}
|
||||||
if (newChoice.skill) {
|
if (newChoice.skill && skillItemNew) {
|
||||||
skillCatId = CONFIG.l5r5e.skills.get(newChoice.skill);
|
const newRank = Math.min(9, skillItemNew.system.rank + 1);
|
||||||
actorData.skills[skillCatId][newChoice.skill] = actorData.skills[skillCatId][newChoice.skill] + 1;
|
await skillItemNew.update({ "system.rank": newRank });
|
||||||
xp_used = actorData.skills[skillCatId][newChoice.skill] * CONFIG.l5r5e.xp.skillCostMultiplier;
|
xp_used = newRank * CONFIG.l5r5e.xp.skillCostMultiplier;
|
||||||
name =
|
name = `${skillItemNew.name} +1 (${newRank - 1} -> ${newRank})`;
|
||||||
game.i18n.localize(`l5r5e.skills.${skillCatId}.${newChoice.skill}`) +
|
|
||||||
` +1 (${actorData.skills[skillCatId][newChoice.skill] - 1} -> ${
|
|
||||||
actorData.skills[skillCatId][newChoice.skill]
|
|
||||||
})`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Actor
|
// Update Actor
|
||||||
@@ -141,7 +149,7 @@ export class AdvancementSheetL5r5e extends ItemSheetL5r5e {
|
|||||||
name: name,
|
name: name,
|
||||||
img: img,
|
img: img,
|
||||||
system: {
|
system: {
|
||||||
xp_used: xp_used,
|
xp_used,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
28
system/scripts/items/skill-sheet.js
Normal file
28
system/scripts/items/skill-sheet.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import { ItemSheetL5r5e } from "./item-sheet.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends {ItemSheet}
|
||||||
|
*/
|
||||||
|
export class SkillSheetL5r5e extends ItemSheetL5r5e {
|
||||||
|
/** @override */
|
||||||
|
static get defaultOptions() {
|
||||||
|
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||||
|
classes: ["l5r5e", "sheet", "skill"],
|
||||||
|
template: CONFIG.l5r5e.paths.templates + "items/skill/skill-sheet.html",
|
||||||
|
width: 520,
|
||||||
|
height: 480,
|
||||||
|
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "description" }],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {Object|Promise}
|
||||||
|
*/
|
||||||
|
async getData(options = {}) {
|
||||||
|
const sheetData = await super.getData(options);
|
||||||
|
|
||||||
|
sheetData.data.SkillCategoriesList = CONFIG.l5r5e.skillCategories;
|
||||||
|
|
||||||
|
return sheetData;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,7 +29,7 @@ export class TechniqueSheetL5r5e extends ItemSheetL5r5e {
|
|||||||
// 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(
|
||||||
TechniqueSheetL5r5e.formatSkillList(sheetData.data.system.skill.split(",")),
|
await TechniqueSheetL5r5e.formatSkillList(sheetData.data.system.skill.split(",")),
|
||||||
false
|
false
|
||||||
).join(", ");
|
).join(", ");
|
||||||
|
|
||||||
@@ -54,9 +54,9 @@ export class TechniqueSheetL5r5e extends ItemSheetL5r5e {
|
|||||||
|
|
||||||
// Sanitize Difficulty and Skill list
|
// Sanitize Difficulty and Skill list
|
||||||
formData["system.difficulty"] = TechniqueSheetL5r5e.formatDifficulty(formData["system.difficulty"]);
|
formData["system.difficulty"] = TechniqueSheetL5r5e.formatDifficulty(formData["system.difficulty"]);
|
||||||
formData["system.skill"] = TechniqueSheetL5r5e.formatSkillList(
|
formData["system.skill"] = (await TechniqueSheetL5r5e.formatSkillList(
|
||||||
TechniqueSheetL5r5e.translateSkillsList(formData["system.skill"].split(","), true)
|
TechniqueSheetL5r5e.translateSkillsList(formData["system.skill"].split(","), true)
|
||||||
).join(",");
|
)).join(",");
|
||||||
|
|
||||||
return super._updateObject(event, formData);
|
return super._updateObject(event, formData);
|
||||||
}
|
}
|
||||||
@@ -143,13 +143,13 @@ export class TechniqueSheetL5r5e extends ItemSheetL5r5e {
|
|||||||
/**
|
/**
|
||||||
* Sanitize the technique skill list
|
* Sanitize the technique skill list
|
||||||
* @param {string[]} skillList
|
* @param {string[]} skillList
|
||||||
* @return {string[]}
|
* @returns {Promise<string|*[]>}
|
||||||
*/
|
*/
|
||||||
static formatSkillList(skillList) {
|
static async formatSkillList(skillList) {
|
||||||
if (!skillList) {
|
if (!skillList) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
const categories = game.l5r5e.HelpersL5r5e.getCategoriesSkillsList();
|
const categories = await game.l5r5e.HelpersL5r5e.getCategoriesSkillsList(this.actor);
|
||||||
|
|
||||||
// List categories
|
// List categories
|
||||||
const unqCatList = new Set();
|
const unqCatList = new Set();
|
||||||
@@ -160,18 +160,6 @@ export class TechniqueSheetL5r5e extends ItemSheetL5r5e {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// List skill (not include in cat)
|
return [...unqCatList];
|
||||||
const unqSkillList = new Set();
|
|
||||||
skillList.forEach((s) => {
|
|
||||||
s = s?.trim();
|
|
||||||
if (!!s && CONFIG.l5r5e.skills.has(s)) {
|
|
||||||
const cat = CONFIG.l5r5e.skills.get(s);
|
|
||||||
if (!unqCatList.has(cat)) {
|
|
||||||
unqSkillList.add(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return [...unqCatList, ...unqSkillList];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ export class WeaponSheetL5r5e extends ItemSheetL5r5e {
|
|||||||
|
|
||||||
async getData(options = {}) {
|
async getData(options = {}) {
|
||||||
const sheetData = await super.getData(options);
|
const sheetData = await super.getData(options);
|
||||||
|
const categories = await game.l5r5e.HelpersL5r5e.getCategoriesSkillsList(this.actor);
|
||||||
|
console.log(categories);
|
||||||
|
|
||||||
// Martial skills only
|
// Martial skills only
|
||||||
sheetData.data.skills = Array.from(CONFIG.l5r5e.skills)
|
sheetData.data.skills = Array.from(CONFIG.l5r5e.skills)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import { CombatL5r5e } from "./combat.js";
|
|||||||
// Items
|
// Items
|
||||||
import { ItemL5r5e } from "./item.js";
|
import { ItemL5r5e } from "./item.js";
|
||||||
import { ItemSheetL5r5e } from "./items/item-sheet.js";
|
import { ItemSheetL5r5e } from "./items/item-sheet.js";
|
||||||
|
import { SkillSheetL5r5e } from "./items/skill-sheet.js";
|
||||||
import { ArmorSheetL5r5e } from "./items/armor-sheet.js";
|
import { ArmorSheetL5r5e } from "./items/armor-sheet.js";
|
||||||
import { WeaponSheetL5r5e } from "./items/weapon-sheet.js";
|
import { WeaponSheetL5r5e } from "./items/weapon-sheet.js";
|
||||||
import { TechniqueSheetL5r5e } from "./items/technique-sheet.js";
|
import { TechniqueSheetL5r5e } from "./items/technique-sheet.js";
|
||||||
@@ -43,6 +44,7 @@ import { MigrationL5r5e } from "./migration.js";
|
|||||||
import { GmToolbox } from "./gm/gm-toolbox.js";
|
import { GmToolbox } from "./gm/gm-toolbox.js";
|
||||||
import { GmMonitor } from "./gm/gm-monitor.js";
|
import { GmMonitor } from "./gm/gm-monitor.js";
|
||||||
import { Storage } from "./storage.js";
|
import { Storage } from "./storage.js";
|
||||||
|
import { DefaultSkillsDialogL5r5e } from "./settings/default-skills-dialog.js";
|
||||||
|
|
||||||
/* ------------------------------------ */
|
/* ------------------------------------ */
|
||||||
/* Initialize system */
|
/* Initialize system */
|
||||||
@@ -92,6 +94,7 @@ Hooks.once("init", async () => {
|
|||||||
GmToolbox,
|
GmToolbox,
|
||||||
GmMonitor,
|
GmMonitor,
|
||||||
HelpDialog,
|
HelpDialog,
|
||||||
|
DefaultSkillsDialogL5r5e,
|
||||||
storage: new Storage(),
|
storage: new Storage(),
|
||||||
sockets: new SocketHandlerL5r5e(),
|
sockets: new SocketHandlerL5r5e(),
|
||||||
migrations: MigrationL5r5e,
|
migrations: MigrationL5r5e,
|
||||||
@@ -132,6 +135,11 @@ Hooks.once("init", async () => {
|
|||||||
label: "TYPES.Item.item",
|
label: "TYPES.Item.item",
|
||||||
makeDefault: true,
|
makeDefault: true,
|
||||||
});
|
});
|
||||||
|
Items.registerSheet(L5R5E.namespace, SkillSheetL5r5e, {
|
||||||
|
types: ["skill"],
|
||||||
|
label: "ITEM.TypeSkill",
|
||||||
|
makeDefault: true,
|
||||||
|
});
|
||||||
Items.registerSheet(L5R5E.namespace, ArmorSheetL5r5e, {
|
Items.registerSheet(L5R5E.namespace, ArmorSheetL5r5e, {
|
||||||
types: ["armor"],
|
types: ["armor"],
|
||||||
label: "TYPES.Item.armor",
|
label: "TYPES.Item.armor",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export class MigrationL5r5e {
|
|||||||
* Minimum Version needed for migration stuff to trigger
|
* Minimum Version needed for migration stuff to trigger
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
static NEEDED_VERSION = "1.3.0";
|
static NEEDED_VERSION = "2.0.0";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the version need some updates
|
* Return true if the version need some updates
|
||||||
@@ -28,6 +28,11 @@ export class MigrationL5r5e {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wait for translation to load
|
||||||
|
if (!options.force && typeof Babele !== "undefined") {
|
||||||
|
await new Promise((r) => setTimeout(r, 5000));
|
||||||
|
}
|
||||||
|
|
||||||
// if (MigrationL5r5e.needUpdate("1.3.0")) {
|
// if (MigrationL5r5e.needUpdate("1.3.0")) {
|
||||||
// ChatMessage.create({"content": "<strong>L5R5E v1.3.0 :</strong><br>"});
|
// ChatMessage.create({"content": "<strong>L5R5E v1.3.0 :</strong><br>"});
|
||||||
// }
|
// }
|
||||||
@@ -42,7 +47,7 @@ export class MigrationL5r5e {
|
|||||||
// Migrate World Actors
|
// Migrate World Actors
|
||||||
for (let actor of game.actors.contents) {
|
for (let actor of game.actors.contents) {
|
||||||
try {
|
try {
|
||||||
const updateData = MigrationL5r5e._migrateActorData(actor, options);
|
const updateData = await MigrationL5r5e._migrateActorData(actor, options);
|
||||||
if (!foundry.utils.isEmpty(updateData)) {
|
if (!foundry.utils.isEmpty(updateData)) {
|
||||||
console.log(`L5R5E | Migration | Migrating Actor document ${actor.name}[${actor._id}]`);
|
console.log(`L5R5E | Migration | Migrating Actor document ${actor.name}[${actor._id}]`);
|
||||||
await actor.update(updateData);
|
await actor.update(updateData);
|
||||||
@@ -225,7 +230,7 @@ export class MigrationL5r5e {
|
|||||||
* @param options
|
* @param options
|
||||||
* @return {Object} The updateData to apply
|
* @return {Object} The updateData to apply
|
||||||
*/
|
*/
|
||||||
static _migrateActorData(actor, options = { force: false }) {
|
static async _migrateActorData(actor, options = { force: false }) {
|
||||||
const updateData = {};
|
const updateData = {};
|
||||||
const system = actor.system;
|
const system = actor.system;
|
||||||
|
|
||||||
@@ -243,7 +248,7 @@ export class MigrationL5r5e {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NPC are now without autostats, we need to save the value
|
// NPC are now without autostats, we need to save the value
|
||||||
if (actor.type === "npc") {
|
if (actor.isNpc) {
|
||||||
if (system.endurance < 1) {
|
if (system.endurance < 1) {
|
||||||
updateData["system.endurance"] = (Number(system.rings.earth) + Number(system.rings.fire)) * 2;
|
updateData["system.endurance"] = (Number(system.rings.earth) + Number(system.rings.fire)) * 2;
|
||||||
updateData["system.composure"] = (Number(system.rings.earth) + Number(system.rings.water)) * 2;
|
updateData["system.composure"] = (Number(system.rings.earth) + Number(system.rings.water)) * 2;
|
||||||
@@ -264,7 +269,7 @@ export class MigrationL5r5e {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NPC have now more than a Strength and a Weakness
|
// NPC have now more than a Strength and a Weakness
|
||||||
if (actor.type === "npc" && system.rings_affinities?.strength) {
|
if (actor.isNpc && system.rings_affinities?.strength) {
|
||||||
const aff = system.rings_affinities;
|
const aff = system.rings_affinities;
|
||||||
updateData["system.rings_affinities." + aff.strength.ring] = aff.strength.value;
|
updateData["system.rings_affinities." + aff.strength.ring] = aff.strength.value;
|
||||||
updateData["system.rings_affinities." + aff.weakness.ring] = aff.weakness.value;
|
updateData["system.rings_affinities." + aff.weakness.ring] = aff.weakness.value;
|
||||||
@@ -276,6 +281,29 @@ export class MigrationL5r5e {
|
|||||||
}
|
}
|
||||||
// ***** End of 1.3.0 *****
|
// ***** End of 1.3.0 *****
|
||||||
|
|
||||||
|
// ***** Start of 2.0.0 *****
|
||||||
|
if (options?.force || MigrationL5r5e.needUpdate("2.0.0")) {
|
||||||
|
// Only PC : Convert fixed skills to items list
|
||||||
|
if (actor.isCharacter && Array.from(actor.items).every(i => i.type !== "skill")) {
|
||||||
|
// Add skills items
|
||||||
|
const update = {items: [], name: actor.name};
|
||||||
|
await game.l5r5e.ActorL5r5e.addSkillsFromDefaultList(update);
|
||||||
|
|
||||||
|
// Set actor value
|
||||||
|
update.items.forEach(item => {
|
||||||
|
const skillId = item.flags?.l5r5e?.skillCoreId;
|
||||||
|
const skillCatId = CONFIG.l5r5e.skills.get(skillId);
|
||||||
|
const skillValue = system.skills[skillCatId][skillId];
|
||||||
|
if (skillCatId && skillValue > 0) {
|
||||||
|
item.system.rank = skillValue;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
updateData.items = update.items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ***** End of 2.0.0 *****
|
||||||
|
|
||||||
return updateData;
|
return updateData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ export const PreloadTemplates = async function () {
|
|||||||
`${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`,
|
||||||
`${tpl}actors/character/skill.html`,
|
|
||||||
`${tpl}actors/character/social.html`,
|
`${tpl}actors/character/social.html`,
|
||||||
`${tpl}actors/character/stance.html`,
|
`${tpl}actors/character/stance.html`,
|
||||||
`${tpl}actors/character/techniques.html`,
|
`${tpl}actors/character/techniques.html`,
|
||||||
@@ -59,6 +58,9 @@ export const PreloadTemplates = async function () {
|
|||||||
`${tpl}items/property/properties.html`,
|
`${tpl}items/property/properties.html`,
|
||||||
`${tpl}items/property/property-entry.html`,
|
`${tpl}items/property/property-entry.html`,
|
||||||
`${tpl}items/property/property-sheet.html`,
|
`${tpl}items/property/property-sheet.html`,
|
||||||
|
`${tpl}items/skill/skill-entry.html`,
|
||||||
|
`${tpl}items/skill/skill-sheet.html`,
|
||||||
|
`${tpl}items/skill/skill-text.html`,
|
||||||
`${tpl}items/signature-scroll/signature-scroll-entry.html`,
|
`${tpl}items/signature-scroll/signature-scroll-entry.html`,
|
||||||
`${tpl}items/signature-scroll/signature-scroll-sheet.html`,
|
`${tpl}items/signature-scroll/signature-scroll-sheet.html`,
|
||||||
`${tpl}items/signature-scroll/signature-scroll-text.html`,
|
`${tpl}items/signature-scroll/signature-scroll-text.html`,
|
||||||
|
|||||||
@@ -7,6 +7,22 @@ export const RegisterSettings = function () {
|
|||||||
/* ------------------------------------ */
|
/* ------------------------------------ */
|
||||||
/* User settings */
|
/* User settings */
|
||||||
/* ------------------------------------ */
|
/* ------------------------------------ */
|
||||||
|
game.settings.registerMenu(CONFIG.l5r5e.namespace, "defaultSkillsListMenu", {
|
||||||
|
name: "SETTINGS.DefaultSkillsList.Title",
|
||||||
|
label: "SETTINGS.DefaultSkillsList.Label",
|
||||||
|
hint: "SETTINGS.DefaultSkillsList.Hint",
|
||||||
|
icon: "fas fa-bars",
|
||||||
|
type: game.l5r5e.DefaultSkillsDialogL5r5e,
|
||||||
|
restricted: true, // GameMaster only
|
||||||
|
});
|
||||||
|
game.settings.register(CONFIG.l5r5e.namespace, "defaultSkillsList", {
|
||||||
|
name: "System Migration Version",
|
||||||
|
scope: "world",
|
||||||
|
config: false,
|
||||||
|
type: Array,
|
||||||
|
default: game.l5r5e.HelpersL5r5e.getDefaultSkillsUuidFromPack(),
|
||||||
|
});
|
||||||
|
|
||||||
game.settings.register(CONFIG.l5r5e.namespace, "rnk-deleteOldMessage", {
|
game.settings.register(CONFIG.l5r5e.namespace, "rnk-deleteOldMessage", {
|
||||||
name: "SETTINGS.RollNKeep.DeleteOldMessage",
|
name: "SETTINGS.RollNKeep.DeleteOldMessage",
|
||||||
hint: "SETTINGS.RollNKeep.DeleteOldMessageHint",
|
hint: "SETTINGS.RollNKeep.DeleteOldMessageHint",
|
||||||
|
|||||||
148
system/scripts/settings/default-skills-dialog.js
Normal file
148
system/scripts/settings/default-skills-dialog.js
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
/**
|
||||||
|
* L5R Settings dialog for default skills list
|
||||||
|
* @extends {FormApplication}
|
||||||
|
*/
|
||||||
|
export class DefaultSkillsDialogL5r5e extends FormApplication {
|
||||||
|
/**
|
||||||
|
* Key for skills list in Settings
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
static skillsLisKey = "defaultSkillsList";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign the default options
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
static get defaultOptions() {
|
||||||
|
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||||
|
id: "l5r5e-settings-default-skills-dialog",
|
||||||
|
classes: ["l5r5e", "settings", "default-skills"],
|
||||||
|
template: CONFIG.l5r5e.paths.templates + "settings/default-skills-dialog.html",
|
||||||
|
title: game.i18n.localize("SETTINGS.DefaultSkillsList.Label"),
|
||||||
|
width: 500,
|
||||||
|
height: 680,
|
||||||
|
resizable: true,
|
||||||
|
closeOnSubmit: false,
|
||||||
|
submitOnClose: false,
|
||||||
|
submitOnChange: false,
|
||||||
|
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent non GM to render this windows
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
render(force = false, options = {}) {
|
||||||
|
if (!this.isEditable) {
|
||||||
|
console.log("L5R5E | You don't have the rights to display this application");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return super.render(force, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the Form Application currently editable?
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
get isEditable() {
|
||||||
|
return game.user.isGM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct and return the data object used to render the HTML template for this form application.
|
||||||
|
* @param options
|
||||||
|
* @return {Object}
|
||||||
|
*/
|
||||||
|
async getData(options = null) {
|
||||||
|
// Transform skills uuids to items by categories
|
||||||
|
let skillList = await game.l5r5e.HelpersL5r5e.getSkillsItemsList();
|
||||||
|
skillList = game.l5r5e.HelpersL5r5e.splitSkillByCategory(skillList);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...(await super.getData(options)),
|
||||||
|
skillList,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle dropped data on the Actor sheet
|
||||||
|
* @param {DragEvent} event
|
||||||
|
*/
|
||||||
|
async _onDrop(event) {
|
||||||
|
// *** Everything below here is only needed if the sheet is editable ***
|
||||||
|
if (!this.isEditable) {
|
||||||
|
console.log("L5R5E | This sheet is not editable");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check item type and subtype
|
||||||
|
const item = await game.l5r5e.HelpersL5r5e.getDragnDropTargetObject(event);
|
||||||
|
if (!item || item.documentName !== "Item" || item?.type !== "skill") {
|
||||||
|
console.log(`L5R5E | Item dropped must be a Skill Item : ${item?.type}`, item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EmbedItem actor item ?
|
||||||
|
if (item.uuid.startsWith('Actor.')) {
|
||||||
|
console.log("L5R5E | This element has been ignored because it's a EmbedItem actor item", item.uuid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const skillListUuids = game.settings.get(CONFIG.l5r5e.namespace, DefaultSkillsDialogL5r5e.skillsLisKey) || [];
|
||||||
|
|
||||||
|
// Dropped an item with same "id" as one owned
|
||||||
|
if (skillListUuids.some((embedItem) => embedItem.uuid === item.uuid)) {
|
||||||
|
console.log("L5R5E | This element has been ignored because it already exists", item.uuid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the uuid and save
|
||||||
|
skillListUuids.push(item.uuid);
|
||||||
|
await game.settings.set(CONFIG.l5r5e.namespace, DefaultSkillsDialogL5r5e.skillsLisKey, skillListUuids);
|
||||||
|
|
||||||
|
// Refresh
|
||||||
|
this.render(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscribe to events from the sheet.
|
||||||
|
* @param {jQuery} html HTML content of the sheet.
|
||||||
|
*/
|
||||||
|
activateListeners(html) {
|
||||||
|
super.activateListeners(html);
|
||||||
|
|
||||||
|
// Commons
|
||||||
|
game.l5r5e.HelpersL5r5e.commonListeners(html);
|
||||||
|
|
||||||
|
// *** Everything below here is only needed if the sheet is editable ***
|
||||||
|
if (!this.isEditable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete an item
|
||||||
|
html.find(`.item-delete`).on("click", this._removeSkill.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an item from it's uuid
|
||||||
|
* @param {Event} event
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
async _removeSkill(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
const itemUuid = $(event.currentTarget).data("item-uuid");
|
||||||
|
if (!itemUuid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove and save
|
||||||
|
const skillListUuids = game.settings.get(CONFIG.l5r5e.namespace, DefaultSkillsDialogL5r5e.skillsLisKey) || [];
|
||||||
|
await game.settings.set(CONFIG.l5r5e.namespace, DefaultSkillsDialogL5r5e.skillsLisKey, skillListUuids.filter((uuid) => uuid !== itemUuid));
|
||||||
|
|
||||||
|
// Refresh
|
||||||
|
this.render(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -7,6 +7,8 @@
|
|||||||
.item {
|
.item {
|
||||||
.item-header {
|
.item-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
.item-img {
|
.item-img {
|
||||||
flex: 0 0 32px;
|
flex: 0 0 32px;
|
||||||
padding-right: 0.25rem;
|
padding-right: 0.25rem;
|
||||||
@@ -110,6 +112,7 @@
|
|||||||
&.peculiarity,
|
&.peculiarity,
|
||||||
&.property,
|
&.property,
|
||||||
&.signature-scroll,
|
&.signature-scroll,
|
||||||
|
&.skill,
|
||||||
&.technique,
|
&.technique,
|
||||||
&.title,
|
&.title,
|
||||||
&.weapon {
|
&.weapon {
|
||||||
@@ -356,6 +359,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.skill {
|
||||||
|
article {
|
||||||
|
&.attributes {
|
||||||
|
height: 4rem;
|
||||||
|
}
|
||||||
|
&.infos {
|
||||||
|
height: calc(100% - 5rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
&.weapon {
|
&.weapon {
|
||||||
article {
|
article {
|
||||||
&.attributes {
|
&.attributes {
|
||||||
|
|||||||
@@ -41,29 +41,63 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
ul {
|
ul {
|
||||||
flex: 50%;
|
flex: 100%;
|
||||||
padding: 0.25rem 0.5rem 0.25rem 0;
|
padding: 0 0.15rem;
|
||||||
li {
|
li {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
line-height: 2rem;
|
line-height: 2rem;
|
||||||
margin: 0.25rem 0;
|
margin: 0.25rem 0;
|
||||||
&.skill {
|
}
|
||||||
text-align: right;
|
&.skill-category-skills-list {
|
||||||
span {
|
img {
|
||||||
color: $l5r5e-black;
|
width: 32px;
|
||||||
&[data-skill="melee"],
|
height: 32px;
|
||||||
&[data-skill="ranged"],
|
object-fit: contain;
|
||||||
&[data-skill="unarmed"] {
|
object-position: 50% 0;
|
||||||
float: left;
|
border: none;
|
||||||
line-height: 1rem;
|
padding: 2px 0;
|
||||||
width: calc(100% - 2rem);
|
}
|
||||||
}
|
|
||||||
|
input {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-header {
|
||||||
|
flex: 4;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.item-img {
|
||||||
|
height: 32px;
|
||||||
|
margin: 0;
|
||||||
|
flex: 0 0 32px;
|
||||||
|
}
|
||||||
|
.item-rank {
|
||||||
|
flex: 0 0 32px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.item-edit,
|
||||||
|
.item-delete {
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
flex: 0 0 1rem;
|
||||||
|
padding: 0 0.1rem;
|
||||||
|
color: $black-light;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.skill-category-ring-actions {
|
&.skill-category-ring-actions {
|
||||||
padding: 0.25rem 0 0.25rem 0.5rem;
|
padding: 0.25rem 0 0.25rem 0.5rem;
|
||||||
|
border-top: 1px dashed $l5r5e-title;
|
||||||
border-left: 1px solid $l5r5e-title;
|
border-left: 1px solid $l5r5e-title;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: space-evenly;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input {
|
input {
|
||||||
|
|||||||
@@ -933,6 +933,41 @@ button {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#l5r5e-settings-default-skills-dialog {
|
||||||
|
.item-header {
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.item-img {
|
||||||
|
flex: 0 0 32px;
|
||||||
|
padding-right: 0.25rem;
|
||||||
|
|
||||||
|
img {
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-name {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1rem;
|
||||||
|
color: $l5r5e-bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-source {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-delete {
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
flex: 0 0 1rem;
|
||||||
|
padding: 0 0.1rem;
|
||||||
|
color: $black-light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.autocomplete-wrapper {
|
.autocomplete-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
"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.11.0/raw/l5r5e.zip?job=build",
|
"download": "https://gitlab.com/teaml5r/l5r5e/-/jobs/artifacts/v2.0.0/raw/l5r5e.zip?job=build",
|
||||||
"version": "1.11.0",
|
"version": "2.0.0",
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"minimum": 11,
|
"minimum": 11,
|
||||||
"verified": "11"
|
"verified": "11"
|
||||||
@@ -50,6 +50,7 @@
|
|||||||
"color": "#019806",
|
"color": "#019806",
|
||||||
"sorting": "m",
|
"sorting": "m",
|
||||||
"packs": [
|
"packs": [
|
||||||
|
"core-skills",
|
||||||
"core-peculiarities-distinctions",
|
"core-peculiarities-distinctions",
|
||||||
"core-peculiarities-passions",
|
"core-peculiarities-passions",
|
||||||
"core-peculiarities-adversities",
|
"core-peculiarities-adversities",
|
||||||
@@ -115,6 +116,13 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packs": [
|
"packs": [
|
||||||
|
{
|
||||||
|
"name": "core-skills",
|
||||||
|
"label": "Skills",
|
||||||
|
"path": "packs/core-skills.db",
|
||||||
|
"type": "Item",
|
||||||
|
"system": "l5r5e"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "core-properties",
|
"name": "core-properties",
|
||||||
"label": "Properties",
|
"label": "Properties",
|
||||||
|
|||||||
@@ -194,7 +194,8 @@
|
|||||||
"signature_scroll",
|
"signature_scroll",
|
||||||
"item_pattern",
|
"item_pattern",
|
||||||
"army_cohort",
|
"army_cohort",
|
||||||
"army_fortification"
|
"army_fortification",
|
||||||
|
"skill"
|
||||||
],
|
],
|
||||||
"templates": {
|
"templates": {
|
||||||
"basics": {
|
"basics": {
|
||||||
@@ -220,6 +221,12 @@
|
|||||||
"properties": []
|
"properties": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"skill": {
|
||||||
|
"templates": ["basics"],
|
||||||
|
"category": "artisan",
|
||||||
|
"rank": 0,
|
||||||
|
"modifier": 0
|
||||||
|
},
|
||||||
"item": {
|
"item": {
|
||||||
"templates": ["basics", "item"]
|
"templates": ["basics", "item"]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -127,7 +127,7 @@
|
|||||||
{{!-- items list --}}
|
{{!-- items list --}}
|
||||||
<h2>{{localize 'l5r5e.sheets.equipment'}}</h2>
|
<h2>{{localize 'l5r5e.sheets.equipment'}}</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>{{localize 'l5r5e.money.title'}} : {{data.system.money.koku}} {{localize 'l5r5e.money.koku'}} / {{data.system.money.bu}} {{localize 'l5r5e.money.bu'}} / {{data.system.money.zeni}} {{localize 'l5r5e.money.zeni'}}</li>
|
<li>{{localize 'l5r5e.money.title'}} : {{data.money.koku}} {{localize 'l5r5e.money.koku'}} / {{data.money.bu}} {{localize 'l5r5e.money.bu'}} / {{data.money.zeni}} {{localize 'l5r5e.money.zeni'}}</li>
|
||||||
{{#each data.splitItemsList as |cat type|}}
|
{{#each data.splitItemsList as |cat type|}}
|
||||||
<li>
|
<li>
|
||||||
<strong>{{localize (localize 'l5r5e.{type}s.title' type=type)}} ({{cat.length}})</strong>
|
<strong>{{localize (localize 'l5r5e.{type}s.title' type=type)}} ({{cat.length}})</strong>
|
||||||
|
|||||||
@@ -46,8 +46,8 @@
|
|||||||
{{!-- 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.skillCategories as |itemsInCategory id|}}
|
||||||
'systems/l5r5e/templates/actors/character/category.html' category=category categoryId=id data=../data}}
|
{{> 'systems/l5r5e/templates/actors/character/category.html' itemsInCategory=itemsInCategory categoryId=id data=../data}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
{{> 'systems/l5r5e/templates/actors/character/techniques.html'}}
|
{{> 'systems/l5r5e/templates/actors/character/techniques.html'}}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<li class="skill-category-wrapper skill-category-content">
|
<li class="skill-category-wrapper skill-category-content">
|
||||||
<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 itemsInCategory as |skill|}}
|
||||||
{{> 'systems/l5r5e/templates/actors/character/skill.html' categoryId=../categoryId skill=skill skillId=id data=../data}}
|
{{> 'systems/l5r5e/templates/items/skill/skill-entry.html' skill=skill 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}}">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<legend class="section-header">{{localize 'l5r5e.money.title'}}</legend>
|
<legend class="section-header">{{localize 'l5r5e.money.title'}}</legend>
|
||||||
<label>
|
<label>
|
||||||
{{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="money.koku" type="number" value="{{data.money.koku}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
|
||||||
<span class="money-buttons">
|
<span class="money-buttons">
|
||||||
<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>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
{{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="money.bu" type="number" value="{{data.money.bu}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
|
||||||
<span class="money-buttons">
|
<span class="money-buttons">
|
||||||
<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>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
{{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="money.zeni" type="number" value="{{data.money.zeni}}" data-dtype="Number" min="0" placeholder="0" {{^if data.editable_not_soft_locked}}disabled{{/if}}/>
|
||||||
<span class="money-buttons">
|
<span class="money-buttons">
|
||||||
<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>
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
<li class="skill skill-wrapper">
|
|
||||||
<label class="skill-content">
|
|
||||||
<span class="dice-picker attribute-label rollable" data-skill="{{skillId}}">{{localizeSkill categoryId skillId}}</span>
|
|
||||||
<input
|
|
||||||
class="centered-input select-on-focus"
|
|
||||||
type="number"
|
|
||||||
name="system.skills.{{categoryId}}.{{skillId}}"
|
|
||||||
value="{{skill}}"
|
|
||||||
data-dtype="Number"
|
|
||||||
min="0"
|
|
||||||
max="9"
|
|
||||||
placeholder="0"
|
|
||||||
{{^if data.editable_not_soft_locked}}disabled{{/if}}
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
{{#each data.skillsList as |skills catId|}}
|
{{#each data.skillsList as |skills catId|}}
|
||||||
<optgroup label="{{localizeSkill catId 'title'}}">
|
<optgroup label="{{localizeSkill catId 'title'}}">
|
||||||
{{#each skills as |obj|}}
|
{{#each skills as |obj|}}
|
||||||
<option value="{{obj.id}}">{{obj.label}}</option>
|
<option value="{{obj.uuid}}">{{obj.name}}</option>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</optgroup>
|
</optgroup>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|||||||
26
system/templates/items/skill/skill-entry.html
Normal file
26
system/templates/items/skill/skill-entry.html
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<li class="item skill flexcol" data-item-id="{{skill.id}}">
|
||||||
|
<ul class="item-header skill-controls flexrow">
|
||||||
|
<li class="item-img"><img src="{{skill.img}}" title="{{skill.name}}" width="32px" height="32px"/></li>
|
||||||
|
<li class="item-name dice-picker attribute-label rollable l5r5e-tooltip" data-item-id="{{skill._id}}" data-skill="{{skill._id}}">{{skill.name}}</li>
|
||||||
|
<li class="item-rank">
|
||||||
|
{{#if data.editable_not_soft_locked}}
|
||||||
|
<input
|
||||||
|
class="centered-input select-on-focus"
|
||||||
|
type="number"
|
||||||
|
name="skillsValues.{{skill._id}}"
|
||||||
|
value="{{skill.system.rank}}"
|
||||||
|
data-dtype="Number"
|
||||||
|
min="0"
|
||||||
|
max="9"
|
||||||
|
placeholder="0"
|
||||||
|
/>
|
||||||
|
{{else}}
|
||||||
|
{{sum skill.system.rank skill.system.modifier}}
|
||||||
|
{{/if}}
|
||||||
|
</li>
|
||||||
|
{{#if data.editable_not_soft_locked}}
|
||||||
|
<li data-item-id="{{skill._id}}" class="item-control item-edit" title="{{localize 'l5r5e.global.edit'}}"><i class="fas fa-edit"></i></li>
|
||||||
|
<li data-item-id="{{skill._id}}" class="item-control item-delete" title="{{localize 'Delete'}}"><i class="fas fa-trash"></i></li>
|
||||||
|
{{/if}}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
27
system/templates/items/skill/skill-sheet.html
Normal file
27
system/templates/items/skill/skill-sheet.html
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<form class="{{cssClass}}" autocomplete="off">
|
||||||
|
<header class="sheet-header">
|
||||||
|
<img class="profile-img" src="{{data.img}}" data-edit="img" title="{{data.name}}"/>
|
||||||
|
<h1 class="charname"><input name="name" type="text" value="{{data.name}}" placeholder="Name"/></h1>
|
||||||
|
</header>
|
||||||
|
{{!-- Sheet Body --}}
|
||||||
|
<section class="sheet-body">
|
||||||
|
{{!-- Attributes Tab --}}
|
||||||
|
<article class="attributes" data-group="primary" data-tab="attributes">
|
||||||
|
<label class="attribute">
|
||||||
|
{{localize 'l5r5e.skills.category'}}
|
||||||
|
<select name="system.category">
|
||||||
|
{{#select data.system.category}}
|
||||||
|
{{#each data.SkillCategoriesList as |id|}}
|
||||||
|
<option value="{{id}}">{{localizeSkill id 'title'}}</option>
|
||||||
|
{{/each}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label class="attribute">
|
||||||
|
{{localize 'l5r5e.sheets.rank'}}
|
||||||
|
<input class="select-on-focus" type="number" name="system.rank" value="{{data.system.rank}}" data-dtype="Number" min="0" placeholder="0"/>
|
||||||
|
</label>
|
||||||
|
</article>
|
||||||
|
{{> 'systems/l5r5e/templates/items/item/item-infos.html'}}
|
||||||
|
</section>
|
||||||
|
</form>
|
||||||
18
system/templates/items/skill/skill-text.html
Normal file
18
system/templates/items/skill/skill-text.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<div class="{{cssClass}}" data-actor-id="{{actor._id}}" data-item-id="{{data._id}}">
|
||||||
|
<header class="card-header">
|
||||||
|
<h2 class="item-name"><img src="{{data.img}}" title="{{data.name}}" /> {{data.name}}</h2>
|
||||||
|
</header>
|
||||||
|
<section class="sheet-body">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<strong>{{localize 'l5r5e.skills.category'}}</strong> : {{localizeSkill data.system.category 'title'}}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>{{localize 'l5r5e.sheets.rank'}}</strong> : {{data.system.rank}}{{#if data.system.modifier}} ({{data.system.modifier}}){{/if}}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{{!--item-infos--}}
|
||||||
|
<p><strong>{{localize 'l5r5e.sheets.description'}}</strong> : {{{data.enrichedHtml.description}}}</p>
|
||||||
|
<p><strong>{{localize 'l5r5e.sheets.book_reference'}}</strong> : {{data.system.book_reference}}</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
19
system/templates/settings/default-skills-dialog.html
Normal file
19
system/templates/settings/default-skills-dialog.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<form autocomplete="off">
|
||||||
|
{{#each skillList as |category name|}}
|
||||||
|
<h2>{{localizeSkill name 'title'}}</h2>
|
||||||
|
<div class="form-group">
|
||||||
|
<ul>
|
||||||
|
{{#each category as |skill|}}
|
||||||
|
<li class="item skill flexcol">
|
||||||
|
<ul class="item-header skill-controls flexrow">
|
||||||
|
<li class="item-img"><img src="{{skill.img}}" title="{{skill.name}}" width="32px" height="32px"/></li>
|
||||||
|
<li class="item-name attribute-label l5r5e-tooltip" data-item-uuid="{{skill.uuid}}">{{skill.name}}</li>
|
||||||
|
<li class="item-source">{{#if skill.pack}}{{skill.pack}}{{else}}world{{/if}}</li>
|
||||||
|
<li data-item-uuid="{{skill.uuid}}" class="item-control item-delete" title="{{localize 'Delete'}}"><i class="fas fa-trash"></i></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</form>
|
||||||
Reference in New Issue
Block a user