Compare commits

...

233 Commits

Author SHA1 Message Date
5d30482ce3 Add new translations 2023-12-04 21:38:10 +01:00
3fb8e92428 Add new translations 2023-12-04 21:37:29 +01:00
7738746994 Add new translations 2023-12-04 21:30:12 +01:00
761179bc5a Now use v11 compendiums 2023-10-28 18:52:13 +02:00
a4d7c13383 Now use v11 compendiums 2023-10-28 18:47:52 +02:00
ee6bf1a4d4 Now use v11 compendiums 2023-10-28 18:46:51 +02:00
469948e296 Now use v11 compendiums 2023-10-28 18:46:29 +02:00
def271b8b9 Initiative 2023-10-15 17:56:01 +02:00
c9ed514ed6 Sync avec mater
Merge branch 'v10' of https://www.uberwald.me/gitea/public/bol into v10
2023-10-15 17:51:31 +02:00
2ffd3f35c8 Initiative 2023-10-15 17:51:07 +02:00
e3b281f195 Merge pull request 'fix: utilisation d’une variable non définie' (#24) from DjLeChuck/bol:fix-damage-without-armor-apply into v10
Reviewed-on: #24
2023-10-15 16:28:23 +02:00
29ecb04ec3 fix: utilisation d’une variable non définie 2023-10-15 16:25:00 +02:00
ca3064dc0a Merge pull request 'fix: data-attribut corrompu sur l’encaissement sans armure' (#23) from DjLeChuck/bol:fix-defense-request-card into v10
Reviewed-on: #23
2023-10-15 16:15:58 +02:00
9fd8751124 fix: data-attribut corrompu sur l’encaissement sans armure 2023-10-15 16:14:55 +02:00
2d63b63b86 Merge pull request 'fix-creatures-compendium' (#22) from DjLeChuck/bol:fix-creatures-compendium into v10
Reviewed-on: #22
2023-10-15 16:13:39 +02:00
b44250e728 fix: tailles du Phong et du Behemathon
- Phong : petité créature et non grande
- Behemathon : monstrueuse créature et non grande
2023-10-15 16:11:56 +02:00
63c3e24296 fix: typage des créatures
- Utilisation de "cartype" et non "type"
2023-10-15 16:08:41 +02:00
8a87f6deab Fix #21 2023-10-15 16:02:26 +02:00
759b099bdf Fix #20 2023-10-15 16:01:31 +02:00
ade88fb54b Corrections sur encaissement 2023-09-16 09:40:08 +02:00
f1a3f2df36 Rollback to previous release system 2023-08-26 21:45:33 +02:00
a357c6ddfc Add gitea CI/CD 2023-08-26 19:17:02 +02:00
26a6c7fc28 Add gitea CI/CD 2023-08-26 19:11:37 +02:00
6fcac36580 Add gitea CI/CD 2023-08-26 19:08:53 +02:00
34924b07c0 Add gitea CI/CD 2023-08-26 19:04:48 +02:00
66bf299ea4 Add gitea CI/CD 2023-08-26 19:01:51 +02:00
37ab0d01dc Add gitea CI/CD 2023-08-26 19:00:25 +02:00
2e3a97de04 Add gitea CI/CD 2023-08-26 18:11:41 +02:00
01dbe76f59 Minor fixes 2023-08-26 18:03:08 +02:00
ca33defd75 Update v11 2023-06-23 09:02:45 +02:00
2e616e3e31 Update v11 2023-06-23 08:37:56 +02:00
3be7f4bf9f Update v11 2023-06-23 08:37:50 +02:00
1b8e0840b0 Update v11 2023-06-22 23:05:50 +02:00
2cdd096c98 Update v11 2023-06-22 23:05:36 +02:00
8fcb17b566 Update v11 2023-06-22 23:05:04 +02:00
ad79dbb015 New combat options 2023-06-22 20:36:40 +02:00
73ccf44dd4 New combat options 2023-06-22 20:34:17 +02:00
ec3649799f v10/v11 compat 2023-05-25 16:29:43 +02:00
3f5f090bb9 Points de creation OK again 2023-05-24 14:00:24 +02:00
268ac0a25a Review initiative 2023-05-01 18:50:32 +02:00
59ee6684ab Fix #19 - Horoscope majeur 2023-04-29 21:48:51 +02:00
41fbc094bb Combat Tracker + power enhancements 2023-04-06 20:15:04 +02:00
5b91041a3f Fix options de combat 2023-04-04 13:41:22 +02:00
e7f3851daa Fix dice default 2023-03-29 23:04:02 +02:00
75d562f922 Nouvelle option d'ignorer les dommages 2023-03-25 08:42:14 +01:00
ba7e25e8c7 Fix and +/- 2023-03-18 13:51:46 +01:00
83d3f17dd0 Messages de recuperation 2023-03-18 10:24:30 +01:00
0c502a2188 Meilleure gestion initiative 2023-03-15 17:35:07 +01:00
5df2b7e624 Minot fixes 2023-02-19 19:35:03 +01:00
f6554f6945 New release 2023-02-03 23:55:59 +01:00
fbe232266f Spell changes to support v1.7 2023-02-01 10:16:21 +01:00
4b9c3bcd1e Spell changes to support v1.7 2023-02-01 10:15:56 +01:00
05f09aa3f5 Add dice selection 2023-01-26 20:50:56 +01:00
727db74545 Update sheet 2023-01-23 20:50:48 +01:00
ccb3a458c0 Add pages 2023-01-05 17:00:11 +01:00
1ac9605f08 Fix init creature + minor changes 2023-01-04 09:57:13 +01:00
1bbefd3499 Astrologie ! 2022-12-25 18:00:42 +01:00
bcb377db7a Gestion de l'astrologie 2022-12-23 23:24:09 +01:00
7a8cf9f8fd Welcome page and init info message 2022-12-23 16:38:41 +01:00
d74f7784bb Fix bougette sur PNJ/Creatures 2022-12-04 13:49:00 +01:00
6d6fec99b0 Fix bougette sur PNJ/Creatures 2022-12-04 13:48:37 +01:00
884823a1bc Init again !!!! 2022-12-02 13:16:42 +01:00
399c22d623 Init again !!!! 2022-12-02 13:15:48 +01:00
085265df5d initiative bugfix 2022-12-01 23:57:33 +01:00
593db9ba5b initiative bugfix 2022-12-01 23:46:27 +01:00
ac96f3ca67 Enhance initiative + fix combat 2022-11-30 20:58:27 +01:00
b2fe67ab05 Enhance tokens/actor management + auto effects 2022-11-30 12:12:44 +01:00
47178d7359 Use bougette v1.2 2022-11-29 15:23:05 +01:00
e1c7304551 Add a PC list summary 2022-11-25 20:47:28 +01:00
7b4e5bcbfa Add a PC list summary 2022-11-25 15:50:12 +01:00
31bd83b0ab Add a PC list summary 2022-11-25 15:50:07 +01:00
e35187433e Fix malus dice (again) and scroll rendering 2022-11-25 14:24:03 +01:00
5e7dc3ad9d Display effects in main sheet (left) and manage it for defense and damages 2022-11-25 08:49:37 +01:00
add6893864 Logo is rotating again 2022-11-25 07:37:44 +01:00
3a591e750a Ajout aide + effets 2022-11-23 21:37:46 +01:00
fe1cda67c4 Ajout aide + effets 2022-11-23 21:34:51 +01:00
985aba0318 Various enhancements 2022-11-23 15:30:31 +01:00
5d8cc300e9 Various enhancements 2022-11-23 15:27:08 +01:00
aa27168c2b fix flaws usage 2022-11-19 22:00:14 +01:00
1135e3aff2 fix flaws usage 2022-11-19 21:56:51 +01:00
30e316d34e Remove to chat button 2022-11-19 19:22:16 +01:00
f3bd84c5c9 Corrections sur creatures/npc et armes de vehicules 2022-10-10 14:14:32 +02:00
985d393de5 Corrections sur creatures/npc et armes de vehicules 2022-10-10 08:46:41 +02:00
815b5ff2ac Ajout distance 2022-10-08 17:43:09 +02:00
edf8325109 Inc version 2022-09-28 23:26:41 +02:00
895aa01419 Enable links in editor 2022-09-27 20:47:30 +02:00
9631e5e72a Merge conteneur 2022-09-26 08:28:47 +02:00
716cc53b29 Merge conteneur 2022-09-26 08:24:39 +02:00
44952d4410 Fix hotbar + tooltip 2022-09-25 21:14:39 +02:00
a7991bce92 Fix hotbar + tooltip 2022-09-25 21:13:15 +02:00
a1c20019e8 v10 init fix 2022-09-19 23:23:54 +02:00
af8576a4a1 Fix initfor combat 2022-09-09 23:49:01 +02:00
6c35ddfb0b rework ID 2022-09-02 17:31:12 +02:00
0cbcaee45e rework ID 2022-09-02 16:21:18 +02:00
904ff821e1 rework ID 2022-09-02 16:19:16 +02:00
5c13cde07a rework ID 2022-09-02 16:08:56 +02:00
51c1e205e9 rework ID 2022-09-01 22:40:29 +02:00
90a83f4571 rework ID 2022-09-01 22:23:58 +02:00
3311bc091a rework ID 2022-09-01 21:26:10 +02:00
fa8f9869a6 v10 sync 2022-08-31 23:00:41 +02:00
36b905134e v10 sync 2022-08-31 22:46:19 +02:00
eeb0a906e7 v10 sync 2022-08-31 22:24:56 +02:00
c552411d61 Allow configurable logo 2022-07-17 18:24:29 +02:00
d3ae59f70d Allow configurable logo 2022-07-17 18:20:05 +02:00
cf7d76fdba Fix d6BB combat roll 2022-07-16 11:06:34 +02:00
89ec404ca8 v10 branch - Update manifest 2022-07-16 11:05:15 +02:00
8f60aa95ee Fix d6BB combat roll 2022-07-16 11:03:33 +02:00
d888c6a2eb v10 branch - Update manifest 2022-07-13 08:07:16 +02:00
165e41fef6 v10 branch - Update manifest 2022-07-13 08:07:04 +02:00
19bb0798c8 Sync 2022-07-07 13:33:31 +02:00
05f044bc7c Foundry v10 version 2022-07-01 16:30:21 +02:00
996ac1c88d Foundry v10 version 2022-07-01 16:00:49 +02:00
cc1964093d Foundry v10 version 2022-07-01 15:48:54 +02:00
d27b78d1d2 Review fight automation + alchimie 2022-06-11 20:56:35 +02:00
7259d3dc21 Review fight automation 2022-06-11 10:21:18 +02:00
ef5cf6f393 BoL Migration 2022-05-24 23:27:33 +02:00
3e50a9135f Various fixes 2022-05-23 18:38:51 +02:00
82c902099f Fix sur points de creation 2022-05-23 16:12:53 +02:00
c26e43bac7 Fix files 2022-05-21 17:57:04 +02:00
4159b6b181 Fix files 2022-05-21 17:56:52 +02:00
45cb082d8e Start adv generator 2022-05-20 21:54:17 +02:00
2637f698ad Start adv generator 2022-05-20 21:50:18 +02:00
9b8762300e Start adv generator 2022-05-20 00:00:49 +02:00
dfac102925 Start adv generator 2022-05-19 23:30:29 +02:00
fad281a7b3 Sync german translations + some fixes in compendium 2022-05-13 16:20:45 +02:00
1191442f04 Merge pull request #17 from gsterling/master
German welcome message
2022-05-13 16:15:36 +02:00
fe93888c1b add mentions for truant spiele for the the german version 2022-05-13 15:38:16 +02:00
127f200c27 add german welcome message 2022-05-13 15:34:04 +02:00
b078ffa992 Translate welcome message 2022-05-12 23:21:00 +02:00
d713066b5c update De translation 2022-05-12 19:38:41 +02:00
7adfbfe148 Merge pull request #15 from gsterling/master
Add newest german translations.
2022-05-12 19:37:59 +02:00
2186d986ca Merge branch 'master' of https://github.com/ZigmundKreud/bol 2022-05-12 19:31:11 +02:00
590fba0cbd add german char bio translations 2022-05-12 19:26:16 +02:00
0c9e598958 add additional german translations 2022-05-12 19:18:55 +02:00
049604ce98 Add new translation keys 2022-05-12 10:15:21 +02:00
471a18cd14 Enhance localization stuff 2022-05-12 08:25:55 +02:00
58c781f2f2 Enhance localization stuff 2022-05-11 22:07:03 +02:00
c9722b9b04 Enhance localization stuff 2022-05-11 22:05:35 +02:00
44ce88dd17 Enhance localization stuff 2022-05-11 19:29:32 +02:00
a31fe251e0 Add german translation 2022-05-11 15:20:02 +02:00
76a050b023 Merge pull request #13 from gsterling/master
add german translation
2022-05-11 15:19:37 +02:00
b68a6dbd23 add german translation 2022-05-11 13:14:58 +02:00
34c7024191 Advantage! 2022-05-10 23:04:04 +02:00
33da01707d Advantage! 2022-05-10 22:27:21 +02:00
70b5324198 Cleanup compendiums data 2022-04-29 16:09:50 +02:00
89566b8e3a Ajout des cartes de BoL 1 et 2 2022-04-10 22:38:39 +02:00
de206498e7 Ajout creatures 2022-04-10 20:15:30 +02:00
e2491b9f54 Ajout creatures 2022-04-10 20:15:03 +02:00
45e239b8e9 Ajout creatures 2022-04-10 16:38:09 +02:00
477c86db0e Fix encaissement par joueur 2022-04-08 23:42:01 +02:00
38025666e9 Add new features 2022-03-27 22:56:43 +02:00
9e5e07b227 Malus armure/bouclier et cout en PP supplementaire 2022-03-27 12:42:29 +02:00
e5b8c8f2c7 Sync 2022-03-26 20:53:08 +01:00
a5ba6d5215 Add HUD actions 2022-03-21 23:21:05 +01:00
fff6b2a733 Fix armors 2022-03-21 13:28:27 +01:00
80725d57e1 Fix XP 2022-03-20 23:17:52 +01:00
1a69116c06 Add fight options 2022-03-10 21:39:12 +01:00
02b3dd5e0f Add fight options 2022-03-10 21:05:53 +01:00
eacd32927c Various enhancements 2022-02-23 20:39:58 +01:00
f63692b6b5 Gods, screen and bugfixes 2022-02-20 10:12:25 +01:00
83188e6aae Fix spells 2022-02-19 17:25:42 +01:00
caf990737e Use another server for measures 2022-02-19 09:10:07 +01:00
7fcaf22424 Ehance rols 2022-02-18 22:38:13 +01:00
53d006ed3d Ehance rols 2022-02-18 22:38:02 +01:00
02b2c84f9d Ehance rols 2022-02-18 22:31:53 +01:00
ec6a1b23bc Ehance rols 2022-02-18 22:15:46 +01:00
0ee9e41a50 Ehance rols 2022-02-18 21:58:53 +01:00
cfdfa27f23 Improvments 2022-02-18 18:19:44 +01:00
5a90db34d7 Update README.md 2022-02-17 08:43:39 +01:00
157dd07bb5 Ajout compendium + creation equipement 2022-02-16 09:11:49 +01:00
aa367657ca Ajout langues et revue equipement 2022-02-15 21:00:29 +01:00
5621f7b27c Ajout langues et revue equipement 2022-02-15 20:53:28 +01:00
1734ce87cd Ajout langues et revue equipement 2022-02-15 20:53:13 +01:00
634e755846 Sync 2022-02-14 22:03:52 +01:00
7407e0b75d Enhance credits and releas 2022-02-12 21:49:26 +01:00
80d58403ab Fix spells 2022-02-12 21:09:28 +01:00
59218de935 Fix location and quantities 2022-02-11 23:29:57 +01:00
1baa51b9de Fix weapon damages 2022-02-02 09:35:32 +01:00
fd82c204d7 Add new stuff 2022-01-30 20:44:28 +01:00
48ae0920b5 Fix equipment drop-down 2022-01-27 07:47:42 +01:00
aeb7739879 Add spells and alchemy 2022-01-23 09:25:09 +01:00
5eb059a2fa Fix release 2022-01-20 17:40:37 +01:00
ae78f7a381 Merge pull request #9 from sladecraven/master
Various fixes
2022-01-20 16:27:27 +01:00
814877100d Ajout compendium 2022-01-19 22:14:22 +01:00
a5e01f051d Merge branch 'ZigmundKreud:master' into master 2022-01-19 21:57:55 +01:00
adfcce10fc New fields for weapons 2022-01-19 21:57:34 +01:00
87a5b36b0a Merge pull request #8 from sladecraven/master
Review/fix combat mode
2022-01-17 23:56:36 +01:00
4e7b8b9a78 Review combat mode 2022-01-17 23:50:57 +01:00
1008c8afb1 Merge pull request #7 from sladecraven/master
Roll window + Reroll
2022-01-16 23:55:32 +01:00
e7898ec769 Rollable damages + protection 2022-01-16 22:58:28 +01:00
2a83ba027b Rollable damages + protection 2022-01-16 22:53:41 +01:00
831b192691 Rollable damages + protection 2022-01-16 22:06:49 +01:00
69b6fbca6b Rollable damages + protection 2022-01-16 22:05:36 +01:00
c2e3f34517 Multiple changes 2022-01-16 21:29:12 +01:00
ad8827c6f5 Fix blesse 2022-01-16 16:39:32 +01:00
7bf9dabf32 Merge pull request #6 from sladecraven/master
Minor fixes
2022-01-09 23:46:23 +01:00
0b77238dc2 Damage multiplier 2022-01-09 20:00:11 +01:00
06cf860505 Add spell 2022-01-09 15:23:14 +01:00
704f5faf34 Add spell 2022-01-09 14:59:48 +01:00
e595a16289 Add spell 2022-01-09 14:52:24 +01:00
54ba3225dd Sync attempt 2022-01-09 14:34:19 +01:00
915b89a8c4 Sync attempt 2022-01-09 13:23:20 +01:00
8538af1907 Minor fixes 2022-01-08 23:47:48 +01:00
a57fb3d738 Minor fixes 2022-01-08 23:40:45 +01:00
8a8f2450d4 Minor fixes 2022-01-08 23:28:16 +01:00
0f20a66cd2 Minor fixes 2022-01-08 22:48:04 +01:00
2f19ba1948 Ajout du modèle de données pour les rencontres. 2022-01-05 22:46:26 +01:00
e9eb9e2cff Merge pull request #5 from sladecraven/master
Fix auto-compute
2022-01-03 00:36:28 +01:00
b034a92541 Fix auto-compute 2022-01-03 00:09:27 +01:00
1074a1d91c Merge pull request #4 from sladecraven/master
Enhance and bugfixes for combat
2022-01-02 14:35:58 +01:00
721cb08059 Enhance and bugfixes for combat 2022-01-01 23:32:48 +01:00
5915b4a0ac Merge pull request #3 from sladecraven/master
Attack process path
2021-12-29 20:53:46 +01:00
ad205f4669 Attack process path 2021-12-29 20:33:59 +01:00
420390eed7 Attack process path 2021-12-29 19:15:06 +01:00
3fe224f1b4 Merge pull request #2 from sladecraven/master
Gestion attaque d'arme, step1
2021-12-27 23:45:37 +01:00
a8d4d40106 Weapon attacke management, step1 2021-12-25 23:26:27 +01:00
498b5bc4a6 Merge branch 'master' of github.com:sladecraven/bol 2021-12-24 18:33:59 +01:00
048e989ac5 Start weapon stuff 2021-12-24 18:33:37 +01:00
c2cdc4201d FIX prise en compte du niveau de carrière dans les jets
FIX erreur quand le personnage n'a pas de carrière
2021-12-24 17:23:43 +01:00
7f6f813734 Support des propriétés d'items
Amélioration de l'interface d'édition d'items
2021-12-24 16:06:26 +01:00
7531937e52 Support des propriétés d'items
Amélioration de l'interface
Améliorations cosmétiques
2021-12-24 04:51:14 +01:00
d5a5990faa Support des jets d'attributs et d'aptitudes
Ajout des macros
Amélioration des cartons dans le chat avec gestion des succès/échecs/échecs critiques.
Support des carrières dans les dialogues de tests d'attibuts et d'aptitudes.
2021-12-22 05:12:40 +01:00
4c349d89a8 Amélioration fiche d'item 2021-12-15 12:37:17 +01:00
0c24f49470 Amélioration fiche d'item 2021-11-08 14:40:29 +01:00
b6ad8a846e Update du numéro de version 2021-11-07 20:23:48 +01:00
5d40642726 Avancement feuille de personnage
Avancement feuille d'items
Ajout des données JSON pour génération des compendiums.
2021-11-07 20:23:02 +01:00
2c8d040881 Merge pull request #1 from sladecraven/master
Merge v1
2021-11-06 12:21:05 +01:00
4820039325 Latest sync 2021-11-06 12:04:42 +01:00
7bfeb96d5e Preliminary rolls 2021-11-01 23:06:34 +01:00
954c95e606 Preliminary rolls 2021-11-01 22:23:56 +01:00
ea034953a6 Preliminary rolls 2021-11-01 22:23:43 +01:00
4452f3826a Roll pour carrière 2021-11-01 00:28:42 +01:00
1992d618a9 initial import 2021-09-24 21:01:41 +02:00
355 changed files with 23627 additions and 1718 deletions

54
.gitea/workflows/main.yml Normal file
View File

@ -0,0 +1,54 @@
name: Release Creation
on:
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "💡 The ${{ gitea.repository }} repository will cloned to the runner."
#- uses: actions/checkout@v3
- uses: RouxAntoine/checkout@v3.5.4
with:
ref: 'v10'
# get part of the tag after the `v`
- name: Extract tag version number
id: get_version
uses: battila7/get-version-action@v2
# Substitute the Manifest and Download URLs in the module.json
- name: Substitute Manifest and Download Links For Versioned Ones
id: sub_manifest_link_version
uses: microsoft/variable-substitution@v1
with:
files: 'system.json'
env:
version: ${{steps.get_version.outputs.version-without-v}}
url: https://www.uberwald.me/gitea/public/bol
manifest: https://www.uberwald.me/gitea/public/bol/releases/latest/system.json
download: https://www.uberwald.me/gitea/public/bol/releases/download/${{github.event.release.tag_name}}/bol.zip
# Create a zip file with all files required by the module to add to the release
- run: |
apt update -y
apt install -y zip
- run: zip -r ./bol.zip system.json template.json README.md LICENSE assets/ css/ fonts/ images/ lang/ module/ packs/ styles/ templates/ ui/
- name: setup go
uses: https://github.com/actions/setup-go@v4
with:
go-version: '>=1.20.1'
- name: Use Go Action
id: use-go-action
uses: https://gitea.com/actions/release-action@main
with:
files: |-
./bol.zip
system.json
api_key: '${{secrets.RELEASE_TOKEN_UBERWALD}}'

117
.gitignore vendored
View File

@ -1,107 +1,10 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# BOL Data
/data/
.vscode/settings.json
.idea
.history
todo.md
/.vscode
/ignored/
/node_modules/
/jsconfig.json
/package.json
/package-lock.json

View File

@ -1 +1,43 @@
# Système Foundry pour Barbarians of Lemuria (VF)
# Système Foundry pour Barbarians of Lemuria (French version)
## EN
Unofficial system for Barbarians of Lemuria (French version from Ludospherik).
This system has been authorized by Ludospherik ( http://www.ludospherik.fr/ ), thanks to them !
Books are manadatory to play and are available at : http://www.ludospherik.fr/content/14-barbarians-of-lemuria
## FR
Système non-officiel pour le JDR Barbarians of Lemuria (Version de Ludospherik).
Ce système a été autorisé par Ludospherik ( http://www.ludospherik.fr/ ), merci à eux !
Les livres du jeu sont nécessaires pour jouer, et sont disponibles ici : http://www.ludospherik.fr/content/14-barbarians-of-lemuria
# Credits
## US Version
Barbarians of Lemuria, Mythic edition, est un jeu de Simon Washbourne
Auteur : Simon Washbourne.
## Crédits de la version française
Barbarians of Lemuria, le jeu de rôle de Sword & Sorcery, est une publication des éditions Ludospherik, tous droits réservés.
Équipe éditoriale : Vincent Basset, Arnaud Prié, Emmanuel Roudier, Andrea Salvatores.
Traduction : Vincent Basset.
La présente traduction du vocabulaire des règles du jeu sest basée pour l essentiel sur celle
de la première édition française de Barbarians of Lemuria, publiée aux Livres de lOurs,
et ce avec laimable autorisation de Kobayashi. Quil en soit ici vivement remercié.
Maps : Emmanuel Roudier.
# Developmement
LeRatierBretonnien, Zigmund (historical)

BIN
assets/bol_monnaies_v1_2.pdf Executable file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

38
changelog.md Normal file
View File

@ -0,0 +1,38 @@
Changes :
# v11.1.2
- Ajout des traductions manquantes en anglais
# v11.1.1
- Re-organisation des compendiums + ajouts de nouveaux equipements
- Correction sur la langue Démonique (1 Parlé, 1 Lu/Ecrit)
# v11.1.0
- Foundry v11 seulement
- Re-organisation des compendiums
- Correction sur les créatures
- Correction sur l'encaissement sans armure
- Ajout d'une note d'explication sur l'initiative
# v11.0.8
- Correction sur les malus de bouclier (blocage)
- Corrrection sur le malus d'init des boucliers qui était mal affiché dans la fiche d'item
# v10.4.0
- Ajout de la gestion d'effets
- Aide intégré
- Intégration du PDF de la bougette
# v10.3.3
- Nouvelles clés de traduction
- Lorsqu'une arme a un dé bonus, prise en compte plus claire du dé bonus et affichage de l'information dans la fenêtre de jet
- Lorsqu'une arme relance les 1 sur ses dégats, l'information est affichée dans le tchat
- Termes corrects pour les PNJs (ie rival)
- Nouveaux équipements issus du Dieu Voilé

View File

@ -1,4 +1,138 @@
/* ----------------------------------------- */
/* LOCAL FONTS */
/* ----------------------------------------- */
@font-face {
font-family: 'Contrail One';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/contrailone/v10/eLGbP-j_JA-kG0_Zo51noafdZQ.ttf) format('truetype');
}
@font-face {
font-family: "CCMeanwhile";
src: url('../fonts/ccmeanwhile-regular.ttf');
}
@font-face {
font-family: "Wolfsbane2";
src: url('../fonts/wolfsbane2.ttf');
}
@font-face {
font-family: "Wolfsbane2Condensed";
src: url('../fonts/wolfsbane2cond.ttf');
}
@font-face {
font-family: "Wolfsbane2Expanded";
src: url('../fonts/wolfsbane2expand.ttf');
}
@font-face {
font-family: "IMFellDWPicaSC-Regular";
src: url('../fonts/IMFellDWPicaSC-Regular.ttf');
}
/* ----------------------------------------- */
/* TEXT STYLES */
/* ----------------------------------------- */
/* -------------- */
/* Font Awesome */
/* Overrides */
/* -------------- */
/* ------------- */
a.entity-link,
a.inline-roll {
border: none;
background: transparent;
border-bottom: 1px dotted grey;
padding: 0;
}
a.inline-roll {
border: none;
}
a:hover {
text-shadow: 0 0 5px #a00;
}
#pause {
background: none;
}
#pause > img {
width: 200px;
height: 200px;
top: -50px;
left: calc(50% - 100px);
opacity: 0.7;
}
#pause h3 {
font-family: "IMFellDWPicaSC-Regular", serif;
font-size: 32px;
text-shadow: 0px 3px 5px #000000;
}
::-webkit-scrollbar-thumb {
outline: none;
border-radius: 3px;
background: #999 !important;
border: 1px solid #333 !important;
border-color: #333 !important;
}
::-webkit-scrollbar-track {
box-shadow: 0 0 3px #005d67 inset !important;
border-radius: 3px;
}
* {
scrollbar-width: thin !important;
scrollbar-color: #005d67 #ccc !important;
}
.element-invisible {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
border: 0;
padding: 0;
clip: rect(0 0 0 0);
overflow: hidden;
}
.roll-box {
border-width: 1px;
border-color: #000000;
margin-bottom: 2px;
}
.hide {
display: none;
}
ul.no-bullets {
list-style-type: none; /* Remove bullets */
padding: 0; /* Remove padding */
margin: 0; /* Remove margins */
}
.ellipsis {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.nomargin {
margin: 0;
padding: 0;
}
.flxrow {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
}
.flxrow > * {
flex: 1;
}
.flxrow .flex1 {
flex: 1;
}
.flxrow .flex2 {
flex: 2;
}
.flxrow .flex3 {
flex: 3;
}
.flxrow .flex4 {
flex: 4;
}
/* ----------------------------------------- */
/* Flexbox */
/* ----------------------------------------- */
.flexrow {
@ -140,7 +274,12 @@
.bol button {
background: rgba(0, 0, 0, 0.1);
}
.chat-button {
font-size: 0.8rem;
}
.bol select {
box-shadow: none;
font-size: 14px;
text-align: center;
text-align-last: center;
@ -149,6 +288,30 @@
border: none;
border-radius: 0;
}
.bol select[multiple] {
box-shadow: none;
border: none;
font-size: 14px;
}
.bol select[multiple]:focus option:checked {
background: darkred linear-gradient(0deg, darkred 0%, darkred 100%);
color: white;
}
.bol option {
font-size: 14px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.bol option:hover,
.bol option:focus,
.bol option:active,
.bol option:checked,
.bol option[selected] {
cursor: pointer;
background: darkred linear-gradient(0deg, darkred 0%, darkred 100%);
color: white;
}
.bol label.checkbox {
flex: auto;
padding: 0;
@ -204,6 +367,9 @@
flex: auto;
text-align: left;
}
.bol .form-group .form-fields .field-value {
text-align: center;
}
.bol .form-group.stacked label {
flex: 0 0 100%;
margin: 0;
@ -213,11 +379,35 @@
text-align: left;
}
.bol .form-header {
margin: 0 0 0.25em 0;
padding: 2px 0;
font-size: 20px;
margin: 0.25em 0 0.25em 0;
padding: 2px 5px;
font-family: "Wolfsbane2Expanded", cursive;
color: #4b4a44;
background-color: lightgray;
}
.bol h1.form-header {
font-size: 2.2em;
font-weight: 700;
}
.bol h2.form-header {
font-size: 1.8em;
font-weight: 500;
border-bottom: 1px groove #eeede0;
}
.bol h3.form-header {
font-size: 1.2em;
font-weight: 500;
border-bottom: 1px groove #eeede0;
}
.bol h4.form-header {
font-size: 1em;
font-weight: 500;
font-family: 'Signika', sans-serif;
color: black;
background-color: transparent;
border-top: none;
border-bottom: 1px groove #eeede0;
}
.bol .tag {
display: inline-block;
margin: 0 2px 0 0;
@ -245,62 +435,281 @@
.bol input::placeholder {
color: lightgray;
}
/* ----------------------------------------- */
/* LOCAL FONTS */
/* ----------------------------------------- */
@font-face {
font-family: 'Contrail One';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/contrailone/v10/eLGbP-j_JA-kG0_Zo51noafdZQ.ttf) format('truetype');
.bol .property {
margin-top: 2px;
}
@font-face {
font-family: "ImaginaryForces";
src: url('../fonts/iforces.ttf');
.bol .inc-dec-btns {
color: #4b4a44;
}
@font-face {
font-family: "OPTIFantastiK";
src: url('../fonts/OPTIFantastiK.otf');
.summmary-number {
padding-left: 4rem;
}
@font-face {
font-family: "CCMeanwhile";
src: url('../fonts/ccmeanwhile-regular.ttf');
/* Items List */
.items-list {
list-style: none;
margin: 7px 0;
padding: 0;
overflow-y:hidden;
/*overflow-y: auto;*/
}
@font-face {
font-family: "Papyrus";
src: url('../fonts/PAPYRUS.TTF');
.items-list .item-header {
font-family: 'Signika', sans-serif;
font-size: 1em;
color: #4b4a44;
background-color: lightgray;
}
@font-face {
font-family: "Wolfsbane2";
src: url('../fonts/wolfsbane2.ttf');
.items-list .item-header .item-name {
font-family: "Wolfsbane2Expanded", cursive;
font-size: 1.5em;
}
@font-face {
font-family: "Wolfsbane2Condensed";
src: url('../fonts/wolfsbane2cond.ttf');
.items-list .item {
min-height: 30px;
line-height: 24px;
padding: 3px 0 3px 3px;
border-bottom: 1px solid #BBB;
align-items: stretch;
}
@font-face {
font-family: "Wolfsbane2Expanded";
src: url('../fonts/wolfsbane2expand.ttf');
.items-list .item .item-image {
flex: 0 0 30px;
padding: 0;
margin: 0 5px 0 0;
height: 30px;
width: 30px;
min-height: 30px;
min-width: 30px;
}
.bol.sheet.actor {
min-width: 760px;
min-height: 700px;
max-height: 700px;
.items-list .item .item-image img {
padding: 0;
margin: 0;
border: none;
height: 30px;
width: 30px;
min-height: 30px;
min-width: 30px;
}
.bol.sheet.actor .window-content {
background-color: white;
background-image: url("/systems/bol/ui/logo.webp");
.items-list .item .item-image.roll-weapon,
.items-list .item .item-image.roll-career {
background-color: transparent;
background-image: url("../../../icons/svg/dice-target.svg") !important;
background-size: 30px 30px;
background-repeat: no-repeat;
background-size: 190px 115px;
background-position: center;
cursor: pointer;
}
.items-list .item .item-image.roll-weapon:hover,
.items-list .item .item-image.roll-career:hover {
background-color: gray;
}
.items-list .item .item-image.roll-weapon:hover img,
.items-list .item .item-image.roll-career:hover img {
visibility: hidden;
}
.items-list .item .item-name,
.items-list .item .item-field {
margin: 0;
}
.items-list .item .item-controls-1 {
flex: 0 0 18px;
}
.items-list .item .item-controls,
.items-list .item .item-controls-2 {
flex: 0 0 36px;
}
.items-list .item .item-controls-3 {
flex: 0 0 54px;
}
.items-list .item .item-control {
color: #4b4a44;
}
.items-list .item-name-fixed-medium {
min-width: 8rem;
width: 8rem;
}
.items-list .item-field-fixed-short {
max-width: 3rem;
min-width: 3rem;
width: 3rem;
}
.bougette-dice-img {
color:rgba(150, 44, 44, 0.70);
}
/* ----------------------------------------- */
/* Premade colors */
/* ----------------------------------------- */
.light {
color: lightgray;
}
.bg-light {
background: lightgray;
}
.darkgray {
color: #23221d;
}
.bg-darkgray {
background: #23221d;
color: #fff;
}
.darkbrown {
color: #464331c4;
}
.bg-darkbrown {
background: #464331c4;
color: #fff;
}
.darkslate {
color: darkslategray;
}
.bg-darkslate {
background: darkslategray;
color: #fff;
}
.darkgreen {
color: #003c1e;
}
.bg-darkgreen {
background: #003c1e;
color: #fff;
}
.darkblue {
color: midnightblue;
}
.bg-darkblue {
background: midnightblue;
color: #fff;
}
.blue {
color: #009ee0;
}
.bg-blue {
background: #009ee0;
color: #fff;
}
.green {
color: #44a12b;
}
.bg-green {
background: #44a12b;
color: #fff;
}
.black {
color: #000;
}
.bg-black {
background: #000;
color: #fff;
}
.red {
color: #cd071e;
}
.bg-red {
background: #cd071e;
color: #fff;
}
.darkred {
color: darkred;
}
.bg-darkred {
background: darkred;
color: #fff;
}
.purple {
color: purple;
}
.bg-purple {
background: purple;
color: #fff;
}
.message-header h2.damage {
color: orangered;
font-weight: bold;
}
.message-header h2.critical {
color: green;
font-weight: bold;
}
.message-header h2.fumble {
color: red;
font-weight: bold;
}
.message-header h2.success {
color: darkgreen;
font-weight: bold;
}
.message-header h2.failure {
color: darkred;
font-weight: bold;
}
h2.good {
color: darkgreen;
font-weight: bold;
}
h2.bad {
color: darkred;
font-weight: bold;
}
.message-header h2.roll {
color: darkslategrey;
font-weight: bold;
}
.chat-message {
margin: 3px;
padding: 10px;
font-size: 14px;
border-radius: 0;
background-color: white;
background-image: url("/systems/bol/ui/box-border-large.webp");
background-repeat: no-repeat;
background-size: 100% 100%;
}
.chat-message .message-header .flavor-text {
font-family: "IMFellDWPicaSC-Regular", serif;
font-size: 14px;
}
.chat-message .message-header .flavor-text h2 {
font-family: "Modesto Condensed", "Palatino Linotype", serif;
font-size: 20px;
}
.chat-message .message-content .dice-roll .dice-result .dice-formula {
border-radius: 0px;
border: 1px inset lightgray;
background-color: #282828;
color: white;
}
.chat-message .message-content .dice-roll .dice-result .dice-tooltip .tooltip-part .part-total {
border-radius: 0px;
border: 1px inset lightgray;
background-color: #2a2a2a;
color: white;
}
.chat-message .message-content .dice-roll .dice-result .dice-total {
border-radius: 0px;
border: 1px inset lightgray;
background-color: #2a2a2a;
color: white;
}
body.system-bol img#logo {
content: url("/systems/bol/ui/logo2.webp");
}
.bol.sheet .window-header {
border: none;
}
.bol.sheet .window-content {
height: 100%;
padding: 5px;
padding: 10px;
overflow-y: hidden;
background: transparent;
}
.bol.sheet.actor .window-content form {
.bol.sheet .window-content form {
border: 10px solid transparent;
border-image: url("/systems/bol/ui/box-border-large.webp") 36 repeat;
border-image-outset: 1;
background: white;
margin: 0;
padding: 0;
height: 100%;
}
.bol.sheet.actor .window-content form .sheet-header {
.bol.sheet .window-content form .sheet-header {
background-image: url("/systems/bol/ui/banner.webp");
background-repeat: no-repeat;
background-size: 330px 62px;
@ -317,7 +726,7 @@
align-items: flex-end;
padding-bottom: 10px;
}
.bol.sheet.actor .window-content form .sheet-header .header-field .header-field-group {
.bol.sheet .window-content form .sheet-header .header-field .header-field-group {
overflow: hidden;
display: flex;
flex-direction: row;
@ -325,16 +734,59 @@
justify-content: flex-start;
align-items: baseline;
}
.bol.sheet.actor .window-content form .sheet-header .header-field .header-field-group .header-field-label {
.bol.sheet .window-content form .sheet-header .header-field .header-field-group .header-field-label {
margin-right: 5px;
}
.bol.sheet.actor .window-content form .sheet-header .header-field .header-field-group .charname,
.bol.sheet.actor .window-content form .sheet-header .header-field .header-field-group .header-field-value {
.bol.sheet .window-content form .sheet-header .header-field .header-field-group .charname,
.bol.sheet .window-content form .sheet-header .header-field .header-field-group .itemname,
.bol.sheet .window-content form .sheet-header .header-field .header-field-group .header-field-value {
color: #4b4a44;
font-family: 'Contrail One', cursive;
font-size: 1.5rem;
background-color: #EEE;
}
.bol.sheet .window-content form .main {
/* Sheet Tabs */
}
.bol.sheet .window-content form .main .tabs {
flex: 0 0 30px;
background-color: black;
}
.bol.sheet .window-content form .main .tabs .item {
line-height: 30px;
font-weight: bold;
font-family: "CCMeanwhile", cursive;
color: white;
padding-top: 4px;
font-size: 0.8em;
}
.bol.sheet .window-content form .main .tabs .item.active {
text-decoration: underline;
text-shadow: none;
}
.bol.sheet .window-content form .main .sheet-body {
overflow: hidden;
}
.bol.sheet .window-content form .main .sheet-body .tab {
height: 95%;
border: none;
overflow-y: auto;
/* Items List */
}
.bol.sheet .window-content form .main .sheet-body .tab.description .editor,
.bol.sheet .window-content form .main .sheet-body .tab.description .editor-content {
height: 100%;
}
.bol.sheet.actor {
min-width: 820px;
min-height: 700px;
height: 700px;
}
.bol.sheet.actor .window-content .bol-actor-form {
background-image: url("/systems/bol/ui/logo.webp");
background-repeat: no-repeat;
background-size: 190px 115px;
}
.bol.sheet.actor .window-content form .sidebar {
padding-top: 115px;
min-width: 250px;
@ -351,75 +803,9 @@
max-width: calc(250px - 10px);
margin-right: 10px;
}
.bol.sheet.actor .window-content form .main {
/* Sheet Tabs */
}
.bol.sheet.actor .window-content form .main .tabs {
flex: 0 0 40px;
background-color: black;
}
.bol.sheet.actor .window-content form .main .tabs .item {
line-height: 40px;
font-weight: bold;
font-family: CCMeanwhile;
color: white;
font-size: 14px;
}
.bol.sheet.actor .window-content form .main .tabs .item.active {
text-decoration: underline;
text-shadow: none;
}
.bol.sheet.actor .window-content form .main .sheet-body {
overflow: hidden;
}
.bol.sheet.actor .window-content form .main .sheet-body .tab {
height: 100%;
overflow-y: auto;
/* Items List */
}
.bol.sheet.actor .window-content form .main .sheet-body .tab .items-list {
list-style: none;
margin: 7px 0;
padding: 0;
overflow-y: auto;
}
.bol.sheet.actor .window-content form .main .sheet-body .tab .items-list .item {
min-height: 30px;
line-height: 24px;
padding: 3px 0 3px 3px;
border-bottom: 1px solid #BBB;
align-items: stretch;
}
.bol.sheet.actor .window-content form .main .sheet-body .tab .items-list .item img {
flex: 0 0 30px;
margin-right: 5px;
}
.bol.sheet.actor .window-content form .main .sheet-body .tab .items-list .item .item-image {
margin: 0;
}
.bol.sheet.actor .window-content form .main .sheet-body .tab .items-list .item .item-name {
margin: 0;
}
.bol.sheet.actor .window-content form .main .sheet-body .tab .items-list .item .item-controls {
flex: 0 0 36px;
}
.bol.sheet.actor .window-content form .main .sheet-body .tab .items-list .item .item-buttons {
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-items: center;
flex: 2;
justify-content: flex-start;
}
.bol.sheet.actor .window-content form .main .sheet-body .tab .items-list .item .item-button {
line-height: 1;
font-size: 11px;
flex: none;
width: auto;
}
.bol.sheet.actor .window-content form .main .sheet-body .tab .items-list .item-header {
font-family: CCMeanwhile;
}
.bol.sheet.actor .window-content form .main .sheet-body .tab .attribute.vigor {
background-image: url("/systems/bol/ui/attributes/vigor.webp");
background-repeat: no-repeat;
@ -447,48 +833,6 @@
.bol.sheet.actor .window-content form .main .sheet-body .tab .attribute .stat-value {
margin-top: -10px;
}
.bol.sheet.actor .window-content form .main .sheet-body .tab.description .editor,
.bol.sheet.actor .window-content form .main .sheet-body .tab.description .editor-content {
background-color: red;
height: 100%;
}
.bol.sheet.actor .stat-value {
font-size: 1.5rem;
font-weight: bold;
color: darkred;
}
.bol.sheet.actor .stat-roll {
font-size: 1.5rem;
}
.bol.sheet.actor .header-field-label,
.bol.sheet.actor .stat-label {
font-weight: bold;
font-family: Wolfsbane2Expanded;
font-size: 2rem;
font-variant: small-caps;
}
.bol.sheet.actor .rounded {
border-radius: 100px;
width: 4rem;
height: 4rem;
}
.bol.sheet.actor .rounded-border {
border: 3px solid #4b4a44;
border-radius: 100px;
width: 4rem;
height: 4rem;
}
.bol.sheet.actor .half-rounded {
border-radius: 100px 100px 0px 0px;
width: 4rem;
height: 4rem;
}
.bol.sheet.actor .half-rounded-border {
border-radius: 100px 100px 0px 0px;
border: 3px solid #4b4a44;
width: 4rem;
height: 4rem;
}
.bol.sheet.actor .bol-footer {
height: 62px;
max-height: 62px;
@ -519,33 +863,223 @@
max-height: 62px;
min-height: 62px;
}
.bol.sheet.actor .stat-max {
font-size: 1rem;
font-weight: bold;
color: #4b4a44;
}
.bol.sheet.actor .bonus-text {
margin-top: 7px;
}
.bol.sheet.actor .stat-value {
font-size: 1.5rem;
font-weight: bold;
color: darkred;
}
.bol.sheet.actor .resource-bonus {
font-weight: bold;
color: darkred;
}
.bol.sheet.actor .resources-value {
background-color:#2a2a2a30;
border-color: #003c1e;
margin-top: 4px;
border-radius: 0.5rem;
}
.bol.sheet.actor .resources-novalue {
background-color:#2a2a2a00;
border-color: #003c1e;
margin-top: 4px;
border-radius: 0.5rem;
}
.bol.sheet.actor .stat-roll {
font-size: 1.5rem;
color: #4b4a44;
}
.bol.sheet.actor .stat-roll.malus {
color: darkred;
}
.bol.sheet.actor .stat-roll.bonus {
color: darkgreen;
}
.bol.sheet.actor .header-field-label,
.bol.sheet.actor .stat-label {
font-weight: bold;
font-family: "Wolfsbane2Expanded", cursive;
font-size: 2rem;
font-variant: small-caps;
}
.bol.sheet.actor .rounded {
border-radius: 100px;
width: 4rem;
height: 4rem;
}
.bol.sheet.actor .rounded-border {
border: 3px solid #4b4a44;
box-shadow: 5px 5px 5px gray;
border-radius: 100px;
width: 4rem;
height: 4rem;
}
.bol.sheet.actor .half-rounded {
border-radius: 100px 100px 0px 0px;
width: 4rem;
height: 4rem;
}
.bol.sheet.actor .half-rounded-border {
border-radius: 100px 100px 0px 0px;
border: 3px solid #4b4a44;
width: 4rem;
height: 4rem;
}
.bol.sheet.item {
min-width: 460px;
min-height: 400px;
}
.bol.sheet.item .window-content {
background-color: white;
background-image: url("/systems/bol/ui/logo.webp");
background-repeat: no-repeat;
background-size: 190px 115px;
height: 100%;
padding: 5px;
overflow-y: hidden;
.bol.sheet.item h1 input.itemname {
font-family: "Wolfsbane2Expanded", cursive;
}
.bol.sheet.item .window-content form {
height: 100%;
.bol.sheet.item .item-properties {
flex: 0 0 150px;
margin: 5px 5px 5px 0;
padding-right: 5px;
border-right: 1px groove #eeede0;
}
.bol.sheet.item .item-properties .form-group {
margin: 0;
}
.bol.sheet.item .item-properties .form-group label {
line-height: 20px;
}
.bol.sheet.item .item-properties .properties-list {
list-style: none;
margin: 0;
padding: 0;
}
.bol.sheet.item .item-properties .properties-list li {
margin: 3px 0;
padding: 0 2px;
background: rgba(0, 0, 0, 0.05);
border: 1px groove #eeede0;
text-align: center;
font-size: 12px;
line-height: 18px;
}
.bol.dialog .sheet-header h3 {
font-family: "Wolfsbane2Expanded", cursive;
font-size: 24px;
color: black;
}
.editor,
.editor-content {
height: 100%;
}
.rollable {
color: #4b4a44;
cursor: pointer;
}
.malus {
color: darkred;
.chat-message .chat-icon {
float: right;
border: 1px outset lightgray;
box-shadow: 3px 3px 3px black;
margin: 3px;
width: 64px;
height: 64px;
}
.bonus {
color: darkgreen;
.dialog-button {
max-height: 2rem;
}
.xp-next {
color: darkgrey;
font-size: 1.0rem;
border: 1px solid #4b4a44;
box-shadow: 1px 1px 1px gray;
border-radius: 100px;
width: 1.25rem;
height: 1.25rem;
}
/** Tooltip section */
.tooltip-container {
position: relative;
display: inline-block;
}
.tooltip-container .tooltiptext {
text-align: center;
/* Position the tooltip text */
position: absolute;
z-index: 1;
/* Fade in tooltip */
visibility: hidden;
opacity: 0;
transition: opacity 0.3s;
background-color: #f2f3a2a0;
padding: 4px;
width: 4rem;
border-radius: 25%;
border-width: 1px;
transform: translate(-40%, -60%);
}
/* Show the tooltip text when you mouse over the tooltip container */
.tooltip-container:hover .tooltiptext {
visibility: visible;
opacity: 1;
}
/** HUD SECTION */
.tokenhudext {
display: flex;
flex: 0 !important;
font-family: CaslonPro;
font-weight: 600;
}
.tokenhudext.left {
justify-content: flex-start;
flex-direction: column;
position: absolute;
top: 2.75rem;
right: 4rem;
}
.tokenhudext.right {
justify-content: flex-start;
flex-direction: column;
position: absolute;
/*transform: translate(0, -30%);*/
top: -4rem;
max-width: 250px;
left: 4rem;
}
.tokenhudext.right2 {
justify-content: flex-start;
flex-direction: column;
position: absolute;
top: -4rem;
left: 12rem;
}
.control-icon.tokenhudicon {
width: fit-content;
height: fit-content;
min-width: 6rem;
flex-basis: auto;
padding: 0;
line-height: 1rem;
margin: 0.25rem;
}
.control-icon.tokenhudicon.right {
margin-left: 8px;
}
#token-hud .status-effects.active{
z-index: 2;
}
.bol-hud-menu label {
font-size: 0.6rem;
}
.bol-margin-tb-2 {
margin-top: 2px;
margin-bottom: 2px;
}
.character-summary-container {
  opacity: 0.95;
}
.character-summary-rollable {
text-decoration: underline;
}

132
data/fr/json/armors.json Normal file
View File

@ -0,0 +1,132 @@
[
{
"name": "Amure légère",
"img": "/systems/bol/ui/icons/armor.webp",
"type": "item",
"data": {
"subtype": "armor",
"description": "<h1>Amure légère</h1><p>Si votre personnage préfère éviter les combats mais sait quil risque de ne pas y couper, vous souhaiterez peut-être quil bénéficie au moins dune petite protection. La catégorie des armures légères comprend les différentes sortes darmures de cuir et les chemises de mailles. Votre personnage pourrait ainsi porter un robuste gilet et des brassards en cuir, ou un pourpoint doublé, accompagné de bottes et de gants en cuir souple. À moins que vous ne décidiez quil soit vêtu dune légère chemise de mailles et de rien dautre.</p><p>Une armure légère est généralement dissimulable (à moins dêtre inspecté de près ou davoir affaire à lœil exercé dun soldat vétéran) et ne vous désigne pas au premier regard comme un guerrier.</p><h2>Effets des armures légères</h2><ul><li>protection d6-3 (0-3 points de réduction des dégâts) ;</li><li>si vous préférez un chiffre fixe, une armure légère offre 1 point de protection ;</li><li>le port dune armure légère handicape un sorcier et augmente de 1 point de pouvoir le coût de ses sorts.</li></ul>",
"properties" : {
"equipable": true,
"protection" : true,
"armor" : true,
"concealable" : true,
"modifiers" : {
"social" : true,
"agility" : -1,
"powercost" : 1
},
"soak" : {
"formula" : "d6-3",
"value" : 1
}
}
}
},
{
"name": "Armure moyenne",
"img": "/systems/bol/ui/icons/armor.webp",
"type": "item",
"data": {
"subtype": "armor",
"description": "<h1>Armure moyenne</h1><p>Ce type darmure, compromis entre la maniabilité de larmure légère et la protection de larmure lourde, est le choix favori des aventuriers qui sattendent à affronter des combats de manière régulière. Il peut sagir dune armure de cuir couvrant la majeure partie du corps, avec des parties en cuir bouilli pour protéger les points vitaux, ou dune armure mêlant le cuir et la cotte de mailles, ou encore dune cuirasse en acier, simple mais efficace.</p><p>Un personnage portant une armure moyenne peut généralement en ôter certaines parties pour la transformer en armure légère sil le souhaite.</p><h2>Effets des armures moyennes</h2><ul><li>protection d6-2 (0-4 points de réduction des dégâts) ;</li><li>si vous préférez un chiffre fixe, une armure moyenne offre 2 points de protection ;</li><li>le port dune armure moyenne saccompagne dun malus de -1 en agilité du fait de lencombrement ;</li><li>le port dune armure moyenne handicape un sorcier et augmente de 2 points de pouvoir le coût de ses sorts.</li></ul>",
"properties" : {
"equipable": true,
"protection" : true,
"armor" : true,
"modifiers" : {
"social" : true,
"agility" : -1,
"powercost" : 2
},
"soak" : {
"formula" : "d6-2",
"value" : 2
}
}
}
},
{
"name": "Armure lourde",
"img": "/systems/bol/ui/icons/armor.webp",
"type": "item",
"data": {
"subtype": "armor",
"description": "<h1>Armure lourde</h1><p>Ce type darmure est porté par des gladiateurs, des chevaliers partant à la guerre, ou par ceux prévoyant de participer à une bataille sanglante dans un proche avenir. Ce n est pas une armure que lon peut porter la journée entière, et encore moins pour voyager ou sadonner aux activités ordinaires du quotidien. Il peut sagir dun haubert de mailles descendant jusquaux genoux ou dune cuirasse en acier, complétée de grèves et de gantelets, ou encore dune brigandine (une veste de cuir cousue de plaques de métal) avec gantelets et hautes bottes.</p><p>Un personnage portant une armure lourde peut généralement ôter certaines parties de celle-ci pour la transformer en armure moyenne sil le souhaite.</p><p>Les personnages ayant moins de 0 en vigueur ne peuvent pas porter darmure lourde (ils ne sont pas assez robustes pour supporter un pareil attirail).</p><h2>Effets des armures lourdes</h2><ul><li>protection d6-1 (0-5 points de réduction des dégâts) ;</li><li>si vous préférez un chiffre fixe, une armure lourde offre 3 points de protection ;</li><li>le port dune armure lourde saccompagne dun malus de -2 en agilité du fait de l encombrement ;</li><li>le port dune armure lourde handicape un sorcier et augmente de 3 points de pouvoir le coût de ses sorts.</li></ul>",
"properties" : {
"equipable": true,
"protection" : true,
"armor" : true,
"modifiers" : {
"social" : true,
"agility" : -2,
"powercost" : 3
},
"soak" : {
"formula" : "d6-1",
"value" : 3
}
}
}
},
{
"name": "Casque",
"img": "/systems/bol/ui/icons/armor.webp",
"type": "item",
"data": {
"subtype": "helm",
"description": "<h1>Casque</h1><p>Si vous êtes équipé dun casque, celui-ci ajoute +1 à la protection de votre armure, dans le cas où vous en portez une. Si vous portez par exemple une armure légère et un casque, votre dé de protection sera égal à d6-2 (d6-1 en armure moyenne et d6 en armure lourde).</p><p>En revanche, un casque vous inflige un malus à linitiative (il est plus difficile de remarquer ce qui se passe autour de vous avec un casque qui limite votre champ de vision), ainsi que dans certaines situations sociales.</p><p>En général, un héros ne porte pas son casque en permanence et ne le met que lorsquil se prépare au combat.</p>",
"properties" : {
"equipable": true,
"protection" : true,
"helm" : true,
"modifiers" : {
"social" : true
},
"soak" : {
"formula" : "+1",
"value" : 1
}
}
}
},
{
"name": "Petit bouclier",
"img": "/systems/bol/ui/icons/shield.webp",
"type": "item",
"data": {
"subtype": "shield",
"description": "<h1>Petit bouclier</h1><p>Un personnage ne peut bénéficier de son bouclier que sil est conscient de lattaque qui le vise, et donc sil est prêt à la parer.</p>",
"properties" : {
"equipable": true,
"protection" : true,
"shield" : true,
"blocking" : {
"malus" : -1,
"nbAttacksPerRound" : "1"
}
}
}
},
{
"name": "Grand bouclier",
"img": "/systems/bol/ui/icons/shield.webp",
"type": "item",
"data": {
"subtype": "shield",
"description": "<h1>Grand bouclier</h1><p>Un personnage ne peut bénéficier de son bouclier que sil est conscient de lattaque qui le vise, et donc sil est prêt à la parer.</p>",
"properties" : {
"equipable": true,
"protection" : true,
"shield" : true,
"modifiers" : {
"agility" : -1
},
"blocking" : {
"malus" : -1,
"nbAttacksPerRound" : "1"
}
}
}
}
]

533
data/fr/json/boons.json Normal file
View File

@ -0,0 +1,533 @@
[
{
"name": "Agilité de lhomme-oiseau",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Agilité de lhomme-oiseau</h1><p>ajoutez 1 à votre agilité. Votre score maximum en agilité passe à 6 au lieu de 5, et votre score de départ maximum en agilité peut être de 4 (au lieu de 3).</p>"
}
},
{
"name": "Ami des bêtes",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Ami des bêtes</h1><p>vous possédez une affinité naturelle avec les animaux. Vous bénéficiez dun dé de bonus quand vous interagissez avec eux. Si vous êtes dresseur, vous pouvez avoir avec vous deux ou trois compagnons animaux de taille petite, ou un seul de taille moyenne ou grande.</p>"
}
},
{
"name": "Ami des céruléens",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Ami des céruléens</h1><p>vous avez grandi à proximité des géants bleus, ou bien des circonstances particulières vous ont valu leur amitié, et ils vous considèrent comme un des leurs. Vous bénéficiez dun dé de bonus quand vous interagissez avec les nomades bleus.</p>"
}
},
{
"name": "Amis dans la pègre",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Amis dans la pègre</h1><p>vous comptez des amis peu recommandables parmi les différentes pègres qui gangrènent la Lémurie. Ils peuvent vous aider à trouver un receleur, vous fournir une planque, etc.</p>"
}
},
{
"name": "Amis haut placés",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Amis haut placés</h1><p>vous jouissez de contacts au sein des plus hauts échelons de la société. Même sils ne seront pas en général disposés à risquer leur tête pour vous, ils pourront vous apporter de laide (comme vous obtenir une audience auprès dun autre personnage important, vous fournir des informations, jouer de leur influence auprès de la noblesse locale, etc.). Bien sûr, ces amis attendront parfois en retour une faveur de votre part...</p>"
}
},
{
"name": "Arme favorite",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Arme favorite</h1><p>vous disposez dune arme de qualité (une grande épée valgardienne, un arc long de Tyrus, une fronde dAxos, un kriss halakhi, un khastok de Malakut, une hache dabordage de Parsool, une rapière de Satarla, ou une arme spécialement fabriquée pour vous ou dont vous avez hérité) et vous vous êtes entraîné à son maniement depuis lenfance. Vous bénéficiez dun dé de bonus lorsque vous utilisez cette arme (ou, si elle est perdue, volée ou détruite, une arme de substitution qui devra reproduire ses qualités uniques, ce qui risque dêtre particulièrement onéreux).</p>"
}
},
{
"name": "Artiste",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Artiste</h1><p>vous avez une sensibilité dartiste. Vous bénéficiez dun dé de bonus pour créer ou estimer des objets dart.</p>"
}
},
{
"name": "Athlète",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Athlète</h1><p>vous bénéficiez dun dé de bonus quand vous entreprenez des activités athlétiques (autres que le combat) comme courir, nager, grimper ou sauter.</p>"
}
},
{
"name": "Attirant",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Attirant</h1><p>vous êtes particulièrement beau ou séduisant. Vous bénéficiez dun dé de bonus dans les situations où lapparence peut jouer un rôle.</p>"
}
},
{
"name": "Bagarreur",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Bagarreur</h1><p>vous êtes un boxeur et un lutteur compétent. Vous bénéficiez dun dé de bonus à lattaque quand vous combattez à mains nues.</p>"
}
},
{
"name": "Baudrier de guerre",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Baudrier de guerre</h1><p>cet avantage autorise votre personnage à ne porter quun pagne ou un bikini en cotte de mailles et un simple baudrier (léquivalent dune armure légère au mieux), tout en considérant quil sagit dune armure moyenne en terme de protection, et ce sans subir le moindre malus darmure.</p>"
}
},
{
"name": "Beau parleur",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Beau parleur</h1><p>vous êtes très persuasif et excellent menteur. Vous bénéficiez dun dé de bonus quand vous voulez mentir, escroquer, baratiner ou tromper quelquun.</p>"
}
},
{
"name": "Bibliothèque savante",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Bibliothèque savante</h1><p>vous disposez dune bibliothèque de qualité pour mener vos recherches. Vous bénéficiez dun dé de bonus pour recueillir des informations lorsque vous vous trouvez dans votre bibliothèque. Vous devez toutefois enrichir régulièrement vos collections, ce qui vous conduit à partir à laventure pour trouver les moyens dacquérir de nouveaux manuscrits.</p>"
}
},
{
"name": "Bien né",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Bien né</h1><p>vous avez grandi dans les palais et les cours, parmi la noblesse et la haute société. Vous bénéficiez dun dé de bonus pour agir selon les règles de létiquette et de la courtoisie.</p>"
}
},
{
"name": "Colosse",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Colosse</h1><p>vous savez mobiliser votre vigueur pour accomplir de véritables tours de force. Vous bénéficiez dun dé de bonus pour briser, lever, tirer ou pousser des objets.</p>"
}
},
{
"name": "Combat à laveugle",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Combat à laveugle</h1><p>pas de lumière ? Aucun problème. En vous basant sur les odeurs, les bruits, les déplacements dair, vous ne faites plus quun avec le monde qui vous entoure. Votre personnage ignore les malus imposés par le MJ pour combattre dans lobscurité.</p>"
}
},
{
"name": "Cri de guerre",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Cri de guerre</h1><p>le personnage pousse son cri de guerre pour effrayer les ennemis à portée de voix. Ces derniers subissent un dé de malus sur tous leurs jets dattaque durant le round qui suit le cri de guerre. Cet avantage ne peut être utilisé gratuitement quune fois par jour ; toute utilisation supplémentaire exigera la dépense de 1 point dhéroïsme.</p>"
}
},
{
"name": "Discret",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Discret</h1><p>vous êtes vif et agile. Vous bénéficiez dun dé de bonus dans les situations où vous essayez de faire preuve de discrétion.</p>"
}
},
{
"name": "Doigts de fée",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Doigts de fée</h1><p>vous bénéficiez dun dé de bonus pour toutes les tâches exigeant une grande dextérité, comme le vol à la tire, la fabrication dobjets, le jonglage ou la triche aux cartes et aux dés.</p>"
}
},
{
"name": "Dur à cuire",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Dur à cuire</h1><p>vous avez la robustesse dun bronyx. Ajoutez 2 points à votre vitalité.</p>"
}
},
{
"name": "Érudit",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Érudit</h1><p>quand vous cherchez à vous souvenir dun fait relevant de votre domaine de compétence, vous bénéficiez dun dé de bonus.</p>"
}
},
{
"name": "Fêtard",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Fêtard</h1><p>vous connaissez bien les auberges et les tavernes, et vous nêtes pas le dernier quand il sagit de lever le coude. Vous bénéficiez dun dé de bonus pour recueillir des informations, trouver des contacts ou obtenir des biens et des services quand vous vous trouvez dans une taverne. De plus, vous tenez très bien lalcool et bénéficiez également dun dé de bonus pour résister aux effets de la boisson.</p>"
}
},
{
"name": "Fils des plaines",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Fils des plaines</h1><p>vous avez grandi dans les plaines. Lorsque vous vous trouvez dans un paysage de plaine, vous bénéficiez dun dé de bonus pour pister, piéger ou chasser, ainsi que pour dautres activités similaires de survie (mais pas pour combattre).</p>"
}
},
{
"name": "Fortuné",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Fortuné</h1><p>vous disposez dune source de revenus ou dun héritage. Vous bénéficiez dun dé de bonus quand vous cherchez à acquérir des biens ou des services dans votre cité dorigine.</p>"
}
},
{
"name": "Gamin des rues",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Gamin des rues</h1><p>vous êtes un enfant des rues. Vous bénéficiez dun dé de bonus quand vous interagissez avec les gens des bas-fonds de la cité, ou pour des activités comme filer quelquun ou remarquer un détail dans la rue (mais pas pour combattre).</p>"
}
},
{
"name": "Inspirateur",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Inspirateur</h1><p>vous savez motiver vos amis et vos partisans. Cela peut se faire au moyen dune invocation aux dieux, dun discours enflammé ou dune musique inspirante, à moins que cela ne vienne simplement de votre présence charismatique. Pour le round qui suit lutilisation de cet avantage, vos compagnons bénéficient dun dé de bonus à tous leurs jets dattaque (à condition dêtre à portée de voix). Cet avantage ne peut être utilisé gratuitement quune fois par jour ; toute utilisation supplémentaire exigera la dépense de 1 point dhéroïsme.</p>"
}
},
{
"name": "Intimidant",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Intimidant</h1><p>vous bénéficiez dun dé de bonus à chaque fois que vous essayez de forcer quelquun à vous donner une information ou à faire une chose à laquelle il répugne.</p>"
}
},
{
"name": "Intrépide",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Intrépide</h1><p>votre personnage est insensible à la peur. Même une peur magiquement induite na aucune prise sur lui.</p>"
}
},
{
"name": "Laboratoire fourni",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Laboratoire fourni</h1><p>vous disposez dun laboratoire de qualité pour mener vos expériences. Vous bénéficiez dun dé de bonus aux jets pour créer des préparations alchimiques ou des instruments mécaniques lorsque vous vous trouvez dans votre laboratoire. Celui-ci doit toutefois être réapprovisionné de temps à autre, ce qui vous conduit à partir à laventure pour trouver les moyens financiers et matériels de refaire vos stocks.</p>"
}
},
{
"name": "Magie des Rois-Sorciers",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Magie des Rois-Sorciers</h1><p>vous avez atteint une certaine compréhension des antiques secrets des Rois-Sorciers. Vous bénéficiez dun dé de bonus pour lancer des sortilèges. Si vous choisissez cet avantage, vous devez prendre un désavantage supplémentaire.</p>"
}
},
{
"name": "Mains guérisseuses",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Mains guérisseuses</h1><p>vous bénéficiez dun dé de bonus sur les tests destinés à aider un blessé à récupérer de ses blessures, dun empoisonnement, etc. Vous devez posséder la carrière médecin pour prendre cet avantage.</p>"
}
},
{
"name": "Maître du déguisement",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Maître du déguisement</h1><p>vous bénéficiez dun dé de bonus quand vous tentez de dissimuler votre identité. De plus, si vous souhaitez intervenir promptement dans une scène où votre personnage nétait pas présent, vous pouvez dépenser 1 point dhéroïsme pour faire partie du décor, par exemple déguisé en garde de la patrouille ou en bourgeois passant dans la rue. En fait, vous étiez là depuis le début, mais incognito!</p>"
}
},
{
"name": "Marqué par les dieux",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Marqué par les dieux</h1><p>les dieux vous accordent leur faveur. Vous gagnez 1 point dhéroïsme supplémentaire.</p>"
}
},
{
"name": "Montagnard",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Montagnard</h1><p>vous avez grandi dans les montagnes. Lorsque vous vous trouvez dans un paysage montagneux, vous bénéficiez dun dé de bonus pour pister, piéger ou chasser, ainsi que pour dautres activités similaires de survie (mais pas pour combattre).</p>"
}
},
{
"name": "Né en selle",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Né en selle</h1><p>vous bénéficiez dun dé de bonus pour chevaucher des montures et agir en selle (mais pas pour combattre).</p>"
}
},
{
"name": "Odorat développé",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Odorat développé</h1><p>à chaque fois que vous effectuez un jet daction sous esprit pour percevoir quelque chose grâce à votre odorat, vous bénéficiez dun dé de bonus.</p>"
}
},
{
"name": "Ouïe fine",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Ouïe fine</h1><p>à chaque fois que vous effectuez un jet daction sous esprit pour percevoir quelque chose grâce à votre ouïe, vous bénéficiez dun dé de bonus.</p>"
}
},
{
"name": "Outillage",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Outillage</h1><p>vous possédez un jeu doutils adaptés à votre métier ou votre artisanat. Vous bénéficiez dun dé de bonus quand vous entreprenez une action où lemploi de ces outils peut se révéler efficace.</p>"
}
},
{
"name": "Peau dure",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Peau dure</h1><p>vous avez une peau particulièrement résistante et épaisse qui vous confère +1 en protection, même quand vous ne portez pas darmure.</p>"
}
},
{
"name": "Perspicace",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Perspicace</h1><p>vous êtes doué pour percer à jour les menteurs. Quand quelquun tente de vous mentir ou de vous entourlouper, vous bénéficiez dun dé de bonus pour le remarquer. Cela ne veut pas dire que vous connaîtrez forcément la vérité, mais vous saurez au moins quon est en train de vous mentir.</p>"
}
},
{
"name": "Pied marin",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Pied marin</h1><p>vous avez grandi dans un environnement de navires et de bateaux. Vous bénéficiez dun dé de bonus pour manœuvrer une embarcation ou entreprendre des activités physiques à bord dun navire (mais pas pour combattre).</p>"
}
},
{
"name": "Pisteur des marais",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Pisteur des marais</h1><p>vous avez grandi dans les marais. Lorsque vous vous trouvez dans un paysage de marécage, vous bénéficiez dun dé de bonus pour pister, piéger ou chasser, ainsi que pour dautres activités similaires de survie (mais pas pour combattre).</p>"
}
},
{
"name": "Poings dacier",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Poings dacier</h1><p>vous avez les poings durs comme la pierre après des années dentraînement ou à force de vous bagarrer dans toutes les tavernes de la ville. Vous ajoutez votre vigueur aux dégâts quand vous combattez à mains nues.</p>"
}
},
{
"name": "Pouvoir du Néant",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Pouvoir du Néant</h1><p>vous avez porté le regard sur labîme de noirceur du Néant, et recevez deux points de pouvoir supplémentaires. Si vous choisissez cet avantage, vous devez aussi prendre un désavantage supplémentaire.</p>"
}
},
{
"name": "Récupération rapide",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Récupération rapide</h1><p>vous jouissiez dune constitution hors norme. Lorsque vous récupérez après un combat, vous regagnez 1 point de vitalité supplémentaire (qui sajoute à la récupération normale, égale à la moitié des points perdus). De plus, si vous êtes blessé, vous récupérez 1 point de vitalité par jour, peu importe les activités que vous entreprenez.</p>"
}
},
{
"name": "Renard du désert",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Renard du désert</h1><p>lorsque vous vous trouvez dans un désert, vous bénéficiez dun dé de bonus pour pister, piéger ou chasser, ainsi que pour dautres activités similaires de survie (mais pas pour combattre).</p>"
}
},
{
"name": "Résistant à la magie",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Résistant à la magie</h1><p>si vous êtes visé par un sortilège, lancez un d6. Sur un 6, le sortilège na aucun effet sur vous.</p>"
}
},
{
"name": "Résistant aux poisons",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Résistant aux poisons</h1><p>vous bénéficiez dun dé de bonus pour résister aux effets des drogues, des venins, des toxines, ainsi que de lalcool.</p>"
}
},
{
"name": "Roi de la jungle",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Roi de la jungle</h1><p>vous avez grandi dans la jungle. Lorsque vous vous trouvez dans un paysage de jungle, vous bénéficiez dun dé de bonus pour pister, piéger ou chasser, ainsi que pour dautres activités similaires de survie (mais pas pour combattre).</p>"
}
},
{
"name": "Roi de lévasion",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Roi de lévasion</h1><p>cordes, chaînes, menottes, prison, rien ne vous retient bien longtemps. Que ce soit par vos talents ou par un coup de chance, vous finissez toujours par vous libérer. Vous bénéficiez dun dé de bonus lorsque vous tentez de vous évader ou de vous libérer de vos liens.</p>"
}
},
{
"name": "Santé de fer",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Santé de fer</h1><p>vous êtes immunisé à toutes les maladies, y compris celles dorigine magique.</p>"
}
},
{
"name": "Savant",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Savant</h1><p>ajoutez 1 à votre esprit. Votre score maximum en esprit passe à 6 au lieu de 5, et votre score de départ maximum en esprit peut être de 4 (au lieu de 3).</p>"
}
},
{
"name": "Sentir la magie",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Sentir la magie</h1><p>vous bénéficiez dun dé de bonus quand vous essayez de reconnaître (ou de traquer) un sorcier, un effet ou un artefact magique.</p>"
}
},
{
"name": "Tigre des neiges",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Tigre des neiges</h1><p>vous avez grandi dans la toundra gelée. Lorsque vous vous trouvez dans un paysage neigeux, vous bénéficiez dun dé de bonus pour pister, piéger ou chasser, ainsi que pour dautres activités similaires de survie (mais pas pour combattre).</p>"
}
},
{
"name": "Tireur puissant",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Tireur puissant</h1><p>avec un type darme à distance choisi (arc, fronde, javelot, etc.), vous ajoutez votre vigueur aux dégâts.</p>"
}
},
{
"name": "Vigilant",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Vigilant</h1><p>vous jouissez dune excellente capacité de réaction face au danger. Vous bénéficiez dun dé de bonus à vos jets de réaction.</p>"
}
},
{
"name": "Vigueur céruléenne",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Vigueur céruléenne</h1><p>vous êtes grand et fort. Ajoutez 1 à votre vigueur. Votre score maximum en vigueur passe à 6 au lieu de 5, et votre score de départ maximum en vigueur peut être de 4 (au lieu de 3).</p>"
}
},
{
"name": "Vision nocturne",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Vision nocturne</h1><p>vous bénéficiez dun dé de bonus quand lobscurité impose un malus à la vision.</p>"
}
},
{
"name": "Vue perçante",
"type": "feature",
"img": "/systems/bol/ui/icons/boon.webp",
"data": {
"subtype": "boon",
"description": "<h1>Vue perçante</h1><p>à chaque fois que vous effectuez un jet daction sous esprit pour percevoir quelque chose grâce à votre vue, vous bénéficiez dun dé de bonus.</p>"
}
}
]

236
data/fr/json/careers.json Normal file
View File

@ -0,0 +1,236 @@
[
{
"name": "Alchimiste (artificier/inventeur)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Alchimiste (artificier/inventeur)</h1><p>Les alchimistes sont les scientifiques et les inventeurs de Lémurie. Souvent confondus avec les sorciers par ceux qui ne comprennent rien à leur science, les alchimistes ont une connaissance approfondie des principes de la chimie et de la métallurgie, ainsi que des vertus des plantes et herbes quils cultivent parfois dans leurs propres jardins médicinaux.</p><p>Les alchimistes sont ainsi capables de créer des parfums, des potions, des poudres et des poisons, de composer des alliages aux propriétés uniques, de concevoir des instruments et des machines étranges, entre autres inventions étonnantes. Certains alchimistes particulièrement brillants sont même capables dassembler des morceaux issus de différentes créatures vivantes pour créer dhorribles chimères. Quand ils conçoivent des machines, les alchimistes travaillent souvent en étroite collaboration avec des forgerons. Vous trouverez davantage dinformations sur lalchimie au chapitre 6.</p><h2>Attributs</h2><p>à lévidence lesprit est lattribut essentiel pour un alchimiste, dont la profession exige une grande intelligence et de vastes connaissances, que ce soit pour mener ses propres recherches ou pour déchiffrer les textes et les plans rédigés par de lointains prédécesseurs.</p><h2>À laventure</h2><p>ce n est pas une carrière très courante chez les héros, car elle impose daustères recherches et beaucoup de patience. Il arrive cependant que des alchimistes audacieux saventurent à explorer dantiques ruines dans l espoir dy découvrir danciennes reliques dont la véritable valeur pourrait échapper à des héros moins instruits queux.</p><h2>Combat</h2><p>les circonstances où des rangs dans la carrière dalchimiste pourraient se révéler utiles au combat sont particulièrement rares.</p><h2>Idées dAvantages</h2><p>bibliothèque savante, doigts de fée, érudit, laboratoire fourni, odorat développé, résistant aux poisons, savant.</p><h2>Idées de Désavantages</h2><p>chétif, distrait, foie jaune, gars de la ville, non-combattant, obsession (savoir ou artefacts anciens).</p><h2>Carrière dangereuse</h2><p>pour chaque rang dalchimiste au-dessus du rang 2, le personnage doit prendre un désavantage (consultez la liste des avantages et désavantages, page 40).</p><h2>Langues</h2><p>les alchimistes doivent apprendre le démonique sils veulent pouvoir utiliser les puissantes créations magiques et alchimiques de lantique race des Rois-Sorciers. Ce langage est particulièrement ardu et ses formes orale et écrite exigent dêtre apprises séparément.</p>"
}
},
{
"name": "Assassin (agent/espion)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Assassin (agent/espion)</h1><p>Tueurs à gages, quand ils ne sont pas des agents au service dun souverain, les espions et les assassins ont élevé le meurtre et le vol au rang dart. Ce sont des experts de la collecte secrète dinformations et de rumeurs, de lattaque sournoise et du meurtre discret, parfois maquillé en mort naturelle (par lusage de poison, par exemple). Ils utilisent des méthodes éprouvées pour réunir des informations sur un sujet ou un personnage, se bâtir un solide réseau de contacts (dont tous ne sont pas forcément très recommandables), et se rapprocher de leur cible (quil sagisse de crocheter une serrure, de mentir ou de se déguiser). Ils savent se montrer patients et peuvent parfois rester en planque des jours durant, à attendre loccasion parfaite de frapper. Il est de notoriété publique que les meilleurs assassins de Lémurie proviennent de la cité dHalakh.</p><h2>Attributs</h2><p>tous les attributs sont importants pour un assassin.</p><h2>À laventure</h2><p>les assassins et les espions sont généralement des solitaires, ce qui nen fait pas des candidats évidents pour rejoindre un groupe daventuriers. En revanche, danciens assassins ont des compétences très utiles à offrir à un groupe de héros.</p><h2>Combat</h2><p>un assassin peut obtenir un avantage ponctuel sil attaque par surprise, en frappant un adversaire qui ne la pas vu approcher, ou en utilisant une arme dissimulée, par exemple.</p><h2>Idées dAvantages</h2><p>amis dans la pègre, amis haut placés, arme favorite, beau parleur, discret, maître du déguisement, ouïe fine, résistant aux poisons, vigilant, vue perçante.</p><h2>Idées de Désavantages</h2><p>arrogant, gars de la ville, mauvaise réputation, obsession (achever la mission), traqué.</p>"
}
},
{
"name": "Barbare (berserk/primitif)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Barbare (berserk/primitif)</h1><p>Ces personnages ne sont pas originaires des grandes cités de Lémurie, mais plutôt des montagnes de lAxos, des toundras glacées de Valgard, du désert de Beshaar ou dautres contrées sauvages du continent.</p><p>Les barbares sont des êtres farouches et sauvages, comme les terres qui les ont vus naître. Doués dinstincts aussi aiguisés que ceux dun fauve, ils possèdent un talent inné pour la survie en milieu hostile et de solides connaissances sur la nature. Ce sont généralement de bons cavaliers. Mais les barbares restent surtout célèbres pour la rage indomptable avec laquelle ils combattent et leur faculté innée dintimider les âmes les mieux trempées.</p><h2>Attributs</h2><p>la vie rude des barbares exige robustesse et endurance, aussi une bonne vigueur est essentielle pour un barbare, bien quil ne doive pas non plus négliger lagilité.</p><h2>Idées de Désavantages</h2><p>arrogant, gars de la ville, mauvaise réputation, obsession (achever la mission), traqué.</p><h2>À laventure</h2><p>les barbares sont des aventuriersnés et possèdent les talents et les aptitudes nécessaires pour survivre aux pires situations.</p><h2>Combat</h2><p>les barbares se battent généralement de manière brutale, sans le moindre raffinement. Cela pourrait impressionner des citadins inaccoutumés à une telle sauvagerie, et offrir un avantage ponctuel à un barbare dans le cadre dun combat particulièrement violent et sans pitié.</p><h2>Idées dAvantages</h2><p>arme favorite, baudrier de guerre, colosse, cri de guerre, dur à cuire, fils des plaines, intimidant, montagnard, odorat développé, ouïe fine, peau dure, pisteur des marais, récupération rapide, roi de la jungle, santé de fer, tigre des neiges, vigilant, vue perçante.</p><h2>Idées de Désavantages</h2><p>bouseux, crédule, illettré, impétueux, lubrique, marin deau douce, méfiance envers la sorcellerie, signe distinctif, taciturne.</p>"
}
},
{
"name": "Bourreau (geôlier/esclavagiste)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Bourreau (geôlier/esclavagiste)</h1><p>Les bourreaux sont chargés des exécutions publiques décrétées par le tribunal ou les autorités.</p><p>Les geôliers soccupent des prisons où croupissent les pires criminels des cités de Lémurie. Ils exercent leur sinistre activité dans de sordides cachots où ils se chargent dextirper des informations aux prisonniers récalcitrants et aux ennemis des rois qui les emploient. Passés maîtres dans lart de lintimidation et de linterrogatoire, ils possèdent de bonnes connaissances de base en anatomie et en premiers soins (des savoirs indispensables pour briser un prisonnier sans quil meure avant davoir parlé).</p><p>Les esclavagistes mènent des raids dans des terres lointaines pour capturer ou acheter des « sauvages » quils ramènent dans les grandes cités de Lémurie afin de les revendre comme gladiateurs, travailleurs de force ou serviteurs, ou pour peupler de jeunes esclaves nubiles les harems des riches.</p><h2>Attributs</h2><p>les bourreaux ont rarement un score daura élevé, tandis que la vigueur reste un attribut indispensable pour accomplir une décapitation dans les règles de lart ou pour maintenir le calme parmi leurs prisonniers.</p><h2>À laventure</h2><p>les geôliers quittent rarement leurs cachots humides, mais il peut arriver quun bourreau se retrouve frappé dexil et contraint de mener une vie derrance et daventure. Les esclavagistes sont toujours par monts et par vaux pour les besoins de leur sordide commerce.</p><h2>Combat</h2><p>les bourreaux préfèrent les grandes haches ou les épées à deux mains, tandis que certains esclavagistes sont particulièrement habiles avec un fouet. Les bourreaux ne sont pas des combattants très subtils et les guerriers expérimentés se laisseront rarement surprendre par leur style de combat brutal et sans finesse.</p><h2>Idées dAvantages</h2><p>amis dans la pègre, arme favorite, colosse, dur à cuire, intimidant, récupération rapide.</p><h2>Idées de Désavantages</h2><p>bigleux, borgne/oreille coupée, cupide, dur doreille, fanatique, fanfaron, gars de la ville, illettré, inquiétant, lent à la détente, manchot/unijambiste, pataud, phobie, poltron, repoussant, soiffard.</p>"
}
},
{
"name": "Chasseur (éclaireur/pisteur)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Chasseur (éclaireur/pisteur)</h1><p>Le chasseur est passé maître dans lart de pister et de traquer les animaux. Une fois quil a localisé sa proie, il utilise des techniques dapproche discrète, la pose de pièges, ou son habileté à larc pour labattre. Les chasseurs sont parfaitement à leur aise dans la nature sauvage et sont capables dy survivre sur de longues périodes, pour ne retourner vers les zones civilisées quune fois quils ont réuni suffisamment de fourrures et de peaux à vendre, ou quand la compagnie de leurs semblables commence à leur manquer.</p><h2>Attributs</h2><p>lagilité est importante pour un chasseur, tout comme la vigueur et lesprit, encore quà un moindre degré.</p><h2>À laventure</h2><p>la traque de bêtes féroces est déjà une aventure en soi. Mais les chasseurs connaissent très bien les territoires sur lesquels ils opèrent et il leur arrive de découvrir au gré de leurs pérégrinations danciennes pistes abandonnées, de vieilles ruines ou des lieux étranges. Pour cette raison, les chasseurs se voient fréquemment proposer de servir de guide à des groupes daventuriers.</p><h2>Combat</h2><p>un chasseur pourra recevoir un bonus de carrière ponctuel sil affronte une créature sauvage quil connaît bien. En revanche, cette carrière est rarement utile contre des adversaires humains.</p><h2>Idées dAvantages</h2><p>ami des bêtes, discret, fils des plaines, montagnard, odorat développé, ouïe fine, outillage, pisteur des marais, renard du désert, vigilant, vision nocturne, vue perçante.</p><h2>Idées de Désavantages</h2><p>borgne/oreille coupée, manchot/unijambiste, marin deau douce, taciturne.</p>"
}
},
{
"name": "Danseur (acrobate/saltimbanque)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Danseur (acrobate/saltimbanque)</h1><p>La danse est un divertissement apprécié en Lémurie. Toute cérémonie ou fête digne de ce nom se doit de comporter des danseurs ou des acrobates. Les danseurs sont de véritables athlètes, capables de prouesses en termes de précision, dagilité et de coordination. Les saltimbanques maîtrisent aussi quelques tours de prestidigitation ou de jonglage, tandis que certaines danseuses pratiquent des danses exotiques et utilisent des voiles qui soulignent plus quils ne masquent vraiment leurs attraits.</p><h2>Attributs</h2><p>les danseurs font principalement appel à leur agilité et leur aura. Les acrobates et les saltimbanques sont souvent plus costauds quils ny paraissent.</p><h2>À laventure</h2><p>les saltimbanques voyagent de ville en ville au sein de troupes itinérantes. Cela peut les confronter aux dangers de la route, quil sagisse de bêtes féroces ou de brigands.</p><h2>Combat</h2><p>cette carrière na rien dune carrière martiale et elle ne sera que rarement utile face à un combattant expérimenté. Dans certaines circonstances, une danseuse pourra obtenir un avantage ponctuel si son adversaire est déconcentré par ses charmes, ou en accomplissant une acrobatie, comme une roulade, pour surprendre son ennemi. Un acrobate pourra cependant tirer parti des lianes, des cordes ou des tentures murales pour effectuer de spectaculaires actions comme on peut en voir dans les films de cape et dépée.</p><h2>Idées dAvantages</h2><p>athlète, attirant, discret, doigts de fée, récupération rapide, roi de lévasion, vigilant.</p><h2>Idées de Désavantages</h2><p>chétif, gars de la ville, non-combattant.</p>"
}
},
{
"name": "Dresseur (maître des bêtes/montreur dours)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Dresseur (maître des bêtes/montreur dours)</h1><p>Les maîtres des bêtes sont demandés dans toute la Lémurie pour leur capacité à soccuper des animaux, envers lesquels ils manifestent généralement une forme particulière dempathie. Ils les dressent à être montés, à servir de bêtes de trait ou à combattre, que ce soit sur le champ de bataille ou dans une arène. Les dresseurs sont capables de calmer une créature enragée, de soigner des animaux blessés ou malades, de reconnaître une bête dangereuse et de dire si celle-ci est sur le point dattaquer. En général, ce sont également des cavaliers émérites et de remarquables conducteurs dattelage. Certains dresseurs tiennent leurs animaux par la peur et les privations plutôt que détablir une relation de confiance avec eux.</p><h2>Attributs</h2><p>un dresseur doit posséder une forte personnalité et une détermination sans faille, tempérées par un cœur généreux (même si ce nest pas toujours le cas). Laura est donc lattribut le plus important pour un dresseur, suivi de près par lesprit.</p><h2>À laventure</h2><p>les dresseurs sont très demandés, que ce soit par des marchands organisant une caravane, par des nobles ou des militaires pour entraîner et soigner leurs montures, par des propriétaires darènes, ou par des aventuriers qui sattendent à croiser détranges bêtes sauvages sur leur route.</p><h2>Combat</h2><p>un dresseur sait comment se comporter face à un animal et a des chances de connaître ses points faibles. Face à une bête sauvage, cette carrière pourra parfois apporter un avantage ponctuel.</p><h2>Idées dAvantages</h2><p>ami des bêtes, baudrier de guerre, né en selle, odorat développé, ouïe fine, résistant aux poisons, vigilant, vision nocturne, vue perçante.</p><h2>Idées de Désavantages</h2><p>bouseux, illettré, impétueux, incapable de mentir.</p>"
}
},
{
"name": "Esclave (serf/serviteur)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Esclave (serf/serviteur)</h1><p>Lesclavage n est pas un choix de carrière évident pour un aventurier, mais il peut contribuer utilement à définir le personnage et offre quelques compétences et talents originaux.</p><p>Cette carrière permet à un personnage dapprendre à ne pas se faire remarquer, à voir et écouter discrètement, à cuisiner, nettoyer, coudre, et à effectuer toutes sortes de travaux ménagers. Certains esclaves (les plus forts ou les fauteurs de trouble) sont parfois vendus aux arènes pour y combattre comme gladiateurs.</p><h2>Attributs</h2><p>selon à quoi ils sont employés, les esclaves ont besoin dune bonne vigueur ou dune bonne agilité. Les femmes esclaves voient leur situation saméliorer (ou empirer !) si elles ont un bon score daura. Les esclaves trop intelligents sont généralement considérés comme des fauteurs de trouble.</p><h2>À laventure</h2><p>les esclaves à lesprit aventureux ne restent pas longtemps sous le joug de leur maître, à moins bien sûr que cela ne serve leurs intérêts. Une vie desclave fugitif mène tout naturellement à laventure.</p><h2>Combat</h2><p>cette carrière n est pas dun grand intérêt au combat. Toutefois des guerriers pourraient négliger de soccuper dun esclave, ne le considérant pas comme une menace, ce qui risque dêtre une grave erreur.</p><h2>Idées dAvantages</h2><p>colosse, discret, ouïe fine, roi de lévasion.</p><h2>Idées de Désavantages</h2><p>foie jaune, gars de la ville, illettré, inadapté au froid, marin deau douce, maudit, muet, non-combattant, phobie, souffreteux, taciturne.</p>"
}
},
{
"name": "Fermier (paysan/berger)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Fermier (paysan/berger)</h1><p>Les fermiers vivent à lextérieur de lenceinte de la cité, mais généralement à moins dune journée de voyage de celle-ci, afin de pouvoir aller y vendre leurs récoltes. Ce sont des gens robustes habitués au dur labeur. Bons connaisseurs des plantes et des animaux dont ils savent prendre soin, les fermiers sont également capables de préparer la cuisine, de cuire du pain, de brasser de la bière, de négocier au meilleur prix leur production sur le marché local, etc.</p><h2>Attributs</h2><p>pour un fermier, il ny a pas dattribut plus important quun autre, encore que laura soit sans doute celui qui lui sera le moins utile.</p><h2>À laventure</h2><p>les fermiers ne sont pas particulièrement aventureux et il faut quelque événement inhabituel ou funeste pour les pousser à abandonner leur ferme et à se lancer dans une vie derrance.</p><h2>Combat</h2><p>en général, les fermiers ne sont pas des combattants aguerris et ils ne recevront quexceptionnellement un avantage au combat en raison de cette carrière, par exemple sils défendent leurs terres contre des pillards ou utilisent un outil agricole comme arme improvisée.</p><h2>Idées dAvantages</h2><p>ami des bêtes, bagarreur, fêtard, marqué par les dieux.</p><h2>Idées de Désavantages</h2><p>bouseux, crédule, lent à la détente, marin deau douce, pataud, repoussant, soiffard, taciturne.</p>"
}
},
{
"name": "Forgeron (armurier)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Forgeron (armurier)</h1><p>Spécialisés dans le travail des métaux, ces artisans passent de longues heures dans leurs forges à créer et réparer des objets en métal. Ils fabriquent aussi bien des instruments et des outils que des armes et des armures, ou encore les pièces métalliques qui entrent dans la construction des galères et des nefs volantes. Les alchimistes font souvent appel à des forgerons pour fabriquer leurs inventions. Leur expérience leur est bien utile quand il sagit destimer et de marchander le prix dobjets en métal, notamment les armes et armures.</p><h2>Attributs</h2><p>les forgerons sont souvent solidement bâtis, avec une bonne vigueur, car le dur labeur de la forge implique force et endurance.</p><h2>À laventure</h2><p>les forgerons ne sont pas vraiment des aventuriers, mais certains sengagent parfois dans une troupe de mercenaires pour soccuper de l entretien des armes et des armures.</p><h2>Combat</h2><p>bien quun forgeron ne soit pas à proprement parler un combattant, il pourra recevoir ponctuellement un bonus de mêlée sil affronte un adversaire portant une armure métallique dont il connaît les spécificités et les éventuels points faibles.</p><h2>Idées dAvantages</h2><p>arme favorite, bagarreur, baudrier de guerre, colosse, outillage.</p><h2>Idées de Désavantages</h2><p>crédule, impétueux, inadapté au froid, lent à la détente, taciturne.</p>"
}
},
{
"name": "Gladiateur (champion, belluaire)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Gladiateur (champion, belluaire)</h1><p>Les gladiateurs sont des experts du duel, habiles au maniement de toutes sortes darmes et capables daffronter des hommes ou des bêtes féroces avec style et panache. Les combattants des arènes sont généralement des esclaves, ou parfois des hommes libres contraints de se battre en remboursement dune dette impayée ou en punition dun crime. Ceux qui survivent au combat sont récompensés par les cris enthousiastes de la foule tandis que leur adversaire agonise à leurs pieds. Les meilleurs gladiateurs acquièrent une renommée qui dépasse le cadre de larène, et qui peut aussi bien jouer à leur avantage quà leur détriment.</p><h2>Attributs</h2><p>pour un gladiateur, la vigueur et lagilité sont essentielles, mais les plus populaires des guerriers de larène possèdent aussi beaucoup daura.</p><h2>À laventure</h2><p>la vie de gladiateur ne conduit pas delle-même à laventure, mais de nombreux héros ont fait un passage dans les arènes, que ce soit par choix, par nécessité, ou au gré de circonstances particulières.</p><h2>Combat</h2><p>les gladiateurs sont entraînés à un style de combat dont le but n est pas simplement de tuer rapidement ladversaire, mais de faire de la passe darmes un échange de coups spectaculaires. Ils pourront obtenir un bonus au combat en tentant une botte particulièrement théâtrale, à condition de ne pas en abuser et, comme toujours, avec lapprobation du MJ.</p><h2>Idées dAvantages</h2><p>arme favorite, athlète, bagarreur, baudrier de guerre, cri de guerre, dur à cuire, intimidant, marqué par les dieux, récupération rapide, vigilant.</p><h2>Idées de Désavantages</h2><p>borgne/oreille coupée, fanfaron, impétueux, manchot/unijambiste, signe distinctif.</p>"
}
},
{
"name": "Marchand (colporteur/négociant)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Marchand (colporteur/négociant)</h1><p>Les marchands ne sont pas des boutiquiers, mais des négociants qui voyagent au loin, à la recherche de produits nouveaux et exotiques à acheter et à vendre. Les personnages marchands ont donc acquis de nombreux savoirs utiles. Ils maîtrisent lart de la négociation, savent estimer les marchandises, ont de bonnes connaissances géographiques, et sont bien renseignés sur des villes et des régions lointaines ainsi que sur les institutions qui gouvernent les cités et les guildes. Si vous recherchez un objet rare ou inhabituel, parlez-en dabord à un marchand !</p><h2>Attributs</h2><p>les marchands ont besoin dun esprit vif et dun certain degré daura pour marchander et faire des affaires.</p><h2>À laventure</h2><p>une vie itinérante est forcément une vie daventure, que le marchand la recherche ou pas. Les marchands sont toujours en quête de nouvelles contrées et de nouveaux marchés, ce qui les entraîne dans de nombreuses aventures.</p><h2>Combat</h2><p>la carrière de marchand nétant pas une carrière martiale, elle ne sera presque jamais utile à un personnage engagé au combat.</p><h2>Idées dAvantages</h2><p>beau parleur, fortuné, perspicace, savant.</p><h2>Idées de Désavantages</h2><p>cupide, lent à la détente, non-combattant, obsession.</p>"
}
},
{
"name": "Marin (matelot/pirate)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Marin (matelot/pirate)</h1><p>Les marins sont les combattants et les aventuriers des mers. Ils savent manœuvrer une embarcation, sorienter aux étoiles, ont de bonnes connaissances sur le milieu marin ainsi que sur les ports et les îles côtières.</p><p>Les matelots expérimentés sont toujours recherchés, et il est rare quun capitaine refuse daccepter à son bord un matelot prêt à payer son voyage en participant à la manœuvre.</p><p>Les pirates sont les brigands des mers. Ils parlent leur propre version du lémurien, quon appelle largot des mers.</p><h2>Attributs</h2><p>les marins ont besoin dune bonne vigueur et dune bonne agilité.</p><h2>À laventure</h2><p>la vie en mer ne manque pas daventures. Les monstres marins, les batailles navales, les ports exotiques remplis de gens étranges et les cartes au trésor sont le pain quotidien des loups de mer.</p><h2>Combat</h2><p>un marin pourra recevoir un bonus ponctuel lors daffrontements en mer, et peut-être aussi contre des créatures marines quil aurait déjà combattues ou dont il aurait entendu parler.</p><h2>Idées dAvantages</h2><p>amis dans la pègre, athlète, bagarreur, baudrier de guerre, cri de guerre, discret, doigts de fée, fêtard, pied marin, vigilant, vue perçante.</p><h2>Idées de Désavantages</h2><p>borgne/oreille coupée, cupide, fanfaron, illettré, impétueux, lubrique, manchot/unijambiste, méfiance envers la sorcellerie, phobie, signe distinctif, soiffard.</p>"
}
},
{
"name": "Médecin (guérisseur/rebouteux)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Médecin (guérisseur/rebouteux)</h1><p>Les médecins et tous ceux capables de soigner les personnes blessées ou malades jouissent dun grand respect au sein des villes de Lémurie. La population sait reconnaître limportance de leur mission et létendue de leur savoir, même si les petites gens nont pas forcément les moyens de soffrir les services dun vrai médecin et sen remettent plutôt à des charlatans.</p><p>Les médecins prescrivent des potions et des onguents, savent réduire les fractures, recoudre les plaies et aident à mettre les enfants au monde. Ils connaissent les maladies et leurs remèdes, savent administrer les premiers soins, et les plantes médicinales nont plus de secret pour eux. Souvent, ils possèdent un petit jardin où ils cultivent des herbes aux vertus curatives puissantes. Certains médecins ont des connaissances de base en alchimie (cf. chapitre 6), et tous se doivent bien sûr de savoir lire et écrire.</p><h2>Attributs</h2><p>lesprit est lattribut essentiel pour un médecin.</p><h2>À laventure</h2><p>la carrière de médecin n est pas en elle-même propice à une vie daventure, mais il arrive que des médecins soient recrutés pour accompagner une expédition maritime ou une armée en marche.</p><h2>Combat</h2><p>au combat, la carrière de médecin n est pas dun grand secours. Ce n est quaprès le combat quelle révèle tout son intérêt !</p><h2>Idées dAvantages</h2><p>bibliothèque savante, doigts de fée, érudit, mains guérisseuses, résistant aux poisons, santé de fer.</p><h2>Idées de Désavantages</h2><p>foie jaune, gars de la ville, incapable de mentir, non-combattant, soiffard.</p>"
}
},
{
"name": "Mendiant (vagabond/clochard)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Mendiant (vagabond/clochard)</h1><p>Les vagabonds errent dun lieu à lautre avec pour seul objectif de réussir à survivre. Ils peuvent à loccasion travailler ici ou là, vendre quelques babioles sorties de leur besace, ou simplement mendier dans les rues quand les temps sont vraiment durs. En dernier recours, certains sadonnent à de petits larcins pour se remplir le ventre.</p><h2>Attributs</h2><p>aucun attribut n est plus important que les autres pour un mendiant. Être affligé dune difformité, dun handicap, ou dune maladie repoussante (ou simplement le simuler) peut cependant se révéler utile quand il sagit de faire appel à la compassion des passants.</p><h2>À laventure</h2><p>la vie dun vagabond implique des rencontres en tous genres sur les routes, ce qui peut mener à laventure sans même la rechercher.</p><h2>Combat</h2><p>en général, un mendiant na rien dun combattant. Cette carrière ne pourra donc se révéler utile dans le cadre dun combat, sauf quand le personnage fait de son mieux pour ne pas être remarqué.</p><h2>Idées dAvantages</h2><p>amis dans la pègre, discret, doigts de fée, gamin des rues.</p><h2>Idées de Désavantages</h2><p>addiction, borgne/ oreille coupée, chétif, gars de la ville, illettré, indigne de confiance, malédiction de Morgazzon, manchot/ unijambiste, maudit, non-combattant, signe distinctif, soiffard, souffreteux.</p>"
}
},
{
"name": "Ménestrel (barde/poète)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Ménestrel (barde/poète)</h1><p>Artistes itinérants, les ménestrels chantent des chansons, jouent de la musique, récitent des poèmes, racontent des fables et des légendes. Ils inventent souvent leurs propres contes ou apprennent des histoires fameuses auxquelles ils ne manquent pas dapporter leur touche personnelle. Certains ménestrels n errent pas de ville en ville pour exercer leur art, mais sont attachés au service de quelque noble et fortuné personnage qui les garde auprès de lui pour le divertir.</p><p>Ces artistes sont toujours heureux de jouer pour un large public et de récolter quelques piécettes pour leur effort. Certains ménestrels étendent leurs talents au jonglage et à la prestidigitation, ce qui peut être une bonne couverture pour un personnage qui est aussi voleur. Comme ils voyagent beaucoup et sont aussi doués pour écouter que pour captiver les foules par leurs récits, ils connaissent de nombreuses légendes anciennes et ont une bonne connaissance du monde et des événements qui agitent les cités. Les ménestrels sont souvent de grands séducteurs ; ils ont un don certain pour savoir trouver les mots qui toucheront le cœur des belles.</p><h2>Attributs</h2><p>la carrière de ménestrel exige un bon score daura, ainsi quune bonne dose dagilité et un esprit aiguisé.</p><h2>À laventure</h2><p>les ménestrels sont itinérants, ce qui les expose forcément aux dangers de la route. Certains choisissent daccompagner des soldats et des aventuriers afin de connaître eux-mêmes lexcitation de laventure et de créer des récits épiques basés sur ce quils auront vécu.</p><h2>Combat</h2><p>la carrière de ménestrel n est pas à la base une carrière martiale, et celle-ci naccordera de bonus au combat que dans de rares situations. Un tour de passe-passe ou une diversion pourra éventuellement permettre à un ménestrel de surprendre son adversaire, ou plus probablement lui offrir une chance de prendre ses jambes à son cou.</p><h2>Idées dAvantages</h2><p>artiste, attirant, beau parleur, érudit, fêtard, inspirateur, maître du déguisement, ouïe fine, outillage (instrument de musique), perspicace.</p><h2>Idées de Désavantages</h2><p>arrogant, chétif, lubrique, non-combattant, soiffard.</p>"
}
},
{
"name": "Mercenaire (brigand/guerrier)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Mercenaire (brigand/guerrier)</h1><p>Les mercenaires sont des guerriers qui louent leurs services au plus offrant. Certains sassemblent en troupes sous lautorité dun chef respecté, tandis que dautres voyagent seuls ou en petits groupes à la recherche dun employeur.</p><p>Ces petites bandes se tournent fréquemment vers le brigandage quand elles se retrouvent trop longtemps sans engagement. Toutes les cités de Lémurie ont déjà fait appel à des mercenaires pour mener leurs guerres et la profession a encore de beaux jours devant elle. Rudes guerriers, bons cavaliers pour certains, les mercenaires savent se montrer intimidants, entretenir leurs armes et leur équipement et se débrouiller pour vivre à la dure en pleine nature. En ville, ils fréquentent assidûment tavernes et tripots.</p><h2>Attributs</h2><p>pour sadonner au métier des armes, les mercenaires doivent posséder de bonnes prédispositions en vigueur et en agilité.</p><h2>À laventure</h2><p>par nature, les mercenaires sont des vagabonds qui parcourent la Lémurie en quête dun nouvel engagement. Même en temps de paix, ils trouvent à semployer pour escorter les caravanes marchandes, participer à des expéditions de chasseurs de trésor, ou servir de gardes du corps pour la noblesse.</p><h2>Combat</h2><p>les mercenaires sont connus pour se battre dautant mieux que la paie est bonne, et pour mettre peu de cœur à louvrage (voire tourner casaque) quand ils sont mal payés ou abusés. Au combat, un mercenaire pourra recevoir un bonus de carrière ponctuel si sa paie est particulièrement satisfaisante.</p><h2>Idées dAvantages</h2><p>arme favorite, bagarreur, baudrier de guerre, combat à laveugle, cri de guerre, dur à cuire, fêtard, inspirateur, né en selle, récupération rapide, vigilant.</p><h2>Idées de Désavantages</h2><p>cupide, fanfaron, impétueux, lubrique.</p>"
}
},
{
"name": "Noble (aristocrate/courtisan)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Noble (aristocrate/courtisan)</h1><p>Ces personnages, qui portent généralement un titre de noblesse (sans forcément le mériter), jouissent dune certaine autorité sur les gens du peuple, les paysans et les esclaves. Ils possèdent souvent de belles propriétés en ville ou des villas dans la campagne environnante, sont en mesure dobtenir des prêts monétaires, disposent de contacts haut placés, connaissent les règles de létiquette et savent shabiller avec élégance. La vie de courtisan développe également leurs talents pour ce qui est du mensonge, du chantage et de lintimidation.</p><h2>Attributs</h2><p>les nobles ont besoin dune aura forte ainsi que dun esprit vif, même si, en fin de compte, cest bien souvent la richesse qui dicte sa loi.</p><h2>À laventure</h2><p>les nobles nont pas de goût particulier pour laventure, même sil arrive quils financent des expéditions lointaines à la recherche dartefacts anciens ou montent des opérations de négoce. Certains nobles audacieux se joignent parfois à ces expéditions afin den assumer eux-mêmes la direction.</p><h2>Combat</h2><p>une carrière de noble apportera rarement un avantage au combat. Toutefois, des paysans ou des gens du bas peuple pourront, selon les circonstances, manifester des réticences à sen prendre à un de leurs supérieurs. Les nobles se retrouvent souvent comme commandants à la tête darmées, quils en aient les qualités ou pas.</p><h2>Idées dAvantages</h2><p>amis haut placés, attirant, bien né, fortuné, inspirateur, né en selle.</p><h2>Idées de Désavantages</h2><p>addiction, arrogant, cupide, fanfaron, gars de la ville, impétueux, lubrique.</p>"
}
},
{
"name": "Ouvrier (docker, manœuvre)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Ouvrier (docker, manœuvre)</h1><p>Les ouvriers sont les travailleurs manuels, ceux qui montent les palissades, creusent les fossés, construisent les maisons, édifient les remparts et les temples, chargent et déchargent les chariots et les bateaux. Ils se déplacent souvent au gré des emplois, dont beaucoup sont saisonniers ou temporaires. Les ouvriers sont habitués à travailler dur et à porter de lourdes charges ; ils savent aussi tenir lalcool et sy entendent en intimidation. Certaines des tâches queffectuent les ouvriers sont parfois confiées à des esclaves.</p><h2>Attributs</h2><p>une forte vigueur est utile aux travailleurs de force que sont les ouvriers.</p><h2>À laventure</h2><p>le labeur des ouvriers est monotone et pas vraiment propice à laventure. Un personnage qui possède cette carrière na pas dû lexercer très longtemps.</p><h2>Combat</h2><p>les ouvriers ne sont pas vraiment des combattants, même sils ont tendance à régler les disputes à coups de poing. Ils peuvent recevoir un bonus lors dune bagarre, notamment quand il sagit de saisir ou détrangler leur adversaire.</p><h2>Idées dAvantages</h2><p>bagarreur, colosse, dur à cuire, fêtard, intimidant, outillage, résistant aux poisons, vigueur céruléenne.</p><h2>Idées de Désavantages</h2><p>dur doreille, illettré, impétueux, incapable de mentir, inquiétant, lubrique, pataud, phobie, soiffard, taciturne.</p>"
}
},
{
"name": "Pilote des airs",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Pilote des airs</h1><p>Les pilotes des airs représentent lélite des combattants de Satarla. Formés au pilotage et à lentretien des nefs volantes, ce sont aussi des navigateurs et des observateurs expérimentés qui remplissent de nombreuses missions en tant quéclaireurs, explorateurs ou messagers. Ce sont généralement danciens soldats, souvent dorigine noble.</p><h2>Attributs</h2><p>esprit et agilité sont très utiles à un pilote des airs, ainsi que vigueur, dans une moindre mesure.</p><h2>À laventure</h2><p>un pilote des airs est par essence un casse-cou et quiconque est passé par cette carrière manifeste forcément un goût pour laventure.</p><h2>Combat</h2><p>un pilote des airs aura toujours un avantage au combat contre un adversaire peu familier des nefs volantes, à condition bien sûr que laffrontement ait lieu en plein ciel.</p><h2>Idées dAvantages</h2><p>amis haut placés, arme favorite, athlète, bien né, fortuné, inspirateur, marqué par les dieux, vue perçante.</p><h2>Idées de Désavantages</h2><p>arrogant, fanfaron, gars de la ville, impétueux.</p>"
}
},
{
"name": "Prêtre (druide/chaman)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Prêtre (druide/chaman)</h1><p>Au sein des temples que lon rencontre dans toutes les grandes cités de Lémurie, les prêtres dirigent le culte rendu aux dieux et sont les interprètes de la volonté divine. Ce sont des lettrés instruits en théologie, en savoir antique et en langues anciennes, en astrologie et en astronomie. Leur fonction leur confère un statut particulier au sein de la cité, et ils jouissent dune forte influence sur les affaires politiques, mais aussi sur larmée et la population en général.</p><p>Les druides rendent un culte aux Seigneurs Sombres et sont moins « fréquentables », notamment du fait quils pratiquent les sacrifices humains.</p><p>Vous trouverez davantage dinformations sur les prêtres au chapitre 6.</p><h2>Attributs</h2><p>les prêtres ont surtout besoin dun esprit aiguisé, mais les meilleurs dentre eux ont également laura nécessaire pour attirer les fidèles en nombre.</p><h2>À laventure</h2><p>certains prêtres mènent une vie particulièrement aventureuse, toujours en quête de savoirs anciens ou de reliques liées à leurs dieux. Dautres préfèrent une vie plus paisible et ne quittent que rarement la sécurité de leur temple.</p><h2>Combat</h2><p>une carrière de prêtre napporte aucun avantage au combat, si ce nest éventuellement lors dun affrontement face à des adversaires superstitieux qui hésiteront à sen prendre à un serviteur des dieux.</p><h2>Idées dAvantages</h2><p>amis haut placés, beau parleur, érudit, inspirateur, marqué par les dieux, perspicace, résistant à la magie, savant, sentir la magie.</p><h2>Idées de Désavantages</h2><p>addiction, arrogant, fanatique, foie jaune, malédiction de Morgazzon, méfiance envers la sorcellerie, non-combattant, obsession.</p><h2>Langues</h2><p>les prêtres et les druides doivent apprendre le démonique sils veulent pouvoir utiliser les puissantes créations magiques et alchimiques de lantique race des Rois-Sorciers. Ce langage est particulièrement ardu et ses formes orale et écrite exigent dêtre apprises séparément.</p>"
}
},
{
"name": "Scribe (érudit/copiste)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Scribe (érudit/copiste)</h1><p>Savants et pédagogues, les scribes sont pourvus dune solide érudition qui couvre une large variété de sujets. Ils sont mathématiciens, cartographes, astronomes, linguistes, historiens et philosophes. Certains se chargent plus spécifiquement de la tâche fastidieuse de copier les manuscrits anciens. Les scribes sont aussi des débatteurs de talent, habitués aux discussions passionnées entre beaux esprits. Il va sans dire que les scribes savent lire et écrire.</p><h2>Attributs</h2><p>lesprit est lattribut essentiel pour un scribe.</p><h2>À laventure</h2><p>les scribes font dordinaire de piètres aventuriers, mais il peut être très utile pour un groupe davoir avec lui un personnage aussi érudit.</p><h2>Combat</h2><p>même si les scribes aiment à rappeler que « la plume est plus forte que lépée », il y a peu de situations où cette carrière pourra être dune quelconque utilité au combat.</p><h2>Idées dAvantages</h2><p>bibliothèque savante, érudit, savant.</p><h2>Idées de Désavantages</h2><p>chétif, foie jaune, gars de la ville, incapable de mentir, non-combattant, obsession.</p>"
}
},
{
"name": "Soldat (garde/milicien)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Soldat (garde/milicien)</h1><p>Les soldats sont les combattants professionnels payés pour garder les remparts dune cité ou constituer les armées des rois. Stoïques, habitués à obéir aux ordres, ce ne sont pas les plus imaginatifs des guerriers. Les soldats, qui peuvent être aussi de bons cavaliers, savent se montrer intimidants et jouissent dune certaine autorité, surtout quand ils sont officiers. Ils connaissent bien la cité quils servent, ainsi que la rude vie des camps militaires.</p><h2>Attributs</h2><p>la vigueur est normalement lattribut essentiel pour un soldat, mais les archers et les cavaliers auront besoin dune bonne agilité. Les officiers doivent avoir de laura pour diriger leurs hommes et un esprit aiguisé pour établir de solides plans de bataille.</p><h2>À laventure</h2><p>la plupart des soldats manquent dinspiration et de fantaisie pour faire de bons aventuriers. En revanche, le temps passé à larmée permet à un personnage daffûter ses talents martiaux en attendant de repartir à laventure.</p><h2>Combat</h2><p>les soldats pourront parfois bénéficier dun bonus de carrière au combat, notamment sils se battent selon une tactique établie, au sein dune unité bien commandée.</p><h2>Idées dAvantages</h2><p>arme favorite, athlète, bagarreur, dur à cuire, fêtard, inspirateur, né en selle, récupération rapide.</p><h2>Idées de Désavantages</h2><p>crédule, dur doreille, fanfaron, lubrique, soiffard, taciturne.</p>"
}
},
{
"name": "Sorcier (magicien/enchanteur)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Sorcier (magicien/enchanteur)</h1><p>Les sorciers sont à la fois craints et respectés. Personne ne les fréquente volontiers à moins dune absolue nécessité car, dans leur grande majorité, ce sont des êtres immoraux et déséquilibrés, quand ils ne sont pas totalement déments et malfaisants. Les sorciers vivent généralement seuls, uniquement entourés de quelques serviteurs ou dun apprenti. Ils sadonnent à létude de sciences ésotériques comme lastrologie, lastronomie et la démonologie, recherchent fiévreusement dantiques manuscrits interdits renfermant un savoir occulte, quand ils ne concluent pas des pactes avec les démons afin dapprendre des mots de pouvoir capables de façonner le tissu de la réalité.</p><p>Beaucoup sont originaires de Zalut, la cité des magiciens, mais on trouve des sorciers de moindre envergure dans presque toutes les grandes cités de Lémurie (à exception de Tyrus, où ils sont proscrits). Vous trouverez davantage dinformations sur les sorciers au chapitre 6.</p><h2>Attributs</h2><p>les sorciers ont besoin dun esprit fort, à la fois pour mener leurs études et pour être en mesure de lancer des sorts puissants.</p><h2>À laventure</h2><p>les sorciers ne font pas de bons aventuriers, préférant déléguer ce genre de choses à leurs sbires et à leurs serviteurs. Mais il arrive parfois quils quittent leur antre pour prendre part eux-mêmes à une expédition dont ils espèrent quelque gain mystique dimportance.</p><h2>Combat</h2><p>rares sont les circonstances où le fait dêtre sorcier offre un avantage durant un combat utilisant des armes ordinaires. Mais cela importe peu, car les sorciers talentueux nont pas besoin de savoir manier une épée pour venir à bout dun adversaire.</p><h2>Carrière dangereuse</h2><p>la sorcellerie est un moyen rapide dobtenir du pouvoir, mais elle a un prix. Pour chaque rang de cette carrière au-delà du premier, vous devez choisir un désavantage supplémentaire (cf. chapitre 5). Cela sapplique également si vous choisissez daugmenter votre rang de sorcier plus tard dans le jeu, par lutilisation de points dexpérience.</p><h2>Idées dAvantages</h2><p>bibliothèque savante, érudit, magie des Rois-Sorciers, perspicace, pouvoir du Néant, résistant à la magie, savant.</p><h2>Idées de Désavantages</h2><p>addiction, arrogant, distrait, indigne de confiance, inquiétant, malédiction de Morgazzon, mauvaise réputation, non-combattant, obsession, phobie, signe distinctif, souffreteux.</p><h2>Langues</h2><p>les sorciers doivent apprendre le démonique sils veulent pouvoir utiliser les puissantes créations magiques et alchimiques de lantique race des Rois-Sorciers. Ce langage est particulièrement ardu et ses formes orale et écrite exigent dêtre apprises séparément.</p>"
}
},
{
"name": "Tentatrice (courtisane/serveuse)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Tentatrice (courtisane/serveuse)</h1><p>Certaines personnes ont élevé la séduction au rang dart. La tentatrice peut être la maîtresse dun noble, une prostituée, ou une simple serveuse de taverne (qui, peut-être, fait les poches des clients distraits par ses charmes), mais dans tous les cas elle sait utiliser son pouvoir sur les hommes pour arriver à ses fins. Elle est aussi dangereuse quelle est belle, car cest le genre de femme pour laquelle les hommes se battent et les guerres éclatent. Une tentatrice est passée maîtresse dans lart de la manipulation et de la séduction.</p><p>N.B. Barbarians of Lemuria étant conçu pour évoquer les thèmes et lambiance des histoires classiques de Sword & Sorcery, cette carrière est présentée au féminin, mais peut très bien être prise par un personnage masculin, selon les circonstances.</p><h2>Attributs</h2><p>laura est lattribut le plus important pour une tentatrice. Lagilité et lesprit sont également utiles.</p><h2>À laventure</h2><p>les tentatrices ne sont dhabitude pas très aventureuses (du moins en dehors dun lit !), et il faudra donc que dautres carrières viennent expliquer ce choix peu probable dune vie itinérante à courir le danger.</p><h2>Combat</h2><p>cette carrière est rarement utile au combat, encore quune tentatrice puisse utiliser son rang dans cette carrière pour distraire des gardes, par exemple.</p><h2>Idées dAvantages</h2><p>amis dans la pègre, amis haut placés, attirant, beau parleur, discret, doigts de fée, fêtard, inspirateur.</p><h2>Idées de Désavantages</h2><p>chétif, gars de la ville, impétueux, lent à la détente, lubrique, noncombattant.</p>"
}
},
{
"name": "Voleur (filou/crapule)",
"img": "/systems/bol/ui/icons/career.webp",
"type": "feature",
"data": {
"subtype": "career",
"description": "<h1>Voleur (filou/crapule)</h1><p>Votre personnage est tombé dans le crime, à moins quil nait commencé sa vie comme gamin des rues obligé de voler pour survivre. Quoi quil en soit, il possède certains talents, que beaucoup jugent peu recommandables. Les voleurs savent grimper aux murs et crocheter les serrures, se faufiler discrètement, faire les poches des passants, monter des arnaques ou tricher aux jeux de hasard. Ils savent aussi se renseigner sur ce qui se passe en ville et appartiennent parfois à une « guilde », une organisation qui réunit les criminels de la cité.</p><h2>Attributs</h2><p>les voleurs ont besoin dune bonne agilité, mais aussi dun esprit aiguisé.</p><h2>À laventure</h2><p>les bons voleurs font des recrues de choix pour les aventuriers prévoyant dexplorer des temples ou des tombeaux renfermant des trésors protégés par des pièges et de solides serrures.</p><h2>Combat</h2><p>en général, les voleurs cherchent plutôt à éviter le combat. Ils peuvent bénéficier dun bonus de carrière quand ils cherchent à prendre la poudre descampette, surtout face aux gardes de la cité.</p><h2>Idées dAvantages</h2><p>amis dans la pègre, discret, doigts de fée, fêtard, gamin des rues, ouïe fine, outillage (outils de voleur), roi de lévasion, vigilant, vision nocturne.</p><h2>Idées de Désavantages</h2><p>cupide, gars de la ville, illettré, indigne de confiance, mauvaise réputation, poltron, souffreteux, traqué.</p>"
}
}
]

492
data/fr/json/equipment.json Normal file
View File

@ -0,0 +1,492 @@
[
{
"name": "Amure légère",
"img": "/systems/bol/ui/icons/armor.webp",
"type": "item",
"data": {
"subtype": "armor",
"description": "<h1>Amure légère</h1><p>Si votre personnage préfère éviter les combats mais sait quil risque de ne pas y couper, vous souhaiterez peut-être quil bénéficie au moins dune petite protection. La catégorie des armures légères comprend les différentes sortes darmures de cuir et les chemises de mailles. Votre personnage pourrait ainsi porter un robuste gilet et des brassards en cuir, ou un pourpoint doublé, accompagné de bottes et de gants en cuir souple. À moins que vous ne décidiez quil soit vêtu dune légère chemise de mailles et de rien dautre.</p><p>Une armure légère est généralement dissimulable (à moins dêtre inspecté de près ou davoir affaire à lœil exercé dun soldat vétéran) et ne vous désigne pas au premier regard comme un guerrier.</p><h2>Effets des armures légères</h2><ul><li>protection d6-3 (0-3 points de réduction des dégâts) ;</li><li>si vous préférez un chiffre fixe, une armure légère offre 1 point de protection ;</li><li>le port dune armure légère handicape un sorcier et augmente de 1 point de pouvoir le coût de ses sorts.</li></ul>",
"properties": {
"equipable": true,
"protection": true,
"armor": true,
"concealable": true,
"modifiers": {
"social": true,
"agility": -1,
"powercost": 1
},
"soak": {
"formula": "d6-3",
"value": 1
}
}
}
},
{
"name": "Armure moyenne",
"img": "/systems/bol/ui/icons/armor.webp",
"type": "item",
"data": {
"subtype": "armor",
"description": "<h1>Armure moyenne</h1><p>Ce type darmure, compromis entre la maniabilité de larmure légère et la protection de larmure lourde, est le choix favori des aventuriers qui sattendent à affronter des combats de manière régulière. Il peut sagir dune armure de cuir couvrant la majeure partie du corps, avec des parties en cuir bouilli pour protéger les points vitaux, ou dune armure mêlant le cuir et la cotte de mailles, ou encore dune cuirasse en acier, simple mais efficace.</p><p>Un personnage portant une armure moyenne peut généralement en ôter certaines parties pour la transformer en armure légère sil le souhaite.</p><h2>Effets des armures moyennes</h2><ul><li>protection d6-2 (0-4 points de réduction des dégâts) ;</li><li>si vous préférez un chiffre fixe, une armure moyenne offre 2 points de protection ;</li><li>le port dune armure moyenne saccompagne dun malus de -1 en agilité du fait de lencombrement ;</li><li>le port dune armure moyenne handicape un sorcier et augmente de 2 points de pouvoir le coût de ses sorts.</li></ul>",
"properties": {
"equipable": true,
"protection": true,
"armor": true,
"modifiers": {
"social": true,
"agility": -1,
"powercost": 2
},
"soak": {
"formula": "d6-2",
"value": 2
}
}
}
},
{
"name": "Armure lourde",
"img": "/systems/bol/ui/icons/armor.webp",
"type": "item",
"data": {
"subtype": "armor",
"description": "<h1>Armure lourde</h1><p>Ce type darmure est porté par des gladiateurs, des chevaliers partant à la guerre, ou par ceux prévoyant de participer à une bataille sanglante dans un proche avenir. Ce n est pas une armure que lon peut porter la journée entière, et encore moins pour voyager ou sadonner aux activités ordinaires du quotidien. Il peut sagir dun haubert de mailles descendant jusquaux genoux ou dune cuirasse en acier, complétée de grèves et de gantelets, ou encore dune brigandine (une veste de cuir cousue de plaques de métal) avec gantelets et hautes bottes.</p><p>Un personnage portant une armure lourde peut généralement ôter certaines parties de celle-ci pour la transformer en armure moyenne sil le souhaite.</p><p>Les personnages ayant moins de 0 en vigueur ne peuvent pas porter darmure lourde (ils ne sont pas assez robustes pour supporter un pareil attirail).</p><h2>Effets des armures lourdes</h2><ul><li>protection d6-1 (0-5 points de réduction des dégâts) ;</li><li>si vous préférez un chiffre fixe, une armure lourde offre 3 points de protection ;</li><li>le port dune armure lourde saccompagne dun malus de -2 en agilité du fait de l encombrement ;</li><li>le port dune armure lourde handicape un sorcier et augmente de 3 points de pouvoir le coût de ses sorts.</li></ul>",
"properties": {
"equipable": true,
"protection": true,
"armor": true,
"modifiers": {
"social": true,
"agility": -2,
"powercost": 3
},
"soak": {
"formula": "d6-1",
"value": 1
}
}
}
},
{
"name": "Casque",
"img": "/systems/bol/ui/icons/helm.webp",
"type": "item",
"data": {
"subtype": "helm",
"description": "<h1>Casque</h1><p>Si vous êtes équipé dun casque, celui-ci ajoute +1 à la protection de votre armure, dans le cas où vous en portez une. Si vous portez par exemple une armure légère et un casque, votre dé de protection sera égal à d6-2 (d6-1 en armure moyenne et d6 en armure lourde).</p><p>En revanche, un casque vous inflige un malus à linitiative (il est plus difficile de remarquer ce qui se passe autour de vous avec un casque qui limite votre champ de vision), ainsi que dans certaines situations sociales.</p><p>En général, un héros ne porte pas son casque en permanence et ne le met que lorsquil se prépare au combat.</p>",
"properties": {
"equipable": true,
"protection": true,
"helm": true,
"modifiers": {
"social": true,
"init": -1
},
"soak": {
"formula": "+1",
"value": 1
}
}
}
},
{
"name": "Petit bouclier",
"img": "/systems/bol/ui/icons/shield.webp",
"type": "item",
"data": {
"subtype": "shield",
"description": "<h1>Petit bouclier</h1><p>Un personnage ne peut bénéficier de son bouclier que sil est conscient de lattaque qui le vise, et donc sil est prêt à la parer.</p>",
"properties": {
"equipable": true,
"protection": true,
"shield": true,
"blocking": {
"malus": -1,
"nbAttacksPerRound": "1"
}
}
}
},
{
"name": "Grand bouclier",
"img": "/systems/bol/ui/icons/shield.webp",
"type": "item",
"data": {
"subtype": "shield",
"description": "<h1>Grand bouclier</h1><p>Un personnage ne peut bénéficier de son bouclier que sil est conscient de lattaque qui le vise, et donc sil est prêt à la parer.</p>",
"properties": {
"equipable": true,
"protection": true,
"shield": true,
"modifiers": {
"agility": -1
},
"blocking": {
"malus": -1,
"nbAttacksPerRound": "1"
}
}
}
},
{
"name": "Arme dhast",
"type": "item",
"img": "/systems/bol/ui/icons/axe.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Arme dhast</h1><p>ce nom recouvre une catégorie darmes possédant toutes un fer destiné à frapper, fixé au bout dune longue hampe en bois, qui offre à son utilisateur une grande allonge. Selon leur forme, ces armes à deux mains portent le nom de hallebarde, coutille, guisarme, vouge…</p>",
"properties": {
"melee": true,
"weapon": true,
"equipable": true,
"2H": true,
"damage": "d6B"
}
}
},
{
"name": "Bâton",
"type": "item",
"img": "/systems/bol/ui/icons/staff.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Bâton</h1><p>une longueur de bois robuste (environ 1,80 m de hauteur), qui sert aussi bien de bâton de marche que darme.</p>",
"properties": {
"melee": true,
"weapon": true,
"equipable": true,
"2H": true,
"bashing": true,
"damage": "d6"
}
}
},
{
"name": "Dague",
"type": "item",
"img": "/systems/bol/ui/icons/dagger.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Dague</h1><p>cette catégorie regroupe toutes les lames courtes destinées à lacérer ou poignarder un adversaire. Les dagues sont à un ou deux tranchants selon les modèles, et peuvent être lancées aussi bien quutilisées au corps à corps. Facilement dissimulable, la dague est larme favorite des truands et des assassins.</p>",
"properties": {
"melee": true,
"weapon": true,
"equipable": true,
"stackable": true,
"concealable": true,
"throwable": true,
"range": 3,
"damage": "d6M"
}
}
},
{
"name": "Épée",
"type": "item",
"img": "/systems/bol/ui/icons/sword.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Épée</h1><p>larme favorite des héros. Elle se décline en différents modèles utilisés un peu partout en Lémurie, comme les sabres dabordage, les tulwars, les cimeterres ou les épées longues. Inscrivez le nom de larme que vous voulez sur la fiche de votre personnage en fonction de limage que vous vous faites de ce dernier. Mais au final, une épée reste une longue lame utilisée pour tuer lennemi.</p>",
"properties": {
"melee": true,
"weapon": true,
"equipable": true,
"damage": "d6"
}
}
},
{
"name": "Épée à deux mains",
"type": "item",
"img": "/systems/bol/ui/icons/sword.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Épée à deux mains</h1><p>Une lourde épée pouvant mesurer jusquà 1,80 m de long pour les plus grandes, et sutilisant à deux mains. Elle peut porter différents noms selon les modèles : claymore, espadon, épée bâtarde…</p>",
"properties": {
"melee": true,
"weapon": true,
"equipable": true,
"2H": true,
"damage": "d6B"
}
}
},
{
"name": "Hâche à deux mains",
"type": "item",
"img": "/systems/bol/ui/icons/axe.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Hâche à deux mains</h1><p>Une lourde hache sutilisant à deux mains.</p>",
"properties": {
"melee": true,
"weapon": true,
"equipable": true,
"2H": true,
"damage": "d6B"
}
}
},
{
"name": "Fléau",
"type": "item",
"img": "/systems/bol/ui/icons/mace.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Fléau</h1><p>un fléau consiste en un manche de bois prolongé dune chaîne, à lextrémité de laquelle est fixée une boule hérissée de pointes métalliques. Les fléaux ne sont pas des armes employées couramment en Lémurie, mais les gladiateurs en utilisent parfois dans les arènes. Les attaques au fléau ignorent le bonus en défense accordé par lemploi dun bouclier.</p>",
"properties": {
"melee": true,
"weapon": true,
"equipable": true,
"ignoreshield": true,
"damage": "d6"
}
}
},
{
"name": "Gourdin",
"type": "item",
"img": "/systems/bol/ui/icons/mace.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Gourdin</h1><p>cest larme la plus rudimentaire qui soit. Un gourdin consiste généralement en un bâton de bois noueux, extrêmement dur et mesurant moins de 90 cm de long. Par commodité, on regroupe sous ce terme toute autre arme contondante du même genre (matraque, etc.). Il est possible dutiliser un gourdin pour infliger des dégâts non létaux et assommer son ennemi plutôt que de le tuer.</p>",
"properties": {
"melee": true,
"weapon": true,
"equipable": true,
"bashing": true,
"damage": "d6M"
}
}
},
{
"name": "Hache",
"type": "item",
"img": "/systems/bol/ui/icons/axe.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Hache</h1><p>un fer à un ou deux tranchants (qui peut être en bronze, en fer ou en acier) monté sur un manche en bois.</p>",
"properties": {
"melee": true,
"weapon": true,
"equipable": true,
"throwable": true,
"range": 3,
"damage": "d6"
}
}
},
{
"name": "Lance",
"type": "item",
"img": "/systems/bol/ui/icons/spear.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Lance</h1><p>une hampe de bois de 1,80 m de long (parfois davantage), pourvue dune pointe, qui peut être lancée ou utilisée au corps à corps, notamment contre des adversaires montés.</p>",
"properties": {
"melee": true,
"weapon": true,
"equipable": true,
"throwable": true,
"range": 6,
"damage": "d6"
}
}
},
{
"name": "Masse darmes",
"type": "item",
"img": "/systems/bol/ui/icons/mace.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Masse darmes</h1><p>cette arme a la même forme quun gourdin, mais possède une tête en métal, souvent agrémentée de pointes ou dailettes pour plus defficacité. Les masses darmes à une main peuvent se lancer, mais à courte distance, car elles ne sont pas vraiment prévues pour cet usage.</p>",
"properties": {
"melee": true,
"weapon": true,
"equipable": true,
"throwable": true,
"range": 1.5,
"damage": "d6"
}
}
},
{
"name": "Massue",
"type": "item",
"img": "/systems/bol/ui/icons/mace.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Massue</h1><p>la version lourde du gourdin. Une massue consiste en un solide manche en bois dont lextrémité, plus volumineuse, sert à fracasser le crâne de ses adversaires, doù son autre nom de casse-tête.</p>",
"properties": {
"melee": true,
"weapon": true,
"equipable": true,
"throwable": true,
"range": 3,
"damage": "d6"
}
}
},
{
"name": "Morgenstern",
"type": "item",
"img": "/systems/bol/ui/icons/mace.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Morgenstern</h1><p>une grosse boule de métal hérissée de pointes, montée à lextrémité dune longue hampe de 1,20 à 1,50 m de long. Rudimentaire, mais efficace.</p>",
"properties": {
"melee": true,
"weapon": true,
"equipable": true,
"2H": true,
"damage": "d6B"
}
}
},
{
"name": "Rapière",
"type": "item",
"img": "/systems/bol/ui/icons/sword.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Rapière</h1><p>cette épée fine et légère est essentiellement utilisée par les bellâtres et les courtisans des cités-états de Lémurie, chez qui lescrime a été élevé au rang dart. La rapière sutilise généralement en conjonction avec une dague de parade (aussi appelée main gauche), un petit bouclier, ou une simple cape roulée en boule.</p>",
"properties": {
"melee": true,
"weapon": true,
"equipable": true,
"damage": "d6M"
}
}
},
{
"name": "Arbalète",
"type": "item",
"img": "/systems/bol/ui/icons/crossbow.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Arbalète</h1><p>une arme de tir qui nécessite peu dentraînement et offre beaucoup de puissance. Les lourds projectiles tirés par une arbalète portent le nom de carreaux. Il faut un round complet pour charger une arbalète.</p>",
"properties": {
"equipable": true,
"2h": true,
"ranged": true,
"reloadable": true,
"weapon": true,
"damage": "d6",
"range": 30,
"reload": 1
}
}
},
{
"name": "Arbalète lourde",
"type": "item",
"img": "/systems/bol/ui/icons/crossbow.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Arbalète lourde</h1><p>plus lourde et plus puissante quune arbalète normale, larbalète lourde est peu usitée en Lémurie, sauf comme arme de siège portative. Il faut 2 rounds complets pour charger une arbalète lourde.</p>",
"properties": {
"equipable": true,
"2h": true,
"ranged": true,
"reloadable": true,
"weapon": true,
"damage": "d6B",
"range": 45,
"reload": 2
}
}
},
{
"name": "Arc",
"type": "item",
"img": "/systems/bol/ui/icons/bow.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Arc</h1><p>une longue tige flexible en bois dont les extrémités sont reliées par une corde et qui permet de tirer des flèches. Il existe différentes formes darcs.</p>",
"properties": {
"equipable": true,
"2h": true,
"ranged": true,
"reloadable": true,
"weapon": true,
"damage": "d6",
"range": 22,
"reload": 0
}
}
},
{
"name": "Bâton-Fronde",
"type": "item",
"img": "/systems/bol/ui/icons/sling.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Bâton-Fronde</h1><p>Version plus puissante de la fronde, montée au bout dun bâton (ce qui en fait une arme à deux mains), qui permet des tirs à plus longue portée.</p>",
"properties": {
"equipable": true,
"2h": true,
"ranged": true,
"reloadable": true,
"weapon": true,
"damage": "d6M",
"range": 18,
"reload": 0
}
}
},
{
"name": "Fronde",
"type": "item",
"img": "/systems/bol/ui/icons/sling.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Fronde</h1><p>simple pièce de cuir équipée de lanières, une fronde permet de projeter de petites pierres ou des billes de plomb avec une certaine force. Cest une arme peu coûteuse et facile à fabriquer. Il existe une version plus puissante, montée au bout dun bâton (ce qui en fait une arme à deux mains), qui permet des tirs à plus longue portée.</p>",
"properties": {
"equipable": true,
"ranged": true,
"reloadable": true,
"weapon": true,
"damage": "d6M",
"range": 9,
"reload": 0
}
}
},
{
"name": "Javelot",
"type": "item",
"img": "/systems/bol/ui/icons/thrown.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Javelot</h1><p>une arme de jet constituée dune courte hampe surmontée dune tête pointue. En général, un guerrier qui utilise le javelot en emporte deux ou trois avec lui. Cette arme a la faveur des hommes-oiseaux de lAxos.</p>",
"properties": {
"equipable": true,
"stackable": true,
"ranged": true,
"throwable": true,
"damage": "d6M",
"range": 6
}
}
},
{
"name": "Fléchettes",
"type": "item",
"img": "/systems/bol/ui/icons/thrown.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Fléchettes</h1><p>de petits projectiles ressemblant à des flèches miniatures, destinés à être lancés à la main. En général, un personnage qui utilise des fléchettes en possède un petit stock.</p>",
"properties": {
"equipable": true,
"stackable": true,
"ranged": true,
"throwable": true,
"weapon": true,
"damage": "d6M",
"range": 6
}
}
}
]

389
data/fr/json/flaws.json Normal file
View File

@ -0,0 +1,389 @@
[
{
"name": "Addiction",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Addiction</h1><p>vous avez développé une dépendance à une substance, et vous en avez besoin de manière quotidienne pour vivre normalement. Si vous passez une journée sans assouvir votre vice, vous subissez un dé de malus sur tous vos jets.</p>"
}
},
{
"name": "Âgé",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Âgé</h1><p>votre personnage na plus vingt ans. Sil ne dispose pas chaque jour dune période décente de repos, il commence à se fatiguer et subit un dé de malus pour toute action physique éreintante. Ce désavantage devrait aussi offrir bien dautres situations cocasses au cours de la partie.</p>"
}
},
{
"name": "Arrogant",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Arrogant</h1><p>vous subissez un dé de malus lorsque vous interagissez avec des provinciaux ou des étrangers, qui pourraient prendre ombrage de votre arrogance. Ce désavantage est très fréquent au sein de la noblesse.</p>"
}
},
{
"name": "Bigleux",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Bigleux</h1><p>lorsque vous faites appel à votre vue pour observer ou repérer quelque chose, vous subissez un dé de malus.</p>"
}
},
{
"name": "Borgne/oreille coupée",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Borgne/oreille coupée</h1><p>vous subissez un dé de malus quand le MJ estime que cela est approprié à la situation.</p>"
}
},
{
"name": "Bouseux",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Bouseux</h1><p>la grande ville est un endroit déstabilisant et impitoyable pour les nouveaux venus. Vous subissez un dé de malus dans les situations concernant la survie en milieu urbain.</p>"
}
},
{
"name": "Chétif",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Chétif</h1><p>vous ne jouissez pas dune solide constitution. Ôtez 2 points à votre score de vitalité.</p>"
}
},
{
"name": "Crédule",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Crédule</h1><p>vous gobez les mensonges les plus gros. Vous subissez un dé de malus quand quelquun essaie de vous convaincre quune idée est bonne, alors quelle ne lest pas.</p>"
}
},
{
"name": "Cupide",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Cupide</h1><p>vous êtes incapable de résister à une occasion de vous enrichir. Sil y a une chance de se remplir les poches, vous perdez tout bon sens. Vous subissez un dé de malus à chaque fois que vous êtes tenté par une offre alléchante.</p>"
}
},
{
"name": "Deux mains gauches",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Deux mains gauches</h1><p>vous subissez un dé de malus pour crocheter une serrure, tirer à larc ou à larbalète, ou accomplir toute autre tâche de précision requérant une bonne dextérité.</p>"
}
},
{
"name": "Distrait",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Distrait</h1><p>vous nêtes pas forcément stupide en fait, vous pouvez même être brillant mais vous êtes tête-en-lair, incapable de vous souvenir de vos obligations ou du nom des gens. Un défaut que le MJ se fera un plaisir dexploiter de temps à autre au détriment de votre personnage…</p>"
}
},
{
"name": "Dur doreille",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Dur doreille</h1><p>lorsque vous faites appel à votre audition pour percevoir quelque chose, vous subissez un dé de malus.</p>"
}
},
{
"name": "Fanatique",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Fanatique</h1><p>ce désavantage est plus fréquent chez les rivaux que chez les héros. Beaucoup dhommes sont prêts à mourir pour leur foi, mais un fanatique est prêt à tuer pour elle. Vous subissez un dé de malus à chaque fois que vous essayez de vous montrer courtois envers un infidèle.</p>"
}
},
{
"name": "Fanfaron",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Fanfaron</h1><p>vous avez une très haute opinion de vous-même et ressentez le besoin de la partager avec le reste du monde. Vous avez tendance à vous attribuer le mérite qui revient à dautres et à exagérer vos propres exploits tout en minimisant le rôle que vos compagnons ont pu jouer. Inutile de le dire, vous prenez de grandes libertés avec la vérité, ce qui pourrait vous valoir dêtre traité de menteur.</p>"
}
},
{
"name": "Foie jaune : quand les épées sont tirées, vous connaissez toujours un moment dindécision. Lancez un d3",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Foie jaune : quand les épées sont tirées, vous connaissez toujours un moment dindécision. Lancez un d3</h1><p>cest le nombre de rounds où vous restez paralysé par la situation, incapable dagir autrement quen effectuant des actions défensives.</p>"
}
},
{
"name": "Gars de la ville",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Gars de la ville</h1><p>vous nêtes pas à votre aise dans les grands espaces naturels. Vous subissez un dé de malus dans les situations concernant la survie en milieu sauvage.</p>"
}
},
{
"name": "Illettré",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Illettré</h1><p>vous ne savez ni lire ni écrire, et ne pouvez pas choisir de carrière exigeant dêtre lettré.</p>"
}
},
{
"name": "Impétueux",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Impétueux</h1><p>vous vous laissez souvent emporter par votre colère et réagissez à la moindre insulte, réelle ou supposée. Vous subissez un dé de malus pour vous efforcer de contrôler votre colère et dagir rationnellement, par exemple pour éviter de faire un esclandre en plein bal au palais, ou pour ignorer la raillerie dun ennemi. Votre colère peut vous mettre en danger, en vous incitant par exemple à vous battre en duel pour des motifs futiles.</p>"
}
},
{
"name": "Inadapté à la chaleur",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Inadapté à la chaleur</h1><p>vous êtes extrêmement sensible à la chaleur. Vous subissez un dé de malus sur toutes les actions entreprises dans un environnement de grande chaleur.</p>"
}
},
{
"name": "Inadapté au froid",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Inadapté au froid</h1><p>vous êtes particulièrement sensible au froid. Vous subissez un dé de malus sur toutes les actions entreprises dans un environnement de grand froid.</p>"
}
},
{
"name": "Incapable de mentir",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Incapable de mentir</h1><p>que ce soit par nervosité ou par respect dun code de lhonneur strict, vous êtes un très mauvais menteur. Vous subissez un dé de malus à chaque fois que vous essayez de tromper autrui, de dire des demi-vérités ou de cacher une information à quelquun qui vous pose une question directe. Vous êtes du genre à répondre « je ne vous dirai rien » plutôt que « je ne vois pas de quoi vous voulez parler ».</p>"
}
},
{
"name": "Indigne de confiance",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Indigne de confiance</h1><p>vous subissez un dé de malus quand la situation exige que quelquun vous croie ou vous fasse confiance.</p>"
}
},
{
"name": "Inquiétant",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Inquiétant</h1><p>il y a quelque chose en vous qui perturbe les autres. Cela peut provenir de votre regard, de votre odeur ou de votre façon de parler. Même les animaux vous évitent. Vous subissez un dé de malus dans les interactions sociales ou quand vous tentez damadouer des animaux.</p>"
}
},
{
"name": "Lent à la détente",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Lent à la détente</h1><p>vous nêtes jamais très vigilant à ce qui se passe autour de vous et vous êtes lent à réagir face au danger. Vous subissez un dé de malus sur vos jets de réaction.</p>"
}
},
{
"name": "Lubrique",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Lubrique</h1><p>vous avez le plus grand mal à résister aux charmes du sexe opposé et subissez un dé de malus sur vos jets pour ne pas succomber à un joli minois.</p>"
}
},
{
"name": "Malédiction de Morgazzon",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Malédiction de Morgazzon</h1><p>vous êtes atteint de démence. Vous devrez travailler avec le MJ pour déterminer la façon dont votre folie se manifeste.</p>"
}
},
{
"name": "Manchot/unijambiste",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Manchot/unijambiste</h1><p>vous subissez un dé de malus quand le MJ estime que cela est approprié à la situation.</p>"
}
},
{
"name": "Marin deau douce",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Marin deau douce</h1><p>vous subissez un dé de malus pour toute activité entreprise à bord dun navire.</p>"
}
},
{
"name": "Maudit",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Maudit</h1><p>les dieux se sont détournés de vous, ou alors cest que vous êtes tout simplement malchanceux. Pour une raison incompréhensible, les tuiles tombent toujours sur vous. Les gardes de la ville vous prennent pour un criminel recherché, la servante de la taverne que vous avez attirée dans votre lit se révèle être une princesse en fuite, vous marchez sur une petite branche qui se brise avec un craquement sonore juste au moment où vous alliez réussir à passer discrètement, etc. En dautres termes, vous commencez le jeu avec 1 point dhéroïsme en moins.</p>"
}
},
{
"name": "Mauvaise réputation",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Mauvaise réputation</h1><p>vous avez commis dans le passé quelque méfait de sinistre mémoire. Peu importe si vous êtes réellement coupable ou pas, ou si vous aviez une bonne raison dagir comme vous lavez fait, vous êtes précédé par votre mauvaise réputation. Vous subissez un dé de malus dans les interactions sociales où il sagit de faire bonne impression, et continuez à subir ce malus jusquà ce que vous ayez (re)gagné la confiance de la personne en question.</p>"
}
},
{
"name": "Méfiance envers la sorcellerie",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Méfiance envers la sorcellerie</h1><p>vous subissez un dé de malus quand vous êtes confronté à des sorciers et des alchimistes.</p>"
}
},
{
"name": "Muet",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Muet</h1><p>vous êtes incapable de parler, et vous subissez toujours un dé de malus dans les interactions sociales où vous avez besoin de vous faire comprendre.</p>"
}
},
{
"name": "Non-combattant",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Non-combattant</h1><p>vous nêtes pas un guerrier, vos talents sont ailleurs. Vous ne disposez que de deux points (au lieu de quatre) à répartir dans les aptitudes de combat, mais vous débutez avec six points de carrière (au lieu de quatre). De plus, le coût en points dexpérience pour améliorer vos aptitudes de combat est doublé.</p>"
}
},
{
"name": "Obsession",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Obsession</h1><p>vous êtes totalement obsédé par quelque chose. Il peut sagir dun but, dune personne ou dun objet. Vous consacrez beaucoup de temps, dénergie et dargent à cette obsession. À chaque fois que vous vous trouvez en présence de lobjet de votre obsession, vous subissez un dé de malus sur tous les jets qui impliquent que vous lignoriez. Il peut arriver que votre obsession vous plonge dans des situations inextricables ou cocasses.</p>"
}
},
{
"name": "Pataud",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Pataud</h1><p>vous navez pas un bon sens de léquilibre. Vous subissez un dé de malus à chaque fois que léquilibre entre en jeu, par exemple pour traverser un précipice sur une passerelle étroite, ou prendre pied sur une saillie à flanc de montagne.</p>"
}
},
{
"name": "Phobie",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Phobie</h1><p>vous êtes affligé dune peur irrationnelle. Vous subissez un dé de malus en présence de lobjet de votre phobie. Il peut sagir par exemple de la peur du feu, des reptiles, des araignées, des hauteurs, de la foule, de la mort, de lobscurité, des espaces confinés, des navires volants, etc.</p>"
}
},
{
"name": "Poltron",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Poltron</h1><p>ce nest pas un désavantage très fréquent chez les héros, mais vous avez les pires difficultés à contrôler votre peur. Vous subissez un dé de malus sur les jets destinés à résister aux effets de la peur ou de lintimidation. De plus, vous faites toujours de votre mieux pour éviter toute forme de conflit.</p>"
}
},
{
"name": "Repoussant",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Repoussant</h1><p>vous êtes particulièrement laid. Vous subissez un dé de malus dans les situations où lapparence peut avoir son importance.</p>"
}
},
{
"name": "Signe distinctif",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Signe distinctif</h1><p>il y a quelque chose chez vous qui ne soublie pas. Il peut sagir dune cicatrice particulière ou dun tatouage, à moins que vous ne soyez né avec six doigts à la main gauche. Bref, vous possédez une caractéristique physique qui se remarque. Vous subissez un dé de malus quand vous essayez de vous déguiser ou de passer inaperçu. Si vous êtes également affligé du désavantage traqué, les chasseurs de primes et les espions ont deux fois plus de chances de vous repérer quand vous entrez ou sortez dune cité.</p>"
}
},
{
"name": "Soiffard",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Soiffard</h1><p>quand vous êtes chargé dune tâche importante par vos compagnons, lancez un dé. Si vous obtenez un 1, vous êtes ivre et incapable de faire quoi que ce soit jusquà ce que vous ayez dessoûlé.</p>"
}
},
{
"name": "Souffreteux",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Souffreteux</h1><p>vous souffrez dune constitution fragile. Vous ne pouvez récupérer de points de vitalité perdus que si vous bénéficiez de soins médicaux ; vous ne récupérez rien par du simple repos, comme cest normalement la règle.</p>"
}
},
{
"name": "Taciturne",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Taciturne</h1><p>votre personnage est incroyablement taiseux. Les jours où il prononce une phrase de plus de trois mots sont à marquer dune pierre blanche, et il est très rare quil engage de lui-même la conversation. Son extrême réticence à parler implique malheureusement quil ne donne jamais une information si on ne la lui demande pas. Vous subissez un dé de malus dans les interactions sociales.</p>"
}
},
{
"name": "Traqué",
"type": "feature",
"img": "/systems/bol/ui/icons/flaw.webp",
"data": {
"subtype": "flaw",
"description": "<h1>Traqué</h1><p>vous êtes recherché par les autorités, ou bien vous avez offensé un aristocrate puissant ou un roi des pirates. Quoi quil en soit, vous devez constamment échapper à leurs agents qui tentent de vous capturer ou de vous tuer. Lancez un d6 à chaque fois que vous entrez dans une ville nouvelle. Sur un 1, les agents à la solde de votre ennemi (ou cet ennemi lui-même) vous auront repéré et vous tomberont dessus.</p>"
}
}
]

128
data/fr/json/languages.json Normal file
View File

@ -0,0 +1,128 @@
[
{
"name": "Argot des mers",
"type": "feature",
"img": "/systems/bol/ui/icons/language.webp",
"data": {
"subtype": "language",
"description": "<h1>Argot des mers</h1><p>les îles du Crâne, à la population hétéroclite en provenance des quatre coins du monde, ont développé leur propre langue, un assemblage bigarré dinfluences diverses. Il nen existe pas de forme écrite.</p>"
}
},
{
"name": "Axien",
"type": "feature",
"img": "/systems/bol/ui/icons/language.webp",
"data": {
"subtype": "language",
"description": "<h1>Axien</h1><p>laxien est la langue des tribus barbares qui vivent dans la chaîne de lAxos. Cette langue reste plutôt confinée à cette région montagneuse, mais on raconte que danciens textes datant de lépoque lointaine où laxien était plus largement répandu seraient entreposés dans des grottes oubliées au cœur des montagnes.</p>"
}
},
{
"name": "Beshaari",
"type": "feature",
"img": "/systems/bol/ui/icons/language.webp",
"data": {
"subtype": "language",
"description": "<h1>Beshaari</h1><p>les nomades du désert de Beshaar parlent et écrivent leur propre langue. La plupart des habitants dHalakh parlent le beshaari en plus du lémurien.</p>"
}
},
{
"name": "Céruléen",
"type": "feature",
"img": "/systems/bol/ui/icons/language.webp",
"data": {
"subtype": "language",
"description": "<h1>Céruléen</h1><p>les nomades bleus parlent leur propre langue, qui na pas de forme écrite. Les marchands dOomis apprennent souvent le céruléen.</p>"
}
},
{
"name": "Démonique",
"type": "feature",
"img": "/systems/bol/ui/icons/language.webp",
"data": {
"subtype": "language",
"description": "<h1>Démonique</h1><p>cest lancienne langue des RoisSorciers, dans laquelle sont rédigés tous les textes remontant à leur époque. Les magiciens, alchimistes, druides et prêtres doivent apprendre le démonique sils veulent pouvoir utiliser les puissants sortilèges et recettes alchimiques de cette antique race. Ce langage est particulièrement ardu et ses formes orale et écrite exigent dêtre apprises séparément. Les magiciens de Zalut conversent toujours en démonique, à moins de devoir parler à des étrangers.</p>"
}
},
{
"name": "Festreli",
"type": "feature",
"img": "/systems/bol/ui/icons/language.webp",
"data": {
"subtype": "language",
"description": "<h1>Festreli</h1><p>à lorigine, le festreli était un dialecte du lémurien, mais il sen est tellement éloigné quil est à présent devenu presque inintelligible pour des locuteurs du lémurien.</p>"
}
},
{
"name": "Grooth",
"type": "feature",
"img": "/systems/bol/ui/icons/language.webp",
"data": {
"subtype": "language",
"description": "<h1>Grooth</h1><p>il ne sagit pas dune langue à proprement parler, mais plutôt dun langage rudimentaire fait de grognements, de grimaces, de tapements du pied et de grands mouvements simiesques. Ce langage na pas de forme écrite et est totalement inusité en dehors des tribus des grooth.</p>"
}
},
{
"name": "Kashtien",
"type": "feature",
"img": "/systems/bol/ui/icons/language.webp",
"data": {
"subtype": "language",
"description": "<h1>Kashtien</h1><p>les habitants des marais de Kasht ont leur propre langue, dont chaque tribu utilise une variante qui lui est propre.</p>"
}
},
{
"name": "Lémurien",
"type": "feature",
"img": "/systems/bol/ui/icons/language.webp",
"data": {
"subtype": "language",
"description": "<h1>Lémurien</h1><p>la langue la plus communément parlée en Lémurie. Chaque cité parle cependant son propre dialecte lémurien, ce qui veut dire quun voyageur aura parfois du mal à comprendre les gens du coin. Le MJ pourra à loccasion vous demander de réussir un jet desprit pour communiquer avec des gens dautres cités que la vôtre.</p>"
}
},
{
"name": "Malakutien",
"type": "feature",
"img": "/systems/bol/ui/icons/language.webp",
"data": {
"subtype": "language",
"description": "<h1>Malakutien</h1><p>les habitants de Malakut et de la région environnante parlent leur propre langue.</p>"
}
},
{
"name": "Shamite",
"type": "feature",
"img": "/systems/bol/ui/icons/language.webp",
"data": {
"subtype": "language",
"description": "<h1>Shamite</h1><p>les habitants de Shamballah et de la région environnante parlent leur propre langue.</p>"
}
},
{
"name": "Chant du vent",
"type": "feature",
"img": "/systems/bol/ui/icons/language.webp",
"data": {
"subtype": "language",
"description": "<h1>Chant du vent</h1><p>la langue chantante des hommes-oiseaux peut évoquer tour à tour le son de la brise se faufilant entre les rochers escarpés des sommets et le sifflement des bourrasques sengouffrant dans les canyons montagneux et les cavernes. Cette langue est très difficile à parler correctement pour un étranger. Elle possède une forme écrite, qui est tout aussi difficile à maîtriser et à traduire.</p>"
}
},
{
"name": "Valgardien",
"type": "feature",
"img": "/systems/bol/ui/icons/language.webp",
"data": {
"subtype": "language",
"description": "<h1>Valgardien</h1><p>les gens du Valgard parlent et écrivent leur propre langue, qui est étonnamment élaborée.</p>"
}
},
{
"name": "Ygddari",
"type": "feature",
"img": "/systems/bol/ui/icons/language.webp",
"data": {
"subtype": "language",
"description": "<h1>Ygddari</h1><p>cest le nom de lancienne langue des hommes (aussi appelée langue des Anciens). Peu dindividus la parlent aujourdhui, et encore moins peuvent la lire. Il arrive cependant que dantiques textes soient retrouvés dans les ruines dYgddar, de Qiddesh, de Qeb, de Qar ou dOosal, mais leur traduction requiert généralement les services dun scribe particulièrement compétent.</p>"
}
}
]

232
data/fr/json/melee.json Normal file
View File

@ -0,0 +1,232 @@
[
{
"name": "Arme dhast",
"type": "item",
"img": "/systems/bol/ui/icons/weapon.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Arme dhast</h1><p>ce nom recouvre une catégorie darmes possédant toutes un fer destiné à frapper, fixé au bout dune longue hampe en bois, qui offre à son utilisateur une grande allonge. Selon leur forme, ces armes à deux mains portent le nom de hallebarde, coutille, guisarme, vouge…</p>",
"properties" : {
"melee": true,
"weapon" : true,
"equipable": true,
"2H" : true,
"damage" : "d6B"
}
}
},
{
"name": "Bâton",
"type": "item",
"img": "/systems/bol/ui/icons/weapon.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Bâton</h1><p>une longueur de bois robuste (environ 1,80 m de hauteur), qui sert aussi bien de bâton de marche que darme.</p>",
"properties" : {
"melee": true,
"weapon" : true,
"equipable": true,
"2H" : true,
"bashing" : true,
"damage" : "d6"
}
}
},
{
"name": "Dague",
"type": "item",
"img": "/systems/bol/ui/icons/weapon.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Dague</h1><p>cette catégorie regroupe toutes les lames courtes destinées à lacérer ou poignarder un adversaire. Les dagues sont à un ou deux tranchants selon les modèles, et peuvent être lancées aussi bien quutilisées au corps à corps. Facilement dissimulable, la dague est larme favorite des truands et des assassins.</p>",
"properties" : {
"melee": true,
"weapon" : true,
"equipable": true,
"stackable": true,
"concealable" : true,
"throwable" : true,
"range" : 3,
"damage" : "d6M"
}
}
},
{
"name": "Épée",
"type": "item",
"img": "/systems/bol/ui/icons/weapon.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Épée</h1><p>larme favorite des héros. Elle se décline en différents modèles utilisés un peu partout en Lémurie, comme les sabres dabordage, les tulwars, les cimeterres ou les épées longues. Inscrivez le nom de larme que vous voulez sur la fiche de votre personnage en fonction de limage que vous vous faites de ce dernier. Mais au final, une épée reste une longue lame utilisée pour tuer lennemi.</p>",
"properties" : {
"melee": true,
"weapon" : true,
"equipable": true,
"damage" : "d6"
}
}
},
{
"name": "Épée à deux mains",
"type": "item",
"img": "/systems/bol/ui/icons/weapon.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Épée à deux mains</h1><p>Une lourde épée pouvant mesurer jusquà 1,80 m de long pour les plus grandes, et sutilisant à deux mains. Elle peut porter différents noms selon les modèles : claymore, espadon, épée bâtarde…</p>",
"properties" : {
"melee": true,
"weapon" : true,
"equipable": true,
"2H" : true,
"damage" : "d6B"
}
}
},
{
"name": "Hâche à deux mains",
"type": "item",
"img": "/systems/bol/ui/icons/weapon.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Hâche à deux mains</h1><p>Une lourde hache sutilisant à deux mains.</p>",
"properties" : {
"melee": true,
"weapon" : true,
"equipable": true,
"2H" : true,
"damage" : "d6B"
}
}
},
{
"name": "Fléau",
"type": "item",
"img": "/systems/bol/ui/icons/weapon.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Fléau</h1><p>un fléau consiste en un manche de bois prolongé dune chaîne, à lextrémité de laquelle est fixée une boule hérissée de pointes métalliques. Les fléaux ne sont pas des armes employées couramment en Lémurie, mais les gladiateurs en utilisent parfois dans les arènes. Les attaques au fléau ignorent le bonus en défense accordé par lemploi dun bouclier.</p>",
"properties" : {
"melee": true,
"weapon" : true,
"equipable": true,
"ignoreshield" : true,
"damage" : "d6"
}
}
},
{
"name": "Gourdin",
"type": "item",
"img": "/systems/bol/ui/icons/weapon.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Gourdin</h1><p>cest larme la plus rudimentaire qui soit. Un gourdin consiste généralement en un bâton de bois noueux, extrêmement dur et mesurant moins de 90 cm de long. Par commodité, on regroupe sous ce terme toute autre arme contondante du même genre (matraque, etc.). Il est possible dutiliser un gourdin pour infliger des dégâts non létaux et assommer son ennemi plutôt que de le tuer.</p>",
"properties" : {
"melee": true,
"weapon" : true,
"equipable": true,
"bashing" : true,
"damage" : "d6M"
}
}
},
{
"name": "Hache",
"type": "item",
"img": "/systems/bol/ui/icons/weapon.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Hache</h1><p>un fer à un ou deux tranchants (qui peut être en bronze, en fer ou en acier) monté sur un manche en bois.</p>",
"properties" : {
"melee": true,
"weapon" : true,
"equipable": true,
"throwable" : true,
"range" : 3,
"damage" : "d6"
}
}
},
{
"name": "Lance",
"type": "item",
"img": "/systems/bol/ui/icons/weapon.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Lance</h1><p>une hampe de bois de 1,80 m de long (parfois davantage), pourvue dune pointe, qui peut être lancée ou utilisée au corps à corps, notamment contre des adversaires montés.</p>",
"properties" : {
"melee": true,
"weapon" : true,
"equipable": true,
"throwable" : true,
"range" : 6,
"damage" : "d6"
}
}
},
{
"name": "Masse darmes",
"type": "item",
"img": "/systems/bol/ui/icons/weapon.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Masse darmes</h1><p>cette arme a la même forme quun gourdin, mais possède une tête en métal, souvent agrémentée de pointes ou dailettes pour plus defficacité. Les masses darmes à une main peuvent se lancer, mais à courte distance, car elles ne sont pas vraiment prévues pour cet usage.</p>",
"properties" : {
"melee": true,
"weapon" : true,
"equipable": true,
"throwable" : true,
"range" : 1.5,
"damage" : "d6"
}
}
},
{
"name": "Massue",
"type": "item",
"img": "/systems/bol/ui/icons/weapon.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Massue</h1><p>la version lourde du gourdin. Une massue consiste en un solide manche en bois dont lextrémité, plus volumineuse, sert à fracasser le crâne de ses adversaires, doù son autre nom de casse-tête.</p>",
"properties" : {
"melee": true,
"weapon" : true,
"equipable": true,
"throwable" : true,
"range" : 3,
"damage" : "d6"
}
}
},
{
"name": "Morgenstern",
"type": "item",
"img": "/systems/bol/ui/icons/weapon.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Morgenstern</h1><p>une grosse boule de métal hérissée de pointes, montée à lextrémité dune longue hampe de 1,20 à 1,50 m de long. Rudimentaire, mais efficace.</p>",
"properties" : {
"melee": true,
"weapon" : true,
"equipable": true,
"2H" : true,
"damage" : "d6B"
}
}
},
{
"name": "Rapière",
"type": "item",
"img": "/systems/bol/ui/icons/weapon.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Rapière</h1><p>cette épée fine et légère est essentiellement utilisée par les bellâtres et les courtisans des cités-états de Lémurie, chez qui lescrime a été élevé au rang dart. La rapière sutilise généralement en conjonction avec une dague de parade (aussi appelée main gauche), un petit bouclier, ou une simple cape roulée en boule.</p>",
"properties" : {
"melee": true,
"weapon" : true,
"equipable": true,
"damage" : "d6M"
}
}
}
]

182
data/fr/json/origins.json Normal file
View File

@ -0,0 +1,182 @@
[
{
"name": "Côte de Feu",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Côte de Feu</h1><p>La Côte de Feu est le domaine où vit la Reine Sorcière, entourée de ses sentinelles kalukans. Si votre héros est originaire de la Côte de Feu, vous pouvez décider den faire un kalukan, à condition que le MJ lautorise. Dans ce cas, reportez-vous au chapitre 5 pour une liste des avantages/désavantages éligibles pour un personnage kalukan. Si vous choisissez plutôt dêtre un humain, utilisez les listes proposées pour Halakh ou les marais de Kasht.</p>"
}
},
{
"name": "Désert de Beshaar",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Désert de Beshaar</h1><p>Les Beshaaris sont des nomades qui chevauchent de gros oiseaux coureurs ressemblant à des autruches. Plutôt de petite taille, les Beshaaris ont une peau basanée qui a tendance à se rider profondément avec lâge en raison du soleil implacable du désert. Ils ont les yeux noirs, marron foncé, verts, violets ou pourpres. Chez eux, on rencontre plus souvent quailleurs des individus aux yeux vairons.</p><p>Les Beshaaris ont la réputation dêtre susceptibles et prompts à la colère. Ils possèdent des coutumes complexes et extrêmement codifiées quils respectent avec un scrupule sourcilleux ; une négociation avec les nomades du Beshaar est un exercice délicat où les occasions de commettre un impair sont nombreuses.</p><p>Lexotique beauté des jeunes filles beshaaries est célèbre, et celles capturées lors de raids contre les tribus nomades se retrouvent souvent vendues</p><p>comme esclaves ou danseuses. Plus dun homme impétueux a perdu la vie en se battant pour les faveurs dune séduisante vierge beshaarie.</p><p>Tous les personnages beshaaris doivent choisir barbare pour première carrière. À la chasse comme à la guerre, les guerriers beshaaris aiment à sarmer de longs javelots quils lancent depuis le dos de leurs montures.</p><h2>Avantages</h2><p>ami des bêtes, arme favorite (javelot), attirant, baudrier de guerre, né en selle, renard du désert, vision nocturne, vue perçante.</p><h2>Désavantages</h2><p>bouseux, chétif, impétueux, inadapté au froid, marin deau douce, signe distinctif, taciturne.</p><h2>Noms masculins</h2><p>Aban, Akar, Akon, Atak, Basit, Boulos, Darwish, Fath, Ferran, Harith, Jalid, Karim, Makil, Mujib, Nur, Sadin, Samad, Surk, Yazan.</p><h2>Noms féminins</h2><p>Alima, Almas, Ambre, Bisara, Dimah, Felina, Hilela, Husina, Isimi, Jamara, Judi, Kalila, Lula, Maysam, Mumi, Namara, Nuha, Qisa, Rua, Thara.</p>"
}
},
{
"name": "Halakh",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Halakh</h1><p>Les graciles Halakhis ont la peau brune, les cheveux noirs et les yeux sombres. Leur cité dans les montagnes est un important centre de commerce pour les nomades beshaaris, qui sont leurs proches cousins, et des marchands de toutes les contrées de Lémurie convergent en ce lieu. Les Halakhis portent souvent le kriss, un long poignard à la lame sinueuse, et il se murmure que cest à Halakh que lon trouve les meilleurs assassins.</p><h2>Avantages</h2><p>arme favorite (kriss), discret, montagnard, outillage, renard du désert, résistant aux poisons, vision nocturne.</p><h2>Désavantages</h2><p>addiction, fanatique, gars de la ville, indigne de confiance, marin deau douce.</p><h2>Noms masculins</h2><p>Angada, Balaram, Bhadrakil, Chalam, Chedi, Daruk, Devad, Drajit, Govardan, Iravan, Janak, Jiwal, Karna, Kichaka, Kurava, Maharak, Mapoutra, Parada, Parasara, Shoumat.</p><h2>Noms féminins</h2><p>Anjana, Ardana, Charla, Damayanti, Devaki, Gadiva, Hanala, Holi, Ilvala, Jasura, Kalindi, Kesha, Madri, Mashini, Nakula, Nala, Neta, Ralekha, Rasena, Vahana.</p>"
}
},
{
"name": "Îles du Crâne",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Îles du Crâne</h1><p>On trouve sur les îles du Crâne des gens originaires des quatre coins de Lémurie, qui forment le pire rassemblement de crapules et de forbans qui se puisse trouver. Les hommes y sont bien plus nombreux que les femmes, lesquelles restent souvent cantonnées au rôle de serveuses dans les tripots, même si certaines ont su se tailler une place parmi les pirates. Ceux qui viennent ici le font généralement pour deux raisons : lappel du large et la promesse du butin. Si votre héros vient des îles du Crâne, une de ses carrières doit être pirate.</p><h2>Avantages</h2><p>amis dans la pègre, athlète, bagarreur, discret, doigts de fée, fêtard, gamin des rues, pied marin, récupération rapide, roi de lévasion, vigilant, vue perçante.</p><h2>Désavantages</h2><p>borgne / oreille coupée, cupide, fanfaron, illettré, indigne de confiance, lubrique, malédiction de Morgazzon, manchot / unijambiste, maudit, phobie, poltron, signe distinctif, soiffard, traqué.</p><h2>Noms</h2><p>comme des gens de tous horizons se retrouvent ici, on y rencontre des noms provenant de toutes les contrées de Lémurie.</p>"
}
},
{
"name": "Jungle de Qo et jungle de Qush",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Jungle de Qo et jungle de Qush</h1><p>Si vous provenez de ces jungles impénétrables, vous serez certainement un grooth (cf. chapitre 5), mais demandez dabord laccord du MJ. Sinon, il existe quelques tribus humaines de barbares et de chasseurs installées à la lisière de la jungle. Si votre héros provient dune de ces tribus, utilisez la liste davantages/désavantages et les noms propres de Shamballah (cf. ci-après).</p>"
}
},
{
"name": "Lysor",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Lysor</h1><p>Les Lysoriens sont des gens paisibles et méditatifs. Alors que leur cité grouille détrangers affairés et bruyants, les natifs de Lysor tranchent par leur calme et leur attitude méditative, comme sils restaient insensibles à lagitation ambiante.</p><p>Les Lysoriens ont habituellement les cheveux blonds ou châtain clair et les yeux bleus ou verts, bien que les autres couleurs ne soient pas non plus inhabituelles. Ils affichent généralement un teint frais, légèrement hâlé, qui respire la santé. Lysor senorgueillit de compter les meilleurs guérisseurs et médecins de toute la Lémurie, même si les fiers Satarlans contestent cette assertion.</p><h2>Avantages</h2><p>amis haut placés, artiste, attirant, bibliothèque savante, érudit, fortuné, mains guérisseuses, perspicace, récupération rapide, résistant aux poisons, santé de fer, savant.</p><h2>Désavantages</h2><p>chétif, foie jaune, gars de la ville, incapable de mentir, lent à la détente, malédiction de Morgazzon, non-combattant.</p><h2>Noms masculins</h2><p>Aklaton, Bardak, Bazyli, Creon, Cyr, Dramik, Erechon, Jenko, Morgos, Myron, Otos, Skorpos, Vaston, Zedek, Zerro.</p><h2>Noms féminins</h2><p>Adara, Alesta, Cora, Dresina, Elma, Furka, Honna, Irusina, Jace, Letha, Megara, Melika, Nirla, Timandra, Uvikka, Vara, Zeva.</p>"
}
},
{
"name": "Malakut",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Malakut</h1><p>Les Malakutis ont une apparence qui leur confère souvent un air inquiétant. Plutôt frêles, le teint olivâtre et les cheveux noirs ou châtain foncé, ils ont les lèvres minces, de petits yeux et le nez aquilin. Deux redoutables guildes de voleurs sopposent à Malakut, les Guenillards et les Poignards Sanglants. Extrêmement puissantes au sein de la cité, les deux guildes étendent également leur influence aux villes voisines de la région. Malakut produit de fameuses lances au fer en forme de longue feuille de laurier, les khastoks, qui sont utilisées par la Garde royale jemadar. Si votre personnage est originaire de Malakut, il y a de fortes chances pour que sa première carrière soit voleur.</p><h2>Avantages</h2><p>amis dans la pègre, arme favorite (khastok), combat à laveugle, discret, doigts de fée, fêtard, fils des plaines, gamin des rues, outillage (outils de voleur), vigilant.</p><h2>Désavantages</h2><p>chétif, gars de la ville, indigne de confiance, marin deau douce, mauvaise réputation, traqué.</p><h2>Noms masculins</h2><p>Arfi, Badar, Crixas, Darzi, Erfan, Firdos, Gilki, Jandak, Krugar, Lodar, Midum, Nakum, Purdos, Qalader, Qatir, Qorbi, Ralak, Sardan, Tamar, Zemar.</p><h2>Noms féminins</h2><p>Adala, Azra, Bursebala, Coza, Daliya, Dua, Ethibela, Lamala, Mirvala, Norva, Qisi, Roshan, Sakina, Saran, Simi, Tala, Tikina, Wella, Xua, Zinah.</p>"
}
},
{
"name": "Marais de Festrel",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Marais de Festrel</h1><p>Les marais de Festrel hébergent une population clairsemée, car cette région est loin dêtre la plus hospitalière de Lémurie. Les hommes qui vivent ici cultivent leur isolement et, quand ils nont pas envie de se montrer aux étrangers, sont très difficiles à trouver. Petits et trapus, ils font preuve dune agilité étonnante et sont de formidables bateliers.</p><h2>Avantages</h2><p>athlète, bagarreur, discret, odorat développé, ouïe fine, pisteur des marais, résistant aux poisons, santé de fer, vigilant.</p><h2>Désavantages</h2><p>bouseux, illettré, inadapté à la chaleur, maudit, taciturne.</p><h2>Noms</h2><p>les habitants des marais de Festrel portent le même genre de noms que ceux de Parsool et dOomis.</p>"
}
},
{
"name": "Marais de Kasht",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Marais de Kasht</h1><p>Les habitants des marais de Kasht sont généralement petits et sveltes, avec des cheveux noirs et la peau pâle. Aussi silencieux et invisibles que des ombres, ils se déplacent à travers leur pays marécageux, empruntant des chemins secrets tracés par plusieurs générations de chasseurs, de trappeurs et de pêcheurs. Ils sont passés maîtres dans lart dutiliser leur environnement pour se camoufler et masquer leur odeur, afin dapprocher les créatures du marais quils chassent pour se nourrir.</p><h2>Avantages</h2><p>ami des bêtes, athlète, discret, odorat développé, ouïe fine, pisteur des marais, résistant aux poisons, santé de fer, vigilant.</p><h2>Désavantages</h2><p>bouseux, chétif, crédule.</p><h2>Noms masculins</h2><p>Achak, Ahmik, Akando, Akule, Ashok, Bidi, Chepi, Chetan, Ciqala, Dogon, Goth, Hinto, Hokee, Jolon, Keme, Knoton, Kourouk, Molimo, Tkala, Tkouna.</p><h2>Noms féminins</h2><p>Aiyana, Alawa, Atiaran, Bly, Camarin, Cathecassa, Chapala, Chimalis, Dena, Doli, Donoma, Etania, Kalama, Landina, Mitenah, Nitika, Onatah, Orenda, Zkala, Zkouna.</p>"
}
},
{
"name": "Montagnes de lAxos",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Montagnes de lAxos</h1><p>Les contreforts de ces montagnes sont habités par plusieurs tribus de farouches barbares. Blancs de peau, grands et athlétiques, ces éleveurs sont aussi dexcellents chasseurs et des grimpeurs réputés. Les hommes des tribus de lAxos mènent une vie fruste ; leur artisanat et leur art nutilisent que les matériaux que leurs offrent leurs montagnes, et cest également le cas pour leurs armes de chasse et de guerre.</p><p>Si vous êtes originaire des montagnes de lAxos, votre première carrière doit être barbare, et il ne serait pas étonnant que vous soyez aussi chasseur. Les tribus de lAxos sont réputées pour leur habileté à la fronde.</p><p>Les cimes de la chaîne de lAxos sont la demeure dun énigmatique peuple dhommesoiseaux (cf. chapitre 5).</p><h2>Avantages</h2><p>arme favorite (fronde de lAxos), athlète, colosse, cri de guerre, dur à cuire, montagnard, odorat développé, ouïe fine, récupération rapide, santé de fer, vigilant.</p><h2>Désavantages</h2><p>bouseux, illettré, inadapté à la chaleur, marin deau douce, méfiance envers la sorcellerie, taciturne.</p><h2>Noms masculins</h2><p>Almod, Amerik, Borc, Drogar, Erkil, Fiak, Finvar, Ginnar, Hakon, Krakar, Oslac, Rokar, Salgarth, Sungar, Thork, Thurkil, Travik, Vali, Vikar, Vogg.</p><h2>Noms féminins</h2><p>Arlin, Asta, Birla, Dalla, Emelle, Esja, Evenni, Finna, Forla, Froda, Gevi, Glevara, Herdis, Jodis, Jofa, Klima, Runa, Rym, Sivora, Varda.</p>"
}
},
{
"name": "Oomis",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Oomis</h1><p>Les Oomisiens sont généralement grands et solidement charpentés, avec les cheveux dun blanc argenté, des yeux de différentes nuances de bleu, des petites oreilles (à peine dessinées) et une peau présentant une légère teinte bleutée. Ces caractéristiques physiques amènent certains à se demander jusquoù va lamitié qui les lie aux nomades bleus…</p><p>Cest un peuple dhabiles négociants, et un personnage originaire dOomis prendra souvent marchand pour première carrière.</p><h2>Avantages</h2><p>ami des céruléens, dur à cuire, fortuné, perspicace.</p><h2>Désavantages</h2><p>cupide, dur doreille, lent à la détente, malédiction de Morgazzon.</p><h2>Noms masculins</h2><p>Aceld, Algeros, Curcio, Dalmar, Deston, Kaarlo, Norf, Quent, Rust, Sevrik, Vardon, Vik.</p><h2>Noms féminins</h2><p>Afrodille, Alix, Daisi, Dany, Delit, Jance, Jenina, Jessamin, Miette, Myrla, Questa.</p>"
}
},
{
"name": "Parsool",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Parsool</h1><p>La population de Parsool est très cosmopolite et lon y croise tous les types de morphologie et toutes les couleurs de peau. Les meilleurs marins de Lémurie viennent de Parsool. Un personnage originaire de cette cité prendra certainement marin parmi ses choix de carrières.</p><h2>Avantages</h2><p>arme favorite (hache dabordage de Parsool), cri de guerre (Parsool), fêtard, pied marin.</p><h2>Désavantages</h2><p>borgne/oreille coupée, gars de la ville, illettré, manchot/unijambiste, soiffard.</p><h2>Noms masculins</h2><p>Agroc, Bardhyl, Besmir, Dar, Driton, Erion, Jaak, Jeton, Jodoc, Juhan, Kalev, Koit, Lek, Loic, Nighul, Paol, Pavo, Ropar, Skender, Toomaas.</p><h2>Noms féminins</h2><p>Arvesa, Besa, Bora, Dritta, Eha, Genta, Kaias, Kaja, Leka, Liridona, Loviise, Marika, Mimiza, Mirjam, Reet, Riina, Rovena, Tuule, Viu, Zami.</p>"
}
},
{
"name": "Plaines de Klaar",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Plaines de Klaar</h1><p>Les plaines de Klaar sont la demeure des céruléens, une race de géants à la peau gris-bleu quon surnomme aussi les nomades bleus. Effrayants par leur taille, les céruléens ne sont pourtant pas un peuple particulièrement agressif. De fait, ce sont surtout dexcellents marchands.</p><p>Si votre personnage est un céruléen, vous devez choisir barbare comme première carrière. Votre deuxième carrière sera certainement marchand, puisque tous les enfants des nomades bleus apprennent dès leur plus jeune âge lart du négoce. Les carrières dalchimiste, de médecin, de scribe et de sorcier sont interdites aux céruléens. Chez eux, les prêtres sont appelés des chamans. Vous trouverez au chapitre 5 une liste des avantages/ désavantages pour un personnage céruléen, ainsi que quelques exemples de noms.</p>"
}
},
{
"name": "Satarla",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Satarla</h1><p>La cité de Satarla, quon surnomme le « Joyau de Lémurie », est un haut lieu de culture et de sophistication. Les Satarlans sont souvent plus grands que la moyenne, mais comme la ville accueille des gens de toutes origines, on y rencontre toutes les morphologies et toutes les couleurs de peau. Il est amusant de noter que ceux qui sinstallent ici ont tôt fait dadopter cet air supérieur qui semble commun à tous les natifs de Satarla. La mendicité y est interdite, aussi un personnage originaire de Satarla ne peut-il débuter avec une carrière de mendiant. Seuls les Satarlans peuvent choisir dadopter la carrière de pilote des airs. Les prouesses des chevaliers de Satarla sont légendaires.</p><h2>Avantages</h2><p>amis haut placés, artiste, bibliothèque savante, bien né, érudit, fortuné, marqué par les dieux, né en selle, savant.</p><h2>Désavantages : arrogant, cupide, gars de la ville. Noms masculins</h2><p>Alban, Avitus, Blasius, Brutor, Cassian, Corvin, Crisus, Drusus, Emilian, Festus, Gallus, Gord, Hilaro, Hort, Juven, Luman, Martis, Nonus, Petron, Regul, Rufin, Sabin, Severan, Terent, Torc, Vitan.</p><h2>Noms féminins</h2><p>Amilia, Arlana, Cassi, Cloel, Domitia, Fabula, Floriana, Gemellia, Junia, Laela, Laurenia, Manda, Marina, Nunia, Quina, Severina, Tullia, Valeria, Varinia, Vita.</p>"
}
},
{
"name": "Shamballah",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Shamballah</h1><p>Les natifs de Shamballah ont la peau mate, les cheveux foncés et des yeux violets, écarlates ou indigo. Ils ont des sens particulièrement affûtés et font dexcellents chasseurs.</p><h2>Avantages</h2><p>ami des bêtes, athlète, odorat développé, ouïe fine, roi de la jungle, vigilant, vue perçante.</p><h2>Désavantages</h2><p>bouseux, illettré, inadapté au froid, marin deau douce, méfiance envers la sorcellerie.</p><h2>Noms masculins</h2><p>Akri, Badran, Bello, Diallo, Donkor, Eze, Jaafar, Juma, Kamouzou, MBoutou, MDogo, Nasso, Ohin, Oulan, Rasoul, Simballa, Talib, Watimou, Zareb, Zouri.</p><h2>Noms féminins</h2><p>Afi, Bembel, Binta, Chipi, Damisi, Dayo, Elomi, Geli, Habika, Jahia, Lila, MLala, Panya, Sabra, Shani, Tabita, Tisha, Yousra, Zalika, Zina.</p>"
}
},
{
"name": "Terres Désolées",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Terres Désolées</h1><p>Personne ne sait grand-chose au sujet des Terres Désolées, et moins encore sur les contrées qui sétendraient au-delà. Des gens vivent assurément dans cette région, sil faut en croire les récits de chasseurs et dexplorateurs qui ont relevé des traces de présence. Mais à ce jour, personne na découvert le moindre village ou hameau, et on ignore tout de lapparence de leurs habitants.</p><p>Si votre héros est originaire des Terres Désolées, il vous faudra travailler avec le MJ pour déterminer à quoi ressemble votre personnage. Mais attendezvous à ce quil soit toujours considéré comme un étranger, où quil se rende en Lémurie.</p>"
}
},
{
"name": "Tyrus",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Tyrus</h1><p>Les habitants de la prospère cité fluviale de Tyrus ont la peau et les cheveux sombres, les yeux verts ou marron. Les soldats de Tyrus sont des archers fameux et les artisans de la ville produisent de magnifiques arcs longs. Les sorciers y sont proscrits.</p><h2>Avantages</h2><p>arme favorite (arc long de Tyrus), bagarreur, cri de guerre (Tyrus), fêtard, résistant à la magie, roi de la jungle, sentir la magie, vigilant.</p><h2>Désavantages</h2><p>fanfaron, gars de la ville, illettré, méfiance envers la sorcellerie, soiffard.</p><h2>Noms masculins</h2><p>Anxo, Baldo, Bartol, Bento, Dimas, Eloy, Ericos, Gaspar, Helder, Jorg, Mogos, Nuno, Ovanto, Pluco, Qido, Raul, Rui, Tacito, Thiago, Valen.</p><h2>Noms féminins</h2><p>Ana, Branca, Carmo, Desideria, Dorotana, Jovita, Judita, Kardelia, Lia, Lotia, Lygia, Miella, Nona, Rebeqa, Sabella, Tuvia, Uxia, Xania, Xoanna, Zeta.</p>"
}
},
{
"name": "Urceb",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Urceb</h1><p>Les habitants dUrceb sont des risque-tout, des joueurs et des opportunistes. Habitués à saventurer dans les souterrains qui sétendent sous leur cité, ils sont à leur aise dans les tunnels, les catacombes et les grottes.</p><h2>Avantages</h2><p>amis dans la pègre, amis haut placés, combat à laveugle, fêtard, outillage, roi de lévasion, vision nocturne.</p><h2>Désavantages : gars de la ville, illettré, taciturne. Noms masculins</h2><p>Ambros, Axel, Bodo, Curd, Dolf, Egond, Falkor, Golo, Hegbran, Jonar, Kurnvarn, Londar, Lothar, Mennus, Rudig, Sepp, Till, Torsten, Urs, Volkard.</p><h2>Noms féminins</h2><p>Alhella, Barbella, Crika, Dorlina, Erna, Frekka, Gusala, Hannelor, Jolanda, Karolinda, Letta, Lieselotte, Margita, Nadja, Pia, Resi, Seffi, Theda, Ursa, Uta.</p>"
}
},
{
"name": "Valgard",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Valgard</h1><p>Grands et musclés, arborant des tignasses blondes ou rousses, les Valgardiens vivent en tribus belliqueuses. Si votre personnage est originaire de Valgard, une de ses carrières doit être barbare. Les sorciers ou les alchimistes sont rares parmi les Valgardiens, sans être non plus totalement inédits.</p><h2>Avantages</h2><p>arme favorite (épée valgardienne), cri de guerre (Valgard), marqué par les dieux, odorat développé, récupération rapide, tigre des neiges.</p><h2>Désavantages</h2><p>bouseux, illettré, inadapté à la chaleur, incapable de mentir, marin deau douce, méfiance envers la sorcellerie, taciturne.</p><h2>Noms masculins</h2><p>Abrak, Ankar, Asvith, Banfar, Borkar, Broti, Craigor, Drakkar, Elkor, Fingor, Gonnar, Grimar, Hevik, Jark, Korik, Krok, Morkrar, Rokor, Thagric, Voldar.</p><h2>Noms féminins</h2><p>Adisa, Alvora, Asara, Berna, Brongara, Disa, Edarra, Erindis, Finnara, Fraorka, Gyllana, Hakatla, Helvera, Jarngera, Jodis, Jolinn, Kitta, Marfora, Rakela, Sesilida.</p>"
}
},
{
"name": "Zalut",
"type": "feature",
"img": "/systems/bol/ui/icons/origin.webp",
"data": {
"subtype": "origin",
"description": "<h1>Zalut</h1><p>Surnommée la cité des magiciens, Zalut est gouvernée par des sorciers, des prêtres et des alchimistes. Les Zalutis ont la peau très pâle (les albinos y sont moins rares quailleurs) et aiment à se raser le crâne. Ils cultivent leur isolement et la légende prétend quils seraient les derniers descendants des Rois-Sorciers.</p><p>En général, les personnages originaires de Zalut possèdent une de ces trois carrières susnommées, ou sont esclaves. Dautres choix de carrières restent toutefois possibles.</p><h2>Avantages</h2><p>érudit, intimidant, magie des RoisSorciers, pouvoir du Néant, résistant à la magie, résistant aux poisons, savant, sentir la magie, vision nocturne.</p><h2>Désavantages</h2><p>addiction, arrogant, chétif, foie jaune, indigne de confiance, inquiétant, malédiction de Morgazzon, maudit, obsession, poltron, signe distinctif, souffreteux.</p><h2>Noms masculins</h2><p>Ariistuzuun, Arsiuqqu, Balathu, Bashaa, Dadanuum, Hunzuu, Ikuppi, Libulluth, Nigsummu, Nikannuur, NurYunna, Nutesh, Puzzur, Rihaatu, Sargon, Suusaandar, Tattaanu, Yamazuubaar, Zorgal, Zuuthusu.</p><h2>Noms féminins</h2><p>Amatia, Ashlultum, Banuna, Gemeti, Iltani, Ishtaya, Jaarthula, Kishu, Ku-Aya, Nidintu, Numunia, Nuteshi, Sillashu, Sumia, Thuulia, Yadidatum, Zadia, Zakiti, Zemibi, Zorkara.</p>"
}
}
]

65
data/fr/json/races.json Normal file
View File

@ -0,0 +1,65 @@
[
{
"name": "Céruléens",
"img": "/systems/bol/ui/icons/race.webp",
"type": "feature",
"data": {
"subtype": "race",
"description": "<h1>Céruléens</h1><p>Malgré leur nom, les céruléens (aussi appelés les nomades bleus) ont plutôt la peau grise, avec des variations de teinte allant du gris-vert au gris-bleu, voire au gris-violet. Les mâles mesurent entre 2,20 et 2,50 m, mais certains peuvent atteindre jusquà 2,70 m. En moyenne, les femmes font une trentaine de centimètres de moins que les hommes et possèdent une silhouette moins massive queux. Tous sont généralement chauves.</p><p>Les céruléens parcourent les plaines de Klaar dans leurs grands chariots, au rythme lent des énormes banths qui les tirent. Cest une race farouche qui se mêle peu aux hommes, à part pour commercer de temps à autre avec certains marchands qui ont su gagner leur confiance, à Urceb ou Oomis. Il existe plusieurs grandes tribus et une vingtaine ou une trentaine de tribus mineures. Chacune possède son propre nom, que ses membres accolent à leur prénom. Voici les noms des tribus les plus connues : Hegga, Karvoona, Kazzorla, Chunth, Thazaar et Kozaar. Chaque tribu est dirigée par un chef et compte également un chaman, qui tient le rôle de chef spirituel et de médecin.</p><p>Malgré leur physique impressionnant, les céruléens ne sont pas un peuple particulièrement belliqueux, même sils ne manquent pas datouts pour le combat. Lorsque deux tribus saffrontent, ils vont à la bataille montés sur des eldaphons spécialement entraînés pour la guerre.</p><p>Les nomades bleus préfèrent le commerce à la guerre. La dernière semaine de chaque mois, différentes tribus se rassemblent dans les ruines dYgddar pour échanger des marchandises et retrouver de vieux amis. Certaines tribus sont en conflit et il arrive parfois que des rixes éclatent, mais ces périodes consacrées au commerce se déroulent en général dans une ambiance cordiale.</p><p>On raconte que les céruléens seraient le résultat dexpériences alchimiques menées par les Rois-Sorciers.</p><p>LEdda pourpre et dautres chroniques anciennes indiquent sans lombre dun doute que des géants à la peau bleue combattaient au côté des Rois-Sorciers à lépoque de Kylarth, comme du temps du roi Thangard. À la bataille du gouffre dHyrdral, le géant bleu Chunak mena ses frères à la révolte contre leurs maîtres reptiliens, quils massacrèrent en grand nombre avant que ceux-ci aient pu faire appel à toute la puissance de leur magie maléfique. Sans ce revirement des céruléens, il est probable que les Rois-Sorciers auraient remporté cette bataille.</p><p>Les céruléens nont aucune aptitude naturelle pour devenir sorciers ou alchimistes ; ces carrières leur sont donc interdites. Les prêtres des céruléens sont appelés des chamans et ils vénèrent principalement Quathoomar.</p><h2>Avantages</h2><p>ami des bêtes, ami des céruléens, bagarreur, colosse, dur à cuire, fils des plaines, intimidant, peau dure, récupération rapide, vigueur céruléenne.</p><h2>Désavantages</h2><p>bouseux, deux mains gauches, marin deau douce, méfiance envers la sorcellerie, pataud, signe distinctif.</p><h2>Noms masculins</h2><p>Bork, Chun, Dekk, Erkk, Fakk, Gort, Gozaar, Gurnt, Jaakko, Jank, Jouka, Jrycki, Kall, Kerrik, Kook, Koozo, Kukk, Lekk, Lozzar, Nukk, Penkk, Tarrk, Venk, Vilk, Vork.</p><h2>Noms féminins</h2><p>Akki, Bekka, Bezis, Danki, Eeva, Furka, Inka, Irka, Joona, Jurva, Kalli, Karis, Kella, Kooki, Krakki, Lazzis, Likka, Lovi, Marjukka, Marzi, Nukeel, Nukka, Oki, Rikki,Tharki.</p>"
}
},
{
"name": "Grooth",
"img": "/systems/bol/ui/icons/race.webp",
"type": "feature",
"data": {
"subtype": "race",
"description": "<h1>Grooth</h1><p>Les grooth sont une race dhommes primitifs anthropophages vivant dans de petits campements de huttes rudimentaires au cœur des jungles. À peine plus évolués que des singes, ils possèdent un corps trapu et puissant, de longs bras musculeux qui pendent presque jusquau sol et des jambes courtaudes et arquées. Ils ont un visage aux traits simiesques, de petits yeux rouges sous un front proéminent et de larges mâchoires aux canines inférieures remontant comme des crocs. Les grooth sarment de solides gourdins ainsi que de lances à pointe en silex, et se ceignent les reins dun pagne en peau danimal, seuls signes chez eux dun semblant de culture.</p><p>Si vous souhaitez jouer un grooth, vous ne pouvez choisir vos carrières de départ que parmi celles-ci : barbare, dresseur, esclavagiste, gladiateur, chasseur, guerrier, chaman (prêtre), esclave, ouvrier.</p><p>Tous les grooth ont automatiquement le désavantage illettré.</p><h2>Avantages</h2><p>bagarreur, colosse, dur à cuire, intimidant, odorat développé, ouïe fine, récupération rapide, roi de la jungle, vision nocturne.</p><h2>Désavantages</h2><p>bigleux, bouseux, deux mains gauches, distrait, impétueux, marin deau douce, maudit, méfiance envers la sorcellerie, phobie du feu, repoussant, signe distinctif, taciturne.</p><h2>Noms masculins et féminins</h2><p>Ak, Bruk, Cek, Dur, Erg, Fik, Grar, Hig, Ig, Jat, Kof, Lurt, Mak, Nin, Op, Prek, Quh, Rir, Sum, Tulk, Um, Vit, Wat, Zuk.</p>"
}
},
{
"name": "Hommes-oiseaux",
"img": "/systems/bol/ui/icons/race.webp",
"type": "feature",
"data": {
"subtype": "race",
"description": "<h1>Hommes-oiseaux</h1><p>Cette race mystérieuse et très secrète vit au cœur de vallées cachées dans les hauteurs des montagnes de lAxos. Les hommes-oiseaux sont élancés, agiles et très créatifs. Ils bâtissent leurs demeures dans des grottes et sur des corniches ; leurs ailes leur permettent de planer ou même de voler sur de courtes distances, à condition de ne pas être trop chargés. Leurs pieds présentent des serres semblables à celles doiseaux, qui leur permettent de grimper les parois rocheuses avec une grande aisance. Ce ne sont pas de grands guerriers et ils se servent essentiellement darmes de jet légères quils utilisent aussi bien à la chasse que pour défendre leur territoire. Les armures sont trop encombrantes et les empêcheraient de voler ; seuls les plus forts dentre eux séquipent en cas de danger de brassards, dun harnais et de jambières en cuir (léquivalent dune armure légère), ou utilisent un petit bouclier.</p><p>Si vous jouez un homme-oiseau, vous pouvez choisir nimporte quelle carrière, mais les carrières suivantes sont rares chez eux, et il vous faudra une bonne histoire pour expliquer ce choix : assassin, bourreau, gladiateur, marin, soldat, voleur, ouvrier, vagabond.</p><h2>Avantages</h2><p>agilité de lhomme-oiseau, ami des bêtes, arme favorite (fléchette), artiste, athlète, montagnard, vigilant, vision nocturne, vue perçante.</p><h2>Désavantages</h2><p>chétif, foie jaune, méfiance envers la sorcellerie, non-combattant, signe distinctif.</p><h2>Noms masculins</h2><p>Aaleevic, Aamaneeth, Aaneet, Cloonacool, Easreth, Eemenearl, Eveearic, Faerloec, Flaanaceel, Graaranic, Heael, Heoorl, Himeen, Hoorcaaarl, Iaoween, Jaoor, Laaric, Meerscaaarl, Nyaneeth, Oorlacooth, Raoeeth, Raor, Saamaneal, Soorth, Urllaanic.</p><h2>Noms féminins</h2><p>Aaroel, Aellaarree, Aerieena, Earraa, Eeleemeena, Evearilla, Flaermeena, Flitillia, Flooressa, Galaania, Gleeemaa, Gleesinra, Haorellee, Heelestraa, Iastreena, Ieliellaa, Ifeelea, Laeesa, Lolaandrea, Loornaea, Meerceena, Nyleea, Oorea, Raoreea, Seeorea.</p>"
}
},
{
"name": "Kalukans",
"img": "/systems/bol/ui/icons/race.webp",
"type": "feature",
"data": {
"subtype": "race",
"description": "<h1>Kalukans</h1><p>Les kalukans sont une race deunuques sans tête, qui possèdent un seul gros œil au centre de leur poitrine, derrière lequel se situe leur cerveau. Créés artificiellement par dantiques rituels alchimiques afin de servir de gardes à leurs maîtres (notamment contre dautres magiciens), ces êtres possèdent une force surhumaine et nont besoin ni de manger, ni de dormir.</p><p>Leur corps est couvert de tatouages investis dune puissante sorcellerie qui les maintient en vie. Ils sont asexués, même sils possèdent des corps musclés et proportionnés comme ceux dhommes adultes.</p><p>La Reine Sorcière de la Côte de Feu utilise des kalukans comme sentinelles dans sa forteresse, où ils veillent armés de ces grands cimeterres qui portent le nom de tulwars.</p><p>Les kalukans nont pas de bouche et sont donc incapables de parler, ce qui leur inflige un dé de malus dans les situations sociales où ils ont besoin de se faire comprendre. Ils ne possèdent pas non plus décriture, ce qui conduit certains à les prendre pour des brutes stupides.</p><p>En réalité, ils font preuve dune grande capacité dapprentissage et peuvent parfaitement apprendre à lire et écrire.</p><p>Tous les kalukans sont nés esclaves, les héros kalukans sont donc automatiquement esclaves pour leur première carrière, et gardes (soldats) ou ouvriers pour leur deuxième carrière. Le choix reste libre pour leurs autres carrières. Étrangement, peut-être parce quils sont eux-mêmes issus dune création alchimique, les kalukans manifestent parfois un grand talent pour la création de potions, dobjets et dinstruments quand ils ont loccasion dapprendre cet art. Les kalukans ne peuvent pas être ménestrels, marchands ou courtisans, et dautres carrières leur sont également difficiles daccès.</p><p>Tous les kalukans ont automatiquement le désavantage muet.</p><h2>Avantages</h2><p>arme favorite (tulwar), colosse, dur à cuire, intimidant, peau dure, récupération rapide, résistant à la magie, résistant aux poisons, santé de fer, sentir la magie, vigilant, vigueur céruléenne, vision nocturne.</p><h2>Désavantages</h2><p>deux mains gauches, illettré, inquiétant, maudit, pataud, signe distinctif.</p><p>Dordinaire, les kalukans nont pas de nom, mais il arrive quils reçoivent un surnom. Si vous jouez un héros kalukan, vous pouvez par exemple demander à un autre joueur (ou au MJ) de donner un surnom à votre personnage.</p>"
}
},
{
"name": "Morgal",
"img": "/systems/bol/ui/icons/race.webp",
"type": "feature",
"data": {
"subtype": "race",
"description": "<h1>Morgal</h1><p>Les morgal sont une race de vampires buveurs de sang qui peuvent vivre pendant des siècles (et peut-être même éternellement). Ils ressemblent au départ à des humains normaux, même sils sont particulièrement grands et pâles de peau. Mais à mesure quils prennent de lâge, les morgal perdent progressivement leur humanité et sombrent dans la démence. La couleur de leurs yeux peut aller du rouge au violet, voire au noir le plus profond. Leurs ongles poussent à une vitesse surnaturelle et à moins quun morgal ne prenne soin de les couper très régulièrement, il suffit dune semaine pour que ses mains soient griffues comme celles dune bête. Certains érudits pensent que les morgal seraient les rejetons dune lignée de Rois-Sorciers qui se serait séparée du reste de leur race dans un lointain passé.</p><h2>Avantages</h2><p>bibliothèque savante, dur à cuire, magie des Rois-Sorciers, perspicace, pouvoir du Néant, récupération rapide, résistant à la magie, savant, vision nocturne.</p><h2>Désavantages</h2><p>addiction, inquiétant, malédiction de Morgazzon, obsession, phobie du feu, poltron, signe distinctif.</p>"
}
},
{
"name": "Rois-Sorciers",
"img": "/systems/bol/ui/icons/race.webp",
"type": "feature",
"data": {
"subtype": "race",
"description": "<h1>Rois-Sorciers</h1><p>La race des Rois-Sorciers a dominé la Lémurie, et sans doute le monde entier, avant la venue de lhomme. Ils possédaient une force et une robustesse exceptionnelles, même sils nétaient pas particulièrement des guerriers. Ils étaient en revanche très intelligents et créatifs, et maîtrisaient une puissante sorcellerie qui tirait sa force dHadron et des autres seigneurs du Néant.</p><p>Les Rois-Sorciers furent détruits à la bataille du gouffre dHyrdral. Seuls quelques-uns dentre eux parvinrent à senfuir pour gagner lîle de Thulé, où leurs descendants vivraient encore de nos jours, dans la ville de Zalut, la cité des magiciens.</p><h2>Avantages</h2><p>beau parleur, bibliothèque savante, dur à cuire, magie des Rois-Sorciers, perspicace, pouvoir du Néant, récupération rapide, résistant à la magie, savant, vigueur céruléenne, vision nocturne.</p><h2>Désavantages</h2><p>addiction, arrogant, foie jaune, inquiétant, non-combattant, obsession, phobie, poltron, signe distinctif.</p><h2>Noms masculins</h2><p>Apuulluunideeszu, Kadashmasazz, Kiipluuu, Nigsummuzzugal, Niiqarquusu, Shamazzad, Shudduggaat, Shu-Thuzzul, Thusuzuu, Ugurnaszir, Vaargaxx, Xhaothigguzzar.</p><h2>Noms féminins</h2><p>Aplazza, Arishakka, Deemethresu, Labashi, Puzuri, Rihatzzi, Ripaazz, Selukzu, Utuala, Yaattirram, Yahattizzi, Zashimbra.</p>"
}
},
{
"name": "Slorth",
"img": "/systems/bol/ui/icons/race.webp",
"type": "feature",
"data": {
"subtype": "race",
"description": "<h1>Slorth</h1><p>Il est presque assuré que les slorth sont une création des Rois-</p><p>Sorciers. Ces serpents à tête de femme</p><p>résident habituellement dans les déserts de Beshaar, mais on peut également les rencontrer (plus exceptionnellement) dans les plaines de Klaar. Ce sont des êtres au corps de serpent blafard (presque incolore) et putride, surmonté dune tête de femme, belle et blanche de peau, aux dents effilées. Leur morsure est venimeuse et plonge la victime dans un profond sommeil.</p><h2>Avantages</h2><p>artiste, beau parleur, discret, fils des plaines, intimidant, odorat développé, peau dure, perspicace, renard du désert, résistant aux poisons, roi de lévasion, vigilant, vision nocturne.</p><h2>Désavantages</h2><p>inadapté au froid, indigne de confiance, inquiétant, maudit, signe distinctif.</p><h2>Noms</h2><p>Bashaa, Demetzri, Eneshu, Giléru, Ishmè, Labashi, Memorashi, Numunia, Salishmè, Tiggarati.</p>"
}
}
]

131
data/fr/json/ranged.json Normal file
View File

@ -0,0 +1,131 @@
[
, {
"name": "Arbalète",
"type": "item",
"img": "/systems/bol/ui/icons/crossbow.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Arbalète</h1><p>une arme de tir qui nécessite peu dentraînement et offre beaucoup de puissance. Les lourds projectiles tirés par une arbalète portent le nom de carreaux. Il faut un round complet pour charger une arbalète.</p>",
"properties" : {
"equipable" : true,
"2h" : true,
"ranged": true,
"reloadable" : true,
"weapon" : true,
"damage" : "d6",
"range" : 30,
"reload" : 1
}
}
},
{
"name": "Arbalète lourde",
"type": "item",
"img": "/systems/bol/ui/icons/crossbow.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Arbalète lourde</h1><p>plus lourde et plus puissante quune arbalète normale, larbalète lourde est peu usitée en Lémurie, sauf comme arme de siège portative. Il faut 2 rounds complets pour charger une arbalète lourde.</p>",
"properties" : {
"equipable" : true,
"2h" : true,
"ranged": true,
"reloadable" : true,
"weapon" : true,
"damage" : "d6B",
"range" : 45,
"reload" : 2
}
}
},
{
"name": "Arc",
"type": "item",
"img": "/systems/bol/ui/icons/bow.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Arc</h1><p>une longue tige flexible en bois dont les extrémités sont reliées par une corde et qui permet de tirer des flèches. Il existe différentes formes darcs.</p>",
"properties" : {
"equipable" : true,
"2h" : true,
"ranged": true,
"reloadable" : true,
"weapon" : true,
"damage" : "d6",
"range" : 22,
"reload" : 0
}
}
},
{
"name": "Bâton-Fronde",
"type": "item",
"img": "/systems/bol/ui/icons/sling.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Bâton-Fronde</h1><p>Version plus puissante de la fronde, montée au bout dun bâton (ce qui en fait une arme à deux mains), qui permet des tirs à plus longue portée.</p>",
"properties" : {
"equipable" : true,
"2h" : true,
"ranged": true,
"reloadable" : true,
"weapon" : true,
"damage" : "d6M",
"range" : 18,
"reload" : 0
}
}
},
{
"name": "Fronde",
"type": "item",
"img": "/systems/bol/ui/icons/sling.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Fronde</h1><p>simple pièce de cuir équipée de lanières, une fronde permet de projeter de petites pierres ou des billes de plomb avec une certaine force. Cest une arme peu coûteuse et facile à fabriquer. Il existe une version plus puissante, montée au bout dun bâton (ce qui en fait une arme à deux mains), qui permet des tirs à plus longue portée.</p>",
"properties" : {
"equipable" : true,
"ranged": true,
"reloadable" : true,
"weapon" : true,
"damage" : "d6M",
"range" : 9,
"reload" : 0
}
}
},
{
"name": "Javelot",
"type": "item",
"img": "/systems/bol/ui/icons/thrown.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Javelot</h1><p>une arme de jet constituée dune courte hampe surmontée dune tête pointue. En général, un guerrier qui utilise le javelot en emporte deux ou trois avec lui. Cette arme a la faveur des hommes-oiseaux de lAxos.</p>",
"properties" : {
"equipable" : true,
"stackable": true,
"ranged": true,
"throwable" : true,
"damage" : "d6M",
"range" : 6
}
}
},
{
"name": "Fléchettes",
"type": "item",
"img": "/systems/bol/ui/icons/thrown.webp",
"data": {
"subtype": "weapon",
"description": "<h1>Fléchettes</h1><p>de petits projectiles ressemblant à des flèches miniatures, destinés à être lancés à la main. En général, un personnage qui utilise des fléchettes en possède un petit stock.</p>",
"properties" : {
"equipable" : true,
"stackable": true,
"ranged": true,
"throwable" : true,
"weapon" : true,
"damage" : "d6M",
"range" : 6
}
}
}
]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 634 KiB

Binary file not shown.

Binary file not shown.

BIN
fonts/skullz.ttf Normal file

Binary file not shown.

4
images/.directory Normal file
View File

@ -0,0 +1,4 @@
[Dolphin]
Timestamp=2022,7,17,14,58,4.757
Version=4
VisibleRoles=Details_text,Details_size,Details_modificationtime,Details_creationtime,CustomizedDetails

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
images/bol_alchimie.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

BIN
images/bol_armes.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
images/bol_armes_bonus.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
images/bol_armures.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
images/bol_creature.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
images/bol_demon.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
images/bol_difficulte.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

BIN
images/bol_init.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
images/bol_jetaction.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
images/bol_pnj.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

BIN
images/bol_portee.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
images/bol_sorts.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
images/langues_lemurie.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
images/map_lemurie.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

BIN
images/plan_halakh.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

BIN
images/plan_satarla.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

BIN
images/plan_ucerb.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 940 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

BIN
images/vademecum.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

490
lang/de.json Normal file
View File

@ -0,0 +1,490 @@
{
"ACTOR.TypeCharacter": "Charakter",
"ACTOR.TypeEncounter": "NSC",
"ITEM.TypeItem": "Objekt",
"ITEM.TypeFeature": "Eigenschaft",
"ITEM.TypeWeapon": "Waffe",
"ITEM.TypeArmor": "Rüstung",
"BOL.attributes.vigor": "Stärke",
"BOL.attributes.halfvigor" : "Demi-vigueur",
"BOL.attributes.agility": "Geschicklichkeit",
"BOL.attributes.mind": "Verstand",
"BOL.attributes.appeal": "Auftreten",
"BOL.aptitudes.init": "Initiative",
"BOL.aptitudes.melee": "Nahkampf",
"BOL.aptitudes.ranged": "Fernkampf",
"BOL.aptitudes.def": "Verteidigung",
"BOL.aptitudes.prot": "Schutz",
"BOL.resources.hp": "Lebensblut",
"BOL.resources.hero": "Heldenpunkte",
"BOL.resources.faith": "Glaube",
"BOL.resources.creation": "Erschaffung",
"BOL.resources.power": "Arkane Macht",
"BOL.resources.villainy": "Boshaftigkeit",
"BOL.resources.alchemypoints": "Alchemiepunkte",
"BOL.traits.xp": "Erfahrung",
"BOL.ui.tab.stats": "Attribute",
"BOL.ui.tab.combat": "Kampf",
"BOL.ui.tab.actions": "Aktionen",
"BOL.ui.tab.features": "Eigenschaften",
"BOL.ui.tab.equipment": "Ausrüstung",
"BOL.ui.tab.description": "Beschreibung",
"BOL.ui.tab.details": "Details",
"BOL.ui.tab.spellalchemy": "Zaubersprüche & Alchemie",
"BOL.ui.properties": "Eigenschaften",
"BOL.ui.description": "Beschreibung",
"BOL.ui.actions": "Aktionen",
"BOL.ui.capacities": "Fähigkeiten",
"BOL.ui.capacityProperties": "Fähigkeitenseigenschaften",
"BOL.ui.damages": "Schaden",
"BOL.ui.details": "Details",
"BOL.ui.category": "Kategorie",
"BOL.ui.subcategory": "Unterkategorie",
"BOL.ui.type": "Typ",
"BOL.ui.subtype": "Untertyp",
"BOL.ui.attribute" : "Attribut",
"BOL.ui.aptitude" : "Einstellungen",
"BOL.ui.advantages" : "Vorteile/Nachteile",
"BOL.ui.modifiers": "Modifikatoren",
"BOL.ui.item": "Objekt",
"BOL.ui.edit": "Ändern",
"BOL.ui.unequip": "Ablegen",
"BOL.ui.equip": "Anlegen",
"BOL.ui.delete": "Löschen",
"BOL.ui.roll" : "Würfeln",
"BOL.ui.equipment" : "Ausrüstung",
"BOL.ui.equipmentProperties" : "Ausrüstungseigenschaften",
"BOL.ui.weaponAttack" : "Waffenangriff",
"BOL.ui.weaponProperties" : "Waffeneigenschaften",
"BOL.ui.protectionProperties" : "Schutzeigenschaften",
"BOL.ui.magicalProperties" : "Magieeigenschaften",
"BOL.ui.capacatyProperties" : "Fähigkeiteneigenschaften",
"BOL.ui.alchemyProperties": "Alchemieeigenschaften",
"BOL.ui.armor" : "Rüstung",
"BOL.ui.reach" : "Reichweite",
"BOL.ui.weapon" : "Waffe",
"BOL.ui.melee" : "Nahkampf",
"BOL.ui.ranged" : "Fernkampf",
"BOL.ui.protection" : "Schutz",
"BOL.ui.shield" : "Schild",
"BOL.ui.blocking" : "Blocken",
"BOL.ui.range" : "Reichweite",
"BOL.ui.quantity" : "Menge",
"BOL.ui.qty" : "Anz.",
"BOL.ui.slot" : "Slot",
"BOL.ui.weight" : "Gewicht",
"BOL.ui.price": "Preis",
"BOL.ui.cancel": "Abbrechen",
"BOL.ui.submit": "OK",
"BOL.ui.attributeCheck" : "Attributsprobe",
"BOL.ui.aptitudeCheck" : "Fähigkeitsprobe",
"BOL.ui.weaponCheck" : "Waffenprobe",
"BOL.ui.spellCheck" : "Zauberprobe",
"BOL.ui.careers" : "Laufbahnen",
"BOL.ui.boons" : "Gaben",
"BOL.ui.flaws" : "Schwächen",
"BOL.ui.rank" : "Rang",
"BOL.ui.success" : "Erfolg",
"BOL.ui.failure" : "Fehlschlag",
"BOL.ui.fumble" : "Kritischer Fehlschlag",
"BOL.ui.critical" : "Mächtiger Erfolg",
"BOL.ui.criticallegend" : "Legendärer Erfolg",
"BOL.ui.maneuvers" : "Kampfmanöver",
"BOL.ui.stacksize" : "Stapelgröße (max)",
"BOL.ui.weapons" : "Waffen",
"BOL.ui.protections" : "Schutz",
"BOL.ui.ammos" : "Munition",
"BOL.ui.containers" : "Behälter",
"BOL.ui.treasure" : "Schätze",
"BOL.ui.vehicles" : "Fahrzeuge/Reittiere",
"BOL.ui.misc" : "Verschiedenes",
"BOL.ui.vehicleProperties" : "Fahrzeugeigenschaften",
"BOL.ui.speed" : "Geschwindigkeit",
"BOL.ui.noWeaponName" : "Unbekannte Waffe",
"BOL.ui.targetDefence": "Verteidigung",
"BOL.ui.applyShieldMalus": "Schildmalus anwenden",
"BOL.ui.shieldMalus": "Schildmalus",
"BOL.ui.defenseScore": "Verteidigungswert",
"BOL.ui.defender": "Verteidiger",
"BOL.ui.difficulty": "Schwierigkeit",
"BOL.ui.spellProperties": "Zaubereigenschaften",
"BOL.ui.duration": "Dauer",
"BOL.ui.spellkeep": "Aufrechterhalten",
"BOL.ui.concentrate": "Konzentrieren",
"BOL.ui.registerInit": "Register Init.",
"BOL.ui.isSorcerer": "Ist Zauberer?",
"BOL.ui.isAlchemist": "Ist Alchemist?",
"BOL.ui.isPriest": "Ist Priester/Druide?",
"BOL.ui.circle": "Kreis",
"BOL.ui.spells": "Zaubersprüche",
"BOL.ui.focusSpell": "Zauberspruch wirken",
"BOL.ui.sorcererRank" : "Zaubererrang",
"BOL.ui.alchemistRank": "Alchemistenrang",
"BOL.ui.mandatoryconditions": "Benötigte Vorraussetzungen",
"BOL.ui.optionnalconditions": "Optionale Vorraussetzungen",
"BOL.ui.ppcost": "Arkane Macht-Kosten",
"BOL.ui.ppAvailable": "Verfügbare Arkane Macht",
"BOL.ui.pccost": "Creation Points cost",
"BOL.ui.pcnow": "Actual Creation Points",
"BOL.ui.alchemyType": "Typ",
"BOL.ui.alchemy": "Alchemie",
"BOL.ui.makeAlchemy": "Alchemika herstellen",
"BOL.ui.alchemyCostTotal": "Alchemiepunkte ingesamt",
"BOL.ui.alchemyInvest": "Alchemiepunkte investieren",
"BOL.ui.alchemyCurrent": "Aktuelle Alchemiepunkte in Objekten",
"BOL.ui.advance": "Status",
"BOL.ui.isadvantage": "Gibt zusätzlichen Würfel?",
"BOL.ui.isbonusdice": "Gibt zusätzlichen Würfel?",
"BOL.ui.ismalusdice": "Gibt zusätzlichen Würfel?",
"BOL.ui.bonusmalus": "Zusätzliche Boni/Mali?",
"BOL.ui.nbdices": "Anzahl der Würfel",
"BOL.ui.totalmod": "Kompletter Mod.",
"BOL.ui.rangeModifiers": "Reichweitenmodifikator",
"BOL.ui.money": "Gold",
"BOL.ui.moneyTitle": "Gold & Schätze",
"BOL.ui.fightOption": "Kampfoptionen",
"BOL.ui.none": "Nichts",
"BOL.ui.fightOptionType": "Kampfoptionstypen",
"BOL.ui.activated": "Aktiviert",
"BOL.ui.deactivated": "Deaktiviert",
"BOL.ui.status": "Status",
"BOL.ui.toactivated": "Aktiv (>Deaktivieren)",
"BOL.ui.todeactivated": "Inaktiv (>Aktivieren)",
"BOL.ui.armorAgiMalus": "Rüschtung+Schild-Malus (Geschick)",
"BOL.ui.armorInitMalus": "Rüstungsmalus (Init)",
"BOL.ui.attackValue": "Angriffswert",
"BOL.ui.initMalus": "Init malus",
"BOL.ui.createEquipment": "Create Equipment",
"BOL.featureCategory.origins": "Herkünfte",
"BOL.featureCategory.races": "Rassen",
"BOL.featureCategory.careers": "Laufbahnen",
"BOL.featureCategory.boons": "Gaben",
"BOL.featureCategory.flaws": "Schwächen",
"BOL.featureCategory.languages": "Sprachen",
"BOL.featureCategory.fightoptions": "Kampfoptionen",
"BOL.featureSubtypes.origin": "Herkunft",
"BOL.featureSubtypes.race": "Rasse",
"BOL.featureSubtypes.career": "Laufbahn",
"BOL.featureSubtypes.boon": "Gabe",
"BOL.featureSubtypes.flaw": "Schwäche",
"BOL.featureSubtypes.language": "Sprache",
"BOL.featureSubtypes.gods": "Glauben & Götter",
"BOL.featureSubtypes.fightOption": "Kampfoption",
"BOL.bougette.nomoney": "Mittellos",
"BOL.bougette.tolive": "Zum Überleben",
"BOL.bougette.easylife": "Einfaches Leben",
"BOL.bougette.luxury" : "Luxuriöses Leben",
"BOL.bougette.rich": "Reich!",
"BOL.fightOptionTypes.armor": "Angriff um die Rüstung zu umgehen",
"BOL.fightOptionTypes.intrepid": "Rücksichtsloser Angriff",
"BOL.fightOptionTypes.twoweaponsdef": "Kampf mit zwei Waffen (Verteidigung)",
"BOL.fightOptionTypes.twoweaponsatt": "Kampf mit zwei Waffen (Angriff)",
"BOL.fightOptionTypes.fulldefense": "Volle Verteidigung",
"BOL.fightOptionTypes.defense": "Verteidigungshaltung",
"BOL.fightOptionTypes.attack": "Angriffshaltung",
"BOL.itemCategory.object": "Objekt",
"BOL.itemCategory.equipment": "Ausrüstung",
"BOL.itemCategory.consumable": "Verbrauchsgut",
"BOL.itemCategory.spell": "Zauber",
"BOL.itemCategory.vehicle": "Fahrzeug/Reittier",
"BOL.itemCategory.other": "Verschiedenes",
"BOL.itemCategory.capacity" : "Fähigkeiten",
"BOL.itemCategory.alchemy": "Alchemie",
"BOL.combatCategory.protections": "Schutz",
"BOL.combatCategory.shields": "Schilde",
"BOL.combatCategory.melee": "Nahkampfwaffen",
"BOL.combatCategory.ranged": "Fernkampfwaffen",
"BOL.combatCategory.fightOptions": "Kampfoptionen",
"BOL.combatCategory.natural": "Natürliche Waffen",
"BOL.equipmentCategory.weapon": "Waffe",
"BOL.equipmentCategory.armor": "Rüstung",
"BOL.equipmentCategory.protection": "Schutz",
"BOL.equipmentCategory.shield": "Schild",
"BOL.equipmentCategory.helm": "Helm",
"BOL.equipmentCategory.jewel": "Schmuck",
"BOL.equipmentCategory.scroll": "Schriftrolle",
"BOL.equipmentCategory.ammunition": "Munition",
"BOL.equipmentCategory.container": "Behälter",
"BOL.equipmentCategory.currency": "Gold",
"BOL.equipmentCategory.other": "Verschiedenes",
"BOL.protectionCategory.armor": "Rüstung",
"BOL.protectionCategory.shield": "Schild",
"BOL.protectionCategory.helm": "Helm",
"BOL.protectionCategory.other": "Verschiedenes",
"BOL.spellItem.charm": "Zauber",
"BOL.spellItem.circle1": "Erster Kreis",
"BOL.spellItem.circle2": "Zweiter Kreis",
"BOL.spellItem.circle3": "Dritter Kreis",
"BOL.alchemyItem.common": "Häufig",
"BOL.alchemyItem.scarce": "Selten",
"BOL.alchemyItem.legend": "Legendär",
"BOL.alchemyItem.mythic": "Mystisch",
"BOL.weaponCategory.melee": "Nahkampf",
"BOL.weaponCategory.ranged": "Fernkampf",
"BOL.weaponCategory.other": "Verschiedenes",
"BOL.itemProperty.damageMultiplier": "Schadensmultiplikator",
"BOL.itemProperty.attackBonusDice": "Angriffsbonuswürfel",
"BOL.itemProperty.equipable": "Ausrüstbar",
"BOL.itemProperty.protection": "Schutz",
"BOL.itemProperty.blocking": "Blocken",
"BOL.itemProperty.magical": "Magisch",
"BOL.itemProperty.magicalProperties": "Magische Eigenschaften",
"BOL.itemProperty.concealable": "Versteckbar",
"BOL.itemProperty.2H": "Zweihändig",
"BOL.itemProperty.helm": "Helm",
"BOL.itemProperty.improvised": "Improvisiert",
"BOL.itemProperty.shield": "Schild",
"BOL.itemProperty.melee": "Nahkampf",
"BOL.itemProperty.throwable": "Werfbar",
"BOL.itemProperty.ignoreshield": "Ignoriert Schilde",
"BOL.itemProperty.bashing": "Nicht-tödlicher Schaden",
"BOL.itemProperty.stackable": "Stapelbar",
"BOL.itemProperty.ranged": "Fernkampf",
"BOL.itemProperty.weapon": "Waffe",
"BOL.itemProperty.reloadable": "Nachladbar",
"BOL.itemProperty.worn": "Angelegt",
"BOL.itemProperty.spell" : "Zauber",
"BOL.itemProperty.armor" : "Rüstung",
"BOL.itemProperty.consumable" : "Verbrauchsgut",
"BOL.itemProperty.bow" : "Bogen",
"BOL.itemProperty.crossbow" : "Armbrust",
"BOL.itemProperty.throwing" : "Wurfwaffe",
"BOL.itemProperty.activable" : "Aktivierbar",
"BOL.itemProperty.powder" : "Schießpulverwaffe",
"BOL.itemProperty.attackAttribute" : "Angriff (Attribut)",
"BOL.itemProperty.attackAptitude" : "Angriff (Fähigkeit)",
"BOL.itemProperty.attackModifiers" : "Angriff (Modifikatoren)",
"BOL.itemProperty.attackReroll1" : "Angriff (bei 1 erneut würfeln)",
"BOL.itemProperty.damage" : "Schaden (Sch)",
"BOL.itemProperty.damageModifiers" : "Schaden (Modifikatoren)",
"BOL.itemProperty.damageAttribute" : "Schaden (Attribut)",
"BOL.itemProperty.damageSpecial" : "Schaden (Spezial)",
"BOL.itemProperty.damageReroll1" : "bei 1 erneut würfeln",
"BOL.itemProperty.range" : "Reichweite (in m)",
"BOL.itemProperty.soakFormula": "Auslösen (Formel)",
"BOL.itemProperty.soakModifiers": "Auslösen (Modifikatoren)",
"BOL.itemProperty.soakValue": "Auslösen (Wert)",
"BOL.itemProperty.armorQuality": "Rüstungsqualität",
"BOL.itemProperty.blockingMalus" : "Blockmalus",
"BOL.itemProperty.blockingAttacksBlocked" : "Angriff geblockt",
"BOL.itemProperty.blocking1Attack" : "Ein Angriff blocken",
"BOL.itemProperty.blockingAllAttacks" : "Alle Angriffe blocken",
"BOL.itemProperty.slot" : "Slotplatz",
"BOL.itemProperty.reload": "Nachladen (Aktion)",
"BOL.itemProperty.weaponSize" : "Waffengröße",
"BOL.itemProperty.difficulty": "Schwierigkeit",
"BOL.itemProperty.natural": "Natürliche Waffe",
"BOL.itemProperty.onlymodifier": "Nur Modifikator (d.h. Angriffe von Kreaturen)",
"BOL.itemStat.quantity": "Anzahl",
"BOL.itemStat.weight": "Gewicht",
"BOL.itemStat.price": "Preis",
"BOL.itemStat.range": "Reichweite",
"BOL.itemStat.damage": "Schaden",
"BOL.itemStat.reload": "Nachladen (Aktion)",
"BOL.itemStat.soak": "Auslösen",
"BOL.itemStat.blocking": "Blocken",
"BOL.itemStat.modifiers": "Modifikatoren",
"BOL.weaponSize.unarmed" : "Unbewaffnet",
"BOL.weaponSize.improvised" : "Improvisiert",
"BOL.weaponSize.light" : "Leicht",
"BOL.weaponSize.medium" : "Mittel",
"BOL.weaponSize.heavy" : "Schwer",
"BOL.itemModifiers.init": "Malus (Initiative)",
"BOL.itemModifiers.social": "Malus (Sozial)",
"BOL.itemModifiers.agility": "Malus (Geschick)",
"BOL.itemModifiers.powercost": "Malus (Zusatzkosten Arkane Macht)",
"BOL.itemBlocking.malus": "Sozial",
"BOL.itemBlocking.nbAttacksPerRound": "Beweglichkeit",
"BOL.soakFormula.none" : "-",
"BOL.soakFormula.light" : "Leicht (Verhindert d6-3 erlittenen Schaden)",
"BOL.soakFormula.medium" : "Mittel (Verhindert d6-2 erlittenen Schaden)",
"BOL.soakFormula.heavy" : "Schwer (Verhindert d6-1 erlittenen Schaden)",
"BOL.armorQuality.none" : "-",
"BOL.armorQuality.light" : "Leicht",
"BOL.armorQuality.lightQ" : "Leicht Qualität",
"BOL.armorQuality.lightSup" : "Leicht Überlegen",
"BOL.armorQuality.lightLeg" : "Leicht Legendär",
"BOL.armorQuality.medium" : "Mittel",
"BOL.armorQuality.mediumQ" : "Mittel Qualität",
"BOL.armorQuality.mediumSup" : "Mittel Überlegen",
"BOL.armorQuality.mediumLeg" : "Mittel Legendär",
"BOL.armorQuality.heavy" : "Schwer",
"BOL.armorQuality.heavyQ" : "Schwer Qualität",
"BOL.armorQuality.heavySup" : "Schwer Überlegen",
"BOL.armorQuality.heavyLeg" : "Schwer Legendär",
"BOL.equipmentSlots.none" : "-",
"BOL.equipmentSlots.head" : "Kopf",
"BOL.equipmentSlots.neck" : "Hals",
"BOL.equipmentSlots.shoulders" : "Schultern",
"BOL.equipmentSlots.body" : "Körper",
"BOL.equipmentSlots.rhand" : "Rechte Hand",
"BOL.equipmentSlots.lhand" : "Linke Hand",
"BOL.equipmentSlots.2hands" : "Zweihändig",
"BOL.equipmentSlots.rarm" : "Rechter Arm",
"BOL.equipmentSlots.larm" : "Linker Arm",
"BOL.equipmentSlots.chest" : "Torso",
"BOL.equipmentSlots.belt" : "Gürtel",
"BOL.equipmentSlots.legs" : "Beine",
"BOL.equipmentSlots.feet" : "Füße",
"BOL.equipmentSlots.finder" : "Finger",
"BOL.equipmentSlots.ear" : "Ohr",
"BOL.vehicleCategory.mount" : "Reittier",
"BOL.vehicleCategory.flying" : "Fluggerät",
"BOL.vehicleCategory.boat" : "Schiff",
"BOL.vehicleCategory.other" : "Anderes",
"BOL.ui.astrologerPoints": "Points d'Astrologie",
"BOL.ui.astrologerPointsLabel": "Points d'Astrologie actuels",
"BOL.ui.ishoroscopemajor": "Horoscope Majeur (ie de groupe) ?",
"BOL.ui.answer": "Réponse",
"BOL.ui.horoscopefavorable": "Favorable (1dB)",
"BOL.ui.horoscopeunfavorable": "Défavorable (1dM)",
"BOL.ui.horoscopes": "Horoscopes",
"BOL.ui.horoscopesBonus": "Horoscopes (Bonus)",
"BOL.ui.horoscopesMalus": "Horoscopes (Malus)",
"BOL.ui.groupHoroscope": "Horoscrope de Groupe de ",
"BOL.range.PointBlank": "Direkt",
"BOL.range.Short": "Kurz",
"BOL.range.Medium": "Mittel",
"BOL.range.Long": "Weit",
"BOL.range.VeryLong": "Sehr weit",
"BOL.range.Extreme": "Extrem weit",
"BOL.range.Maximum": "Maximale Reichweite",
"BOL.notification.MacroMultipleTokensSelected": "Du hast mehrere Token ausgewählt",
"BOL.notification.MacroNoActorAvailable": "Es konnte kein Akteur gefunden werden",
"BOL.notification.MacroNoTokenSelected": "Du musst einen Token auswählen",
"BOL.size.tiny": "Winzig",
"BOL.size.verysmall": "Sehr klein",
"BOL.size.small" : "Klein",
"BOL.size.medium" : "Mittel",
"BOL.size.large" : "Groß",
"BOL.size.verylarge": "Sehr groß",
"BOL.size.huge" :"Riesig",
"BOL.size.massive" : "Massiv",
"BOL.size.enormous": "Enorm",
"BOL.size.gigantic": "Gigantisch",
"BOL.size.immense": "Immens",
"BOL.size.colossal": "Kolossal",
"BOL.chat.fightactive": "{name} aktiviert die Kampfoption {foName} für diese Runde!",
"BOL.chat.fightunactive": "{name} deaktiviert die Kampfoption {foName} für diese Runde!",
"BOL.chat.isdead": "{name} ist tot!",
"BOL.chat.epitaph": "Möge sein Name auf den Schlachtfeldern Lemurias in Ehren gehalten werden.!",
"BOL.chat.vitalityzero": "Das Lebensblut von {name} ist {hp}: {name} geht zu Boden und wird bewusstlos!",
"BOL.chat.vitalityheroism": "Gib einen Heldenpunkt aus um für eine Runde wieder auf die Beine zu kommen.",
"BOL.chat.vitalityheroismhint": "Dadurch steigt dein Lebensblut auf das Maximum geteilt durch 2 (aufgerundet).",
"BOL.chat.vitalitydying": "Das Lebensblut von {name} ist {hp}! {name} stirbt...",
"BOL.chat.vitalitydyingheroism": "Gib einen Heldenpunkt aus um den Tod herauszufordern.",
"BOL.chat.alchemytitle": "Alchemiepräparat: {name}",
"BOL.chat.alchemypoints": "Investierte Charaktererschaffungspunkte: {pcCostCurrent}",
"BOL.chat.alchemysuccess": "Das alchemistische Präparat wurde erfolgreich abgeschlossen!<br>Erstelle den entsprechenden Gegenstand oder Effekt in deinem Inventar.<br>Der Vorbereitungsfortschritt wurde auf 0 zurückgesetzt.",
"BOL.chat.alchemyfailure": "Das Alchemistische Präparat ist fehlgeschlagen!<br>Der Fortschritt wurde auf 0 zurückgesetzt.",
"BOL.chat.rolldamage": "Schaden auswürfeln",
"BOL.chat.rolldamage6": "Schaden auswürfeln +6",
"BOL.chat.rolldamage12": "Schaden auswürfeln +12 (1 Heldenpunkt)",
"BOL.chat.damageresult": "Schaden von {name}: {total}",
"BOL.chat.damagetarget": "Ziel: {target}",
"BOL.chat.applydamagetotarget": "Schaden auf Ziel anwenden",
"BOL.chat.fightoption": "Kampfoption",
"BOL.chat.reroll": "Erneut Würfeln (1 Heldenpunkt)",
"BOL.chat.toheroic": "In mächtigen Erfolg umwandeln (1 Heldenpunkt)",
"BOL.chat.tolegend": "In legendären Erfolg umwandeln (1 Heldenpunkt)",
"BOL.chat.hurttitle": "{name} wird {damageTotal} Schaden erleiden!",
"BOL.chat.armordefault": "Dieser Angriff richtet sich gegen Fehler in deiner Rüstung. Du musst den Schaden ohne den Schutz deiner Rüstung einstecken!",
"BOL.chat.witharmor": "Schaden MIT Rüstungsschutz anwenden",
"BOL.chat.withoutarmor": "Schaden OHNE Rüstungsschutz anwenden",
"BOL.chat.shakeoff": "Nur ein Kratzer (1 Heldenpunkt)",
"BOL.chat.splinteredshield": "Opfere dein Schild/Schwert {name} (1 Heldenpunkt)",
"BOL.chat.damagesummary": "Schaden durch {name} erlitten",
"BOL.chat.protectvalue": "Rüstungsschutz",
"BOL.chat.noprotectvalue": "Kein Rüstungsschutz!",
"BOL.chat.heroreducedamage": "Gib einen Heldenpunkt aus um eine zusätzliche Schadensreduktion von {total} zu bekommen.",
"BOL.chat.herosplintered": "Du hast keinen Schaden eingesteckt dank {weaponHero.name}. Leider wurde es während der Parade zerstört. Du hast einen Heldenpunkt verloren.",
"BOL.chat.finaldamage": "Endergebnis: {finalDamage} Schaden!",
"BOL.chat.spell": "Zauber",
"BOL.chat.spellcost": "Arkane Macht-Kosten",
"BOL.chat.spellremaining": "Verbleibende Arkane Macht",
"BOL.dialog.soeasy": "Trivial (+4)",
"BOL.dialog.veryeasy": "Sehr leicht (+2)",
"BOL.dialog.easy": "Leicht (+1)",
"BOL.dialog.moderate": "Normal (0)",
"BOL.dialog.hard": "Knifflig (-1)",
"BOL.dialog.tough": "Schwierig (-2)",
"BOL.dialog.demanding": "Sehr Schwierig (-4)",
"BOL.dialog.formidable": "Herausfordernd (-6)",
"BOL.dialog.heroic": "Heldenhaft (-8)",
"BOL.dialog.mythic": "Mystisch (-10)",
"BOL.dialog.divine": "Göttlich (-12)",
"BOL.dialog.pointblank": "Direkt (+1)",
"BOL.dialog.close": "Kurz (0)",
"BOL.dialog.medium": "Mittel (-1)",
"BOL.dialog.long": "Weit (-2)",
"BOL.dialog.distant": "Sehr Weit (-4)",
"BOL.dialog.extreme": "Extrem Weit (-6)",
"BOL.dialog.utmost": "Maximale Reichweite (-8)",
"BOL.ui.name": "Name",
"BOL.ui.xp": "Erfahrung",
"BOL.ui.xpspent": "Ausgegeben",
"BOL.ui.xptotal": "Insgesamt",
"BOL.ui.biosize": "Größe",
"BOL.ui.bioweight": "Gewicht",
"BOL.ui.bioage": "Alter",
"BOL.ui.biohair": "Haare",
"BOL.ui.bioeyes": "Augen",
"BOL.ui.biosigns": "Erkennungszeichen",
"BOL.ui.biodescription": "Beschreibung",
"BOL.ui.bionotes": "Notizen",
"BOL.chat.welcome1": "Willkommen zu Barbarians of Lemuria (französische Ludospherik-Version, deutsche Übersetzung von Truant Spiele)",
"BOL.chat.welcome2": "Zum Spielen werden zwingend die passenden BoL Bücher benötigt. Die französischen Originalbücher für dieses System gibt es hier: http://www.ludospherik.fr/content/14-barbarians-of-lemuria<br>Die deutsche Übersetzung gibt es bei Truant Spiele: https://truant.com/produkt/barbarians-of-lemuria-2",
"BOL.chat.welcome3": "Die enthaltenen Karten wurden von Guillaume Tavernier und Ludospherik zur Verfügung gestellt. Vielen Dank dafür!",
"BOL.chat.welcome4": "Im Discord findet ihr Support für die FoundryVTT-Implementierung dieses Systems: https://discord.gg/pPSDNJk",
"BOL.chat.welcome5": "Auf ein gutes Spiel in Lemuria!",
"BOL.chat.welcome6": "",
"BOL.settings.rollArmor": "Roll for armor",
"BOL.settings.rollArmorTooltip": "Roll for armor value, fixed value if unchecked",
"BOL.settings.useBougette": "Use Bougette (fan-made French rule)",
"BOL.settings.useBougetteTooltip": "Use the Bougette value, as described in Annales Lemurienne from LeRatierBretonnien (https://www.lahiette.com/leratierbretonnien/)",
"BOL.settings.removeDead": "Automatically remove dead NPCs by end of the round",
"BOL.settings.removeDeadTooltip": "Remove NPCs Automatically when HP are 0 or less, at the end of each round",
"BOL.settings.diceFormula": "Dice Formula",
"BOL.settings.diceFormulaTooltip": "Main dice formula (2d6 per default)",
"BOL.settings.diceSuccessValue" : "Success value",
"BOL.settings.diceSuccessValueTooltip": "Value of the success threshold (9 per default for 2d6)",
"BOL.settings.diceCriticalValue" : "Critical success value",
"BOL.settings.diceCriticalValueTooltip": "Minimum value for critical success (12 per default for 2d6)",
"BOL.settings.diceCriticalFailure" : "Critical failure value",
"BOL.settings.diceCriticalFailureTooltip": "Maximum value for critical failure (2 per default for 2d6)",
"BOL.settings.defaultLogoActorSheetPath" : "Path for Actor sheet logo",
"BOL.settings.defaultLogoPathActorSheetTooltip": "Path of the Actor sheet logo (346 x 200, default : /systems/bol/ui/logo.webp)",
"BOL.settings.defaultLogoTopLeftPath" : "Path for main top left logo",
"BOL.settings.defaultLogoTopLeftPathTooltip": "Path of the logo in the top left window (718 x 416, default : /systems/bol/ui/logo2.webp)"
}

View File

@ -1,5 +1,13 @@
{
"ACTOR.TypeCharacter": "Character",
"ACTOR.TypeEncounter": "Encounter",
"ITEM.TypeItem": "Item",
"ITEM.TypeFeature": "Feature",
"ITEM.TypeWeapon": "Weapon",
"ITEM.TypeArmor": "Armor",
"BOL.attributes.vigor": "Strength",
"BOL.attributes.halfvigor" : "Half-Strength",
"BOL.attributes.agility": "Agility",
"BOL.attributes.mind": "Mind",
"BOL.attributes.appeal": "Appeal",
@ -8,10 +16,477 @@
"BOL.aptitudes.ranged": "Ranged",
"BOL.aptitudes.def": "Defense",
"BOL.aptitudes.prot": "Protection",
"BOL.resources.hp": "Hit points",
"BOL.resources.hero": "Hero points",
"BOL.resources.faith": "Faith points",
"BOL.resources.creation": "Creation points",
"BOL.resources.power": "Power points",
"BOL.traits.xp": "Experience"
"BOL.resources.hp": "Vitality",
"BOL.resources.hero": "Hero",
"BOL.resources.faith": "Faith",
"BOL.resources.creation": "Creation",
"BOL.resources.power": "Power",
"BOL.resources.villainy": "Villany",
"BOL.resources.alchemypoints": "Alchemy Points",
"BOL.traits.xp": "Experience",
"BOL.ui.tab.stats": "Attributes",
"BOL.ui.tab.combat": "Combat",
"BOL.ui.tab.actions": "Actions",
"BOL.ui.tab.features": "Traits",
"BOL.ui.tab.equipment": "Equipment",
"BOL.ui.tab.description": "Description",
"BOL.ui.tab.details": "Details",
"BOL.ui.tab.spellalchemy": "Spells & Alchemy",
"BOL.ui.tab.astrologer": "Astrologer",
"BOL.ui.astrologerPoints": "Points d'Astrologie",
"BOL.ui.astrologerPointsLabel": "Points d'Astrologie actuels",
"BOL.ui.ishoroscopemajor": "Horoscope Majeur (ie de groupe) ?",
"BOL.ui.answer": "Réponse",
"BOL.ui.horoscopefavorable": "Favorable (1dB)",
"BOL.ui.horoscopeunfavorable": "Défavorable (1dM)",
"BOL.ui.horoscopes": "Horoscopes",
"BOL.ui.horoscopesBonus": "Horoscopes (Bonus)",
"BOL.ui.horoscopesMalus": "Horoscopes (Malus)",
"BOL.ui.groupHoroscope": "Horoscrope de Groupe de ",
"BOL.ui.properties": "Properties",
"BOL.ui.description": "Description",
"BOL.ui.actions": "Actions",
"BOL.ui.capacities": "Capacity",
"BOL.ui.damages": "Damage",
"BOL.ui.details": "Details",
"BOL.ui.category": "Category",
"BOL.ui.subcategory": "Sub-Category",
"BOL.ui.type": "Type",
"BOL.ui.subtype": "Subtype",
"BOL.ui.attribute" : "Attribute",
"BOL.ui.aptitude" : "Aptitude",
"BOL.ui.advantages" : "Boons/Flaws",
"BOL.ui.modifiers": "Modifiers",
"BOL.ui.item": "Item",
"BOL.ui.edit": "Edit",
"BOL.ui.unequip": "Unequip",
"BOL.ui.equip": "Equip",
"BOL.ui.delete": "Delete",
"BOL.ui.roll" : "Roll",
"BOL.ui.equipment" : "Equipment",
"BOL.ui.equipmentProperties" : "Equipment properties",
"BOL.ui.weaponAttack" : "Weapon attack",
"BOL.ui.weaponProperties" : "Weapon properties",
"BOL.ui.protectionProperties" : "Protection properties",
"BOL.ui.magicalProperties" : "Magical properties",
"BOL.ui.alchemyProperties": "Alchemy properties",
"BOL.ui.armor" : "Armor",
"BOL.ui.reach" : "Reach",
"BOL.ui.weapon" : "Weapon",
"BOL.ui.melee" : "Melee",
"BOL.ui.ranged" : "Ranged",
"BOL.ui.protection" : "Protection",
"BOL.ui.shield" : "Shield",
"BOL.ui.blocking" : "Blocking",
"BOL.ui.range" : "Range",
"BOL.ui.quantity" : "Quantity",
"BOL.ui.qty" : "Qty",
"BOL.ui.slot" : "Slot",
"BOL.ui.weight" : "Weight",
"BOL.ui.price": "Price",
"BOL.ui.cancel": "Cancel",
"BOL.ui.submit": "OK",
"BOL.ui.attributeCheck" : "Attribute Check",
"BOL.ui.aptitudeCheck" : "Aptitude Check",
"BOL.ui.weaponCheck" : "Weapon Check",
"BOL.ui.spellCheck" : "Spell Check",
"BOL.ui.careers" : "Careers",
"BOL.ui.boons" : "Boons",
"BOL.ui.flaws" : "Flaws",
"BOL.ui.rank" : "Rank",
"BOL.ui.success" : "Success",
"BOL.ui.failure" : "Failure",
"BOL.ui.fumble" : "Fumble",
"BOL.ui.critical" : "Critical Success",
"BOL.ui.maneuvers" : "Maneuvers",
"BOL.ui.stacksize" : "Stack Size (max)",
"BOL.ui.weapons" : "Weapons",
"BOL.ui.protections" : "Protection",
"BOL.ui.ammos" : "Ammo",
"BOL.ui.containers" : "Container",
"BOL.ui.treasure" : "Treasure",
"BOL.ui.vehicles" : "Vehicles/Mounts",
"BOL.ui.misc" : "Misc",
"BOL.ui.vehicleProperties" : "Vehicle properties",
"BOL.ui.speed" : "Speed",
"BOL.ui.noWeaponName" : "Weapon Name",
"BOL.ui.targetDefence": "Defense",
"BOL.ui.applyShieldMalus": "Apply Shield Modifier",
"BOL.ui.shieldMalus": "Shield Modifier",
"BOL.ui.defenseScore": "Defense Score",
"BOL.ui.defender": "Defender",
"BOL.ui.difficulty": "Difficulty",
"BOL.ui.spellProperties": "Spell Properties",
"BOL.ui.duration": "Duration",
"BOL.ui.spellkeep": "Maintain",
"BOL.ui.concentrate": "Concentrate",
"BOL.ui.registerInit": "Register Init.",
"BOL.ui.isSorcerer": "Is Sorcerer ?",
"BOL.ui.isAlchemist": "Is Alchemist ?",
"BOL.ui.isPriest": "Is Priest/Druid ?",
"BOL.ui.isAstrologer": "Is Astrologer?",
"BOL.ui.circle": "Circle",
"BOL.ui.spells": "Spells",
"BOL.ui.focusSpell": "Cast a spell",
"BOL.ui.sorcererRank" : "Sorcerer Rank",
"BOL.ui.alchemistRank": "Alchemist Rank",
"BOL.ui.mandatoryconditions": "Mandatory conditions",
"BOL.ui.optionnalconditions": "Optional conditions",
"BOL.ui.ppcost": "Power Points cost",
"BOL.ui.ppAvailable": "Available Power Points",
"BOL.ui.pccost": "Creation Points cost",
"BOL.ui.pcnow": "Actual Creation Points",
"BOL.ui.alchemyType": "Type",
"BOL.ui.alchemy": "Alchemy",
"BOL.ui.makeAlchemy": "Make Alchemy",
"BOL.ui.alchemyCostTotal": "Alchemy Points Total Cost",
"BOL.ui.alchemyInvest": "Invest Alchemy Points",
"BOL.ui.alchemyCurrent": "Current Alchemy Points in Object",
"BOL.ui.advance": "Status",
"BOL.ui.isadvantage": "Provides a bonus dice?",
"BOL.ui.bonusmalus": "Additional bonus/penalty",
"BOL.ui.nbdices": "Number of Dice",
"BOL.ui.totalmod": "Total Mod.",
"BOL.ui.rangeModifiers": "Range modifier",
"BOL.ui.money": "Money",
"BOL.ui.moneyTitle": "Gold & Treasure",
"BOL.ui.fightOption": "Fight Options",
"BOL.ui.none": "None",
"BOL.ui.fightOptionType": "Fight Option types",
"BOL.ui.activated": "Activated",
"BOL.ui.deactivated": "Deactivated",
"BOL.ui.status": "Status",
"BOL.ui.toactivated": "Active (>Deactivated)",
"BOL.ui.todeactivated": "Inactive (>Active)",
"BOL.ui.armorAgiMalus": "Armor+Shield Modifier (Agi)",
"BOL.ui.armorInitMalus": "Armor Modifier (Init)",
"BOL.ui.attackValue": "Attack Value",
"BOL.ui.weaponbonus": "Cette arme bénéficie déja d'un Dé de Bonus (Arme Favorite prise en compte, par exemple)",
"BOL.ui.initMalus": "Init malus",
"BOL.ui.isspecial": "Spécial ?",
"BOL.ui.createEquipment": "Create Equipment",
"BOL.featureCategory.origins": "Origins",
"BOL.featureCategory.races": "Races",
"BOL.featureCategory.careers": "Careers",
"BOL.featureCategory.boons": "Boons",
"BOL.featureCategory.flaws": "Flaws",
"BOL.featureCategory.languages": "Languages",
"BOL.featureCategory.fightoptions": "Fight Options",
"BOL.featureSubtypes.origin": "Origin",
"BOL.featureSubtypes.race": "Race",
"BOL.featureSubtypes.career": "Career",
"BOL.featureSubtypes.boon": "Boon",
"BOL.featureSubtypes.flaw": "Flaw",
"BOL.featureSubtypes.language": "Language",
"BOL.featureSubtypes.gods": "Faith & Gods",
"BOL.featureSubtypes.fightOption": "Combat Option",
"BOL.bougette.nomoney": "Nothing",
"BOL.bougette.tolive": "To live",
"BOL.bougette.easylife": "Easy Life",
"BOL.bougette.luxury" : "Luxury life",
"BOL.bougette.rich": "Rich!",
"BOL.fightOptionTypes.armor": "Armor Attack Option",
"BOL.fightOptionTypes.intrepid": "Fearless Attack",
"BOL.fightOptionTypes.twoweaponsdef": "Two Weapon (Defense)",
"BOL.fightOptionTypes.twoweaponsatt": "Two Weapon (Attack)",
"BOL.fightOptionTypes.fulldefense": "Full Defense",
"BOL.fightOptionTypes.defense": "Defensive Posture",
"BOL.fightOptionTypes.attack": "Offensive Posture",
"BOL.fightOptionTypes.other": "Other",
"BOL.itemCategory.object": "Object",
"BOL.itemCategory.equipment": "Equipment",
"BOL.itemCategory.consumable": "Consumable",
"BOL.itemCategory.spell": "Spell",
"BOL.itemCategory.vehicle": "Mount/Vehicle",
"BOL.itemCategory.other": "Other",
"BOL.itemCategory.capacity" : "Capacity",
"BOL.itemCategory.alchemy": "Alchemy",
"BOL.combatCategory.protections": "Protections",
"BOL.combatCategory.shields": "Shields",
"BOL.combatCategory.melee": "Melee",
"BOL.combatCategory.ranged": "Ranged",
"BOL.combatCategory.fightOptions": "Fight options",
"BOL.combatCategory.natural": "Natural Weapons",
"BOL.equipmentCategory.weapon": "Weapon",
"BOL.equipmentCategory.armor": "Armor",
"BOL.equipmentCategory.protection": "Protection",
"BOL.equipmentCategory.shield": "Shield",
"BOL.equipmentCategory.helm": "Helm",
"BOL.equipmentCategory.jewel": "Jewel",
"BOL.equipmentCategory.scroll": "Scroll",
"BOL.equipmentCategory.ammunition": "Ammunition",
"BOL.equipmentCategory.container": "Container",
"BOL.equipmentCategory.currency": "Money",
"BOL.equipmentCategory.other": "Other",
"BOL.protectionCategory.armor": "Armor",
"BOL.protectionCategory.shield": "Shield",
"BOL.protectionCategory.helm": "Helm",
"BOL.protectionCategory.other": "Other",
"BOL.spellItem.charm": "Charm",
"BOL.spellItem.circle1": "First Circle",
"BOL.spellItem.circle2": "Second Circle",
"BOL.spellItem.circle3": "Third Circle",
"BOL.alchemyItem.common": "Common",
"BOL.alchemyItem.scarce": "Scarce",
"BOL.alchemyItem.legend": "Legendary",
"BOL.alchemyItem.mythic": "Mythic",
"BOL.weaponCategory.melee": "Melee",
"BOL.weaponCategory.ranged": "Ranged",
"BOL.weaponCategory.other": "Other",
"BOL.itemProperty.damageMultiplier": "Damage Multiplier",
"BOL.itemProperty.attackBonusDice": "Attack Bonus Dice",
"BOL.itemProperty.equipable": "Equipable",
"BOL.itemProperty.protection": "Protection",
"BOL.itemProperty.blocking": "Blocking",
"BOL.itemProperty.magical": "Magical",
"BOL.itemProperty.concealable": "Concealable",
"BOL.itemProperty.2H": "2H Weapon",
"BOL.itemProperty.helm": "Helm",
"BOL.itemProperty.improvised": "Improvised",
"BOL.itemProperty.shield": "Shield",
"BOL.itemProperty.melee": "Melee",
"BOL.itemProperty.throwable": "Throwable",
"BOL.itemProperty.ignoreshield": "Ignore Shield",
"BOL.itemProperty.bashing": "Bashing",
"BOL.itemProperty.stackable": "Stackable",
"BOL.itemProperty.ranged": "Ranged",
"BOL.itemProperty.weapon": "Weapon",
"BOL.itemProperty.reloadable": "Reloadable",
"BOL.itemProperty.worn": "Equipped",
"BOL.itemProperty.spell" : "Spell",
"BOL.itemProperty.armor" : "Armor",
"BOL.itemProperty.consumable" : "Consumable",
"BOL.itemProperty.bow" : "Bow",
"BOL.itemProperty.crossbow" : "Crossbow",
"BOL.itemProperty.throwing" : "Throwing",
"BOL.itemProperty.activable" : "Activable",
"BOL.itemProperty.powder" : "Powder",
"BOL.itemProperty.attackAttribute" : "Attack (Attribute)",
"BOL.itemProperty.attackAptitude" : "Attack (Aptitude)",
"BOL.itemProperty.attackModifiers" : "Attack (Modifiers)",
"BOL.itemProperty.attackReroll1" : "Attack (Reroll 1's)",
"BOL.itemProperty.damage" : "Damage (Dmg)",
"BOL.itemProperty.damageModifiers" : "Damage (Modifiers)",
"BOL.itemProperty.damageAttribute" : "Damage (Attribute)",
"BOL.itemProperty.damageSpecial" : "Damage (Special)",
"BOL.itemProperty.damageReroll1" : "Reroll 1's",
"BOL.itemProperty.range" : "Range (in m)",
"BOL.itemProperty.soakFormula": "Soak (Formula)",
"BOL.itemProperty.soakModifiers": "Soak (Modifiers)",
"BOL.itemProperty.soakValue": "Soak (Default Value)",
"BOL.itemProperty.armorQuality": "Armor Quality",
"BOL.itemProperty.blockingMalus" : "Blocking Modifier",
"BOL.itemProperty.blockingAttacksBlocked" : "Attacks blocked",
"BOL.itemProperty.blocking1Attack" : "Block 1 attack",
"BOL.itemProperty.blockingAllAttacks" : "Block all attacks",
"BOL.itemProperty.slot" : "Slot",
"BOL.itemProperty.reload": "Reload (Actions)",
"BOL.itemProperty.weaponSize" : "Weapon Size",
"BOL.itemProperty.difficulty": "Difficulty",
"BOL.itemProperty.natural": "Natural weapon",
"BOL.itemProperty.onlymodifier": "Modifier only (ie creatures attacks)",
"BOL.itemStat.quantity": "Quantity",
"BOL.itemStat.weight": "Weight",
"BOL.itemStat.price": "Price",
"BOL.itemStat.range": "Range",
"BOL.itemStat.damage": "Damage",
"BOL.itemStat.reload": "Reload (Actions)",
"BOL.itemStat.soak": "Soak",
"BOL.itemStat.blocking": "Blocking",
"BOL.itemStat.modifiers": "Modifiers",
"BOL.weaponSize.unarmed" : "Unarmed",
"BOL.weaponSize.improvised" : "Improvised",
"BOL.weaponSize.light" : "Light",
"BOL.weaponSize.medium" : "Medium",
"BOL.weaponSize.heavy" : "heavy",
"BOL.itemModifiers.init": "Modifier (Initiative)",
"BOL.itemModifiers.social": "Modifier (Social)",
"BOL.itemModifiers.agility": "Modifier (Agility)",
"BOL.itemModifiers.powercost": "Modifier (Additional Cost in PP)",
"BOL.itemBlocking.malus": "Modifier",
"BOL.itemBlocking.nbAttacksPerRound": "Agility",
"BOL.soakFormula.none" : "-",
"BOL.soakFormula.light" : "Light (Cancels d6-3 damage)",
"BOL.soakFormula.medium" : "Medium (Cancels d6-2 damage)",
"BOL.soakFormula.heavy" : "Heavy (Cancels d6-1 damage)",
"BOL.armorQuality.none" : "-",
"BOL.armorQuality.light" : "Light",
"BOL.armorQuality.lightQ" : "Light Quality",
"BOL.armorQuality.lightSup" : "Light Superior",
"BOL.armorQuality.lightLeg" : "Light Legendary",
"BOL.armorQuality.medium" : "Medium",
"BOL.armorQuality.mediumQ" : "Medium Quality",
"BOL.armorQuality.mediumSup" : "Medium Superior",
"BOL.armorQuality.mediumLeg" : "Medium Legendary",
"BOL.armorQuality.heavy" : "Heavy",
"BOL.armorQuality.heavyQ" : "Heavy Quality",
"BOL.armorQuality.heavySup" : "Heavy Superior",
"BOL.armorQuality.heavyLeg" : "Heavy Legendary",
"BOL.equipmentSlots.none" : "-",
"BOL.equipmentSlots.head" : "Head",
"BOL.equipmentSlots.neck" : "Neck",
"BOL.equipmentSlots.shoulders" : "Shoulders",
"BOL.equipmentSlots.body" : "Body",
"BOL.equipmentSlots.rhand" : "Right hand",
"BOL.equipmentSlots.lhand" : "Left hand",
"BOL.equipmentSlots.2hands" : "2 hands",
"BOL.equipmentSlots.rarm" : "Right arm",
"BOL.equipmentSlots.larm" : "Left arm",
"BOL.equipmentSlots.chest" : "Chest",
"BOL.equipmentSlots.belt" : "Belt",
"BOL.equipmentSlots.legs" : "Legs",
"BOL.equipmentSlots.feet" : "Feet",
"BOL.equipmentSlots.finder" : "Finger",
"BOL.equipmentSlots.ear" : "Ear",
"BOL.vehicleCategory.mount" : "Ground Mount",
"BOL.vehicleCategory.flying" : "Flying Mount",
"BOL.vehicleCategory.boat" : "Boat",
"BOL.vehicleCategory.other" : "Other",
"BOL.range.PointBlank": "Point Blank",
"BOL.range.Short": "Short",
"BOL.range.Medium": "Medium",
"BOL.range.Long": "Long",
"BOL.range.VeryLong": "Very Long",
"BOL.range.Extreme": "Extreme",
"BOL.range.Maximum": "Maximum",
"BOL.notification.MacroMultipleTokensSelected": "You have selected several tokens!",
"BOL.notification.MacroNoActorAvailable": "No actor could be targeted!",
"BOL.notification.MacroNoTokenSelected": "You must select a token!",
"BOL.size.tiny": "Tiny",
"BOL.size.verysmall": "Very Small",
"BOL.size.small" : "Small",
"BOL.size.medium" : "Medium",
"BOL.size.large" : "Large",
"BOL.size.verylarge": "Very Large",
"BOL.size.huge" :"Huge",
"BOL.size.massive" : "Massive",
"BOL.size.enormous": "Enormous",
"BOL.size.gigantic": "Gigantic",
"BOL.size.immense": "Immense",
"BOL.size.colossal": "Colossal",
"BOL.chat.fightactive": "{name} activates the fight option {foName} for this round !",
"BOL.chat.fightunactive": "{name} deactivates the fight option {foName} for this round !",
"BOL.chat.isdead": "{name} is dead !",
"BOL.chat.epitaph": "Keep his name and memory in honor !",
"BOL.chat.vitalityzero": "Lifeblood of {name} is now {hp} : he is going to fall unconscious !",
"BOL.chat.vitalityheroism": "You can spent 1 Hero Point to raise up for 1 round.",
"BOL.chat.vitalityheroismhint": "In this case, your lifeblood raises up to its maximum divided by 2.",
"BOL.chat.vitalitydying": "Lifeblood of {name} is now {hp} ! He is dying ...",
"BOL.chat.vitalitydyingheroism": "You can spent 1 Hero Point to Defy Death.",
"BOL.chat.alchemytitle": "Alchemy recipe : {name}",
"BOL.chat.alchemypoints": "Craft Points cost : {pcCostCurrent}",
"BOL.chat.alchemysuccess": "The alchemy recipe is a success !<br>Create the relevant item/effect in your Inventory.<br>Stage counter has been resetted.",
"BOL.chat.alchemyfailure": "The alchemy recipe has failed !<br>Stage counter has been resetted.",
"BOL.chat.rolldamage": "Roll for damages",
"BOL.chat.rolldamage6": "Roll for damages +6",
"BOL.chat.rolldamage12": "Roll for damages +12 (1 HP)",
"BOL.chat.damageresult": "Damages of {name} : {total}",
"BOL.chat.damagetarget": "Target : {target}",
"BOL.chat.applydamagetotarget": "Apply damages to the target",
"BOL.chat.fightoption": "Combat options",
"BOL.chat.reroll": "Reroll (1 HP)",
"BOL.chat.toheroic": "Convert to Mighty success (1 HP)",
"BOL.chat.tolegend": "Convert to Legendary succes (1 HP)",
"BOL.chat.hurttitle": "{name} is going to receive {damageTotal} damages !",
"BOL.chat.armordefault": "This attack is bypassing armor : armor is not used to reduce damages !",
"BOL.chat.witharmor": "Hit with armor",
"BOL.chat.withoutarmor": "Hit without armor",
"BOL.chat.shakeoff": "Shake off Wounds (1 HP)",
"BOL.chat.splinteredshield": "Splintered Shield/Sword {name} (1 HP)",
"BOL.chat.damagesummary": "Damages received by {name}",
"BOL.chat.protectvalue": "Armor protect",
"BOL.chat.noprotectvalue": "No armor !",
"BOL.chat.heroreducedamage": "One Hero Point has been spent, for reducing damges by {total}.",
"BOL.chat.herosplintered": "No damages received, thanks to splintered shield/sword with {weaponHero.name}. The weapon/shield has been destroyed ! One HP point has been spent also.",
"BOL.chat.finaldamage": "Final Damage : {finalDamage} damages !",
"BOL.chat.spell": "Spell",
"BOL.chat.spellcost": "Power Points cost",
"BOL.chat.spellremaining": "Remaining Power Points",
"BOL.dialog.soeasy": "So easy (+4)",
"BOL.dialog.veryeasy": "Very easy (+2)",
"BOL.dialog.easy": "Easy (+1)",
"BOL.dialog.moderate": "Moderate (0)",
"BOL.dialog.hard": "Hard (-1)",
"BOL.dialog.tough": "Tough (-2)",
"BOL.dialog.demanding": "Demanding (-4)",
"BOL.dialog.formidable": "Formidable (-6)",
"BOL.dialog.heroic": "Heroic (-8)",
"BOL.dialog.mythic": "Mythic (-10)",
"BOL.dialog.divine": "Divine (-12)",
"BOL.dialog.pointblank": "Point blank (+1)",
"BOL.dialog.close": "Close (0)",
"BOL.dialog.medium": "Medium (-1))",
"BOL.dialog.long": "Long (-2)",
"BOL.dialog.distant": "Distant (-4)",
"BOL.dialog.extreme": "Extreme (-6)",
"BOL.dialog.utmost": "Utmost (-8)",
"BOL.ui.name": "Name",
"BOL.ui.xp": "Experience",
"BOL.ui.xpspent": "Spent",
"BOL.ui.xptotal": "Total",
"BOL.ui.biosize": "Size",
"BOL.ui.bioweight": "Weight",
"BOL.ui.bioage": "Age",
"BOL.ui.biohair": "Hair",
"BOL.ui.bioeyes": "Eyes",
"BOL.ui.biosigns": "Signs",
"BOL.ui.biodescription": "Description",
"BOL.ui.bionotes": "Notes",
"BOL.chat.welcome1": "Welcome to Barbarians of Lemuria (Ludospherik version)",
"BOL.chat.welcome2": "Books are necessary to play, and ca be found here : http://www.ludospherik.fr/content/14-barbarians-of-lemuria",
"BOL.chat.welcome3": "The integrated maps are authorized by Guillaume Tavernier and Ludospherik. Thanks to them !.",
"BOL.chat.welcome4": "All support for this system is available on this Discord server : https://discord.gg/pPSDNJk",
"BOL.chat.welcome5": "Good game in Lemuria !",
"BOL.chat.welcome6": "",
"BOL.settings.rollArmor": "Roll for armor",
"BOL.settings.rollArmorTooltip": "Roll for armor value, fixed value if unchecked",
"BOL.settings.useBougette": "Use Bougette (fan-made French rule)",
"BOL.settings.useBougetteTooltip": "Use the Bougette value, as described in Annales Lemurienne from LeRatierBretonnien (https://www.lahiette.com/leratierbretonnien/)",
"BOL.settings.removeDead": "Automatically remove dead NPCs by end of the round",
"BOL.settings.removeDeadTooltip": "Remove NPCs Automatically when HP are 0 or less, at the end of each round",
"BOL.settings.diceFormula": "Dice Formula",
"BOL.settings.diceFormulaTooltip": "Main dice formula (2d6 per default)",
"BOL.settings.diceSuccessValue" : "Success value",
"BOL.settings.diceSuccessValueTooltip": "Value of the success threshold (9 per default for 2d6)",
"BOL.settings.diceCriticalValue" : "Critical success value",
"BOL.settings.diceCriticalValueTooltip": "Minimum value for critical success (12 per default for 2d6)",
"BOL.settings.diceCriticalFailure" : "Critical failure value",
"BOL.settings.diceCriticalFailureTooltip": "Maximum value for critical failure (2 per default for 2d6)",
"BOL.settings.defaultLogoActorSheetPath" : "Path for Actor sheet logo",
"BOL.settings.defaultLogoPathActorSheetTooltip": "Path of the Actor sheet logo (346 x 200, default : /systems/bol/ui/logo.webp)",
"BOL.settings.defaultLogoTopLeftPath" : "Path for main top left logo",
"BOL.settings.defaultLogoTopLeftPathTooltip": "Path of the logo in the top left window (718 x 416, default : /systems/bol/ui/logo2.webp)"
}

View File

@ -1,8 +1,26 @@
{
"BOL.attributes.vigor": "Force",
"TYPES": {
"Actor": {
"character": "Personnage",
"npc": "PNJ",
"vehicle": "Véhicule"
},
"Item": {
"item": "Objet",
"feature": "Trait",
"weapon": "Arme",
"armure": "Armure"
}
},
"BOL.attributes.vigor": "Vigueur",
"BOL.attributes.halfvigor": "Demi-vigueur",
"BOL.attributes.agility": "Agilité",
"BOL.attributes.mind": "Esprit",
"BOL.attributes.appeal": "Aura",
"BOL.attributes.hull": "Coque",
"BOL.attributes.crew": "Equipage",
"BOL.attributes.resources": "Resources",
"BOL.attributes.row": "Rames",
"BOL.aptitudes.init": "Initiative",
"BOL.aptitudes.melee": "Mêlée",
"BOL.aptitudes.ranged": "Tir",
@ -13,5 +31,581 @@
"BOL.resources.faith": "Foi",
"BOL.resources.creation": "Création",
"BOL.resources.power": "Pouvoir",
"BOL.traits.xp": "Expérience"
}
"BOL.resources.villainy": "Vilénie",
"BOL.resources.alchemypoints": "Points de Creation",
"BOL.resources.astrologypoints": "Points d'Astrologie",
"BOL.traits.xp": "Expérience",
"BOL.ui.tab.stats": "Attributs",
"BOL.ui.tab.combat": "Combat",
"BOL.ui.tab.actions": "Actions",
"BOL.ui.tab.features": "Traits",
"BOL.ui.tab.equipment": "Equipement",
"BOL.ui.tab.description": "Description",
"BOL.ui.tab.details": "Details",
"BOL.ui.tab.spellalchemy": "Mystères",
"BOL.ui.astrologerPoints": "Points d'Astrologie",
"BOL.ui.astrologerPointsLabel": "Points d'Astrologie actuels",
"BOL.ui.ishoroscopemajor": "Horoscope Majeur (ie de groupe) ?",
"BOL.ui.answer": "Réponse",
"BOL.ui.horoscopefavorable": "Favorable (1dB)",
"BOL.ui.horoscopeunfavorable": "Défavorable (1dM)",
"BOL.ui.horoscopes": "Horoscopes",
"BOL.ui.horoscopesBonus": "Horoscopes (Bonus)",
"BOL.ui.horoscopesMalus": "Horoscopes (Malus)",
"BOL.ui.groupHoroscope": "Horoscrope de Groupe de ",
"BOL.ui.properties": "Propriétés",
"BOL.ui.description": "Description",
"BOL.ui.actions": "Actions",
"BOL.ui.capacities": "Capacités",
"BOL.ui.damages": "Dommages",
"BOL.ui.details": "Détails",
"BOL.ui.category": "Catégorie",
"BOL.ui.subcategory": "Sous-catégorie",
"BOL.ui.type": "Type",
"BOL.ui.subtype": "Sous-type",
"BOL.ui.attribute": "Attribut",
"BOL.ui.aptitude": "Aptitude",
"BOL.ui.advantages": "Avantages/Désavantages",
"BOL.ui.modifiers": "Modificateurs",
"BOL.ui.item": "Objet",
"BOL.ui.edit": "Editer",
"BOL.ui.unequip": "Déséquiper",
"BOL.ui.equip": "Équiper",
"BOL.ui.delete": "Supprimer",
"BOL.ui.roll": "Utiliser",
"BOL.ui.equipment": "Équipement",
"BOL.ui.equipmentProperties": "Propriétés d'équipement",
"BOL.ui.weaponAttack": "Attaque d'arme",
"BOL.ui.weaponProperties": "Propriétés offensives",
"BOL.ui.protectionProperties": "Protection",
"BOL.ui.magicalProperties": "Propriétés magiques",
"BOL.ui.capacityProperties": "Propriétés de capacité",
"BOL.ui.alchemyProperties": "Propriétés des Préparations Alchimiques",
"BOL.ui.armor": "Armure",
"BOL.ui.reach": "Allonge",
"BOL.ui.weapon": "Arme",
"BOL.ui.melee": "Arme de contact",
"BOL.ui.ranged": "Arme à distance",
"BOL.ui.protection": "Protection",
"BOL.ui.shield": "Bouclier",
"BOL.ui.blocking": "Blocage",
"BOL.ui.range": "Portée",
"BOL.ui.quantity": "Quantité",
"BOL.ui.qty": "Qté",
"BOL.ui.slot": "Empl.",
"BOL.ui.weight": "Poids",
"BOL.ui.price": "Prix",
"BOL.ui.cancel": "Annuler",
"BOL.ui.submit": "OK",
"BOL.ui.attributeCheck": "Test d'attribut",
"BOL.ui.aptitudeCheck": "Test d'aptitude",
"BOL.ui.weaponCheck": "Jet d'attaque",
"BOL.ui.spellCheck": "Jet de sort",
"BOL.ui.careers": "Carrières",
"BOL.ui.boons": "Avantages",
"BOL.ui.flaws": "Désavantages",
"BOL.ui.rank": "Rang",
"BOL.ui.success": "Succès",
"BOL.ui.failure": "Échec",
"BOL.ui.fumble": "Échec critique",
"BOL.ui.critical": "Succès Héroïque",
"BOL.ui.criticallegend": "Succès Légendaire !",
"BOL.ui.maneuvers": "Actions de combat",
"BOL.ui.stacksize": "Taille de pile (max)",
"BOL.ui.weapons": "Armes",
"BOL.ui.protections": "Protections",
"BOL.ui.ammos": "Munitions",
"BOL.ui.containers": "Conteneurs",
"BOL.ui.treasure": "Trésor",
"BOL.ui.vehicles": "Véhicules/Montures",
"BOL.ui.misc": "Divers",
"BOL.ui.vehicleProperties": " Propriétés de véhicule",
"BOL.ui.speed": "Vitesse",
"BOL.ui.noWeaponName": "Arme Inconnue",
"BOL.ui.targetDefence": "Défense",
"BOL.ui.applyShieldMalus": "Appliquer le Malus de Petit Bouclier",
"BOL.ui.shieldMalus": "Malus de Bouclier",
"BOL.ui.defenseScore": "Score de Defense",
"BOL.ui.defender": "Défenseur",
"BOL.ui.difficulty": "Difficulté",
"BOL.ui.spellProperties": "Propriétés du Sort",
"BOL.ui.duration": "Durée",
"BOL.ui.spellkeep": "Prolongation possible ?",
"BOL.ui.concentrate": "Concentration à maintenir ?",
"BOL.ui.aggressive": "Sort aggressif ?",
"BOL.ui.registerInit": "Enregistrer comme Init. de combat",
"BOL.ui.initMalus": "Malus d'initiative",
"BOL.ui.magicnewrules": "Règles supplémentaires (cf. supplément fan-made Sorcellerie!)",
"BOL.ui.isSorcerer": "Carrière de Sorcier ?",
"BOL.ui.isAlchemist": "Carrière d'Alchimiste ?",
"BOL.ui.isPriest": "Carrière de Prêtre/Druide ?",
"BOL.ui.isAstrologer": "Carrière d'Astrologue?",
"BOL.ui.circle": "Cercle",
"BOL.ui.spells": "Sorts",
"BOL.ui.focusSpell": "Lance un sort",
"BOL.ui.sorcererRank": "Rang du Sorcier",
"BOL.ui.alchemistRank": "Rang de l'Alchimiste",
"BOL.ui.mandatoryconditions": "Conditions obligatoires",
"BOL.ui.optionnalconditions": "Conditions optionnelles",
"BOL.ui.ppcost": "Cout en Points de Pouvoir",
"BOL.ui.ppAvailable": "Points de Pouvoir actuels",
"BOL.ui.pccost": "Coût en Points de Création",
"BOL.ui.pcnow": "Points de Création actuels",
"BOL.ui.alchemyType": "Type",
"BOL.ui.alchemy": "Préparations Alchimiques",
"BOL.ui.makeAlchemy": "Réaliser une Préparation Alchmique",
"BOL.ui.alchemyCostTotal": "Points de Création nécessaires pour la Préparation",
"BOL.ui.alchemyInvest": "Points de Création investis",
"BOL.ui.alchemyCurrent": "Points de Création actuel dans la Préparation",
"BOL.ui.astrology": "Astrologie et Horoscopes",
"BOL.ui.astrologyMinor": "Etablir un Horoscope Mineur",
"BOL.ui.astrologyMajor": "Etablir un Horoscope Majeur",
"BOL.ui.astrologyMajorGroup": "Etablir un Horoscope Majeur de Groupe",
"BOL.ui.makeHoroscope": "Etablir un Horoscope",
"BOL.ui.astrologerRank": "Rang de l'Astrologue",
"BOL.ui.horoscopeCost": "Cout en Points d'Astrologie",
"BOL.ui.minor": "Mineur",
"BOL.ui.major": "Majeur",
"BOL.ui.majorgroup": "Majeur de Groupe",
"BOL.ui.horoscopeGroup": "Horoscopes de Groupe",
"BOL.ui.horoscopeDiceRemaining": "Dés restants",
"BOL.ui.horoscopeDiceMax": "Dés Max",
"BOL.ui.astrologyNoPoints": "Vous n'avez pas assez de Points d'Astrologie!",
"BOL.ui.advance": "Avancement",
"BOL.ui.isbonusdice": "Fourni un dé bonus?",
"BOL.ui.ismalusdice": "Fourni un dé malus?",
"BOL.ui.bonusmalus": "Dés Bonus/Malus additionnels",
"BOL.ui.nbdices": "Nombre de dés",
"BOL.ui.totalmod": "Total Mod.",
"BOL.ui.rangeModifiers": "Mod. de Portée",
"BOL.ui.money": "Bougette",
"BOL.ui.moneyTitle": "Or et Piecettes",
"BOL.ui.fightOption": "Options de Combat",
"BOL.ui.none": "Aucune",
"BOL.ui.fightOptionType": "Types d'options de Combat",
"BOL.ui.activated": "Active",
"BOL.ui.deactivated": "Inactive",
"BOL.ui.toactivated": "Active (>Désactiver)",
"BOL.ui.todeactivated": "Inactive (>Activer)",
"BOL.ui.status": "Statut",
"BOL.ui.armorAgiMalus": "Malus d'Armure+Bouclier (Agi)",
"BOL.ui.armorInitMalus": "Malus d'Armure (Init)",
"BOL.ui.attackValue": "Valeur d'attaque",
"BOL.ui.vehicleWeapons": "Armes de véhicules",
"BOL.ui.hullDamage": "D.coque",
"BOL.ui.crewDamage": "D.équipage",
"BOL.ui.fireDamage": "Feu ?",
"BOL.ui.weaponbonus": "Cette arme bénéficie déja d'un Dé de Bonus (Arme Favorite prise en compte, par exemple)",
"BOL.ui.creature": "Creature",
"BOL.ui.rabble": "Piétaille",
"BOL.ui.tough": "Coriace",
"BOL.ui.villain": "Rival",
"BOL.ui.attributaptitude": "Attribut ou Aptitude",
"BOL.ui.always": "Tout les jets (ie toujours)",
"BOL.ui.effectbonusmalus": "Bonus ou Malus à appliquer",
"BOL.ui.boleffects": "Effets (automatiques)",
"BOL.ui.modifier": "Modificateur",
"BOL.ui.effects": "Effets en cours",
"BOL.ui.pcname": "PJs",
"BOL.ui.npcname": "PNJs",
"BOL.ui.pclistbutton": "Vue compacte",
"BOL.ui.noactorfound": "PNJ inconnu, le PNJ doit être présent dans le monde pour s'afficher ici.",
"BOL.ui.deletetitle": "Suppression",
"BOL.ui.confirmdelete": "Vous êtes sûr de vouloir supprimer cet item ?",
"BOL.ui.nomorealchemypoints": "Plus assez de Points de Création !",
"BOL.ui.armornoformula": "L'armure {protect.name} n'a pas de formule pour la protection !",
"BOL.ui.selectactor": "Selectionnez votre personnage pour utiliser la macro",
"BOL.ui.itemnotfound": "Impossible de trouver l'objet de cette macro",
"BOL.ui.noinit": "Pas d'initiative trouvée, veuillez en enregistrer une.",
"BOL.ui.warninitiative": "Votre initiative n'est pas disponible. Effectuez un jet d'Initiative pour ce combat.",
"BOL.ui.isspecial": "Spéciale ?",
"BOL.ui.createEquipment": "Créer un Equipement",
"BOL.featureCategory.origins": "Origines",
"BOL.featureCategory.races": "Races",
"BOL.featureCategory.careers": "Carrières",
"BOL.featureCategory.boons": "Avantages",
"BOL.featureCategory.flaws": "Désavantages",
"BOL.featureCategory.languages": "Langues",
"BOL.featureCategory.fightoptions": "Options de Combat",
"BOL.bougette.nomoney": "A sec",
"BOL.bougette.tolive": "De quoi vivre",
"BOL.bougette.easylife": "A l'aise",
"BOL.bougette.luxury": "Luxe&Volupté",
"BOL.bougette.rich": "Richissime",
"BOL.featureSubtypes.origin": "Origine",
"BOL.featureSubtypes.race": "Race",
"BOL.featureSubtypes.career": "Carrière",
"BOL.featureSubtypes.boon": "Avantage",
"BOL.featureSubtypes.flaw": "Désavantage",
"BOL.featureSubtypes.language": "Langue",
"BOL.featureSubtypes.gods": "Dieux & Foi",
"BOL.featureSubtypes.fightOption": "Option de Combat",
"BOL.featureSubtypes.effect": "Effet",
"BOL.featureSubtypes.effects": "Effets",
"BOL.featureSubtypes.boleffect": "Effet",
"BOL.featureSubtypes.horoscope": "Horoscope",
"BOL.fightOptionTypes.armor": "Attaque au défaut d'armure",
"BOL.fightOptionTypes.intrepid": "Attaque intrépide",
"BOL.fightOptionTypes.twoweaponsdef": "Combat à 2 armes (Défense)",
"BOL.fightOptionTypes.twoweaponsatt": "Combat à 2 armes (Attaque)",
"BOL.fightOptionTypes.fulldefense": "Défense totale",
"BOL.fightOptionTypes.defense": "Posture défensive",
"BOL.fightOptionTypes.attack": "Posture offensive",
"BOL.fightOptionTypes.other": "Autres",
"BOL.itemCategory.object": "Objet",
"BOL.itemCategory.equipment": "Équipement",
"BOL.itemCategory.consumable": "Consommable",
"BOL.itemCategory.spell": "Sort",
"BOL.itemCategory.vehicle": "Monture/Véhicule",
"BOL.itemCategory.other": "Autre",
"BOL.itemCategory.capacity": "Capacité",
"BOL.itemCategory.alchemy": "Préparation Alchimique",
"BOL.itemCategory.vehicleweapon": "Armes de Véhicule",
"BOL.combatCategory.protections": "Protections",
"BOL.combatCategory.shields": "Boucliers",
"BOL.combatCategory.melee": "Armes de contact",
"BOL.combatCategory.ranged": "Armes à distance",
"BOL.combatCategory.fightOptions": "Options de combat",
"BOL.combatCategory.natural": "Armes Naturelless",
"BOL.equipmentCategory.weapon": "Arme",
"BOL.equipmentCategory.armor": "Armure",
"BOL.equipmentCategory.protection": "Protection",
"BOL.equipmentCategory.shield": "Bouclier",
"BOL.equipmentCategory.helm": "Casque",
"BOL.equipmentCategory.jewel": "Bijou",
"BOL.equipmentCategory.scroll": "Parchemin",
"BOL.equipmentCategory.ammunition": "Munition",
"BOL.equipmentCategory.container": "Conteneur",
"BOL.equipmentCategory.currency": "Monnaie",
"BOL.equipmentCategory.other": "Autre",
"BOL.protectionCategory.armor": "Armure",
"BOL.protectionCategory.shield": "Bouclier",
"BOL.protectionCategory.helm": "Casque",
"BOL.protectionCategory.other": "Autre",
"BOL.spellItem.charm": "Charme",
"BOL.spellItem.circle1": "Premier Cercle",
"BOL.spellItem.circle2": "Second Cercle",
"BOL.spellItem.circle3": "Troisième Cercle",
"BOL.alchemyItem.common": "Courante",
"BOL.alchemyItem.scarce": "Rare",
"BOL.alchemyItem.legend": "Légendaire",
"BOL.alchemyItem.mythic": "Mythique",
"BOL.weaponCategory.melee": "Arme de mêlée",
"BOL.weaponCategory.ranged": "Arme de tir",
"BOL.weaponCategory.other": "Autre",
"BOL.itemProperty.damageMultiplier": "Multiplicateur de dommages",
"BOL.itemProperty.attackBonusDice": "Dé de Bonus d'attaque",
"BOL.itemProperty.equipable": "Équipable",
"BOL.itemProperty.protection": "Protection",
"BOL.itemProperty.blocking": "Blocage",
"BOL.itemProperty.magical": "Magique",
"BOL.itemProperty.concealable": "Dissimulable",
"BOL.itemProperty.2H": "Arme à 2 mains",
"BOL.itemProperty.helm": "Casque",
"BOL.itemProperty.improvised": "Improvisée",
"BOL.itemProperty.shield": "Bouclier",
"BOL.itemProperty.melee": "Arme de contact",
"BOL.itemProperty.throwable": "Peut être lancée",
"BOL.itemProperty.ignoreshield": "Ignore les boucliers",
"BOL.itemProperty.bashing": "Dégâts non létaux",
"BOL.itemProperty.stackable": "Empilable",
"BOL.itemProperty.ranged": "A distance",
"BOL.itemProperty.weapon": "Offensive",
"BOL.itemProperty.reloadable": "Rechargeable",
"BOL.itemProperty.worn": "Équipé",
"BOL.itemProperty.spell": "Sort",
"BOL.itemProperty.armor": "Armure",
"BOL.itemProperty.consumable": "Consommable",
"BOL.itemProperty.bow": "Arc",
"BOL.itemProperty.crossbow": "Arbalète",
"BOL.itemProperty.throwing": "Arme de jet",
"BOL.itemProperty.activable": "Activable",
"BOL.itemProperty.powder": "Arme à poudre",
"BOL.itemProperty.attackAttribute": "Attaque (Attribut)",
"BOL.itemProperty.attackAptitude": "Attaque (Aptitude)",
"BOL.itemProperty.attackModifiers": "Attaque (Modificateurs)",
"BOL.itemProperty.attackReroll1": "Attaque (Relancer les 1)",
"BOL.itemProperty.damage": "Dommages (Dés)",
"BOL.itemProperty.damageModifiers": "Dommages (Modificateurs)",
"BOL.itemProperty.damageAttribute": "Dommages (Attribut)",
"BOL.itemProperty.damageSpecial": "Dommages (Spécial)",
"BOL.itemProperty.damageReroll1": "Relancer les 1",
"BOL.itemProperty.range": "Portée (en m)",
"BOL.itemProperty.soakFormula": "Encaissement (Formule)",
"BOL.itemProperty.soakModifiers": "Encaissement (Modificateur)",
"BOL.itemProperty.soakValue": "Encaissement (Valeur par défaut)",
"BOL.itemProperty.armorQuality": "Qualité d'armure",
"BOL.itemProperty.blockingMalus": "Malus de blocage",
"BOL.itemProperty.blockingAttacksBlocked": "Attaques bloquée",
"BOL.itemProperty.blocking1Attack": "Bloque 1 attaque",
"BOL.itemProperty.blockingAllAttacks": "Bloque toutes les attaques",
"BOL.itemProperty.slot": "Emplacement utilisé",
"BOL.itemProperty.reload": "Rechargement (Actions)",
"BOL.itemProperty.weaponSize": "Classe d'arme",
"BOL.itemProperty.difficulty": "Difficulté",
"BOL.itemProperty.natural": "Arme naturelle",
"BOL.itemProperty.onlymodifier": "Modificateur uniquement (ie attaques de créatures)",
"BOL.itemProperty.vehicleDamageType": "Type de dommages de véhicules",
"BOL.itemProperty.isfiredamage": "Dommages de Feu",
"BOL.itemProperty.ishulldamage": "Dommages à la coque",
"BOL.itemProperty.iscrewdamage": "Dommages à l'équipage",
"BOL.itemProperty.hulldamage": "Valeur des dommages à la coque",
"BOL.itemProperty.crewdamage": "Valeur des dommages à l'équipage",
"BOL.itemProperty.hullDamageMultiplier": "Multiplicateur",
"BOL.itemProperty.crewDamageMultiplier": "Multiplicateur",
"BOL.itemProperty.isboarding": "Abordage",
"BOL.itemProperty.isspur": "Eperonnage",
"BOL.itemProperty.isbreakrow": "Briser les rames",
"BOL.itemStat.quantity": "Quantité",
"BOL.itemStat.weight": "Poids",
"BOL.itemStat.price": "Prix",
"BOL.itemStat.range": "Portée",
"BOL.itemStat.damage": "Dommages",
"BOL.itemStat.reload": "Rechargement (Actions)",
"BOL.itemStat.soak": "Valeur de protection",
"BOL.itemStat.blocking": "Bloquage",
"BOL.itemStat.modifiers": "Modificateurs",
"BOL.weaponSize.unarmed": "Mains nues",
"BOL.weaponSize.improvised": "Arme improvisée",
"BOL.weaponSize.light": "Légère",
"BOL.weaponSize.medium": "Moyenne",
"BOL.weaponSize.heavy": "Lourde",
"BOL.itemModifiers.init": "Malus (Initiative)",
"BOL.itemModifiers.social": "Malus (Social)",
"BOL.itemModifiers.agility": "Malus (Agilité)",
"BOL.itemModifiers.powercost": "Malus (Coût supplémentaire en PP)",
"BOL.itemBlocking.malus": "Social",
"BOL.itemBlocking.nbAttacksPerRound": "Agilité",
"BOL.soakFormula.none": "-",
"BOL.soakFormula.light": "Légère (Annule d6-3 dégâts subis)",
"BOL.soakFormula.medium": "Moyenne (Annule d6-2 dégâts subis)",
"BOL.soakFormula.heavy": "Lourde (Annule d6-1 dégâts subis)",
"BOL.armorQuality.none": "-",
"BOL.armorQuality.light": "Légère",
"BOL.armorQuality.lightQ": "Légère de qualité",
"BOL.armorQuality.lightSup": "Légère Supérieure",
"BOL.armorQuality.lightLeg": "Légère Légendaire",
"BOL.armorQuality.medium": "Moyenne",
"BOL.armorQuality.mediumQ": "Moyenne de qualité",
"BOL.armorQuality.mediumSup": "Moyenne Supérieure",
"BOL.armorQuality.mediumLeg": "Moyenne Légendaire",
"BOL.armorQuality.heavy": "Lourde",
"BOL.armorQuality.heavyQ": "Lourde de qualité",
"BOL.armorQuality.heavySup": "Lourde Supérieure",
"BOL.armorQuality.heavyLeg": "Lourde Légendaire",
"BOL.equipmentSlots.none": "-",
"BOL.equipmentSlots.head": "Tête",
"BOL.equipmentSlots.neck": "Cou",
"BOL.equipmentSlots.shoulders": "Épaules",
"BOL.equipmentSlots.body": "Corps",
"BOL.equipmentSlots.rhand": "Main droite",
"BOL.equipmentSlots.lhand": "Main gauche",
"BOL.equipmentSlots.2hands": "2 mains",
"BOL.equipmentSlots.rarm": "Bras droit",
"BOL.equipmentSlots.larm": "Bras gauche",
"BOL.equipmentSlots.chest": "Torse",
"BOL.equipmentSlots.belt": "Ceinture",
"BOL.equipmentSlots.legs": "Jambes",
"BOL.equipmentSlots.feet": "Pieds",
"BOL.equipmentSlots.finder": "Doigt",
"BOL.equipmentSlots.ear": "Oreille",
"BOL.vehicleCategory.mount": "Monture terrestre",
"BOL.vehicleCategory.flying": "Monture volante",
"BOL.vehicleCategory.boat": "Bateau",
"BOL.vehicleCategory.other": "Autre",
"BOL.range.PointBlank": "Bout portant",
"BOL.range.Short": "Courte",
"BOL.range.Medium": "Moyenne",
"BOL.range.Long": "Long",
"BOL.range.VeryLong": "Très longue",
"BOL.range.Extreme": "Extrême",
"BOL.range.Maximum": "Maximale",
"BOL.notification.MacroMultipleTokensSelected": "Vous avez sélectionné plusieurs tokens",
"BOL.notification.MacroNoActorAvailable": "Aucun acteur n'a pu être ciblé",
"BOL.notification.MacroNoTokenSelected": "Vous devez sélectionner un token",
"BOL.size.tiny": "Minuscule",
"BOL.size.verysmall": "Très petite",
"BOL.size.small": "Petite",
"BOL.size.medium": "Moyenne",
"BOL.size.large": "Grande",
"BOL.size.verylarge": "Très grande",
"BOL.size.huge": "Enorme",
"BOL.size.massive": "Massive",
"BOL.size.enormous": "Colossale",
"BOL.size.gigantic": "Gigantesque",
"BOL.size.immense": "Immense",
"BOL.size.colossal": "Monstrueuse",
"BOL.chat.fightactive": "{name} active son option de combat {foName} pour ce round !",
"BOL.chat.fightunactive": "{name} désactive son option de combat {foName} pour ce round !",
"BOL.chat.isdead": "{name} est mort !",
"BOL.chat.epitaph": "Que son nom soit honoré sur les champs de batailles de Lémurie !",
"BOL.chat.vitalityzero": "La Vitalité de {name} est {hp} : il va s'écrouler au sol et sombrer dans l'inconscience !",
"BOL.chat.vitalityheroism": "Vous pouvez dépenser 1 Point d'Héroisme/Vilainie pour reprendre vos esprits pendant 1 round.",
"BOL.chat.vitalityheroismhint": "Dans ce cas votre vitalité remonte à son maximum divisé par 2 (arrondi au supérieur).",
"BOL.chat.vitalitydying": "La Vitalité de {name} est de {hp} ! Il est mourant ...",
"BOL.chat.vitalitydyingheroism": "Vous pouvez cependant dépenser 1 Point d'Héroisme/Vilainie pour Défier la Mort (cf. page 58).",
"BOL.chat.alchemytitle": "Préparation Alchimique : {name}",
"BOL.chat.alchemypoints": "Points de Création Investis : {pcCostCurrent}",
"BOL.chat.alchemysuccess": "La préparation alchimique a été réalisée avec succès !<br>Créez l'item ou l'effet correspondant dans votre Inventaire.<br>L'avancement dans la préparation a été remis à 0.",
"BOL.chat.alchemyfailure": "La préparation alchimique a échouée !<br>L'avancement dans la préparation a été remis à 0.",
"BOL.chat.rolldamage": "Lancer les dommages",
"BOL.chat.rolldamage6": "Lancer les dommages +6",
"BOL.chat.rolldamage12": "Dommages +12 (1 Pt. d'Heroisme)",
"BOL.chat.damageresult": "Dommages de {name} : {total}",
"BOL.chat.damagetarget": "Cible : {target}",
"BOL.chat.applydamagetotarget": "Appliquer les dommages à la cible",
"BOL.chat.fightoption": "Option de combat",
"BOL.chat.reroll": "Relancer (1 P. Heroisme)",
"BOL.chat.heroicreminder": "En plus des actions indiquées sur les boutons ci-dessous, vous pouvez : <ul><li>Carnage : Attaquer une seconde fois le même adversaire</li><li>Coup précis : Un dé de malus à votre adversaire sur une localisation choisie</li><li>Désarmement</li><li>Massacrer la piétaille</li><li>Renversement : Renversez votre adversaire (1 taille de plus max)</li></ul>Si vous dépensez un Point d'Héroisme en plus, tout ces effets peuvent être doublés",
"BOL.chat.toheroic": "Transformer en succés Héroïque (1 P. Héroisme/Vilainie)",
"BOL.chat.tolegend": "Transformer en succes Légendaire (1 P. Heroisme/Vilainie)",
"BOL.chat.hurttitle": "{name} va encaisser {damageTotal} dégats !",
"BOL.chat.armordefault": "C'est une attaque au défaut de l'armure : vous devez encaisser SANS la protection de l'armure !",
"BOL.chat.witharmor": "Encaisser avec la protection de l'armure",
"BOL.chat.withoutarmor": "Encaisser sans la protection de l'armure",
"BOL.chat.shakeoff": "Juste une égratignure (1 Point d'Héroisme/Vilainie)",
"BOL.chat.splinteredshield": "Parade in Extremis avec {name} (1 Point d'Héroisme/Vilainie)",
"BOL.chat.damagesummary": "Dégats subis par {name}",
"BOL.chat.protectvalue": "Protection de l'armure",
"BOL.chat.noprotectvalue": "Aucune protection d'armure !",
"BOL.chat.heroreducedamage": "Un point d'héroisme/vilainie dépensé, pour une réduction des dommages supplémentaire de {total}.",
"BOL.chat.herosplintered": "Aucun dommage encaissé, grâce à la parade in-extremis avec {weaponHero.name}. L'arme a été détruite pendant cette parade ! Un point d'héroisme/vilainie a également été dépensé.",
"BOL.chat.finaldamage": "Encaissement final : {finalDamage} dégats !",
"BOL.chat.spell": "Sort",
"BOL.chat.spellcost": "Cout en Points de Pouvoir",
"BOL.chat.spellremaining": "Points de Pouvoir restants",
"BOL.chat.nodamagesummary": "Aucun dégats n'a été subi ....",
"BOL.chat.damageresume": "{name} a subi des blessures ...",
"BOL.chat.fumblemessage": "Si vous acceptez les conséquences d'un echec catastrophique (au choix du MJ), vous pourrez bénéficier d'1 point d'Héroïsme supplémentaire",
"BOL.chat.rangeinfo": "Tir/Lancer de {attackerName} vers {defenderName}",
"BOL.chat.rangeweaponinfo": "Arme : {weaponName} - Portée de base {weaponRange}",
"BOL.chat.rangeout": "Modificateur : Hors de portée",
"BOL.chat.range0": "Modificateur : Bout portant (+1)",
"BOL.chat.range1": "Modificateur : Portée courte (0)",
"BOL.chat.range2": "Modificateur : Portée moyenne (-1)",
"BOL.chat.range3": "Modificateur : Portée longue (-2)",
"BOL.chat.range4": "Modificateur : Portée très longue (-4)",
"BOL.chat.range5": "Modificateur : Portée extrême (-6)",
"BOL.chat.range6": "Modificateur : Portée maximale (-8)",
"BOL.chat.rangeprefix": "Distance évaluée : ",
"BOL.chat.rangevisible": "La ligne de vue est dégagée entre les protagonistes.",
"BOL.chat.rangenotvisible": "La ligne de vue est bloquée entre les protagonistes.",
"BOL.chat.rangetitle": "Information MJ",
"BOL.chat.weaponreroll1": "Pour information, cette arme relance les 1 sur ses dégâts.",
"BOL.chat.rollbougette": "Jet de Bougette",
"BOL.chat.bougettesuccess": "Votre bougette reste inchangée !",
"BOL.chat.bougettefailure": "Vous avez trop dépensé, votre bougette s'est réduite...",
"BOL.chat.initiative": "Rang d'intiative (10 à 1)",
"BOL.chat.horoscope": "Horoscope",
"BOL.chat.horoscopepoints": "Coût : {points} Points d'Astrologie",
"BOL.chat.horoscopeminorsuccess": "Votre horoscope mineur est un succès : éditez le nom de l'horoscope sur votre fiche. Vous bénéficiez d'1 dé Bonus pour cette situation.",
"BOL.chat.horoscopeminorfailure": "Votre horoscope mineur est un échec : éditez le nom de l'horoscope sur votre fiche. Vous souffrez d'1 dé Malus pour cette situation.",
"BOL.chat.horoscopemajorsuccess": "Votre horoscope majeur est un succès : {horoscopeName} bénéficie d'1 point d'Héroisme de plus pour cette aventure. Ce point a été ajouté automatiquement.",
"BOL.chat.horoscopemajorfailure": "Votre horoscope majeur est un échec : {horoscopeName} a perdu 1 point d'Héroisme pour cette aventure. Ce point a été enlevé automatiquement.",
"BOL.chat.horoscopemajorgroupsuccess": "Votre horoscope majeur de groupe est un succès. Vous et vos amis bénéficiez de {careerBonus} dés bonus pendant cette aventure.",
"BOL.chat.horoscopemajorgroupfailure": "Votre horoscope majeur de groupe est un échec. Vous et vos amis souffrez de {careerBonus} dés malus pendant cette aventure.",
"BOL.chat.usedhoroscope": "Horoscope utilisé",
"BOL.chat.horoscopedeleted": "Le(s) Horoscopes utilisé(s) a/ont été supprimé(s) automatiquement.",
"BOL.chat.criticaloptions": "Succès critique !! Vous pouvez faire (1 option au choix) :",
"BOL.chat.criticalcarnage": "Faire un Carnage : vous avez une attaque gratuite supplémentaire. Cette seconde attaque ne peut bénéficier d'un Point d'Héroisme/vilainie.",
"BOL.chat.criticalplus6": "Coup Dévastateur : +6 aux dommages (cf bouton ci-dessous).",
"BOL.chat.criticalprecise": "Coup Précis : Vous frappez pour diminuer les capacités de votre adversaire. Décrivez ce que vous faites, et si le MJ l'accepte, votre opposant subira un Dé de Malus pour les actions concernées.",
"BOL.chat.criticalunarm": "Désarmement : Si votre adversaire a une arme en main, vous le désarmez.",
"BOL.chat.criticalrabble": "Massacrer la piétaille : Si vous combattez de la Piétaille, les résultats des dommages indiquent le nombre d'adversaires mis hors de combat.",
"BOL.chat.criticalpush": "Renversement : Si la taille le permet, vous poussez votre adversaire au sol, il souffrira d'1 Dé de Malus pour toutes ses actions au round suivant.",
"BOL.chat.criticalup": "Transformer en Légendaire : En dépensant 1 point d'Héroisme/Vilainie, vous pouvez transformer ce Succès Héroïque en Légendaire, qui vous permet de prendre 2 options dans la liste ci-dessus (cf. bouton pour un +12 aux dommages par exemple).",
"BOL.chat.criticalinfo": "C'est un succès Héroïque ou Légendaire ! Choisissez vos options et effets !",
"BOL.chat.criticalbuttonjournal": "Succès Héroïque/Légendaire",
"BOL.chat.losshp": "{name} a perdu {lossHP} points de Vitalité. Si il se repose quelques minutes, il peut récupérer {recupHP} points de Vitalité.",
"BOL.chat.applyrecup": "Récupérer pendant quelques minutes (+{recupHP} Vitalité)",
"BOL.chat.inforecup": "{name} vient de récupérer {recupHP} points de Vitalité après quelques minutes de repos.",
"BOL.dialog.soeasy": "Inmanquable (+4)",
"BOL.dialog.veryeasy": "Trés Facile (+2)",
"BOL.dialog.easy": "Facile (+1)",
"BOL.dialog.moderate": "Moyenne (0)",
"BOL.dialog.hard": "Ardue (-1)",
"BOL.dialog.tough": "Difficile (-2)",
"BOL.dialog.demanding": "Très Difficile (-4)",
"BOL.dialog.formidable": "Impossible (-6)",
"BOL.dialog.heroic": "Héroïque (-8)",
"BOL.dialog.mythic": "Mythique (-10)",
"BOL.dialog.divine": "Divine (-12)",
"BOL.dialog.pointblank": "Bout portant (+1)",
"BOL.dialog.close": "Courte (0)",
"BOL.dialog.medium": "Moyenne (-1))",
"BOL.dialog.long": "Longue (-2)",
"BOL.dialog.distant": "Très longue (-4)",
"BOL.dialog.extreme": "Extrême (-6)",
"BOL.dialog.utmost": "Maximale (-8)",
"BOL.ui.name": "Nom",
"BOL.ui.xp": "Experience",
"BOL.ui.xpspent": "Dépensée",
"BOL.ui.xptotal": "Totale",
"BOL.ui.biosize": "Taille",
"BOL.ui.bioweight": "Poids",
"BOL.ui.bioage": "Age",
"BOL.ui.biohair": "Cheveux",
"BOL.ui.bioeyes": "Yeux",
"BOL.ui.biosigns": "Signes distinctifs",
"BOL.ui.biodescription": "Description",
"BOL.ui.bionotes": "Notes",
"BOL.chat.welcome1": "Bienvenue dans Barbarians of Lemuria (Ludospherik version)",
"BOL.chat.welcome2": "Les livres nécessaires pour jouer sont disponibles sur le site de <a href='http://www.ludospherik.fr/content/14-barbarians-of-lemuria'>l'éditeur Ludospherik.</a>",
"BOL.chat.welcome3": "Les cartes intégrées au système le sont grace à l'aimable autorisation de leur auteur Guillaume Tavernier et des éditions Ludospherik. Merci à eux !.",
"BOL.chat.welcome4": "Tout le support et le suivi de ce système est disponible via le <a href='https://discord.gg/pPSDNJk'>Discord Foundry FR</a>.",
"BOL.chat.welcome5": "Consulter l'aide en ligne pour plus d'informations : @UUID[Compendium.bol.aides-de-jeu.97rugQOtiwt8zPfQ]{Aide du Jeu}.",
"BOL.chat.welcome6": "Bon jeu en Lemurie !",
"BOL.chat.nodamage": "Ne pas appliquer les dommages",
"BOL.settings.rollArmor": "Effectuer des jets pour les armures",
"BOL.settings.rollArmorTooltip": "Effectue un jet de dés pour les armures (valeur fixe si désactivé)",
"BOL.settings.useBougette": "Utiliser la Bougette (règle fan-made)",
"BOL.settings.useBougetteTooltip": "Utilise un indicateur de Bougette, comme décrit dans l'aide de jeu Annales Lemurienne du RatierBretonnien (https://www.lahiette.com/leratierbretonnien/)",
"BOL.settings.removeDead": "Enlever les PNJs morts automatiquement au round suivant",
"BOL.settings.removeDeadTooltip": "Supprime les PNJ (piétaille, créatures, coriaces) automatiquement du combat lorsqu'ils sont à 0 Vitalité ou moins, lors du passage au round suivant",
"BOL.settings.diceFormula": "Formule de dés",
"BOL.settings.diceFormulaTooltip": "Formule de dés utilisée pour les jets de dés (par défaut 2d6)",
"BOL.settings.diceSuccessValue" : "Seuil de succès",
"BOL.settings.diceSuccessValueTooltip": "Seuil de succès pour les jets de dés (par défaut 9 pour 2d6)",
"BOL.settings.diceCriticalValue" : "Seuil de succès critique",
"BOL.settings.diceCriticalValueTooltip": "Seuil de succès critique pour les jets de dés (par défaut 12 pour 2d6)",
"BOL.settings.diceCriticalFailure" : "Valeur max d'échec critique",
"BOL.settings.diceCriticalFailureTooltip": "Valeur max d'échec critique pour les jets de dés (par défaut 2 pour 2d6)",
"BOL.settings.defaultLogoActorSheetPath" : "Chemin du logo des fiches de perso",
"BOL.settings.defaultLogoPathActorSheetTooltip": "Vous pouvez changer le logo BoL des fiches de perso, pour jouer dans un autre univers (idéalement 346 x 200, défaut : /systems/bol/ui/logo.webp)",
"BOL.settings.defaultLogoTopLeftPath" : "Chemin du logo haut gauche",
"BOL.settings.defaultLogoTopLeftPathTooltip": "Vous pouvez changer le logo BoL en haut à gauche de chaque écran (idéalement 718 x 416, défaut : /systems/bol/ui/logo2.webp)"
}

View File

@ -2,6 +2,9 @@
* Extend the basic ActorSheet with some very simple modifications
* @extends {ActorSheet}
*/
import { BoLRoll } from "../controllers/bol-rolls.js";
import { BoLUtility } from "../system/bol-utility.js";
export class BoLActorSheet extends ActorSheet {
/** @override */
@ -9,42 +12,26 @@ export class BoLActorSheet extends ActorSheet {
return mergeObject(super.defaultOptions, {
classes: ["bol", "sheet", "actor"],
template: "systems/bol/templates/actor/actor-sheet.hbs",
width: 600,
width: 860,
height: 600,
dragDrop: [{ dragSelector: ".items-list .item", dropSelector: null }],
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "stats" }]
});
}
/* -------------------------------------------- */
/** @override */
getData() {
console.debug("getData");
const actor = super.getData();
console.log(actor.data);
actor.data.details = actor.data.data.details;
actor.data.attributes = Object.values(actor.data.data.attributes);
actor.data.aptitudes = Object.values(actor.data.data.aptitudes);
actor.data.resources = Object.values(actor.data.data.resources);
actor.data.equipment = actor.data.items.filter(i => i.type === "item");
actor.data.features = {
"origin" : actor.data.items.find(i => i.type === "feature" && i.data.subtype === "origin"),
"race" : actor.data.items.find(i => i.type === "feature" && i.data.subtype === "race"),
"careers" : actor.data.items.filter(i => i.type === "feature" && i.data.subtype === "career"),
"boons" : actor.data.items.filter(i => i.type === "feature" && i.data.subtype === "boon"),
"flaws" : actor.data.items.filter(i => i.type === "feature" && i.data.subtype === "flaw")
};
// data.attributes = ["String", "Number", "Boolean"];
// for (let attr of Object.values(data.data.attributes)) {
// attr.isCheckbox = attr.dtype === "Boolean";
// }
return actor;
}
/** @override */
activateListeners(html) {
super.activateListeners(html);
function onLoad() {
let logoSheet = BoLUtility.getLogoActorSheet()
$(".bol-actor-form").css("backgroundImage",`url(${logoSheet})`)
}
// Setup everything onload
$(function () { onLoad(); });
// Everything below here is only needed if the sheet is editable
if (!this.options.editable) return;
@ -55,23 +42,139 @@ export class BoLActorSheet extends ActorSheet {
html.find('.item-edit').click(ev => {
const li = $(ev.currentTarget).parents(".item");
const item = this.actor.items.get(li.data("itemId"));
console.log(item);
item.sheet.render(true);
})
// Equip/Unequip item
html.find('.item-equip').click(this._onToggleEquip.bind(this));
html.find('.create_item').click(ev => {
this.actor.createEmbeddedDocuments('Item', [{ name: "Nouvel Equipement", type: "item" }], { renderSheet: true });
});
html.find(".toggle-fight-option").click((ev) => {
const li = $(ev.currentTarget).parents(".item")
this.actor.toggleFightOption(li.data("itemId"))
})
html.find(".inc-dec-btns-alchemy").click((ev) => {
const li = $(ev.currentTarget).parents(".item");
this.actor.spendAlchemyPoint(li.data("itemId"), 1)
})
html.find(".inc-dec-btns-resource").click((ev) => {
const dataset = ev.currentTarget.dataset;
const target = dataset.target
const incr = parseInt(dataset.incr)
this.actor.incDecResources(target, incr)
})
// Incr./Decr. career ranks
html.find(".inc-dec-btns").click((ev) => {
const li = $(ev.currentTarget).parents(".item");
if (li) {
const item = this.actor.items.get(li.data("itemId"));
if (item) {
const dataset = ev.currentTarget.dataset;
const operator = dataset.operator;
const target = dataset.target;
const incr = parseInt(dataset.incr)
const min = parseInt(dataset.min)
const max = parseInt(dataset.max) || 10000
let value = eval("item." + target)
value = value || 0
//console.log("IncDec", item, target, value, operator, min, max)
if (operator === "minus") {
if (value >= min + incr) value -= incr;
else value = min;
}
if (operator === "plus") {
if (value <= max - incr) value += incr;
else value = max;
}
let update = { [`${target}`]: value };
item.update(update);
}
}
});
// Delete Inventory Item
html.find('.item-delete').click(ev => {
const li = $(ev.currentTarget).parents(".item");
this.actor.deleteEmbeddedDocuments("Item", [li.data("itemId")])
li.slideUp(200, () => this.render(false));
Dialog.confirm({
title: game.i18n.localize("BOL.ui.deletetitle"),
content: game.i18n.localize("BOL.ui.confirmdelete"),
yes: () => {
const li = $(ev.currentTarget).parents(".item");
this.actor.deleteEmbeddedDocuments("Item", [li.data("itemId")])
li.slideUp(200, () => this.render(false));
},
no: () => { },
defaultYes: false,
});
});
// Rollable abilities.
html.find('.rollable').click(this._onRoll.bind(this));
}
/* -------------------------------------------- */
/** @override */
async getData(options) {
const data = super.getData(options)
const actorData = duplicate(data)
let formData = duplicate(data)
formData.config = game.bol.config
formData.data = actorData
formData.details = this.actor.details
formData.attributes = this.actor.attributes
formData.aptitudes = this.actor.aptitudes
formData.resources = this.actor.getResourcesFromType()
formData.xp = this.actor.system.xp
formData.equipment = this.actor.equipment
formData.equipmentCreature = this.actor.equipmentCreature
formData.weapons = this.actor.weapons
formData.protections = this.actor.protections
formData.spells = this.actor.spells
formData.alchemy = this.actor.alchemy
formData.containers = this.actor.containers
formData.treasure = this.actor.treasure
formData.boleffects = this.actor.boleffects
formData.alchemyrecipe = this.actor.alchemyrecipe
formData.horoscopes = this.actor.horoscopes
formData.vehicles = this.actor.vehicles
formData.fightoptions = this.actor.fightoptions
formData.ammos = this.actor.ammos
formData.misc = this.actor.misc
formData.combat = this.actor.buildCombat()
formData.initiativeRank = this.actor.getInitiativeRank()
//formData.combatCreature = this.actor.buildCombatCreature()
formData.features = this.actor.buildFeatures()
formData.isGM = game.user.isGM
formData.options = this.options
formData.owner = this.document.isOwner
formData.editScore = this.options.editScore
formData.useBougette = (this.actor.type == "character" && BoLUtility.getUseBougette()) || false
formData.bougette = this.actor.getBougette()
formData.charType = this.actor.getCharType()
formData.villainy = this.actor.getVillainy()
formData.biography = await TextEditor.enrichHTML(this.object.system.details?.biography || "", {async: true})
formData.notes = await TextEditor.enrichHTML(this.object.system.details.notes || "", {async: true})
formData.isSorcerer = this.actor.isSorcerer()
formData.isAlchemist = this.actor.isAlchemist()
formData.isAstrologer = this.actor.isAstrologer()
formData.isMysteries = formData.isSorcerer || formData.isAlchemist || formData.isAstrologer
formData.isPriest = this.actor.isPriest()
formData.horoscopeGroupList = game.settings.get("bol", "horoscope-group")
formData.isGM = game.user.isGM
console.log("ACTORDATA", formData)
return formData;
}
/* -------------------------------------------- */
/**
* Handle creating a new Owned Item for the actor using initial data defined in the HTML dataset
* @param {Event} event The originating click event
@ -99,6 +202,13 @@ export class BoLActorSheet extends ActorSheet {
return this.actor.createEmbeddedDocuments("Item", [itemData]);
}
_onToggleEquip(event) {
event.preventDefault();
const li = $(event.currentTarget).closest(".item");
const item = this.actor.items.get(li.data("itemId"));
return this.actor.toggleEquipItem(item);
}
/**
* Handle clickable rolls.
* @param {Event} event The originating click event
@ -106,17 +216,64 @@ export class BoLActorSheet extends ActorSheet {
*/
_onRoll(event) {
event.preventDefault();
const element = event.currentTarget;
const dataset = element.dataset;
if (dataset.roll) {
let roll = new Roll(dataset.roll, this.actor.data.data);
let label = dataset.label ? `Rolling ${dataset.label}` : '';
roll.roll().toMessage({
speaker: ChatMessage.getSpeaker({ actor: this.actor }),
flavor: label
});
const element = event.currentTarget
const dataset = element.dataset
const rollType = dataset.rollType
const li = $(event.currentTarget).closest(".item")
switch (rollType) {
case "attribute":
BoLRoll.attributeCheck(this.actor, dataset.key, event)
break;
case "aptitude":
BoLRoll.aptitudeCheck(this.actor, dataset.key, event)
break;
case "weapon":
BoLRoll.weaponCheck(this.actor, event)
break;
case "spell":
BoLRoll.spellCheck(this.actor, event)
break;
case "alchemy":
BoLRoll.alchemyCheck(this.actor, event)
break;
case "protection":
this.actor.rollProtection(li.data("item-id"))
break;
case "damage":
this.actor.rollWeaponDamage(li.data("item-id"))
break;
case "aptitudexp":
this.actor.incAptitudeXP(dataset.key)
break;
case "attributexp":
this.actor.incAttributeXP(dataset.key)
break;
case "bougette":
this.actor.rollBougette()
break;
case "careerxp":
this.actor.incCareerXP( li.data("item-id"))
break;
case "horoscope-minor":
BoLRoll.horoscopeCheck(this.actor, event, "minor")
break
case "horoscope-major":
BoLRoll.horoscopeCheck(this.actor, event, "major")
break
case "horoscope-major-group":
BoLRoll.horoscopeCheck(this.actor, event, "majorgroup")
break
default: break;
}
}
/** @override */
setPosition(options = {}) {
const position = super.setPosition(options);
const sheetBody = this.element.find(".sheet-body");
const bodyHeight = position.height - 192;
sheetBody.css("height", bodyHeight);
return position;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,229 @@
/**
* Extend the basic ActorSheet with some very simple modifications
* @extends {ActorSheet}
*/
import { BoLRoll } from "../controllers/bol-rolls.js";
import { BoLUtility } from "../system/bol-utility.js";
export class BoLVehicleSheet extends ActorSheet {
/** @override */
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
classes: ["bol", "sheet", "actor"],
template: "systems/bol/templates/actor/vehicle-sheet.hbs",
width: 860,
height: 600,
dragDrop: [{ dragSelector: ".items-list .item", dropSelector: null }],
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "stats" }]
});
}
/* -------------------------------------------- */
/** @override */
activateListeners(html) {
super.activateListeners(html);
function onLoad() {
let logoSheet = BoLUtility.getLogoActorSheet()
$(".bol-actor-form").css("backgroundImage",`url(${logoSheet})`)
}
// Setup everything onload
$(function () { onLoad(); });
// Everything below here is only needed if the sheet is editable
if (!this.options.editable) return;
// Add Inventory Item
html.find('.item-create').click(this._onItemCreate.bind(this));
// Update Inventory Item
html.find('.item-edit').click(ev => {
const li = $(ev.currentTarget).parents(".item");
const item = this.actor.items.get(li.data("itemId"));
item.sheet.render(true);
})
// Equip/Unequip item
html.find('.item-equip').click(this._onToggleEquip.bind(this));
html.find('.create_item').click(ev => {
this.actor.createEmbeddedDocuments('Item', [{ name: "Nouvel Equipement", type: "item" }], { renderSheet: true });
});
html.find(".toggle-fight-option").click((ev) => {
const li = $(ev.currentTarget).parents(".item")
this.actor.toggleFightOption(li.data("itemId"))
})
html.find(".inc-dec-btns-alchemy").click((ev) => {
const li = $(ev.currentTarget).parents(".item");
this.actor.spendAlchemyPoint(li.data("itemId"), 1)
})
// Incr./Decr. career ranks
html.find(".inc-dec-btns").click((ev) => {
const li = $(ev.currentTarget).parents(".item");
if (li) {
const item = this.actor.items.get(li.data("itemId"));
if (item) {
const dataset = ev.currentTarget.dataset;
const operator = dataset.operator;
const target = dataset.target;
const incr = parseInt(dataset.incr)
const min = parseInt(dataset.min)
const max = parseInt(dataset.max) || 10000
let value = eval("item." + target)
value = value || 0
//console.log("IncDec", item, target, value, operator, min, max)
if (operator === "minus") {
if (value >= min + incr) value -= incr;
else value = min;
}
if (operator === "plus") {
if (value <= max - incr) value += incr;
else value = max;
}
let update = { [`${target}`]: value };
item.update(update);
}
}
});
// Delete Inventory Item
html.find('.item-delete').click(ev => {
Dialog.confirm({
title: "Suppression",
content: `Vous êtes sûr de vouloir supprimer cet item ?`,
yes: () => {
const li = $(ev.currentTarget).parents(".item");
this.actor.deleteEmbeddedDocuments("Item", [li.data("itemId")])
li.slideUp(200, () => this.render(false));
},
no: () => { },
defaultYes: false,
});
});
// Rollable abilities.
html.find('.rollable').click(this._onRoll.bind(this));
}
/* -------------------------------------------- */
/** @override */
async getData(options) {
const data = super.getData(options)
const actorData = duplicate(data)
let formData = duplicate(data)
formData.config = game.bol.config
formData.name = this.actor.name
formData.img = this.actor.img
formData.system = duplicate(this.actor.system)
formData.weapons = this.actor.vehicleWeapons
formData.isGM = game.user.isGM
formData.options = this.options
formData.owner = this.document.isOwner
formData.editScore = this.options.editScore
formData.description = await TextEditor.enrichHTML(this.actor.system.description, {async: true})
formData.isGM = game.user.isGM
console.log("VEHICLEDATA", formData)
return formData;
}
/* -------------------------------------------- */
/**
* Handle creating a new Owned Item for the actor using initial data defined in the HTML dataset
* @param {Event} event The originating click event
* @private
*/
_onItemCreate(event) {
event.preventDefault();
const header = event.currentTarget;
// Get the type of item to create.
const type = header.dataset.type;
// Grab any data associated with this control.
const data = duplicate(header.dataset);
// Initialize a default name.
const name = `New ${type.capitalize()}`;
// Prepare the item object.
const itemData = {
name: name,
type: type,
data: data
};
// Remove the type from the dataset since it's in the itemData.type prop.
delete itemData.data["type"];
// Finally, create the item!
return this.actor.createEmbeddedDocuments("Item", [itemData]);
}
_onToggleEquip(event) {
event.preventDefault();
const li = $(event.currentTarget).closest(".item");
const item = this.actor.items.get(li.data("itemId"));
return this.actor.toggleEquipItem(item);
}
/**
* Handle clickable rolls.
* @param {Event} event The originating click event
* @private
*/
_onRoll(event) {
event.preventDefault();
const element = event.currentTarget
const dataset = element.dataset
const rollType = dataset.rollType
const li = $(event.currentTarget).closest(".item")
switch (rollType) {
case "attribute":
BoLRoll.attributeCheck(this.actor, dataset.key, event)
break;
case "aptitude":
BoLRoll.aptitudeCheck(this.actor, dataset.key, event)
break;
case "weapon":
BoLRoll.weaponCheck(this.actor, event)
break;
case "spell":
BoLRoll.spellCheck(this.actor, event)
break;
case "alchemy":
BoLRoll.alchemyCheck(this.actor, event)
break;
case "protection":
this.actor.rollProtection(li.data("item-id"))
break;
case "damage":
this.actor.rollWeaponDamage(li.data("item-id"))
break;
case "aptitudexp":
this.actor.incAptitudeXP(dataset.key)
break;
case "attributexp":
this.actor.incAttributeXP(dataset.key)
break;
case "careerxp":
this.actor.incCareerXP( li.data("item-id"))
break;
default: break;
}
}
/** @override */
setPosition(options = {}) {
const position = super.setPosition(options);
const sheetBody = this.element.find(".sheet-body");
const bodyHeight = position.height - 192;
sheetBody.css("height", bodyHeight);
return position;
}
}

View File

@ -1,90 +1,131 @@
/* -------------------------------------------- */
// Import Modules
import {BoLActor} from "./actor/actor.js";
import {BoLActorSheet} from "./actor/actor-sheet.js";
import {BoLItem} from "./item/item.js";
import {BoLItemSheet} from "./item/item-sheet.js";
import {System, BOL} from "./system/config.js";
import {preloadHandlebarsTemplates} from "./system/templates.js";
import {registerHandlebarsHelpers} from "./system/helpers.js";
import {registerSystemSettings} from "./system/settings.js";
import registerHooks from "./system/hooks.js";
import {DataLoader} from "./system/data.js";
import { BoLActor } from "./actor/actor.js"
import { BoLActorSheet } from "./actor/actor-sheet.js"
import { BoLVehicleSheet } from "./actor/vehicle-sheet.js"
import { BoLItem } from "./item/item.js"
import { BoLItemSheet } from "./item/item-sheet.js"
import { System, BOL } from "./system/config.js"
import { preloadHandlebarsTemplates } from "./system/templates.js"
import { registerHandlebarsHelpers } from "./system/helpers.js"
import registerHooks from "./system/hooks.js"
import { Macros } from "./system/macros.js"
import { BoLUtility } from "./system/bol-utility.js"
import { BoLCombatManager } from "./system/bol-combat.js"
import { BoLTokenHud } from "./system/bol-action-hud.js"
import { BoLHotbar } from "./system/bol-hotbar.js"
import { BoLAdventureGenerator } from "./system/bol-adventure-generator.js"
import { BoLCommands} from "./system/bol-commands.js"
import { BoLCharacterSummary} from "./system/bol-character-summary.js"
/* -------------------------------------------- */
Hooks.once('init', async function () {
game.bol = {
BoLActor,
BoLItem
};
game.bol = {
BoLActor,
BoLItem,
BoLHotbar,
macros: Macros,
config: BOL
};
// Game socket
game.socket.on("system.bol", sockmsg => {
BoLUtility.onSocketMessage(sockmsg);
})
/**
* Set an initiative formula for the system
* @type {String}
*/
CONFIG.Combat.initiative = {
formula: "1d20",
decimals: 2
};
// Define custom Entity classes
CONFIG.Actor.documentClass = BoLActor;
CONFIG.Item.documentClass = BoLItem;
/**
* Set an initiative formula for the system
* @type {String}
*/
CONFIG.Combat.initiative = {
formula: "2d6+@attributes.mind.value+@aptitudes.init.value",
decimals: 2
};
// Define custom Entity classes
CONFIG.Actor.documentClass = BoLActor;
CONFIG.Item.documentClass = BoLItem;
CONFIG.Combat.documentClass = BoLCombatManager;
// Register sheet application classes
Actors.unregisterSheet("core", ActorSheet);
Actors.registerSheet("bol", BoLActorSheet, {makeDefault: true});
Items.unregisterSheet("core", ItemSheet);
Items.registerSheet("bol", BoLItemSheet, {makeDefault: true});
// Register sheet application classes
Actors.unregisterSheet("core", ActorSheet);
Actors.registerSheet("bol", BoLActorSheet, { types: ["character", "encounter"], makeDefault: true })
Actors.registerSheet("bol", BoLVehicleSheet, { types: ["vehicle"], makeDefault: true })
// Register System Settings
registerSystemSettings();
Items.unregisterSheet("core", ItemSheet);
Items.registerSheet("bol", BoLItemSheet, { makeDefault: true });
// Preload Handlebars Templates
preloadHandlebarsTemplates();
// Inot useful stuff
BoLUtility.init()
BoLTokenHud.init()
BoLHotbar.init()
BoLCommands.init()
BoLAdventureGenerator.init()
// Register Handlebars helpers
registerHandlebarsHelpers();
// Preload Handlebars Templates
await preloadHandlebarsTemplates();
// Register hooks
registerHooks();
// Register Handlebars helpers
registerHandlebarsHelpers();
// Register hooks
registerHooks()
// // If you need to add Handlebars helpers, here are a few useful examples:
// Handlebars.registerHelper('concat', function() {
// var outStr = '';
// for (var arg in arguments) {
// if (typeof arguments[arg] != 'object') {
// outStr += arguments[arg];
// }
// }
// return outStr;
// });
//
// Handlebars.registerHelper('toLowerCase', function(str) {
// return str.toLowerCase();
// });
});
/* -------------------------------------------- */
// Register world usage statistics
function registerUsageCount( registerKey ) {
if ( game.user.isGM ) {
game.settings.register(registerKey, "world-key", {
name: "Unique world key",
scope: "world",
config: false,
default: "",
type: String
});
/**
* Ready hook loads tables, and override's foundry's entity link functions to provide extension to pseudo entities
*/
let worldKey = game.settings.get(registerKey, "world-key")
if ( worldKey == undefined || worldKey == "" ) {
worldKey = randomID(32)
game.settings.set(registerKey, "world-key", worldKey )
}
// Simple API counter
let regURL = `https://www.uberwald.me/fvtt_appcount/count.php?name="${registerKey}"&worldKey="${worldKey}"&version="${game.release.generation}.${game.release.build}"&system="${game.system.id}"&systemversion="${game.system.version}"`
//$.ajaxSetup({
//headers: { 'Access-Control-Allow-Origin': '*' }
//})
$.ajax(regURL)
}
}
Hooks.once("ready", async () => {
/* -------------------------------------------- */
function welcomeMessage() {
ChatMessage.create({
user: game.user.id,
whisper: [game.user.id],
content: `<div id="welcome-message-pegasus"><span class="rdd-roll-part">
<strong>` + game.i18n.localize("BOL.chat.welcome1") + `</strong><p>` +
game.i18n.localize("BOL.chat.welcome2") + "<p>" +
game.i18n.localize("BOL.chat.welcome3") + "<p>" +
game.i18n.localize("BOL.chat.welcome4") + "</p>" +
game.i18n.localize("BOL.chat.welcome5") + "<br>" +
game.i18n.localize("BOL.chat.welcome6")
} )
}
console.debug("Importing data");
/* -------------------------------------------- */
Hooks.once('ready', async function () {
// DataLoader.loadData("boons");
// DataLoader.loadData("flaws");
// DataLoader.loadData("careers");
// DataLoader.loadData("origins");
// DataLoader.loadData("races");
// DataLoader.loadData("equipment");
BoLUtility.ready()
BoLCharacterSummary.ready()
registerUsageCount(game.system.id)
welcomeMessage()
})
// UpdateUtils.updatePacks();
// UpdateUtils.updatePaths();
// UpdateUtils.updateProfiles();
// UpdateUtils.updateSpecies();
// UpdateUtils.updateEncounters();
console.info("BOL | System Initialized.");
});

View File

@ -0,0 +1,803 @@
import { BoLUtility } from "../system/bol-utility.js";
const _apt2attr = { init: "mind", melee: "agility", ranged: "agility", def: "vigor" }
/* -------------------------------------------- */
export class BoLRoll {
/* -------------------------------------------- */
static options() {
return { classes: ["bol", "dialog"], width: 480, height: 'fit-content' };
}
/* -------------------------------------------- */
static getDefaultAttribute(key) {
return _apt2attr[key]
}
/* -------------------------------------------- */
static updateApplicableEffects(rollData) {
let appEffects = []
for (let effect of rollData.bolEffects) {
if (effect.system.properties.identifier == "always") {
appEffects.push(effect)
} else if (effect.system.properties.identifier.includes(rollData.attribute.key)) {
appEffects.push(effect)
} else if (rollData.aptitude && effect.system.properties.identifier.includes(rollData.aptitude.key)) {
appEffects.push(effect)
}
}
return appEffects
}
/* -------------------------------------------- */
static buildHoroscopeGroupList() {
let horoscopes = game.settings.get("bol", "horoscope-group")
let horoList = [{ id: -1, name: "Aucun", type: "malus", nbDice: 0 }]
for (let id in horoscopes) {
let horo = horoscopes[id]
for (let i = 0; i < horo.availableDice; i++) {
horoList.push({ id: id, name: horo.name, type: horo.type, nbDice: i + 1 })
}
}
return horoList
}
/* -------------------------------------------- */
static getCommonRollData(actor, mode, attribute, aptitude = undefined) {
let rollData = {
mode: mode,
actorId: actor.id,
tokenId: actor.token?.id,
img: actor.img,
attribute: attribute,
attrValue: attribute.value,
aptValue: 0,
careerBonus: 0,
horoscopeBonus: 0,
horoscopeMalus: 0,
selectedHoroscope: [],
armorAgiMalus: actor.getArmorAgiMalus(),
armorInitMalus: actor.getArmorInitMalus(),
horoscopeBonusList: actor.getHoroscopesBonus(),
horoscopeMalusList: actor.getHoroscopesMalus(),
adv: "0",
mod: 0,
modRanged: 0,
aptValue: 0,
bolEffects: actor.boleffects,
horoscopeGroupList: this.buildHoroscopeGroupList()
}
if (aptitude) {
rollData.aptitude = aptitude
rollData.aptValue = aptitude.value
}
rollData.bolApplicableEffects = this.updateApplicableEffects(rollData)
return rollData
}
/* -------------------------------------------- */
static attributeCheck(actor, key, event, combatData) {
let attribute = eval(`actor.system.attributes.${key}`)
let rollData = this.getCommonRollData(actor, "attribute", attribute)
rollData.description = game.i18n.localize('BOL.ui.attributeCheck') + " - " + game.i18n.localize(attribute.label)
rollData.label = (attribute.label) ? game.i18n.localize(attribute.label) : null
console.log(">>>>>>>>>>", rollData, actor)
return this.displayRollDialog(rollData)
}
/* -------------------------------------------- */
static aptitudeCheck(actor, key, event, combatData) {
let aptitude = eval(`actor.system.aptitudes.${key}`)
let attrKey = this.getDefaultAttribute(key)
let attribute = eval(`actor.system.attributes.${attrKey}`)
let rollData = this.getCommonRollData(actor, "aptitude", attribute, aptitude)
rollData.label = (aptitude.label) ? game.i18n.localize(aptitude.label) : null
rollData.description = game.i18n.localize('BOL.ui.aptitudeCheck') + " - " + game.i18n.localize(aptitude.label)
rollData.combatData = combatData // For initiative mainly
return this.displayRollDialog(rollData)
}
/* -------------------------------------------- */
static async detectDistance(weapon, target) {
let visible, dist
if (target && (weapon.system.properties.ranged || weapon.system.properties.throwing)) {
console.log("target", target, weapon)
visible = canvas.effects.visibility.testVisibility(target.center, { object: _token })
dist = Number(canvas.grid.measureDistances([{ ray: new Ray(_token.center, target.center) }], { gridSpaces: false })).toFixed(2)
let range = Number(weapon.system.properties.range)
let rangeMsg = "BOL.chat.rangeout"
if (dist <= range) {
rangeMsg = "BOL.chat.range0"
} else if (dist < range * 2) {
rangeMsg = "BOL.chat.range1"
} else if (dist < range * 3) {
rangeMsg = "BOL.chat.range2"
} else if (dist < range * 4) {
rangeMsg = "BOL.chat.range3"
} else if (dist < range * 5) {
rangeMsg = "BOL.chat.range4"
} else if (dist < range * 6) {
rangeMsg = "BOL.chat.range5"
} else if (dist < range * 7) {
rangeMsg = "BOL.chat.range6"
}
ChatMessage.create({
content: await renderTemplate('systems/bol/templates/chat/chat-info-range.hbs', {
weapon: weapon,
attackerName: _token.actor.name,
defenderName: target.actor.name,
weaponRange: weapon.system.properties.range,
visible: visible,
distance: dist,
rangeMsg: rangeMsg
})
})
}
}
/* -------------------------------------------- */
static weaponCheckWithWeapon(actor, weapon) {
let target = BoLUtility.getTarget()
let weaponData = weapon.system
let attribute = eval(`actor.system.attributes.${weaponData.properties.attackAttribute}`)
let aptitude = eval(`actor.system.aptitudes.${weaponData.properties.attackAptitude}`)
let rollData = this.getCommonRollData(actor, "weapon", attribute, aptitude)
// Compute distance
this.detectDistance(weapon, target)
// Manage specific case
let fightOption = actor.getActiveFightOption()
if (fightOption && fightOption.system.properties.fightoptiontype == "fulldefense") {
ui.notifications.warn(`{{actor.name}} est en Défense Totale ! Il ne peut pas attaquer ce round.`)
return
}
// Update the roll structure
rollData.weapon = weapon
rollData.isRanged = weaponData.properties.ranged || weaponData.properties.throwing
rollData.targetId = target?.id
rollData.fightOption = fightOption
rollData.defenderId = target?.actor.id
rollData.label = (weapon.name) ? weapon.name : game.i18n.localize('BOL.ui.noWeaponName')
rollData.description = game.i18n.localize('BOL.ui.weaponAttack') + " : " + weapon.name
return this.displayRollDialog(rollData)
}
/* -------------------------------------------- */
static weaponCheck(actor, event) {
const li = $(event.currentTarget).parents(".item")
let weapon = actor.items.get(li.data("item-id"))
if (!weapon) {
ui.notifications.warn("Unable to find weapon !")
return
}
weapon = duplicate(weapon)
return this.weaponCheckWithWeapon(actor, weapon)
}
/* -------------------------------------------- */
static alchemyCheck(actor, event) {
const li = $(event.currentTarget).parents(".item");
let alchemy = actor.items.get(li.data("item-id"));
if (!alchemy) {
ui.notifications.warn("Unable to find Alchemy !");
return;
}
alchemy = duplicate(alchemy)
let alchemyData = alchemy.system
if (alchemyData.properties.pccurrent < alchemyData.properties.pccost) {
ui.notifications.warn("Pas assez de Points de Création investis dans la Préparation !")
return
}
let rollData = this.getCommonRollData(actor, "alchemy", actor.system.attributes.mind)
rollData.alchemy = alchemy
rollData.careerBonus = actor.getAlchemistBonus()
rollData.pcCost = Number(alchemyData.properties.pccost)
rollData.pcCostCurrent = Number(alchemyData.properties.pccurrent)
rollData.mod = Number(alchemyData.properties.difficulty)
rollData.label = alchemy.name
rollData.description = game.i18n.localize('BOL.ui.makeAlchemy') + "+" + alchemy.name
console.log("ALCHEMY!", rollData);
return this.displayRollDialog(rollData);
}
/* -------------------------------------------- */
static horoscopeCheck(actor, event, horoscopeType) {
let target = BoLUtility.getTarget()
let cost = (horoscopeType == "minor") ? 1 : 2
if (cost > actor.getAstrologyPoints()) {
ui.notifications.warn(game.i18n.localize("BOL.ui.astrologyNoPoints"))
return
}
let rollData = this.getCommonRollData(actor, "horoscope", actor.system.attributes.mind)
rollData.careerBonus = actor.getAstrologerBonus()
rollData.horoscopeType = horoscopeType
rollData.horoscopeTypeLabel = "BOL.ui." + horoscopeType
rollData.astrologyPointsCost = cost
rollData.label = game.i18n.localize('BOL.ui.makeHoroscope')
rollData.description = game.i18n.localize('BOL.ui.makeHoroscope') + " " + game.i18n.localize(rollData.horoscopeTypeLabel)
rollData.targetId = target?.id
console.log("HOROSCOPE!", rollData);
return this.displayRollDialog(rollData);
}
/* -------------------------------------------- */
static spellCheckWithSpell(actor, spell) {
let rollData = this.getCommonRollData(actor, "spell", actor.system.attributes.mind)
rollData.spell = spell
rollData.ppCurrent = Number(actor.system.resources.power.value),
rollData.careerBonus = actor.getSorcererBonus(),
rollData.ppCostArmor = actor.getPPCostArmor(),
rollData.ppCost = Number(spell.system.properties.ppcost),
rollData.mod = Number(spell.system.properties.difficulty),
rollData.label = spell.name,
rollData.description = game.i18n.localize('BOL.ui.focusSpell') + " : " + spell.name
//console.log("SPELL!", spellDef)
return this.displayRollDialog(rollData)
}
/* -------------------------------------------- */
static spellCheck(actor, event) {
if (actor.system.resources.power.value <= 0) {
ui.notifications.warn("Plus assez de points de Pouvoir !")
return
}
const li = $(event.currentTarget).parents(".item")
let spell = actor.items.get(li.data("item-id"))
if (!spell) {
ui.notifications.warn("Impossible de trouver ce sort !")
return
}
spell = duplicate(spell)
return this.spellCheckWithSpell(actor, spell)
}
/* -------------------------------------------- */
static updateTotalDice() {
this.updateArmorMalus(this.rollData)
this.updatePPCost(this.rollData)
// get basic dices from boons/flaws
let effectModifier = 0
this.rollData.bmDice = this.rollData.nbBoons - this.rollData.nbFlaws + this.rollData.bDice - this.rollData.mDice
// add applicable bonus/malus dices effects
for (let effect of this.rollData.bolApplicableEffects) {
if (effect.system.properties.modifier == "1B") {
this.rollData.bmDice++;
} else if (effect.system.properties.modifier == "2B") {
this.rollData.bmDice += 2;
} else if (effect.system.properties.modifier == "1M") {
this.rollData.bmDice--;
} else if (effect.system.properties.modifier == "2M") {
this.rollData.bmDice -= 2;
} else {
effectModifier += Number(effect.system.properties.modifier)
}
}
this.rollData.bmDice += this.rollData.horoscopeBonus
this.rollData.bmDice -= this.rollData.horoscopeMalus
if (this.rollData.selectedGroupHoroscopeIndex && this.rollData.selectedGroupHoroscopeIndex > 0) {
let horo = this.rollData.horoscopeGroupList[this.rollData.selectedGroupHoroscopeIndex]
this.rollData.bmDice += (horo.type == "malus") ? -horo.nbDice : horo.nbDice;
}
// Keep track of the final effect modifier
this.rollData.effectModifier = effectModifier
// Final number of dices
this.rollData.nbDice = 2 + Math.abs(this.rollData.bmDice)
// Bonus or Malus ?
if (this.rollData.bmDice == 0) {
$('#roll-nbdice').val("2")
} else {
let letter = (this.rollData.bmDice > 0) ? "B" : "M"
$('#roll-nbdice').val("2 + " + String(Math.abs(this.rollData.bmDice)) + letter)
}
let rollbase = this.rollData.attrValue + "+" + this.rollData.aptValue
if (this.rollData.weapon && this.rollData.weapon.system.properties.onlymodifier) {
rollbase = ""
}
$('#roll-modifier').val(rollbase + "+" + this.rollData.careerBonus + "+" + this.rollData.mod + "+" +
this.rollData.modRanged + "+" + this.rollData.weaponModifier + "-" + this.rollData.defence + "-" + this.rollData.modArmorMalus + "-" +
this.rollData.shieldMalus + "+" + this.rollData.attackModifier + "+" + this.rollData.appliedArmorMalus + "+" + effectModifier)
// Rebuild lits of applicable effects
let selectEffects = ""
for (let effect of this.rollData.bolApplicableEffects) {
selectEffects += `<option value="${effect.id}" selected>${effect.name}</option>`
}
$('#applicable-effects').html(selectEffects)
}
/* -------------------------------------------- */
static preProcessFightOption(rollData) {
rollData.damagesIgnoresArmor = false // Always reset flags
rollData.modArmorMalus = 0
rollData.attackModifier = 0
let fgItem = rollData.fightOption
if (fgItem) {
console.log(fgItem)
if (fgItem.system.properties.fightoptiontype == "armordefault") {
rollData.modArmorMalus = rollData.armorMalus // Activate the armor malus
rollData.damagesIgnoresArmor = true
}
if (fgItem.system.properties.fightoptiontype == "intrepid") {
rollData.attackModifier += 2
}
if (fgItem.system.properties.fightoptiontype == "defense") {
rollData.attackModifier += -1
}
if (fgItem.system.properties.fightoptiontype == "attack") {
rollData.attackModifier += 1
}
if (fgItem.system.properties.fightoptiontype == "twoweaponsdef" || fgItem.system.properties.fightoptiontype == "twoweaponsatt") {
rollData.attackModifier += -1
}
}
}
/* -------------------------------------------- */
static updateArmorMalus(rollData) {
rollData.appliedArmorMalus = 0
if (rollData.attribute.key == "agility") {
$("#armor-agi-malus").show()
rollData.appliedArmorMalus += rollData.armorAgiMalus
} else {
$("#armor-agi-malus").hide()
}
if (rollData.aptitude && rollData.aptitude.key == "init") {
$("#armor-init-malus").show()
rollData.appliedArmorMalus += rollData.armorInitMalus
} else {
$("#armor-init-malus").hide()
}
}
/* ------------------------------ -------------- */
static updatePPCost(rollData) {
$('#ppcost').html(rollData.ppCost + " + Armor(" + rollData.ppCostArmor + ")=" + Number(rollData.ppCost + rollData.ppCostArmor))
}
/* ------------------------------ -------------- */
static rollDialogListener(html) {
this.updateTotalDice()
html.find('#optcond').change((event) => { // Dynamic change of PP cost of spell
let pp = BoLUtility.computeSpellCost(this.rollData.spell, event.currentTarget.selectedOptions.length)
this.rollData.ppCost = pp
this.updatePPCost(this.rollData)
})
html.find('#mod').change((event) => {
this.rollData.mod = Number(event.currentTarget.value)
this.updateTotalDice()
})
html.find('#modRanged').change((event) => {
this.rollData.modRanged = Number(event.currentTarget.value)
this.updateTotalDice()
})
html.find('#attr').change((event) => {
let attrKey = event.currentTarget.value
let actor = BoLUtility.getActorFromRollData(this.rollData)
this.rollData.attribute = duplicate(actor.system.attributes[attrKey])
this.rollData.attrValue = actor.system.attributes[attrKey].value
this.rollData.bolApplicableEffects = this.updateApplicableEffects(this.rollData)
this.updateTotalDice()
})
html.find('#apt').change((event) => {
let aptKey = event.currentTarget.value
let actor = BoLUtility.getActorFromRollData(this.rollData)
this.rollData.aptitude = duplicate(actor.system.aptitudes[aptKey])
this.rollData.aptValue = actor.system.aptitudes[aptKey].value
this.rollData.bolApplicableEffects = this.updateApplicableEffects(this.rollData)
this.updateTotalDice()
})
html.find('#applyShieldMalus').click((event) => {
if (event.currentTarget.checked) {
this.rollData.shieldMalus = this.rollData.shieldAttackMalus
} else {
this.rollData.shieldMalus = 0
}
this.updateTotalDice()
})
html.find('#career').change((event) => {
let careers = $('#career').val()
this.rollData.careerBonus = (!careers || careers.length == 0) ? 0 : Math.max(...careers.map(i => parseInt(i)))
this.updateTotalDice()
})
html.find('#boon').change((event) => {
let boons = $('#boon').val()
this.rollData.nbBoons = (!boons || boons.length == 0) ? 0 : boons.length
this.updateTotalDice()
})
html.find('#flaw').change((event) => {
let flaws = $('#flaw').val()
this.rollData.nbFlaws = (!flaws || flaws.length == 0) ? 0 : flaws.length
this.updateTotalDice()
})
html.find('.bdice').click((event) => {
this.rollData.mDice = 0
this.rollData.bDice = Number(event.currentTarget.value)
this.updateTotalDice()
})
html.find('.mdice').click((event) => {
this.rollData.bDice = 0
this.rollData.mDice = Number(event.currentTarget.value)
this.updateTotalDice()
})
html.find('#horoscope-bonus-applied').change((event) => {
this.rollData.selectedHoroscope = []
for (let option of event.currentTarget.selectedOptions) {
this.rollData.selectedHoroscope.push(duplicate(this.rollData.horoscopeBonusList[Number(option.index)]))
}
let horoscopes = $('#horoscope-bonus-applied').val()
this.rollData.horoscopeBonus = (!horoscopes || horoscopes.length == 0) ? 0 : horoscopes.length
this.updateTotalDice()
})
html.find('#horoscope-malus-applied').change((event) => {
this.rollData.selectedHoroscope = []
for (let option of event.currentTarget.selectedOptions) {
this.rollData.selectedHoroscope.push(duplicate(this.rollData.horoscopeBonusList[Number(option.index)]))
}
let horoscopes = $('#horoscope-malus-applied').val()
this.rollData.horoscopeMalus = (!horoscopes || horoscopes.length == 0) ? 0 : horoscopes.length
this.updateTotalDice()
})
html.find('#horoscope-group-applied').change((event) => {
this.rollData.selectedGroupHoroscopeIndex = event.currentTarget.value
this.updateTotalDice()
})
}
/* -------------------------------------------- */
static preProcessWeapon(rollData, defender) {
if (rollData.mode == "weapon") {
rollData.weaponModifier = rollData.weapon.system.properties.attackModifiers ?? 0
rollData.attackBonusDice = rollData.weapon.system.properties.attackBonusDice
if (rollData.attackBonusDice) {
rollData.adv = "1B"
rollData.bDice = 1
}
if (defender) { // If target is selected
rollData.defence = defender.defenseValue
rollData.armorMalus = defender.armorMalusValue
rollData.defenderHeroPoints = defender.getHeroPoints()
rollData.shieldBlock = 'none'
let shields = defender.shields
//console.log("Defender stats", defender)
for (let shield of shields) {
rollData.shieldBlock = (shield.system.properties.blocking.blockingAll) ? 'blockall' : 'blockone';
rollData.shieldAttackMalus = (shield.system.properties.blocking.malus) ? shield.system.properties.blocking.malus : 1;
}
}
}
}
/* ROLL DIALOGS */
/* -------------------------------------------- */
static async displayRollDialog(rollData, onEnter = "submit") {
// initialize default flags/values
const rollOptionTpl = `systems/bol/templates/dialogs/${rollData.mode}-roll-dialog.hbs`
let actor = BoLUtility.getActorFromRollData(rollData)
let defender
if (rollData.targetId) {
let token = game.scenes.current.tokens.get(rollData.targetId)
defender = token.actor
}
rollData.careers = actor.careers
rollData.boons = actor.bonusBoons
rollData.flaws = actor.malusFlaws
rollData.rollOwnerID = actor.id
rollData.defence = 0
rollData.attackModifier = 0 // Used for fight options
rollData.modArmorMalus = 0 // Used for fight options
rollData.bDice = 0
rollData.mDice = 0
rollData.nbBoons = 0
rollData.nbFlaws = 0
rollData.nbDice = 0
rollData.isHeroAdversary = actor.isHeroAdversary()
rollData.careerBonus = rollData.careerBonus ?? 0
rollData.modRanged = rollData.modRanged ?? 0
rollData.mod = rollData.mod ?? 0
rollData.id = randomID(16)
rollData.weaponModifier = 0
rollData.attackBonusDice = false
rollData.armorMalus = 0
// Specific stuff
this.preProcessWeapon(rollData, defender)
this.preProcessFightOption(rollData)
this.updateArmorMalus(rollData)
this.updatePPCost(rollData)
// Prepare blocking case
if (rollData.shieldBlock == 'blockall') {
rollData.shieldMalus = rollData.shieldAttackMalus;
} else {
rollData.shieldMalus = 0
}
// Save
this.rollData = rollData
console.log("ROLLDATA", rollData)
// Then display+process the dialog
const rollOptionContent = await renderTemplate(rollOptionTpl, rollData);
let d = new Dialog({
title: rollData.label,
content: rollOptionContent,
rollData: rollData,
render: html => this.rollDialogListener(html),
buttons: {
cancel: {
icon: '<i class="fas fa-times"></i>',
label: game.i18n.localize("BOL.ui.cancel"),
callback: () => {
}
},
submit: {
icon: '<i class="fas fa-check"></i>',
label: game.i18n.localize("BOL.ui.submit"),
callback: (html) => {
if (rollData.mode == 'spell' && rollData.ppCurrent < rollData.ppCost) { // Check PP available
ui.notifications.warn("Pas assez de Points de Pouvoir !")
return
}
rollData.registerInit = (rollData.aptitude && rollData.aptitude.key == 'init') ? $('#register-init').is(":checked") : false;
const isMalus = (rollData.bmDice < 0)
let rollbase = rollData.attrValue + rollData.aptValue
if (rollData.weapon?.system.properties.onlymodifier) {
rollbase = 0
}
let diceData = BoLUtility.getDiceData()
let malusInit = rollData.combatData?.malusInit || 0
const modifiers = rollbase + rollData.careerBonus + rollData.mod + rollData.weaponModifier - rollData.defence - rollData.modArmorMalus + rollData.shieldMalus + rollData.attackModifier + rollData.appliedArmorMalus + rollData.effectModifier - malusInit
const formula = (isMalus) ? rollData.nbDice + "d" + diceData.diceFormula + "kl2 + " + modifiers : rollData.nbDice + "d" + diceData.diceFormula + "kh2 + " + modifiers
rollData.formula = formula
rollData.modifiers = modifiers
console.log("Rolldata before", rollData)
let r = new BoLDefaultRoll(rollData);
r.roll();
}
}
},
default: onEnter,
close: () => { }
}, this.options());
return d.render(true);
}
}
/* -------------------------------------------- */
export class BoLDefaultRoll {
constructor(rollData) {
this.rollData = rollData
if (this.rollData.isSuccess == undefined) { // First init
this.rollData.isSuccess = false;
this.rollData.isCritical = false;
this.rollData.isFumble = false;
}
if (this.rollData.optionsId) {
BoLUtility.cleanupButtons(this.rollData.optionsId)
}
if (this.rollData.applyId) {
BoLUtility.cleanupButtons(this.rollData.applyId)
}
this.rollData.optionsId = randomID(16)
this.rollData.applyId = randomID(16)
}
/* -------------------------------------------- */
async roll() {
const r = new Roll(this.rollData.formula)
//console.log("Roll formula", this.rollData.formula)
await r.roll({ "async": false })
let diceData = BoLUtility.getDiceData()
//console.log("DICEDATA", diceData)
const activeDice = r.terms[0].results.filter(r => r.active)
const diceTotal = activeDice.map(r => r.result).reduce((a, b) => a + b)
this.rollData.roll = r
this.rollData.isSuccess = (r.total >= diceData.successValue)
this.rollData.isCritical = (diceTotal >= diceData.criticalSuccessValue)
this.rollData.isRealCritical = (diceTotal >= diceData.criticalSuccessValue)
this.rollData.isHeroic = (diceTotal >= diceData.criticalSuccessValue)
this.rollData.isLegendary = false
this.rollData.isFumble = (diceTotal <= diceData.criticalFailureValue)
this.rollData.isFailure = !this.rollData.isSuccess
let actor = BoLUtility.getActorFromRollData(this.rollData)
if (this.rollData.reroll == undefined) {
this.rollData.reroll = actor.heroReroll()
}
if (this.rollData.registerInit) {
await actor.registerInit(this.rollData)
this.rollData.initiativeRank = actor.getInitiativeRank(this.rollData)
if (this.rollData.combatData) { // If combatData present
let combat = game.combats.get(this.rollData.combatData.combatId)
console.log("SET INIT!!!!!", this.rollData.initiativeRank)
combat.setInitiative(this.rollData.combatData.combatantId, this.rollData.initiativeRank)
}
}
if (this.rollData.isSuccess && this.rollData.mode == "spell") { // PP cost management
this.rollData.remainingPP = actor.spendPowerPoint(this.rollData.ppCost + this.rollData.ppCostArmor)
}
if (this.rollData.mode == "alchemy") { // PP cost management
actor.resetAlchemyStatus(this.rollData.alchemy._id)
}
if (this.rollData.mode == "bougette" && this.rollData.isFailure) {
actor.decBougette()
}
await this.sendChatMessage()
if (this.rollData.mode == "horoscope") { // PP cost management
actor.manageHoroscope(this.rollData)
}
if (this.rollData.selectedHoroscope.length > 0) { // PP cost management
actor.removeHoroscopeMinor(this.rollData)
}
if (this.rollData.selectedGroupHoroscopeIndex && this.rollData.selectedGroupHoroscopeIndex > 0) { // PP cost management
BoLUtility.removeGroupHoroscope(this.rollData)
}
}
/* -------------------------------------------- */
async sendChatMessage() {
let actor = BoLUtility.getActorFromRollData(this.rollData)
this._buildChatMessage(this.rollData).then(async msgFlavor => {
//console.log("MSG", msgFlavor )
let msg = await this.rollData.roll.toMessage({
user: game.user.id,
rollMode: game.settings.get("core", "rollMode"),
flavor: msgFlavor,
speaker: ChatMessage.getSpeaker({ actor: actor }),
})
this.rollData.roll = duplicate(this.rollData.roll) // Remove object, keep data (v111 ready)
msg.setFlag("world", "bol-roll-data", this.rollData)
})
}
/* -------------------------------------------- */
upgradeToLegendary() {
// Force to Critical roll
let diceData = BoLUtility.getDiceData()
let maxValue = Number(diceData.diceFormula) * 2
this.rollData.isCritical = true
this.rollData.isLegendary = true
this.rollData.isRealCritical = false
this.rollData.isSuccess = true
this.rollData.isFailure = false
this.rollData.roll = new Roll(maxValue + "+" + this.rollData.modifiers)
this.rollData.reroll = false
this.sendChatMessage()
}
/* -------------------------------------------- */
upgradeToHeroic() {
// Force to Critical roll
let diceData = BoLUtility.getDiceData()
let maxValue = Number(diceData.diceFormula) * 2
this.rollData.isCritical = true
this.rollData.isHeroic = true
this.rollData.isLegendary = false
this.rollData.isRealCritical = false
this.rollData.isSuccess = true
this.rollData.isFailure = false
this.rollData.roll = new Roll(maxValue + "+" + this.rollData.modifiers)
this.rollData.reroll = false
this.sendChatMessage()
}
/* -------------------------------------------- */
setSuccess(flag) {
this.rollData.isSuccess = flag
}
/* -------------------------------------------- */
async sendDamageMessage() {
let actor = BoLUtility.getActorFromRollData(this.rollData)
this._buildDamageChatMessage(this.rollData).then(async msgFlavor => {
let msg = await this.rollData.damageRoll.toMessage({
user: game.user.id,
flavor: msgFlavor,
speaker: ChatMessage.getSpeaker({ actor: actor }),
flags: { msgType: "default" }
})
this.rollData.damageRoll = duplicate(this.rollData.damageRoll)
this.rollData.actor = undefined // Cleanup
msg.setFlag("world", "bol-roll-data", this.rollData)
})
}
/* -------------------------------------------- */
getDamageAttributeValue(attrDamage, actorId = undefined) {
let actor = BoLUtility.getActorFromRollData(this.rollData)
return actor.getDamageAttributeValue(attrDamage)
}
/* -------------------------------------------- */
async rollDamage() {
if (this.rollData.mode != "weapon") { // Only specific process in Weapon mode
return
}
if (this.rollData.isSuccess) {
if (!this.rollData.damageRoll) {
let bonusDmg = 0
if (this.rollData.damageMode == 'damage-plus-6') {
bonusDmg = 6
}
if (this.rollData.damageMode == 'damage-plus-12') {
bonusDmg = 12
}
let attrDamageValue = this.getDamageAttributeValue(this.rollData.weapon.system.properties.damageAttribute)
let weaponFormula = BoLUtility.getDamageFormula(this.rollData.weapon.system, this.rollData.fightOption)
let damageFormula = weaponFormula + "+" + bonusDmg + "+" + attrDamageValue
//console.log("Formula", weaponFormula, damageFormula, this.rollData.weapon.data.data.properties.damage)
this.rollData.damageFormula = damageFormula
this.rollData.damageRoll = new Roll(damageFormula)
await this.rollData.damageRoll.roll({ "async": false })
this.rollData.damageTotal = this.rollData.damageRoll.total
console.log("DAMAGE !!!", damageFormula, attrDamageValue, this.rollData)
}
BoLUtility.cleanupButtons(this.rollData.optionsId)
this.sendDamageMessage()
}
}
/* -------------------------------------------- */
_buildDamageChatMessage(rollData) {
const rollMessageTpl = 'systems/bol/templates/chat/rolls/damage-roll-card.hbs';
return renderTemplate(rollMessageTpl, rollData)
}
/* -------------------------------------------- */
_buildChatMessage(rollData) {
const rollMessageTpl = 'systems/bol/templates/chat/rolls/default-roll-card.hbs'
return renderTemplate(rollMessageTpl, rollData)
}
}

View File

@ -1,3 +1,5 @@
import { BoLUtility } from "../system/bol-utility.js";
/**
* Extend the basic ItemSheet with some very simple modifications
* @extends {ItemSheet}
@ -8,37 +10,81 @@ export class BoLItemSheet extends ItemSheet {
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
classes: ["bol", "sheet", "item"],
width: 520,
height: 480,
template: "systems/bol/templates/item/item-sheet.hbs",
width: 650,
height: 780,
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "description" }]
});
}
/* -------------------------------------------- */
/** @override */
get template() {
const path = "systems/bol/templates/item";
// Return a single sheet for all item types.
return `${path}/item-sheet.hbs`;
// Alternatively, you could use the following return statement to do a
// unique item sheet by type, like `weapon-sheet.html`.
async getData(options) {
const data = super.getData(options)
let itemData = duplicate(data.document)
data.config = game.bol.config
data.item = itemData
data.category = itemData.system.category
data.isGM = game.user.isGM;
data.itemProperties = this.item.itemProperties;
data.description = await TextEditor.enrichHTML(this.object.system.description, { async: true })
// return `${path}/${this.item.data.type}-sheet.html`;
// Dynamic default data fix/adapt
if (itemData.type == "item") {
if (!itemData.system.category) {
itemData.system.category = "equipment"
}
if (itemData.system.category == "equipment" && itemData.system.properties.equipable) {
if (!itemData.system.properties.slot) {
itemData.system.properties.slot = "-"
}
}
if (itemData.system.category == 'spell') {
if (!itemData.system.properties.mandatoryconditions) {
itemData.system.properties.mandatoryconditions = []
}
if (!itemData.system.properties.optionnalconditions) {
itemData.system.properties.optionnalconditions = []
}
for (let i = 0; i < 4; i++) {
itemData.system.properties.mandatoryconditions[i] = itemData.system.properties.mandatoryconditions[i] ?? ""
}
for (let i = 0; i < 8; i++) {
itemData.system.properties.optionnalconditions[i] = itemData.system.properties.optionnalconditions[i] ?? ""
}
}
} else {
if (!itemData.system.subtype) {
itemData.system.category = "origin"
}
}
console.log("ITEMDATA", data);
return data;
}
/* -------------------------------------------- */
/** @override */
getData() {
const item = super.getData();
console.debug("Item getData");
item.data.description = item.data.data.description;
item.data.properties = item.data.data.properties;
console.log(item.data);
return item;
_getHeaderButtons() {
let buttons = super._getHeaderButtons();
buttons.unshift({
class: "post",
icon: "fas fa-comment",
onclick: ev => this.postItem()
});
return buttons
}
/* -------------------------------------------- */
postItem() {
let chatData = duplicate(this.item)
if (this.actor) {
chatData.actor = { id: this.actor.id };
}
BoLUtility.postItem(chatData);
}
/* -------------------------------------------- */
/** @override */
setPosition(options = {}) {
const position = super.setPosition(options);
@ -52,11 +98,18 @@ export class BoLItemSheet extends ItemSheet {
/** @override */
activateListeners(html) {
super.activateListeners(html);
super.activateListeners(html);
// Everything below here is only needed if the sheet is editable
if (!this.options.editable) return;
// Roll handlers, click handlers, etc. would go here.
html.find('.armorQuality').change(ev => {
const li = $(ev.currentTarget);
console.log(game.bol.config.soakFormulas[li.val()]);
$('.soakFormula').val(game.bol.config.soakFormulas[li.val()]);
});
}
}

View File

@ -7,12 +7,30 @@ export class BoLItem extends Item {
* Augment the basic Item data model with additional dynamic data.
*/
prepareData() {
super.prepareData();
console.debug("Item prepareData");
// Get the Item's data
const itemData = this.data;
console.log(itemData);
const actorData = this.actor ? this.actor.data : {};
const data = itemData.data;
super.prepareData()
const actorData = this.actor ? this.actor.system : {}
}
/* -------------------------------------------- */
get properties() {
return this.system.properties
}
/* -------------------------------------------- */
/**
* Get the Array of item properties which are used in the small sidebar of the description tab
* @return {Array}
* @private
*/
get itemProperties() {
const props = [];
if ( this.type === "item" ) {
const entries = Object.entries(this.system.properties)
props.push(...entries.filter(e => e[1] === true).map(e => { return game.bol.config.itemProperties2[e[0]] }))
}
return props.filter(p => !!p)
}
}

View File

@ -0,0 +1,620 @@
{
"titre1": [
{
"prefix": "la",
"name": "Prophétie"
},
{
"prefix": "les",
"name": "Grottes",
"isLieu": true
},
{
"prefix": "les",
"name": "Collines",
"isLieu": true
},
{
"prefix": "les",
"name": "Voleurs",
"isEnnemi": true,
"isCarriere": true
},
{
"prefix": "les",
"name": "Sorcier(s)",
"isEnnemi": true,
"isCarriere": true
},
{
"prefix": "la",
"name": "Bataille"
},
{
"prefix": "la",
"name": "Légende"
},
{
"prefix": "la",
"name": "Tour",
"isLieu": true
},
{
"prefix": "l'",
"name": "Ile",
"isLieu": true
},
{
"prefix": "les",
"name": "Pirates",
"isEnnemi": true,
"isCarriere": true
},
{
"prefix": "les",
"name": "Druide(s)",
"isEnnemi": true,
"isCarriere": true
},
{
"prefix": "le",
"name": "Navire",
"isCarriere": false
},
{
"prefix": "la",
"name": "Couronne",
"isObjet": true
},
{
"prefix": "la",
"name": "Cité",
"isLieu": true
},
{
"prefix": "le",
"name": "Désert",
"isLieu": true
},
{
"prefix": "les",
"name": "Bête(s)",
"isEnnemi": true,
"isLieu": false
},
{
"prefix": "les",
"name": "Démon(s)",
"isEnnemi": true,
"isLieu": false
},
{
"prefix": "le",
"name": "Trésor",
"isObjet": true
},
{
"prefix": "l'",
"name": "Epée",
"isObjet": true
},
{
"prefix": "l'",
"name": "Arène",
"isLieu": true
},
{
"prefix": "les",
"name": "Marais",
"isLieu": true
},
{
"prefix": "les",
"name": "Seigneur(s)",
"isEnnemi": true,
"isLieu": false
},
{
"prefix": "les",
"name": "Assassin(s)",
"isEnnemi": true,
"isCarriere": true
},
{
"prefix": "le",
"name": "Culte",
"isEnnemi": true,
"isCarriere": false
},
{
"prefix": "le",
"name": "Secret",
"isCarriere": false
},
{
"prefix": "le",
"name": "Palais",
"isLieu": true
},
{
"prefix": "la",
"name": "Mer",
"isLieu": true
},
{
"prefix": "les",
"name": "Barbares",
"isEnnemi": true,
"isCarriere": true
},
{
"prefix": "le",
"name": "Manuscrit",
"isObjet": true
},
{
"prefix": "les",
"name": "Plaines",
"isLieu": true
},
{
"prefix": "le",
"name": "Sang",
"isLieu": false
},
{
"prefix": "la",
"name": "Tombe",
"isLieu": true
},
{
"prefix": "la",
"name": "Forêt",
"isLieu": true
},
{
"prefix": "les",
"name": "Esclaves",
"isEnnemi": true,
"isCarriere": true
},
{
"prefix": "les",
"name": "Mendiant(s)",
"isEnnemi": true,
"isCarriere": true
},
{
"prefix": "les",
"name": "Montagnes",
"isCarriereLieu": true
}
],
"titre2": [
{
"prefix": "du",
"name": "mal"
},
{
"prefix": "et le",
"name": "Roi Maussade",
"isEnnemi": true
},
{
"prefix": "et la",
"name": "pestilence",
"isEnnemi": false
},
{
"prefix": "de",
"name": "Malakut",
"isLieu": true
},
{
"prefix": "d'",
"name": "Halakh",
"isLieu": true
},
{
"prefix": "d'",
"name": "Hyrdral",
"isLieu": true
},
{
"prefix": "des",
"name": "esprits abandonnés",
"isEnnemi": true
},
{
"prefix": "du",
"name": "chaos",
"isEnnemi": true
},
{
"prefix": "de la",
"name": "folie",
"isEnnemi": false
},
{
"prefix": "de",
"name": "Satarla",
"isLieu": true
},
{
"prefix": "d'",
"name": "Urceb",
"isLieu": true
},
{
"prefix": "des",
"name": "Terres Désolées",
"isLieu": true
},
{
"prefix": "de la",
"name": "mort",
"isLieu": false
},
{
"prefix": "des",
"name": "idoles impies",
"isObjet": true
},
{
"prefix": "des",
"name": "ténèbres",
"isObjet": false
},
{
"prefix": "de",
"name": "Parsool",
"isLieu": true
},
{
"prefix": "de",
"name": "Qiddesh",
"isLieu": true
},
{
"prefix": "de",
"name": "Kasht",
"isLieu": true
},
{
"prefix": "de la ",
"name": "falalité",
"isLieu": false
},
{
"prefix": "du",
"name": "Nécromant",
"isEnnemi": true
},
{
"prefix": "du",
"name": "Néant",
"isEnnemi": false
},
{
"prefix": "de",
"name": "Lysor",
"isLieu": true
},
{
"prefix": "d'",
"name": "Oosal",
"isLieu": true
},
{
"prefix": "de",
"name": "Thulé",
"isLieu": true
},
{
"prefix": "du",
"name": "désespoir",
"isLieu": false
},
{
"prefix": "du",
"name": "Dieu Bouffi",
"isEnnemi": true
},
{
"prefix": "du",
"name": "silence",
"isEnnemi": false
},
{
"prefix": "de",
"name": "Tyrus",
"isLieu": true
},
{
"prefix": "d'",
"name": "Ygddar",
"isLieu": true
},
{
"prefix": "de",
"name": "la Côte de Feu",
"isLieu": true
},
{
"prefix": "des",
"name": "ombres cruelles",
"isLieu": false
},
{
"prefix": "de la",
"name": "poussière écarlate",
"isLieu": false
},
{
"prefix": "du",
"name": "destin",
"isLieu": false
},
{
"prefix": "du",
"name": "Valgard",
"isLieu": true
},
{
"prefix": "de",
"name": "Qeb",
"isLieu": true
},
{
"prefix": "de",
"name": "la Mer Inconnue",
"isLieu": true
}
],
"mission": [
{
"name": "dattaquer un lieu."
},
{
"name": "de détruire un certain objet."
},
{
"name": "de kidnapper quelquun."
},
{
"name": "dobtenir une certaine chose."
},
{
"name": "dexplorer un lieu."
},
{
"name": "de sauver une personne."
},
{
"name": "déchapper à quelquun."
},
{
"name": "de fuir un lieu."
},
{
"name": "de trouver une personne."
},
{
"name": "de trouver un lieu."
},
{
"name": "de trouver chose."
},
{
"name": "de protéger une personne."
},
{
"name": "de protéger un lieu."
},
{
"name": "de protéger chose."
},
{
"name": "de dérober une certaine chose."
},
{
"name": "de tuer une personne."
},
{
"name": "de détruire une chose."
},
{
"name": "descorter une personne."
},
{
"name": "de transporter une chose."
}
],
"carriere": [
"Noble",
"Acrobate",
"Sorcier",
"Alchimiste",
"Esclave",
"Courtisane",
"Médecin",
"Marin",
"Érudit",
"Mendiant",
"Scribe",
"Poète",
"Forgeron",
"Prêtre",
"Danseur",
"Marchand",
"Pilote des airs",
"Fermier"
],
"lieux1": [
"Palais",
"Donjon",
"Ruines",
"Sanctuaire",
"Crypte",
"Forteresse",
"Tombeau",
"Grottes",
"Tour",
"Antre",
"Île",
"Montagne"
],
"lieux2": [
"de la mort.",
"de la destruction.",
"du désespoir.",
"des morts-vivants.",
"du sage.",
"de l'or.",
"de la tempête.",
"de la terreur.",
"descannibales.",
"du désespoir.",
"des Rois-Sorciers.",
"des âmes perdues."
],
"objets1": [
"Livre",
"Anneau",
"Coupe",
"Joyau",
"Casque",
"Parchemin",
"Couronne",
"Sceau",
"Cristal",
"Crâne",
"Épée",
"Bâton"
],
"objets2": [
"des sept sceaux.",
"de l'éternelle douleur.",
"du sang bouillonnant.",
"de la mort hideuse.",
"du pouvoir suprême.",
"du serpent sournois.",
"du plaisir infini.",
"de la richesse illusoire.",
"de la cruelle trahison.",
"du froid funeste.",
"des spectres inapaisés.",
"du mystère."
],
"motivation": [
"cest le genre de choses que fait Krongar.",
"sinon il finira en prison.",
"il est victime dun chantage.",
"il a trouvé une carte.",
"il a été maudit.",
"il a eu une vision (peut-être un soir de beuverie).",
"il a été engagé pour le faire.",
"il a surpris une conversation.",
"il a lu quelque chose dans un ancien manuscrit.",
"il est tombé accidentellement dans cette affaire.",
"il cherche à assouvir une vengeance.",
"il a ,été dupé."
],
"rival": [
"un poète obsédé.",
"un prince (esse) guerrier.",
"un ministre corrompu.",
"un sectateur fanatique.",
"un noble arrogant.",
"un étrange alchimiste.",
"un sorcier maléfique.",
"un druide cruel.",
"un marchand cupide.",
"un brigand sans foi ni loi.",
"un démon sanguinaire.",
"un fantôme errant."
],
"dieu": [
"Tharungozoth",
"Yrzlak",
"Dyr",
"Knothakon",
"Hadron",
"Shazzadion",
"Chiomalla",
"SaTel",
"Morgazzon",
"Hurm",
"Afyra",
"Grondil",
"Zaggath",
"Zalkyr",
"Fillana",
"Lilandra",
"Zylidith",
"Quathoomar",
"Iondal",
"Piandra",
"Nemmereth",
"Charkond",
"Karyzon",
"Zarymphyxos",
"Kryphondus"
],
"complique1": [
"cest toujours comme ça avec Krongar !",
"la situation réveille chez Krongar des peurs ancestrales.",
"un usurier et ses hommes de main veulent récupérer leur argent.",
"une grave épidémie ravage la région.",
"Krongar est traqué pour un crime passé.",
"les actions dun groupe de rebelles rendent la région peu sûre.",
"des hordes de guerriers envahissent la région pour la conquérir",
"un(e) ancien(ne) admirateur (trice) éconduit(e) cherche à se venger.",
"la loi locale est très sévère et interdit une chose nécessaire à laccomplissement de la mission.",
"un(e) admirateur (trice) inattendu(e) déclare son amour.",
"un rival qui fut défait autrefois réapparaît et met son grain de sel.",
"la folie de Morgazzon fait des ravages dans la région."
],
"obstacle": [
"dun ancien secret.",
"dun long voyage.",
"dune malédiction.",
"dun voleur rusé.",
"dune forte troupe de soldats.",
"dun énorme monstre.",
"dune horde de monstres.",
"dun manque de temps.",
"de gardes et de pièges magiques.",
"dune catastrophe naturelle sur le point de se produire.",
"dune énigme à résoudre.",
"dune bataille à gagner."
],
"retournement": [
"Lennemi est en fait Krongar lui-même, venu dune autre réalité !",
"Toute cette histoire était un piège machiavélique !",
"Lennemi est en fait un vieil ami ou un allié qui a comploté dans lombre !",
"Krongar est contraint de sassocier à un rival pour accomplir la mission !",
"Tout ce qui semblait ordinaire se révèle en fait surnaturel !",
"Lennemi est en fait le père, la mère, le frère ou la sœur de Krongar !",
"Une toute autre mission attend en fait notre héros !",
"Parfois, il ny a pas de retournement de situation !",
"i la mission est accomplie, cela entraînera de terribles répercussions !",
"Le destin offre à Krongar une chance daméliorer les choses, et il est renvoyé dans le temps au début de laventure. La saga recommence, mais cette fois sans retournement de situation !",
"Un ami ou un allié a trahi Krongar !",
"Les dieux sont furieux et lui imposent d'autres tâches"
],
"recompense": [
"Rien du tout ! On sest joué de lui !",
"Beaucoup moins quescompté.",
"Beaucoup moins quescompté, mais il gagne au moins la reconnaissance dune personne haut placée.",
"Beaucoup moins quescompté, mais il est marqué par les dieux (avantage).",
"La récompense escomptée.",
"La récompense escomptée, et il est marqué par les dieux (avantage).",
"La récompense escomptée, ainsi que la reconnaissance dune personne haut placée.",
"Plus quescompté.",
"Plus quescompté, ainsi que la reconnaissance dune personne haut placée.",
"Plus quescompté, et il est marqué par les dieux (avantage).",
"Plus quescompté, ainsi que la reconnaissance dune personne haut placée, et il est marqué par les dieux (avantage).",
"Une promotion... Longue vie au roi Krongar !"
]
}

View File

@ -0,0 +1,96 @@
/* -------------------------------------------- */
import { BoLRoll } from "../controllers/bol-rolls.js";
import { BoLUtility } from "../system/bol-utility.js";
/* -------------------------------------------- */
export class BoLTokenHud {
static init() {
// Integration du TokenHUD
Hooks.on('renderTokenHUD', (app, html, data) => { BoLTokenHud.addTokenHudExtensions(app, html, data._id) });
}
/* -------------------------------------------- */
static async removeExtensionHud(app, html, tokenId) {
html.find('.control-icon.bol-roll').remove()
html.find('.control-icon.bol-action').remove()
}
/* -------------------------------------------- */
static async addExtensionHud(app, html, tokenId) {
let token = canvas.tokens.get(tokenId)
let actor = token.actor
app.hasExtension = true
const hudData = { actor: actor, actionsList: actor.buildListeActions(), rollsList: actor.buildRollList() }
const controlIconActions = html.find('.control-icon[data-action=combat]');
// initiative
await BoLTokenHud._configureSubMenu(controlIconActions, 'systems/bol/templates/token/hud-actor-actions.hbs', hudData,
(event) => {
let actionIndex = Number(event.currentTarget.attributes['data-action-index'].value)
let action = hudData.actionsList[actionIndex]
const actionItem = actor.items.get(action._id)
if (actionItem.system.subtype == "weapon") {
BoLRoll.weaponCheckWithWeapon(hudData.actor, duplicate(actionItem))
} else if (actionItem.system.subtype == "fightoption") {
let chatData = duplicate(actionItem)
if (actionItem.actor) {
chatData.actor = { id: actionItem.actor._id };
}
BoLUtility.postItem(chatData);
}
})
const controlIconTarget = html.find('.control-icon[data-action=target]');
// att+apt+career
await BoLTokenHud._configureSubMenu(controlIconTarget, 'systems/bol/templates/token/hud-actor-rolls.hbs', hudData,
(event) => {
let rollIndex = Number(event.currentTarget.attributes['data-roll-index'].value)
let roll = hudData.rollsList[rollIndex]
if (roll.type == "aptitude") {
BoLRoll.aptitudeCheck(actor, roll.key)
} else if (roll.type == "attribute") {
BoLRoll.attributeCheck(actor, roll.key)
}
})
}
/* -------------------------------------------- */
static async addTokenHudExtensions(app, html, tokenId) {
const controlIconCombat = html.find('.control-icon[data-action=combat]')
if (controlIconCombat.length > 0) {
BoLTokenHud.addExtensionHud(app, html, tokenId);
}
}
/* -------------------------------------------- */
static async _configureSubMenu(insertionPoint, template, hudData, onMenuItem) {
const hud = $(await renderTemplate(template, hudData))
const list = hud.find('div.bol-hud-list')
BoLTokenHud._toggleHudListActive(hud, list);
hud.find('img.bol-hud-togglebutton').click(event => BoLTokenHud._toggleHudListActive(hud, list));
list.find('.bol-hud-menu').click(onMenuItem);
insertionPoint.after(hud);
}
/* -------------------------------------------- */
static _showControlWhen(control, condition) {
if (condition) {
control.show()
}
else {
control.hide()
}
}
/* -------------------------------------------- */
static _toggleHudListActive(hud, list) {
hud.toggleClass('active')
BoLTokenHud._showControlWhen(list, hud.hasClass('active'))
}
}

View File

@ -0,0 +1,86 @@
/* -------------------------------------------- */
import { BoLUtility } from "./bol-utility.js";
/* -------------------------------------------- */
export class BoLAdventureGenerator {
/* -------------------------------------------- */
static async init() {
this.adventureData = await fetchJsonWithTimeout("systems/bol/module/system/adventure_data.json")
}
/* -------------------------------------------- */
static async createAdventure() {
let roll1 = new Roll("1d" + this.adventureData.titre1.length).evaluate({ async: false })
let roll2 = new Roll("1d" + this.adventureData.titre2.length).evaluate({ async: false })
let p1 = this.adventureData.titre1[roll1.result - 1]
let p2 = this.adventureData.titre2[roll2.result - 1]
let story = {}
story.title = "Krongar et " + p1.prefix + " " + p1.name + " " + p2.prefix + " " + p2.name
let rollM = new Roll("1d" + this.adventureData.mission.length).evaluate({ async: false })
story.mission = "La mission de Krongar est de " + this.adventureData.mission[rollM.result - 1].name
if (!p1.isCarriere && !p2.isCarriere) {
let rollC = new Roll("1d" + this.adventureData.carriere.length).evaluate({ async: false })
story.carriere = "Une carrière : " + this.adventureData.carriere[rollC.result - 1]
}
if (!p1.isLieu && !p2.isLieu) {
let rollL1 = new Roll("1d" + this.adventureData.lieux1.length).evaluate({ async: false })
let rollL2 = new Roll("1d" + this.adventureData.lieux2.length).evaluate({ async: false })
story.lieu = "Un lieu : " + this.adventureData.lieux1[rollL1.result - 1] + " " + this.adventureData.lieux2[rollL2.result - 1]
}
if (!p1.isObjet && !p2.isObjet) {
let rollO1 = new Roll("1d" + this.adventureData.objets1.length).evaluate({ async: false })
let rollO2 = new Roll("1d" + this.adventureData.objets2.length).evaluate({ async: false })
story.objet = "Un objet : " + this.adventureData.objets1[rollO1.result - 1] + " " + this.adventureData.objets2[rollO2.result - 1]
}
let rollMOT = new Roll("1d" + this.adventureData.motivation.length).evaluate({ async: false })
story.motivation = "Krongar entreprend cette mission parce que " + this.adventureData.motivation[rollMOT.result - 1]
if (!p1.isEnnemi && !p2.isEnnemi) {
let rollE = new Roll("1d" + this.adventureData.rival.length).evaluate({ async: false })
story.rival = "Un rival : " + this.adventureData.rival[rollE.result - 1]
}
let rollDieu = new Roll("1d6").evaluate({ async: false })
if (rollDieu.result == 6) {
rollDieu = new Roll("1d" + this.adventureData.dieu.length).evaluate({ async: false })
story.dieu = "Un Dieu est impliqué : " + this.adventureData.dieu[rollDieu.result - 1]
}
let rollComp = new Roll("1d6").evaluate({ async: false })
if (rollComp.result >= 5) {
rollComp = new Roll("1d" + this.adventureData.complique1.length).evaluate({ async: false })
story.complication = "Une complication : " + this.adventureData.complique1[rollComp.result - 1]
}
let rollObs = new Roll("1d6").evaluate({ async: false })
if (rollObs.result >= 5) {
rollObs = new Roll("1d" + this.adventureData.obstacle.length).evaluate({ async: false })
story.obstacle = "Un obstacle : " + this.adventureData.obstacle[rollObs.result - 1]
}
let rollRet = new Roll("1d6").evaluate({ async: false })
if (rollRet.result == 6) {
rollRet = new Roll("1d" + this.adventureData.retournement.length).evaluate({ async: false })
story.retournement = "Un retournement : " + this.adventureData.retournement[rollRet.result - 1]
}
let rollRec = new Roll("1d" + this.adventureData.recompense.length).evaluate({ async: false })
story.recompense = "Pour sa peine, Krongar reçoit " + this.adventureData.recompense[rollRec.result - 1]
ChatMessage.create({
alias: this.name,
whisper: BoLUtility.getUsers(user => user.isGM),
content: await renderTemplate('systems/bol/templates/chat/chat-adventure-result.hbs',
{ name: "Aventure !", img: "icons/commodities/gems/gem-cluster-red.webp", story : story})
})
}
}

View File

@ -0,0 +1,466 @@
/* -------------------------------------------- */
import { BolCalendarEditor } from "./bol-calendar-editor.js";
import { BoLUtility } from "./bol-utility.js";
/* -------------------------------------------- */
const monthDef = [
{ label: "Vishka", saison: "Saison du Renouveau" },
{ label: "Istha", saison: "Saison du Renouveau" },
{ label: "Sadha", saison: "Saison du Renouveau" },
{ label: "Vana", saison: "Saison du Renouveau" },
{ label: "Pada", saison: "Saison Sèche" },
{ label: "Vina", saison: "Saison Sèche" },
{ label: "Tika", saison: "Saison Sèche" },
{ label: "Sha", saison: "Saison Sèche" },
{ label: "Pausa", saison: "Saison Sèche" },
{ label: "Magha", saison: "Saison des Pluies" },
{ label: "Phal", saison: "Saison des Pluies" },
{ label: "Chatra", saison: "Saison des Pluies" }
]
const BOL_DAY_PER_MONTH = 30
/* -------------------------------------------- */
export class BoLCalendar extends Application {
static createCalendarPos() {
return { top: 200, left: 200 };
}
static getCalendar(index) {
let calendar = {
heure: 0,
minutes: 0,
day: 0,
year: 900,
month: 0,
}
return calendar
}
constructor() {
super();
// position
this.calendarPos = duplicate(game.settings.get("bol", "calendar-pos"));
if (this.calendarPos == undefined || this.calendarPos.top == undefined) {
this.calendrierPos = BoLCalendar.createCalendarPos()
game.settings.set("bol", "calendar-pos", this.calendarPos)
}
// Calendar
this.calendar = duplicate(game.settings.get("bol", "calendar") ?? BoLCalendar.getCalendar(0));
this.calendar.year = this.calendar.year || 900
this.calendar.month = 0
if (game.isGM()) { // Uniquement si GM
game.settings.set("bol", "calendar", this.calendar)
}
}
/* -------------------------------------------- */
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
template: "systems/bol/templates/calendar-template.html",
popOut: false,
resizable: false
})
}
/* -------------------------------------------- */
getCurrentHeure() {
return this.calendar.hour
}
/* -------------------------------------------- */
async onCalendarButton(ev) {
ev.preventDefault();
const calendarAvance = ev.currentTarget.attributes['data-calendar-avance']
const calendarSet = ev.currentTarget.attributes['data-calendar-set']
if (calendarAvance) {
await this.incrementTime(Number(calendarAvance.value))
}
else if (calendarSet) {
this.setHour(Number(calendarSet.value))
}
this.updateDisplay()
}
/* -------------------------------------------- */
async incrementTime(minutes = 0) {
this.calendar.minutes += minutes
if (this.calendar.minutes >= 60) {
this.calendar.minutes -= 60
this.calendar.hour += 1;
}
if (this.calendar.hour >= 24) {
this.calendar.hour -= 24
await this.incrementDay()
}
game.settings.set("bol", "calendar", duplicate(this.calendar));
// Notification aux joueurs // TODO: replace with Hook on game settings update
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_sync_time",
data: duplicate(this.calendrier)
});
}
/* -------------------------------------------- */
async incrementerJour() {
const index = this.getCurrentDayIndex() + 1;
this.calendrier = RdDCalendrier.getCalendrier(index);
await this.rebuildListeNombreAstral();
}
/* -------------------------------------------- */
syncPlayerTime(calendrier) {
this.calendrier = duplicate(calendrier); // Local copy update
this.updateDisplay();
}
/* -------------------------------------------- */
async positionnerHeure(indexHeure) {
if (indexHeure <= this.calendrier.heureRdD) {
await this.incrementerJour();
}
this.calendrier.heureRdD = indexHeure;
this.calendrier.minutesRelative = 0;
game.settings.set(SYSTEM_RDD, "calendrier", duplicate(this.calendrier));
}
/* -------------------------------------------- */
fillCalendrierData(formData = {}) {
console.log(this.calendrier);
let moisKey = heuresList[this.calendrier.moisRdD];
let heureKey = heuresList[this.calendrier.heureRdD];
console.log(moisKey, heureKey);
const mois = heuresDef[moisKey];
const heure = heuresDef[heureKey];
formData.heureKey = heureKey;
formData.moisKey = moisKey;
formData.jourMois = this.calendrier.jour + 1;
formData.nomMois = mois.label; // heures et mois nommés identiques
formData.iconMois = dossierIconesHeures + mois.icon;
formData.nomHeure = heure.label;
formData.iconHeure = dossierIconesHeures + heure.icon;
formData.nomSaison = saisonsDef[mois.saison].label;
formData.heureRdD = this.calendrier.heureRdD;
formData.minutesRelative = this.calendrier.minutesRelative;
formData.isGM = game.user.isGM;
return formData;
}
/* -------------------------------------------- */
getLectureAstrologieDifficulte(dateIndex) {
let indexNow = this.getCurrentDayIndex();
let diffDay = dateIndex - indexNow;
return - Math.floor(diffDay / 2);
}
/* -------------------------------------------- */
async requestNombreAstral(request) {
if (Misc.isUniqueConnectedGM()) { // Only once
console.log(request);
let jourDiff = this.getLectureAstrologieDifficulte(request.date);
let niveau = Number(request.astrologie.data.niveau) + Number(request.conditions) + Number(jourDiff) + Number(request.etat);
let rollData = {
caracValue: request.carac_vue,
finalLevel: niveau,
showDice: HIDE_DICE,
rollMode: "blindroll"
};
await RdDResolutionTable.rollData(rollData);
let nbAstral = this.getNombreAstral(request.date);
request.rolled = rollData.rolled;
request.isValid = true;
if (!request.rolled.isSuccess) {
request.isValid = false;
nbAstral = await RdDDice.rollTotal("1dhr" + nbAstral, { rollMode: "selfroll" });
// Mise à jour des nombres astraux du joueur
let astralData = this.listeNombreAstral.find((nombreAstral, i) => nombreAstral.index == request.date);
astralData.valeursFausses.push({ actorId: request.id, nombreAstral: nbAstral });
game.settings.set(SYSTEM_RDD, "liste-nombre-astral", this.listeNombreAstral);
}
request.nbAstral = nbAstral;
if (Misc.getActiveUser(request.userId)?.isGM) {
RdDUtility.responseNombreAstral(request);
} else {
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_response_nombre_astral",
data: request
});
}
}
}
/* -------------------------------------------- */
findHeure(heure) {
heure = Grammar.toLowerCaseNoAccentNoSpace(heure);
let parHeureOuLabel = Object.values(heuresDef).filter(it => (it.heure + 1) == parseInt(heure) || Grammar.toLowerCaseNoAccentNoSpace(it.label) == heure);
if (parHeureOuLabel.length == 1) {
return parHeureOuLabel[0];
}
let parLabelPartiel = Object.values(heuresDef).filter(it => Grammar.toLowerCaseNoAccentNoSpace(it.label).includes(heure));
if (parLabelPartiel.length > 0) {
parLabelPartiel.sort(Misc.ascending(h => h.label.length));
return parLabelPartiel[0];
}
return undefined;
}
/* -------------------------------------------- */
getHeureNumber( hNum) {
let heure = Object.values(heuresDef).find(it => (it.heure) == hNum);
return heure
}
/* -------------------------------------------- */
getHeuresChanceMalchance(heureNaissance) {
let heuresChancesMalchances = [];
let defHeure = this.findHeure(heureNaissance);
if (defHeure) {
let hn = defHeure.heure;
let chiffreAstral = this.getCurrentNombreAstral() ?? 0;
heuresChancesMalchances[0] = { value : "+4", heures: [this.getHeureNumber((hn + chiffreAstral) % RDD_HEURES_PAR_JOUR).label]};
heuresChancesMalchances[1] = { value : "+2", heures: [this.getHeureNumber((hn + chiffreAstral+4) % RDD_HEURES_PAR_JOUR).label,
this.getHeureNumber((hn + chiffreAstral + 8) % RDD_HEURES_PAR_JOUR).label ] };
heuresChancesMalchances[2] = { value : "-4", heures: [this.getHeureNumber((hn + chiffreAstral+6) % RDD_HEURES_PAR_JOUR).label]};
heuresChancesMalchances[3] = { value : "-2", heures: [this.getHeureNumber((hn + chiffreAstral+3) % RDD_HEURES_PAR_JOUR).label,
this.getHeureNumber((hn + chiffreAstral + 9) % RDD_HEURES_PAR_JOUR).label ]};
}
return heuresChancesMalchances;
}
/* -------------------------------------------- */
getAjustementAstrologique(heureNaissance, name = undefined) {
let defHeure = this.findHeure(heureNaissance);
if (defHeure) {
let hn = defHeure.heure;
let chiffreAstral = this.getCurrentNombreAstral() ?? 0;
let heureCourante = this.calendrier.heureRdD;
let ecartChance = (hn + chiffreAstral - heureCourante) % RDD_HEURES_PAR_JOUR;
switch (ecartChance) {
case 0: return 4;
case 4: case 8: return 2;
case 6: return -4;
case 3: case 9: return -2;
}
}
else if (name) {
ui.notifications.warn(name + " n'a pas d'heure de naissance, ou elle est incorrecte : " + heureNaissance);
}
else {
ui.notifications.warn(heureNaissance + " ne correspond pas à une heure de naissance");
}
return 0;
}
/* -------------------------------------------- */
getData() {
let formData = super.getData();
this.fillCalendrierData(formData);
this.setPos(this.calendrierPos);
return formData;
}
/* -------------------------------------------- */
setPos(pos) {
return new Promise(resolve => {
function check() {
let elmnt = document.getElementById("calendar-time-container");
if (elmnt) {
elmnt.style.bottom = null;
let xPos = (pos.left) > window.innerWidth ? window.innerWidth - 200 : pos.left;
let yPos = (pos.top) > window.innerHeight - 20 ? window.innerHeight - 100 : pos.top;
elmnt.style.top = (yPos) + "px";
elmnt.style.left = (xPos) + "px";
resolve();
} else {
setTimeout(check, 30);
}
}
check();
});
}
/* -------------------------------------------- */
updateDisplay() {
let data = this.fillCalendrierData();
// Rebuild data
let dateHTML = `Jour ${data.jourMois} de ${data.nomMois} (${data.nomSaison})`
if (game.user.isGM) {
dateHTML = dateHTML + " - NA: " + (this.getCurrentNombreAstral() ?? "indéterminé");
}
for (let handle of document.getElementsByClassName("calendar-date-rdd")) {
handle.innerHTML = dateHTML;
}
for (let heure of document.getElementsByClassName("calendar-heure-texte")) {
heure.innerHTML = data.nomHeure;
}
for (const minute of document.getElementsByClassName("calendar-time-disp")) {
minute.innerHTML = `${data.minutesRelative} minutes`;
}
for (const heureImg of document.getElementsByClassName("calendar-heure-img")) {
heureImg.src = data.iconHeure;
}
}
/* -------------------------------------------- */
async saveEditeur(calendrierData) {
this.calendrier.minutesRelative = Number(calendrierData.minutesRelative);
this.calendrier.jour = Number(calendrierData.jourMois) - 1;
this.calendrier.moisRdD = RdDCalendrier.getChiffreFromSigne(calendrierData.moisKey);
this.calendrier.heureRdD = RdDCalendrier.getChiffreFromSigne(calendrierData.heureKey);
game.settings.set(SYSTEM_RDD, "calendrier", duplicate(this.calendrier));
await this.rebuildListeNombreAstral();
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_sync_time",
data: duplicate(this.calendrier)
});
this.updateDisplay();
}
/* -------------------------------------------- */
async showCalendarEditor() {
let calendrierData = duplicate(this.fillCalendrierData());
if (this.editeur == undefined) {
calendrierData.jourMoisOptions = RdDCalendrier.buildJoursMois();
calendrierData.heuresOptions = [0, 1];
calendrierData.minutesOptions = Array(RDD_MINUTES_PAR_HEURES).fill().map((item, index) => 0 + index);
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/calendar-editor-template.html', calendrierData);
this.editeur = new RdDCalendrierEditeur(html, this, calendrierData)
}
this.editeur.updateData(calendrierData);
this.editeur.render(true);
}
static buildJoursMois() {
return Array(RDD_JOUR_PAR_MOIS).fill().map((item, index) => 1 + index);
}
/* -------------------------------------------- */
async showAstrologieEditor() {
let calendrierData = duplicate(this.fillCalendrierData());
let astrologieArray = [];
this.listeNombreAstral = this.listeNombreAstral || [];
for (let astralData of this.listeNombreAstral) {
astralData.humanDate = this.getDateFromIndex(astralData.index);
for (let vf of astralData.valeursFausses) {
let actor = game.actors.get(vf.actorId);
vf.actorName = (actor) ? actor.name : "Inconnu";
}
astrologieArray.push(duplicate(astralData));
}
let heuresParActeur = {};
for (let actor of game.actors) {
let heureNaissance = actor.getHeureNaissance();
if ( heureNaissance) {
heuresParActeur[actor.name] = this.getHeuresChanceMalchance(heureNaissance);
}
}
//console.log("ASTRO", astrologieArray);
calendrierData.astrologieData = astrologieArray;
calendrierData.heuresParActeur = heuresParActeur;
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/calendar-astrologie-template.html', calendrierData);
let astrologieEditeur = new RdDAstrologieEditeur(html, this, calendrierData)
astrologieEditeur.updateData(calendrierData);
astrologieEditeur.render(true);
}
/* -------------------------------------------- */
/** @override */
async activateListeners(html) {
super.activateListeners(html);
HtmlUtility._showControlWhen($(".gm-only"), game.user.isGM);
await this.updateDisplay();
html.find('.calendar-btn').click(ev => this.onCalendarButton(ev));
html.find('.calendar-btn-edit').click(ev => {
ev.preventDefault();
this.showCalendarEditor();
});
html.find('.astrologie-btn-edit').click(ev => {
ev.preventDefault();
this.showAstrologieEditor();
});
html.find('#calendar-move-handle').mousedown(ev => {
ev.preventDefault();
ev = ev || window.event;
let isRightMB = false;
if ("which" in ev) { // Gecko (Firefox), WebKit (Safari/Chrome) & Opera
isRightMB = ev.which == 3;
} else if ("button" in ev) { // IE, Opera
isRightMB = ev.button == 2;
}
if (!isRightMB) {
dragElement(document.getElementById("calendar-time-container"));
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
function dragElement(elmnt) {
elmnt.onmousedown = dragMouseDown;
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
// set the element's new position:
elmnt.style.bottom = null
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
}
function closeDragElement() {
// stop moving when mouse button is released:
elmnt.onmousedown = null;
document.onmouseup = null;
document.onmousemove = null;
let xPos = (elmnt.offsetLeft - pos1) > window.innerWidth ? window.innerWidth - 200 : (elmnt.offsetLeft - pos1);
let yPos = (elmnt.offsetTop - pos2) > window.innerHeight - 20 ? window.innerHeight - 100 : (elmnt.offsetTop - pos2)
xPos = xPos < 0 ? 0 : xPos;
yPos = yPos < 0 ? 0 : yPos;
if (xPos != (elmnt.offsetLeft - pos1) || yPos != (elmnt.offsetTop - pos2)) {
elmnt.style.top = (yPos) + "px";
elmnt.style.left = (xPos) + "px";
}
game.system.rdd.calendrier.calendrierPos.top = yPos;
game.system.rdd.calendrier.calendrierPos.left = xPos;
if (game.user.isGM) {
game.settings.set(SYSTEM_RDD, "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos));
}
}
}
} else if (isRightMB) {
game.system.rdd.calendrier.calendrierPos.top = 200;
game.system.rdd.calendrier.calendrierPos.left = 200;
if (game.user.isGM) {
game.settings.set(SYSTEM_RDD, "calendrier-pos", duplicate(game.system.rdd.calendrier.calendrierPos));
}
this.setPos(game.system.rdd.calendrier.calendrierPos);
}
});
}
}

View File

@ -0,0 +1,162 @@
/* -------------------------------------------- */
import { BoLUtility } from "./bol-utility.js";
import { BoLRoll } from "../controllers/bol-rolls.js";
/* -------------------------------------------- */
export class BoLCharacterSummary extends Application {
/* -------------------------------------------- */
static displayPCSummary(){
game.bol.charSummary.render(true)
}
/* -------------------------------------------- */
updatePCSummary(){
if ( this.rendered) {
this.render(true)
}
}
/* -------------------------------------------- */
static createSummaryPos() {
return { top: 200, left: 200 };
}
/* -------------------------------------------- */
static ready() {
if ( !game.user.isGM ) { // Uniquement si GM
return
}
let charSummary = new BoLCharacterSummary()
game.bol.charSummary = charSummary
}
/* -------------------------------------------- */
constructor() {
super();
//game.settings.set("world", "character-summary-data", {npcList: [], x:0, y:0})
this.settings = game.settings.get("world", "character-summary-data")
}
/* -------------------------------------------- */
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
template: "systems/bol/templates/apps/character-summary-template.html",
popOut: true,
resizable: true,
dragDrop: [{ dragSelector: ".items-list .item", dropSelector: null }],
classes: ["bol", "dialog"], width: 820, height: 'fit-content'
})
}
/* -------------------------------------------- */
getData() {
let formData = super.getData();
formData.pcs = game.actors.filter( ac => ac.type == "character" && ac.hasPlayerOwner )
formData.npcs = []
let newList = []
let toUpdate = false
for( let actorId of this.settings.npcList ) {
let actor = game.actors.get(actorId)
if (actor) {
formData.npcs.push( actor )
newList.push(actorId)
} else {
toUpdate = true
}
}
formData.config = game.bol.config
formData.horoscopeGroupList = game.settings.get("bol", "horoscope-group")
if ( toUpdate ) {
this.settings.npcList = newList
//console.log("Going to update ...", this.settings)
game.settings.set("world", "character-summary-data", this.settings)
}
return formData
}
/* -------------------------------------------- */
updateNPC() {
game.settings.set("world", "character-summary-data", game.bol.charSummary.settings)
game.bol.charSummary.close()
setTimeout( function() { game.bol.charSummary.render(true)}, 500)
}
/* -------------------------------------------- */
async _onDrop(event) {
//console.log("Dragged data are : ", dragData)
let data = event.dataTransfer.getData('text/plain')
let dataItem = JSON.parse( data)
let actor = fromUuidSync(dataItem.uuid)
if (actor) {
game.bol.charSummary.settings.npcList.push( actor.id )
game.bol.charSummary.updateNPC()
} else {
ui.notifications.warn( game.i18n.localize("BOL.ui.noactorfound") )
}
}
/* -------------------------------------------- */
/** @override */
async activateListeners(html) {
super.activateListeners(html);
html.find('.actor-open').click((event) => {
const li = $(event.currentTarget).parents(".item")
const actor = game.actors.get(li.data("actor-id"))
actor.sheet.render(true)
})
html.find('.summary-roll').click((event) => {
const li = $(event.currentTarget).parents(".item")
const actor = game.actors.get(li.data("actor-id"))
let type = $(event.currentTarget).data("type")
let key = $(event.currentTarget).data("key")
if ( type == "attribute") {
BoLRoll.attributeCheck(actor, key, event)
} else if (type == "aptitude") {
BoLRoll.aptitudeCheck(actor, key, event)
}
})
html.find('.actor-delete').click(event => {
const li = $(event.currentTarget).parents(".item");
let actorId = li.data("actor-id")
let newList = game.bol.charSummary.settings.npcList.filter(id => id != actorId)
game.bol.charSummary.settings.npcList = newList
game.bol.charSummary.updateNPC()
})
html.find('#horoscope-group-edit-available').change(event => {
const horoId = $(event.currentTarget).data("horo-id")
let newValue = event.currentTarget.value
let horoscopes = duplicate(game.settings.get("bol", "horoscope-group"))
if ( horoId && horoscopes[horoId]) {
horoscopes[horoId].availableDice = Number(newValue)
if (newValue <= 0) {
horoscopes[horoId] = undefined
}
game.settings.set("bol", "horoscope-group", horoscopes)
setTimeout(function() { BoLUtility.updateSheets()}, 800 )
}
})
html.find('#horoscope-group-edit-max').change(event => {
const horoId = $(event.currentTarget).data("horo-id")
let newValue = event.currentTarget.value
let horoscopes = duplicate(game.settings.get("bol", "horoscope-group"))
if ( horoId && horoscopes[horoId]) {
horoscopes[horoId].maxDice = Number(newValue)
if (newValue <= 0) {
horoscopes[horoId] = undefined
}
game.settings.set("bol", "horoscope-group", horoscopes)
setTimeout(function() { BoLUtility.updateSheets()}, 800 )
}
})
}
}

View File

@ -0,0 +1,84 @@
/*
Init order =
10 - Legendary
9 - Heroic
8 - Success
7 - Rivals/adversary
6 - Coriaces/tough
5 - Failure
4 - Pietaille
3 - Echec critique
*/
import { BoLUtility } from "../system/bol-utility.js";
export class BoLCombatManager extends Combat {
/************************************************************************************/
async rollInitiative(ids, formula = undefined, messageOptions = {}) {
console.log(`${game.system.title} | Combat.rollInitiative()`, ids, formula, messageOptions);
// Structure input data
ids = typeof ids === "string" ? [ids] : ids;
// Get initiative malus from tough/adversary
let malusInit = 0
for (let combatant of this.combatants) {
malusInit = Math.max(malusInit, combatant.actor.getInitiativeMalus())
}
// calculate initiative
for (let cId = 0; cId < ids.length; cId++) {
const combatant = this.combatants.get(ids[cId])
let fvttInit = combatant.actor.getInitiativeRank(false, true, { combatId: this.id, combatantId: combatant.id, malusInit })
fvttInit += (cId / 100)
await this.updateEmbeddedDocuments("Combatant", [{ _id: ids[cId], initiative: fvttInit }]);
}
}
/************************************************************************************/
nextRound() {
if (game.user.isGM) {
let combatants = this.combatants.contents
let autoRemoveDead = game.settings.get("bol", "auto-remove-dead") // Optionnal auto-removal of dead char.
for (let c of combatants) {
//let actor = game.actors.get(c.actorId)
c.actor.clearRoundModifiers()
let toRemove = []
if (autoRemoveDead && c.actor.type == "encounter" && (c.actor.system.chartype == "tough" || c.actor.system.chartype == "creature" || c.actor.system.chartype == "base") && c.actor.system.resources.hp.value <= 0) {
toRemove.push(c.id || c._id)
}
//console.log("REM", autoRemoveDead, toRemove, c.actor)
if (toRemove.length > 0) {
this.deleteEmbeddedDocuments('Combatant', toRemove)
}
}
}
super.nextRound()
}
/************************************************************************************/
startCombat() {
if (game.user.isGM) {
let combatants = this.combatants.contents
for (let c of combatants) {
let actor = game.actors.get(c.actorId)
actor.storeVitaliteCombat()
}
}
return super.startCombat()
}
/*-***********************************************************************************/
_onDelete() {
if (game.user.isGM) {
let combatants = this.combatants.contents
for (let c of combatants) {
let actor = game.actors.get(c.actorId)
actor.clearInitiative()
actor.displayRecuperation()
}
}
super._onDelete()
}
}

View File

@ -0,0 +1,110 @@
/* -------------------------------------------- */
import { BoLAdventureGenerator } from "./bol-adventure-generator.js"
import { BoLCharacterSummary } from "./bol-character-summary.js"
/* -------------------------------------------- */
export class BoLCommands {
static init() {
if (!game.bol.commands) {
const bolCommands = new BoLCommands()
bolCommands.registerCommand({ path: ["/adventure"], func: (content, msg, params) => BoLAdventureGenerator.createAdventure(), descr: "Nouvelle idée d'aventure!" });
bolCommands.registerCommand({ path: ["/pcview"], func: (content, msg, params) => BoLCharacterSummary.displayPCSummary(), descr: "Affiche la liste des PJs!" });
game.bol.commands = bolCommands
}
Hooks.on("chatMessage", (html, content, msg) => {
if (content[0] == '/') {
let regExp = /(\S+)/g;
let commands = content.match(regExp);
if (game.bol.commands.processChatCommand(commands, content, msg)) {
return false;
}
}
return true
})
}
constructor() {
this.commandsTable = {}
}
/* -------------------------------------------- */
registerCommand(command) {
this._addCommand(this.commandsTable, command.path, '', command);
}
/* -------------------------------------------- */
_addCommand(targetTable, path, fullPath, command) {
if (!this._validateCommand(targetTable, path, command)) {
return;
}
const term = path[0];
fullPath = fullPath + term + ' '
if (path.length == 1) {
command.descr = `<strong>${fullPath}</strong>: ${command.descr}`;
targetTable[term] = command;
}
else {
if (!targetTable[term]) {
targetTable[term] = { subTable: {} };
}
this._addCommand(targetTable[term].subTable, path.slice(1), fullPath, command)
}
}
/* -------------------------------------------- */
_validateCommand(targetTable, path, command) {
if (path.length > 0 && path[0] && command.descr && (path.length != 1 || targetTable[path[0]] == undefined)) {
return true;
}
console.warn("bolCommands._validateCommand failed ", targetTable, path, command);
return false;
}
/* -------------------------------------------- */
/* Manage chat commands */
processChatCommand(commandLine, content = '', msg = {}) {
// Setup new message's visibility
let rollMode = game.settings.get("core", "rollMode");
if (["gmroll", "blindroll"].includes(rollMode)) msg["whisper"] = ChatMessage.getWhisperRecipients("GM");
if (rollMode === "blindroll") msg["blind"] = true;
msg["type"] = 0;
let command = commandLine[0].toLowerCase();
let params = commandLine.slice(1);
return this.process(command, params, content, msg);
}
/* -------------------------------------------- */
process(command, params, content, msg) {
return this._processCommand(this.commandsTable, command, params, content, msg);
}
/* -------------------------------------------- */
_processCommand(commandsTable, name, params, content = '', msg = {}, path = "") {
console.log("===> Processing command")
let command = commandsTable[name];
path = path + name + " ";
if (command && command.subTable) {
if (params[0]) {
return this._processCommand(command.subTable, params[0], params.slice(1), content, msg, path)
}
else {
this.help(msg, command.subTable);
return true;
}
}
if (command && command.func) {
const result = command.func(content, msg, params);
if (result == false) {
BoLCommands._chatAnswer(msg, command.descr);
}
return true;
}
return false;
}
}

View File

@ -0,0 +1,67 @@
import { BoLRoll } from "../controllers/bol-rolls.js";
export class BoLHotbar {
static async assignToHotBar( item, slot) {
let command = `game.bol.BoLHotbar.rollMacro("${item.name}", "${item.type}");`
let macro = game.macros.contents.find(m => (m.name === item.name) && (m.command === command))
if (!macro) {
macro = await Macro.create({
name: item.name,
type: "script",
img: item.img,
command: command
}, { displaySheet: false })
}
await game.user.assignHotbarMacro(macro, slot);
}
/**
* Create a macro when dropping an entity on the hotbar
* Item - open roll dialog for item
* Actor - open actor sheet
* Journal - open journal sheet
*/
static init( ) {
Hooks.on("hotbarDrop", (bar, documentData, slot) => {
// Create item macro if rollable item - weapon, spell, prayer, trait, or skill
if (documentData.type == "Item") {
let item = fromUuidSync(documentData.uuid)
if (item == undefined) {
item = this.actor.items.get(documentData.uuid)
}
if (item && (item.system.subtype === "weapon" || item.system.category === "spell")) {
this.assignToHotBar( item, slot )
return false
}
}
return true
})
}
/** Roll macro */
static rollMacro(itemName, itemType, bypassData) {
const speaker = ChatMessage.getSpeaker()
let actor
if (speaker.token) actor = game.actors.tokens[speaker.token]
if (!actor) actor = game.actors.get(speaker.actor)
if (!actor) {
return ui.notifications.warn( game.i18n.localize("BOL.ui.selectactor") )
}
let item = actor.items.find(it => it.name === itemName && it.type == itemType)
if (!item ) {
return ui.notifications.warn( game.i18n.localize("BOL.ui.itemnotfound") )
}
// Trigger the item roll
if (item.system.category === "equipment" && item.system.subtype === "weapon") {
return BoLRoll.weaponCheckWithWeapon( actor, item)
}
if (item.system.category === "spell") {
return BoLRoll.spellCheckWithSpell( actor, item)
}
}
}

View File

@ -0,0 +1,756 @@
import { BoLRoll, BoLDefaultRoll } from "../controllers/bol-rolls.js";
// Spell circle to min PP cost
const __circle2minpp = { 0: 0, 1: 2, 2: 6, 3: 11 }
const __validDices = { "6": 1, "8": 1, "10": 1, "12": 1 }
export class BoLUtility {
/* -------------------------------------------- */
static init() {
game.settings.register("bol", "rollArmor", {
name: game.i18n.localize("BOL.settings.rollArmor"),
hint: game.i18n.localize("BOL.settings.rollArmorTooltip"),
scope: "world",
config: true,
default: true,
type: Boolean,
onChange: lang => window.location.reload()
})
game.settings.register("bol", "useBougette", {
name: game.i18n.localize("BOL.settings.useBougette"),
hint: game.i18n.localize("BOL.settings.useBougetteTooltip"),
scope: "world",
config: true,
default: false,
type: Boolean,
onChange: lang => window.location.reload()
})
game.settings.register("bol", "auto-remove-dead", {
name: game.i18n.localize("BOL.settings.removeDead"),
hint: game.i18n.localize("BOL.settings.removeDeadTooltip"),
scope: "world",
config: true,
default: false,
type: Boolean
})
game.settings.register("bol", "dice-formula", {
name: game.i18n.localize("BOL.settings.diceFormula"),
hint: game.i18n.localize("BOL.settings.diceFormulaTooltip"),
scope: "world",
config: true,
default: "6",
type: String,
choices: { "6": "2d6", "8": "2d8", "10": "2d10", "12": "2d12", "20": "2d20" },
onChange: value => {
BoLUtility.setDiceFormula(value)
}
})
game.settings.register("bol", "dice-success-value", {
name: game.i18n.localize("BOL.settings.diceSuccessValue"),
hint: game.i18n.localize("BOL.settings.diceSuccessValueTooltip"),
scope: "world",
config: true,
default: 9,
range: {
min: 2,
max: 40,
step: 1
},
type: Number,
onChange: value => {
BoLUtility.setSuccessValue(value)
}
})
game.settings.register("bol", "dice-critical-success-value", {
name: game.i18n.localize("BOL.settings.diceCriticalValue"),
hint: game.i18n.localize("BOL.settings.diceCriticalValueTooltip"),
scope: "world",
config: true,
default: 12,
range: {
min: 2,
max: 40,
step: 1
},
type: Number,
onChange: value => {
BoLUtility.setCriticalSuccessValue(value)
}
})
game.settings.register("bol", "dice-critical-failure-value", {
name: game.i18n.localize("BOL.settings.diceCriticalFailure"),
hint: game.i18n.localize("BOL.settings.diceCriticalFailureTooltip"),
scope: "world",
config: true,
default: 2,
range: {
min: 2,
max: 40,
step: 1
},
type: Number,
onChange: value => {
BoLUtility.setCriticalFailureValue(value)
}
})
game.settings.register("world", "character-summary-data", {
name: "character-summary-data",
scope: "world",
config: false,
default: { npcList: [], x: 200, y: 200 },
type: Object
})
game.settings.register("bol", "logoActorSheet", {
name: game.i18n.localize("BOL.settings.defaultLogoActorSheetPath"),
hint: game.i18n.localize("BOL.settings.defaultLogoPathActorSheetTooltip"),
scope: "world",
config: true,
default: "/systems/bol/ui/logo.webp",
type: String,
onChange: lang => window.location.reload()
})
game.settings.register("bol", "logoTopLeft", {
name: game.i18n.localize("BOL.settings.defaultLogoTopLeftPath"),
hint: game.i18n.localize("BOL.settings.defaultLogoTopLeftPathTooltip"),
scope: "world",
config: true,
default: "/systems/bol/ui/logo2.webp",
type: String,
onChange: lang => window.location.reload()
})
game.settings.register("bol", "horoscope-group", {
name: "horoscope-group",
scope: "world",
config: false,
default: {},
type: Object
})
this.rollArmor = game.settings.get("bol", "rollArmor") // Roll armor or not
this.useBougette = game.settings.get("bol", "useBougette") // Use optionnal bougette rules
this.actorSheetLogo = game.settings.get("bol", "logoActorSheet") || "/systems/bol/ui/logo.webp"
this.logoTopLeft = game.settings.get("bol", "logoTopLeft") || "/systems/bol/ui/logo2.webp"
this.diceFormula = game.settings.get("bol", "dice-formula")
this.successValue = Number(game.settings.get("bol", "dice-success-value"))
this.criticalSuccessValue = Number(game.settings.get("bol", "dice-critical-success-value"))
this.criticalFailureValue = Number(game.settings.get("bol", "dice-critical-failure-value"))
}
/* -------------------------------------------- */
static setDiceFormula(value) {
this.diceFormula = value
}
static setSuccessValue(value) {
this.successValue = Number(value)
}
static setCriticalSuccessValue(value) {
this.criticalSuccessValue = Number(value)
}
static setCriticalFailureValue(value) {
this.criticalFailureValue = Number(value)
}
static getDiceData() {
let df = this.diceFormula
if (!__validDices[String(this.diceFormula)]) {
df = "6"
}
return {
diceFormula: df,
successValue: this.successValue,
criticalSuccessValue: this.criticalSuccessValue,
criticalFailureValue: this.criticalFailureValue
}
}
/* -------------------------------------------- */
static getRollArmor() {
return this.rollArmor
}
/* -------------------------------------------- */
static getUseBougette() {
return this.useBougette
}
/* -------------------------------------------- */
static getLogoActorSheet() {
return this.actorSheetLogo
}
/* -------------------------------------------- */
static getLogoTopLeft() {
return this.logoTopLeft
}
/* -------------------------------------------- */
static getActorFromRollData(rollData) {
let actor = game.actors.get(rollData.actorId)
if (rollData.tokenId) {
let token = canvas.tokens.placeables.find(t => t.id == rollData.tokenId)
if (token) {
actor = token.actor
}
}
return actor
}
/* -------------------------------------------- */
static async ready() {
//$("#logo").attr("src", this.getLogoTopLeft() )
$("#logo").css("content", `url(${this.getLogoTopLeft()})`)
CONFIG.statusEffects = duplicate(game.bol.config.statusEffects)
}
/* -------------------------------------------- */
static chatDataSetup(content, modeOverride, isRoll = false, forceWhisper) {
let chatData = {
user: game.user.id,
rollMode: modeOverride || game.settings.get("core", "rollMode"),
content: content
};
if (["gmroll", "blindroll"].includes(chatData.rollMode)) chatData["whisper"] = ChatMessage.getWhisperRecipients("GM").map(u => u.id);
if (chatData.rollMode === "blindroll") chatData["blind"] = true;
else if (chatData.rollMode === "selfroll") chatData["whisper"] = [game.user];
if (forceWhisper) { // Final force !
chatData["speaker"] = ChatMessage.getSpeaker();
chatData["whisper"] = ChatMessage.getWhisperRecipients(forceWhisper);
}
return chatData;
}
/* -------------------------------------------- */
static postItem(chatData) {
// Don't post any image for the item (which would leave a large gap) if the default image is used
if (chatData.img.includes("/blank.png")) {
chatData.img = null;
}
// JSON object for easy creation
chatData.jsondata = JSON.stringify(
{
compendium: "postedItem",
payload: chatData,
});
renderTemplate('systems/bol/templates/item/post-item.hbs', chatData).then(html => {
let chatOptions = BoLUtility.chatDataSetup(html);
ChatMessage.create(chatOptions, "selfroll")
});
}
/* -------------------------------------------- */
static createDirectOptionList(min, max) {
let options = {};
for (let i = min; i <= max; i++) {
options[`${i}`] = `${i}`;
}
return options;
}
/* -------------------------------------------- */
static buildListOptions(min, max) {
let options = [];
for (let i = min; i <= max; i++) {
options.push(`<option value="${i}">${i}</option>`);
}
return options.join("");
}
/* -------------------------------------------- */
static async showDiceSoNice(roll, rollMode) {
if (game.modules.get("dice-so-nice")?.active) {
if (game.dice3d) {
let whisper = null;
let blind = false;
rollMode = rollMode ?? game.settings.get("core", "rollMode");
switch (rollMode) {
case "blindroll": //GM only
blind = true;
case "gmroll": //GM + rolling player
whisper = this.getUsers(user => user.isGM);
break;
case "roll": //everybody
whisper = this.getUsers(user => user.active);
break;
case "selfroll":
whisper = [game.user.id];
break;
}
await game.dice3d.showForRoll(roll, game.user, true, whisper, blind);
}
}
}
/* -------------------------------------------- */
static getUsers(filter) {
return game.users.filter(filter).map(user => user.id);
}
/* -------------------------------------------- */
static getWhisperRecipients(rollMode, name) {
switch (rollMode) {
case "blindroll": return this.getUsers(user => user.isGM);
case "gmroll": return this.getWhisperRecipientsAndGMs(name);
case "selfroll": return [game.user.id];
}
return undefined;
}
/* -------------------------------------------- */
static getOtherWhisperRecipients(name) {
let users = []
for (let user of game.users) {
if (!user.isGM && user.name != name) {
users.push(user.id)
}
}
return users
}
/* -------------------------------------------- */
static getWhisperRecipientsAndGMs(name) {
let recep1 = ChatMessage.getWhisperRecipients(name) || [];
return recep1.concat(ChatMessage.getWhisperRecipients('GM'));
}
/* -------------------------------------------- */
static blindMessageToGM(chatOptions) {
let chatGM = duplicate(chatOptions);
chatGM.whisper = this.getUsers(user => user.isGM);
chatGM.content = "Blind message of " + game.user.name + "<br>" + chatOptions.content;
console.log("blindMessageToGM", chatGM);
game.socket.emit("system.bol", { name: "msg_gm_chat_message", data: chatGM });
}
/* -------------------------------------------- */
static sendAttackSuccess(rollData) {
if (rollData.targetId) {
// Broadcast to GM or process it directly in case of GM defense
if (!game.user.isGM) {
game.socket.emit("system.bol", { name: "msg_attack_success", data: duplicate(rollData) })
} else {
BoLUtility.processAttackSuccess(rollData)
}
}
}
/* -------------------------------------------- */
static async chatMessageHandler(message, html, data) {
const chatCard = html.find('.flavor-text')
if (chatCard.length > 0) {
// If the user is the message author or the actor owner, proceed
const actor = game.actors.get(data.message.speaker.actor)
//console.log("FOUND 1!!! ", actor)
if (actor && actor.isOwner) return
else if (game.user.isGM || data.author.id === game.user.id) return
const divButtons = chatCard.find('.actions-section')
divButtons.hide()
}
}
/* -------------------------------------------- */
static getRollDataFromMessage(event) {
let messageId = BoLUtility.findChatMessageId(event.currentTarget)
let message = game.messages.get(messageId)
return message.getFlag("world", "bol-roll-data")
}
/* -------------------------------------------- */
static requestInitRoll(actorId, combatData) {
let actor = game.actors.get(actorId)
if (actor && actor.isOwner) {
ui.notifications.info(game.i18n.localize("BOL.ui.warninitiative"))
BoLRoll.aptitudeCheck(actor, "init", undefined, combatData)
}
}
/* -------------------------------------------- */
static cleanupButtons(id) {
$(`#${id}`).hide() // Hide the options roll buttons
game.socket.emit("system.bol", { name: "msg_cleanup_buttons", data: { id: id } })
}
/* -------------------------------------------- */
static async chatListeners(html) {
// Damage handling
html.on("click", '.chat-damage-apply', event => {
let rollData = BoLUtility.getRollDataFromMessage(event)
BoLUtility.cleanupButtons(rollData.applyId)
BoLUtility.sendAttackSuccess(rollData)
});
html.on("click", '.chat-damage-roll', event => {
event.preventDefault()
let rollData = BoLUtility.getRollDataFromMessage(event)
rollData.damageMode = event.currentTarget.attributes['data-damage-mode'].value
let bolRoll = new BoLDefaultRoll(rollData)
bolRoll.rollDamage()
});
html.on("click", '.transform-legendary-roll', event => {
event.preventDefault();
let rollData = BoLUtility.getRollDataFromMessage(event)
let actor = game.actors.get(rollData.actorId)
actor.subHeroPoints(1)
let r = new BoLDefaultRoll(rollData)
r.upgradeToLegendary()
})
html.on("click", '.transform-heroic-roll', event => {
event.preventDefault();
let rollData = BoLUtility.getRollDataFromMessage(event)
let actor = game.actors.get(rollData.actorId)
actor.subHeroPoints(1)
let r = new BoLDefaultRoll(rollData)
r.upgradeToHeroic()
})
html.on("click", '.hero-reroll', event => {
event.preventDefault();
let rollData = BoLUtility.getRollDataFromMessage(event)
let actor = game.actors.get(rollData.actorId)
actor.subHeroPoints(1)
rollData.reroll = false // Disable reroll option for second roll
let r = new BoLDefaultRoll(rollData)
r.roll();
});
html.on("click", '.damage-handling', event => {
event.preventDefault()
let attr = event.currentTarget.attributes['data-attack-id']
if ( !attr) {
ui.notifications.warn("Impossible de trouver l'attaque correspondante, erreur de suivi de combat.")
return
}
let attackId = event.currentTarget.attributes['data-attack-id'].value
let defenseMode = event.currentTarget.attributes['data-defense-mode'].value
let weaponId = (event.currentTarget.attributes['data-weapon-id']) ? event.currentTarget.attributes['data-weapon-id'].value : -1
// Remove message for all
let msgId = BoLUtility.findChatMessageId(event.currentTarget)
if (game.user.isGM) {
BoLUtility.processDamageHandling(attackId, defenseMode, weaponId, msgId)
} else {
game.socket.emit("system.bol", { name: "msg_damage_handling", data: { msgId: msgId, attackId: attackId, defenseMode: defenseMode, weaponId: weaponId } })
}
})
html.on("click", '.recup-vitalite', event => {
event.preventDefault()
let actorId = event.currentTarget.attributes['data-actor-id'].value
let recupHP = event.currentTarget.attributes['data-recup-hp'].value
let actor = game.actors.get(actorId)
let messageId = BoLUtility.findChatMessageId(event.currentTarget)
BoLUtility.removeChatMessageId(messageId)
actor.applyRecuperation(recupHP)
})
}
/* -------------------------------------------- */
static async processDamageHandling(attackId, defenseMode, weaponId = -1, msgId) {
if (!game.user.isGM) {
return
}
let message = game.messages.get(msgId)
let rollData = message.getFlag("world", "bol-roll-data")
BoLUtility.removeChatMessageId(msgId)
console.log("Damage Handling", attackId, defenseMode, weaponId)
// Only GM process this
if (rollData && rollData.defenderId) {
if (rollData.defenseDone || defenseMode == 'damage-not-applied') {
return
} // ?? Why ???
rollData.defenseDone = true
rollData.defenseMode = defenseMode
let token = game.scenes.current.tokens.get(rollData.targetId)
let defender = token.actor
if (defenseMode == 'damage-with-armor') {
let armorFormula = defender.getArmorFormula()
rollData.rollArmor = new Roll(armorFormula)
rollData.rollArmor.roll({ async: false })
rollData.armorProtect = (rollData.rollArmor.total < 0) ? 0 : rollData.rollArmor.total
rollData.finalDamage = rollData.damageTotal - rollData.armorProtect
rollData.finalDamage = (rollData.finalDamage < 0) ? 0 : rollData.finalDamage
defender.sufferDamage(rollData.finalDamage)
console.log("Armor roll -> result ", rollData)
}
if (defenseMode == 'damage-without-armor') {
rollData.finalDamage = rollData.damageTotal
defender.sufferDamage(rollData.finalDamage)
}
if (defenseMode == 'hero-reduce-damage') {
let armorFormula = defender.getArmorFormula()
rollData.rollArmor = new Roll(armorFormula)
rollData.rollArmor.roll({ async: false })
rollData.armorProtect = (rollData.rollArmor.total < 0) ? 0 : rollData.rollArmor.total
rollData.rollHero = new Roll("1d6")
rollData.rollHero.roll({ async: false })
rollData.finalDamage = rollData.damageTotal - rollData.rollHero.total - rollData.armorProtect
rollData.finalDamage = (rollData.finalDamage < 0) ? 0 : rollData.finalDamage
defender.sufferDamage(rollData.finalDamage)
defender.subHeroPoints(1)
}
if (defenseMode == 'hero-in-extremis') {
rollData.finalDamage = 0;
rollData.weaponHero = defender.weapons.find(item => item._id == weaponId);
defender.deleteEmbeddedDocuments("Item", [weaponId]);
}
let defenderUser
for (let user of game.users) {
if (user.character && user.character.id == defender.id) {
defenderUser = user
}
}
let damageResults = {
attackId: rollData.id,
attacker: rollData.attacker,
rollArmor: rollData.rollArmor,
rollHero: rollData.rollHero,
weaponHero: rollData.weaponHero,
armorProtect: rollData.armorProtect,
name: defender.name,
defender: defender,
defenseMode: rollData.defenseMode,
finalDamage: rollData.finalDamage
}
ChatMessage.create({
alias: defender.name,
whisper: BoLUtility.getWhisperRecipientsAndGMs(defender.name),
content: await renderTemplate('systems/bol/templates/chat/rolls/defense-result-card.hbs', damageResults)
})
console.log("Defender data : ", defenderUser)
ChatMessage.create({
alias: defender.name,
whisper: BoLUtility.getOtherWhisperRecipients(defenderUser?.name),
content: await renderTemplate('systems/bol/templates/chat/rolls/defense-summary-card.hbs', damageResults)
})
}
}
/* -------------------------------------------- */
static createChatMessage(name, rollMode, chatOptions) {
switch (rollMode) {
case "blindroll": // GM only
if (!game.user.isGM) {
this.blindMessageToGM(chatOptions);
chatOptions.whisper = [game.user.id];
chatOptions.content = "Message only to the GM";
}
else {
chatOptions.whisper = this.getUsers(user => user.isGM);
}
break;
default:
chatOptions.whisper = this.getWhisperRecipients(rollMode, name);
break;
}
chatOptions.alias = chatOptions.alias || name;
ChatMessage.create(chatOptions);
}
/* -------------------------------------------- */
static createChatWithRollMode(name, chatOptions) {
this.createChatMessage(name, game.settings.get("core", "rollMode"), chatOptions);
}
/* -------------------------------------------- */
static isRangedWeapon(weapon) {
return weapon.system.type == 'ranged' || weapon.system.thrown;
}
/* -------------------------------------------- */
static removeChatMessageId(messageId) {
if (messageId) {
game.messages.get(messageId)?.delete();
}
}
static findChatMessageId(current) {
return BoLUtility.getChatMessageId(BoLUtility.findChatMessage(current));
}
static getChatMessageId(node) {
return node?.attributes.getNamedItem('data-message-id')?.value;
}
static findChatMessage(current) {
return BoLUtility.findNodeMatching(current, it => it.classList.contains('chat-message') && it.attributes.getNamedItem('data-message-id'));
}
static findNodeMatching(current, predicate) {
if (current) {
if (predicate(current)) {
return current;
}
return BoLUtility.findNodeMatching(current.parentElement, predicate);
}
return undefined;
}
/* -------------------------------------------- */
static getTarget() {
if (game.user.targets && game.user.targets.size == 1) {
for (let target of game.user.targets) {
return target
}
}
return undefined;
}
/* -------------------------------------------- */
static async processAttackSuccess(rollData) {
console.log("Attack success processing", rollData)
if (!game.user.isGM || !rollData.defenderId) { // Only GM process this
return
}
// Build and send the defense message to the relevant people (ie GM + defender)
let defender = game.actors.get(rollData.defenderId)
let defenderWeapons = defender.weapons || []
let msg = await ChatMessage.create({
alias: defender.name,
whisper: BoLUtility.getWhisperRecipientsAndGMs(defender.name),
content: await renderTemplate('systems/bol/templates/chat/rolls/defense-request-card.hbs', {
attackId: rollData.id,
attacker: rollData.attacker,
defender: defender,
defenderHeroPoints:defender.getHeroPoints(),
defenderWeapons: defenderWeapons,
damageTotal: rollData.damageTotal,
damagesIgnoresArmor: rollData.damagesIgnoresArmor,
})
})
msg.setFlag("world", "bol-roll-data", rollData)
console.log("DEF WEP", rollData, defender)
}
/* -------------------------------------------- */
static onSocketMessage(sockmsg) {
if (sockmsg.name == "msg_attack_success") {
BoLUtility.processAttackSuccess(sockmsg.data)
}
if (sockmsg.name == "msg_cleanup_buttons") {
$(`#${sockmsg.data.id}`).hide() // Hide the options roll buttons
}
if (sockmsg.name == "msg_request_init_roll") {
this.requestInitRoll(sockmsg.data.actorId, sockmsg.data.combatData)
}
if (sockmsg.name == "msg_damage_handling") {
BoLUtility.processDamageHandling(sockmsg.data.attackId, sockmsg.data.defenseMode, sockmsg.data.weaponId, sockmsg.data.msgId)
}
}
/* -------------------------------------------- */
static computeSpellCost(spell, nbOptCond = 0) {
let pp = spell.system.properties.ppcost
let minpp = __circle2minpp[spell.system.properties.circle]
pp = (pp - nbOptCond < minpp) ? minpp : pp - nbOptCond
return pp
}
/* -------------------------------------------- */
static getDamageFormula(weaponData, fightOption) {
let upgradeDamage = (fightOption && fightOption.system.properties.fightoptiontype == "twoweaponsatt")
let damageString = weaponData.properties.damage
let modifier = weaponData.properties.damageModifiers ?? 0
let multiplier = weaponData.properties.damageMultiplier ?? 1
if (damageString[0] == 'd') { damageString = "1" + damageString } // Help parsing
if (modifier == null) modifier = 0;
let reroll = (weaponData.properties.damageReroll1) ? "r1" : "" // Reroll 1 option
let formula = damageString
if (damageString.includes("d") || damageString.includes("D")) {
let myReg = new RegExp('(\\d+)[dD]([\\d]+)([MB]*)?([\\+\\d]*)?', 'g')
let res = myReg.exec(damageString)
let nbDice = parseInt(res[1])
let postForm = 'kh' + nbDice
let modIndex = 3
// Upgrade damage if needed
if (upgradeDamage && (!res[3] || res[3] == "")) {
res[3] = "B" // Upgrade to bonus
}
if (res[3]) {
if (upgradeDamage && res[3] == 'M') {
res[3] = "" // Disable lamlus for upgradeDamage
}
if (res[3] == 'M') {
postForm = 'kl' + nbDice
nbDice++
modIndex = 4
}
if (res[3] == 'MM') {
postForm = 'kl' + nbDice
nbDice += 2
modIndex = 4
}
if (res[3] == 'B') {
postForm = 'kh' + nbDice
nbDice++
modIndex = 4
}
if (res[3] == 'BB') {
postForm = 'kh' + nbDice
nbDice += 2
modIndex = 4
}
}
formula = "(" + nbDice + "d" + res[2] + reroll + postForm + "+" + modifier + ") *" + multiplier
}
return formula
}
/* -------------------------------------------- */
static async loadCompendiumData(compendium) {
const pack = game.packs.get(compendium);
return await pack?.getDocuments() ?? [];
}
/* -------------------------------------------- */
static async loadCompendium(compendium, filter = item => true) {
let compendiumData = await this.loadCompendiumData(compendium);
return compendiumData.filter(filter);
}
/* -------------------------------------------- */
static async searchItem(dataItem) {
let item
if (dataItem.pack) {
let id = dataItem.id || dataItem._id
let items = await this.loadCompendium(dataItem.pack, item => item.id == id)
item = items[0] || undefined
} else {
item = game.items.get(dataItem.id)
}
return item
}
/* -------------------------------------------- */
static updateSheets() {
// Then force opened actor refresh if needed
for (let actor of game.actors) {
if (actor.sheet.rendered) {
actor.sheet.render()
}
}
game.bol.charSummary.updatePCSummary() // Refresh if needed
}
/* -------------------------------------------- */
static removeGroupHoroscope(rollData) {
let horo = rollData.horoscopeGroupList[rollData.selectedGroupHoroscopeIndex]
let horoscopes = duplicate(game.settings.get("bol", "horoscope-group"))
let toChange = duplicate(horoscopes[horo.id])
toChange.availableDice -= horo.nbDice // Remove the dice
if (toChange.availableDice <= 0) {
horoscopes[horo.id] = undefined
} else {
horoscopes[horo.id] = toChange
}
game.settings.set("bol", "horoscope-group", horoscopes)
this.updateSheets()
}
}

View File

@ -9,66 +9,284 @@ System.debugMode = true;
export const BOL = {};
BOL.itemProperties = {
"equipable": "BOL.properties.equipable",
"stackable": "BOL.properties.stackable",
"unique": "BOL.properties.unique",
"tailored": "BOL.properties.tailored",
"2h": "BOL.properties.2H",
"predilection": "BOL.properties.predilection",
"ranged": "BOL.properties.ranged",
"proficient": "BOL.properties.proficient",
"finesse": "BOL.properties.finesse",
"two-handed": "BOL.properties.two-handed",
"equipment": "BOL.properties.equipment",
"weapon": "BOL.properties.weapon",
"protection": "BOL.properties.protection",
"reloadable": "BOL.properties.reloadable",
"bow": "BOL.properties.bow",
"crossbow": "BOL.properties.crossbow",
"powder": "BOL.properties.powder",
"throwing": "BOL.properties.throwing",
"dr": "BOL.properties.dr",
"sneak": "BOL.properties.sneak",
"powerful": "BOL.properties.powerful",
"critscience": "BOL.properties.critscience",
"specialization": "BOL.properties.specialization",
"effects": "BOL.properties.effects",
"activable": "BOL.properties.activable",
"2H": "BOL.properties.2H",
"13strmin": "BOL.properties.13strmin",
"bashing": "BOL.properties.bashing",
"sling": "BOL.properties.sling",
"spell": "BOL.properties.spell",
"profile": "BOL.properties.profile",
"prestige": "BOL.properties.prestige",
"alternative": "BOL.properties.alternative",
"consumable": "BOL.properties.consumable",
"racial": "BOL.properties.racial",
"creature" : "BOL.properties.creature"
};
BOL.damageValues = {
"1": "1",
"2": "2",
"3": "3",
"d3" : "d3",
"d6M" : "d6M (Malus)",
"d6" : "d6",
"d6B" : "d6B (Bonus)",
"d6BB" : "d6B + dé bonus",
}
BOL.damageMultiplier = {
"1": "x1",
"2": "x2",
"3": "x3",
"4": "x4",
"5": "x5",
"6": "x6",
"7": "7",
"8": "x8"
}
BOL.spellType = {
"0": "BOL.spellItem.charm",
"1": "BOL.spellItem.circle1",
"2": "BOL.spellItem.circle2",
"3": "BOL.spellItem.circle3"
}
BOL.alchemyType = {
"common": "BOL.alchemyItem.common",
"scarce": "BOL.alchemyItem.scarce",
"legend": "BOL.alchemyItem.legend",
"mythic": "BOL.alchemyItem.mythic",
}
BOL.equipmentSlots = {
"none" : "BOL.equipmentSlots.none",
"head" : "BOL.equipmentSlots.head",
"neck" : "BOL.equipmentSlots.neck",
"shoulders" : "BOL.equipmentSlots.shoulders",
"body" : "BOL.equipmentSlots.body",
"rhand" : "BOL.equipmentSlots.rhand",
"lhand" : "BOL.equipmentSlots.lhand",
"2hands" : "BOL.equipmentSlots.2hands",
"rarm" : "BOL.equipmentSlots.rarm",
"larm" : "BOL.equipmentSlots.larm",
"chest" : "BOL.equipmentSlots.chest",
"belt" : "BOL.equipmentSlots.belt",
"legs" : "BOL.equipmentSlots.legs",
"feet" : "BOL.equipmentSlots.feet",
"finder" : "BOL.equipmentSlots.finder",
"ear" : "BOL.equipmentSlots.ear"
}
BOL.armorQualities = {
"none" : "BOL.armorQuality.none",
"light" : "BOL.armorQuality.light",
"lightQ" : "BOL.armorQuality.lightQ",
"lightSup" : "BOL.armorQuality.lightSup",
"lightLeg" : "BOL.armorQuality.lightLeg",
"medium" : "BOL.armorQuality.medium",
"mediumQ" : "BOL.armorQuality.mediumQ",
"mediumSup" : "BOL.armorQuality.mediumSup",
"mediumLeg" : "BOL.armorQuality.mediumLeg",
"heavy" : "BOL.armorQuality.heavy",
"heavyQ" : "BOL.armorQuality.heavyQ",
"heavySup" : "BOL.armorQuality.heavySup",
"heavyLeg" : "BOL.armorQuality.heavyLeg"
}
BOL.soakFormulas = {
"none" : "0",
"light" : "1d6-3",
"lightQ" : "1d6r1-3",
"lightSup" : "1d6-2",
"lightLeg" : "2d6kh1-2",
"medium" : "1d6-2",
"mediumQ" : "1d6r1-2",
"mediumSup" : "1d6-1",
"mediumLeg" : "2d6kh1-1",
"heavy" : "1d6-1",
"heavyQ" : "1d6r1-1",
"heavySup" : "1d6",
"heavyLeg" : "2d6kh1"
}
BOL.attackAttributes = {
"vigor" : "BOL.attributes.vigor",
"agility" : "BOL.attributes.agility",
"mind" : "BOL.attributes.mind",
"appeal" : "BOL.attributes.appeal"
}
BOL.attackAptitudes = {
"melee" : "BOL.aptitudes.melee",
"ranged" : "BOL.aptitudes.ranged"
}
BOL.aptitudes = {
"melee" : "BOL.aptitudes.melee",
"ranged" : "BOL.aptitudes.ranged",
"init" : "BOL.aptitudes.init",
"def" : "BOL.aptitudes.def"
}
BOL.resources = {
"hp" : "BOL.resources.hp",
"hero" : "BOL.resources.hero",
"faith" : "BOL.resources.faith",
"power" : "BOL.resources.power",
"alchemypoints" : "BOL.resources.alchemypoints"
}
BOL.weaponSizes = {
"unarmed" : "BOL.weaponSize.unarmed",
"improvised" : "BOL.weaponSize.improvised",
"light" : "BOL.weaponSize.light",
"medium" : "BOL.weaponSize.medium",
"heavy" : "BOL.weaponSize.heavy"
}
BOL.damageAttributes = {
"zero" : "0",
"vigor" : "BOL.attributes.vigor",
"half-vigor" : "BOL.attributes.halfvigor"
}
BOL.itemCategories = {
"other": "BOL.category.other",
"armor": "BOL.category.armor",
"shield": "BOL.category.shield",
"melee": "BOL.category.melee",
"ranged": "BOL.category.ranged",
"spell": "BOL.category.spell",
"jewel": "BOL.category.jewel",
"scroll": "BOL.category.scroll",
"wand": "BOL.category.wand",
"ammunition": "BOL.category.ammunition",
"consumable": "BOL.category.consumable",
"container": "BOL.category.container",
"mount": "BOL.category.mount",
"currency": "BOL.category.currency",
"trapping": "BOL.category.trapping"
"equipment" : "BOL.itemCategory.equipment",
"capacity" : "BOL.itemCategory.capacity",
"spell" : "BOL.itemCategory.spell",
"alchemy" : "BOL.itemCategory.alchemy",
"vehicle" : "BOL.itemCategory.vehicle",
"vehicleweapon": "BOL.itemCategory.vehicleweapon",
"other" : "BOL.itemCategory.other"
}
BOL.itemSubtypes = {
"armor" : "BOL.equipmentCategory.armor",
"weapon" : "BOL.equipmentCategory.weapon",
"shield" : "BOL.equipmentCategory.shield",
"helm" : "BOL.equipmentCategory.helm",
"jewel" : "BOL.equipmentCategory.jewel",
"scroll" : "BOL.equipmentCategory.scroll",
"container" : "BOL.equipmentCategory.container",
"ammunition" : "BOL.equipmentCategory.ammunition",
"currency" : "BOL.equipmentCategory.currency",
"other" : "BOL.equipmentCategory.other"
}
BOL.vehicleSubtypes = {
"mount" : "BOL.vehicleCategory.mount",
"flying" : "BOL.vehicleCategory.flying",
"boat" : "BOL.vehicleCategory.boat",
"other" : "BOL.vehicleCategory.other"
}
// BOL.equipmentCategories = {
// "armor" : "BOL.equipmentCategory.armor",
// "weapon" : "BOL.equipmentCategory.weapon",
// "shield" : "BOL.equipmentCategory.shield",
// "helm" : "BOL.equipmentCategory.helm",
// "jewel" : "BOL.equipmentCategory.jewel",
// "scroll" : "BOL.equipmentCategory.scroll",
// "container" : "BOL.equipmentCategory.container",
// "ammunition" : "BOL.equipmentCategory.ammunition",
// "currency" : "BOL.equipmentCategory.currency",
// "other" : "BOL.equipmentCategory.other"
// }
BOL.protectionCategories = {
"armor" : "BOL.protectionCategory.armor",
"shield" : "BOL.protectionCategory.shield",
"helm" : "BOL.protectionCategory.helm",
"other" : "BOL.protectionCategory.other"
}
BOL.weaponCategories = {
"melee" : "BOL.weaponCategory.melee",
"ranged" : "BOL.weaponCategory.ranged",
"other" : "BOL.weaponCategory.other"
}
BOL.itemProperties1 = {
"equipable" : "BOL.itemProperty.equipable",
"protection" : "BOL.itemProperty.protection",
"magical" : "BOL.itemProperty.magical",
"worn" : "BOL.itemProperty.worn",
}
BOL.itemProperties2 = {
"equipable" : "BOL.itemProperty.equipable",
"protection" : "BOL.itemProperty.protection",
"blocking" : "BOL.itemProperty.blocking",
"magical" : "BOL.itemProperty.magical",
"concealable" : "BOL.itemProperty.concealable",
"2H" : "BOL.itemProperty.2H",
"helm" : "BOL.itemProperty.helm",
"improvised" : "BOL.itemProperty.improvised",
"shield" : "BOL.itemProperty.shield",
"melee" : "BOL.itemProperty.melee",
"throwable" : "BOL.itemProperty.throwable",
"ignoreshield" : "BOL.itemProperty.ignoreshield",
"bashing" : "BOL.itemProperty.bashing",
"stackable" : "BOL.itemProperty.stackable",
"ranged" : "BOL.itemProperty.ranged",
"weapon" : "BOL.itemProperty.weapon",
"reloadable" : "BOL.itemProperty.reloadable",
"worn" : "BOL.itemProperty.worn",
"spell" : "BOL.itemProperty.spell",
"armor" : "BOL.itemProperty.armor",
"consumable" : "BOL.itemProperty.consumable",
"bow" : "BOL.itemProperty.bow",
"crossbow" : "BOL.itemProperty.crossbow",
"throwing" : "BOL.itemProperty.throwing",
"activable" : "BOL.itemProperty.activable",
"powder" : "BOL.itemProperty.powder",
"damage" : "BOL.itemProperty.damage",
"difficulty": "BOL.itemProperty.difficulty"
}
BOL.itemStats = {
"quantity" : "BOL.itemStat.quantity",
"weight" : "BOL.itemStat.weight",
"price" : "BOL.itemStat.price",
"range" : "BOL.itemStat.range",
"damage" : "BOL.itemStat.damage",
"reload" : "BOL.itemStat.reload",
"soak" : "BOL.itemStat.soak",
"blocking" : "BOL.itemStat.blocking",
"modifiers" : "BOL.itemStat.modifiers"
}
BOL.itemModifiers = {
"init" : "BOL.itemModifiers.init",
"social" : "BOL.itemModifiers.social",
"agility" : "BOL.itemModifiers.agility",
"powercost" : "BOL.itemModifiers.powercost"
}
BOL.itemBlocking = {
"malus" : "BOL.itemBlocking.malus",
"nbAttacksPerRound" : "BOL.itemBlocking.nbAttacksPerRound"
}
BOL.itemSoak = {
"formula" : "BOL.itemSoak.formula",
"value" : "BOL.itemSoak.value"
}
BOL.featureSubtypes = {
"origin" : "BOL.featureSubtypes.origin",
"race" : "BOL.featureSubtypes.race",
"career" : "BOL.featureSubtypes.career",
"boon" : "BOL.featureSubtypes.boon",
"flaw" : "BOL.featureSubtypes.flaw",
"language" : "BOL.featureSubtypes.language",
"godsfaith" : "BOL.featureSubtypes.gods",
"fightoption" : "BOL.featureSubtypes.fightOption",
"boleffect": "BOL.featureSubtypes.effect",
"horoscope": "BOL.featureSubtypes.horoscope",
}
BOL.fightOptionTypes = {
"armordefault": "BOL.fightOptionTypes.armor",
"intrepid": "BOL.fightOptionTypes.intrepid",
"twoweaponsdef": "BOL.fightOptionTypes.twoweaponsdef",
"twoweaponsatt": "BOL.fightOptionTypes.twoweaponsatt",
"fulldefense": "BOL.fightOptionTypes.fulldefense",
"defense": "BOL.fightOptionTypes.defense",
"attack": "BOL.fightOptionTypes.attack",
"other": "BOL.fightOptionTypes.other"
}
BOL.itemIcons = {
"item": "icons/containers/chest/chest-worn-oak-tan.webp",
"capacity":"icons/sundries/scrolls/scroll-plain-tan-red.webp",
"capacity": "icons/sundries/scrolls/scroll-plain-tan-red.webp",
"species": "icons/environment/people/group.webp",
"profile": "icons/sundries/documents/blueprint-axe.webp",
"path": "icons/sundries/books/book-embossed-gold-red.webp"
@ -76,8 +294,168 @@ BOL.itemIcons = {
BOL.actorIcons = {
"npc": "icons/environment/people/commoner.webp",
"encounter":"icons/svg/mystery-man-black.svg",
"encounter": "icons/svg/mystery-man-black.svg",
"loot": "icons/containers/bags/sack-simple-leather-brown.webp"
}
BOL.bougetteState = {
"0": "BOL.bougette.nomoney",
"1": "BOL.bougette.tolive",
"2": "BOL.bougette.easylife",
"3": "BOL.bougette.luxury",
"4": "BOL.bougette.rich"
}
BOL.bougetteDice = {
"0": "0",
"1": "2d6-1",
"2": "2d6",
"3": "2d6+1",
"4": "2d6+2"
}
BOL.creatureSize = {
"tiny": {order: 1, label: "BOL.size.tiny"},
"verysmall": {order: 2, label: "BOL.size.verysmall"},
"small": {order: 3, label: "BOL.size.small"},
"medium": {order: 4, label: "BOL.size.medium"},
"large": {order: 5, label: "BOL.size.large"},
"verylarge": {order: 6, label: "BOL.size.verylarge"},
"huge": {order: 7, label: "BOL.size.huge"},
"massive": {order: 8, label: "BOL.size.massive"},
"enormous": {order: 9, label: "BOL.size.enormous"},
"gigantic": {order: 10, label: "BOL.size.gigantic"},
"immense": {order: 11, label: "BOL.size.immense"},
"colossal": {order: 12, label: "BOL.size.colossal"}
}
BOL.horoscopeAnswer = {
"favorable": "BOL.ui.horoscopefavorable",
"unfavorable": "BOL.ui.horoscopeunfavorable",
}
BOL.bolEffectModifier = {
"-8": "-8",
"-6": "-6",
"-4": "-4",
"-2": "-2",
"-1": "-1",
"1B": "1B",
"2B": "2B",
"1M": "1M",
"2M": "2M",
"+1": "+1",
"+2": "+2",
"+4": "+4",
"+6": "+6",
"+8": "+8",
}
BOL.statusEffects = [
{
"id": "dead",
"label": "EFFECT.StatusDead",
"icon": "icons/svg/skull.svg"
},
{
"id": "unconscious",
"label": "EFFECT.StatusUnconscious",
"icon": "icons/svg/unconscious.svg"
},
{
"id": "sleep",
"label": "EFFECT.StatusAsleep",
"icon": "icons/svg/sleep.svg"
},
{
"id": "stun",
"label": "EFFECT.StatusStunned",
"icon": "icons/svg/daze.svg"
},
{
"id": "prone",
"label": "EFFECT.StatusProne",
"icon": "icons/svg/falling.svg"
},
{
"id": "restrain",
"label": "EFFECT.StatusRestrained",
"icon": "icons/svg/net.svg"
},
{
"id": "paralysis",
"label": "EFFECT.StatusParalysis",
"icon": "icons/svg/paralysis.svg"
},
{
"id": "fly",
"label": "EFFECT.StatusFlying",
"icon": "icons/svg/wing.svg"
},
{
"id": "blind",
"label": "EFFECT.StatusBlind",
"icon": "icons/svg/blind.svg"
},
{
"id": "deaf",
"label": "EFFECT.StatusDeaf",
"icon": "icons/svg/deaf.svg"
},
{
"id": "silence",
"label": "EFFECT.StatusSilenced",
"icon": "icons/svg/silenced.svg"
},
{
"id": "fear",
"label": "EFFECT.StatusFear",
"icon": "icons/svg/terror.svg"
},
{
"id": "burning",
"label": "EFFECT.StatusBurning",
"icon": "icons/svg/fire.svg"
},
{
"id": "frozen",
"label": "EFFECT.StatusFrozen",
"icon": "icons/svg/frozen.svg"
},
{
"id": "shock",
"label": "EFFECT.StatusShocked",
"icon": "icons/svg/lightning.svg"
},
{
"id": "disease",
"label": "EFFECT.StatusDisease",
"icon": "icons/svg/biohazard.svg"
},
{
"id": "poison",
"label": "EFFECT.StatusPoison",
"icon": "icons/svg/poison.svg"
},
{
"id": "curse",
"label": "EFFECT.StatusCursed",
"icon": "icons/svg/sun.svg"
},
{
"id": "invisible",
"label": "EFFECT.StatusInvisible",
"icon": "icons/svg/invisible.svg"
},
{
"id": "target",
"label": "EFFECT.StatusTarget",
"icon": "icons/svg/target.svg"
},
{
"id": "eye",
"label": "EFFECT.StatusMarked",
"icon": "icons/svg/eye.svg"
}
]
BOL.debug = false;

View File

@ -1,103 +1,146 @@
export const registerHandlebarsHelpers = function () {
Handlebars.registerHelper('isNull', function (val) {
return val == null;
});
Handlebars.registerHelper('isNull', function (val) {
return val == null;
});
Handlebars.registerHelper('isEmpty', function (list) {
if (list) return list.length == 0;
else return 0;
});
Handlebars.registerHelper('exists', function (val) {
return val != null && val != undefined;
});
Handlebars.registerHelper('notEmpty', function (list) {
return list.length > 0;
});
Handlebars.registerHelper('isEmpty', function (list) {
if (list) return list.length == 0;
else return 0;
});
Handlebars.registerHelper('isNegativeOrNull', function (val) {
return val <= 0;
});
Handlebars.registerHelper('notEmpty', function (list) {
return list.length > 0;
});
Handlebars.registerHelper('isNegative', function (val) {
return val < 0;
});
Handlebars.registerHelper('isNegativeOrNull', function (val) {
return val <= 0;
});
Handlebars.registerHelper('isPositive', function (val) {
return val > 0;
});
Handlebars.registerHelper('isNegative', function (val) {
return val < 0;
});
Handlebars.registerHelper('equals', function (val1, val2) {
return val1 == val2;
});
Handlebars.registerHelper('isPositive', function (val) {
return val > 0;
});
Handlebars.registerHelper('neq', function (val1, val2) {
return val1 !== val2;
});
Handlebars.registerHelper('equals', function (val1, val2) {
return val1 == val2;
});
Handlebars.registerHelper('gt', function (val1, val2) {
return val1 > val2;
});
Handlebars.registerHelper('neq', function (val1, val2) {
return val1 !== val2;
});
Handlebars.registerHelper('lt', function (val1, val2) {
return val1 < val2;
});
Handlebars.registerHelper('gt', function (val1, val2) {
return val1 > val2;
})
Handlebars.registerHelper('gte', function (val1, val2) {
return val1 >= val2;
});
Handlebars.registerHelper('lt', function (val1, val2) {
return val1 < val2;
})
Handlebars.registerHelper('lte', function (val1, val2) {
return val1 <= val2;
});
Handlebars.registerHelper('and', function (val1, val2) {
return val1 && val2;
});
Handlebars.registerHelper('gte', function (val1, val2) {
return val1 >= val2;
})
Handlebars.registerHelper('or', function (val1, val2) {
return val1 || val2;
});
Handlebars.registerHelper('lte', function (val1, val2) {
return val1 <= val2;
})
Handlebars.registerHelper('and', function (val1, val2) {
return val1 && val2;
})
Handlebars.registerHelper('or', function (val1, val2) {
return val1 || val2;
})
Handlebars.registerHelper('not', function (cond) {
return !cond;
});
Handlebars.registerHelper('or3', function (val1, val2, val3) {
return val1 || val2 || val3;
})
Handlebars.registerHelper('count', function (list) {
return list.length;
});
Handlebars.registerHelper('for', function (from, to, incr, block) {
var accum = '';
for (var i = from; i < to; i += incr)
accum += block.fn(i);
return accum;
})
Handlebars.registerHelper('isEnabled', function (configKey) {
return game.settings.get("bol", configKey);
});
Handlebars.registerHelper('not', function (cond) {
return !cond;
})
Handlebars.registerHelper('count', function (list) {
return list.length;
})
Handlebars.registerHelper('countKeys', function (obj) {
return Object.keys(obj).length;
})
Handlebars.registerHelper('isEnabled', function (configKey) {
return game.settings.get("bol", configKey);
})
Handlebars.registerHelper('split', function (str, separator, keep) {
return str.split(separator)[keep];
})
Handlebars.registerHelper('split', function (str, separator, keep) {
return str.split(separator)[keep];
});
// If you need to add Handlebars helpers, here are a few useful examples:
Handlebars.registerHelper('concat', function () {
var outStr = '';
for (var arg in arguments) {
if (typeof arguments[arg] != 'object') {
outStr += arguments[arg];
}
}
return outStr;
})
// If you need to add Handlebars helpers, here are a few useful examples:
Handlebars.registerHelper('concat', function () {
var outStr = '';
for (var arg in arguments) {
if (typeof arguments[arg] != 'object') {
outStr += arguments[arg];
}
}
return outStr;
});
Handlebars.registerHelper('add', function (a, b) {
return parseInt(a) + parseInt(b);
});
Handlebars.registerHelper('mul', function (a, b) {
return parseInt(a) * parseInt(b);
})
Handlebars.registerHelper('sub', function (a, b) {
return parseInt(a) - parseInt(b);
})
Handlebars.registerHelper('abbrev2', function (a) {
return a.substring(0,2);
})
Handlebars.registerHelper('abbrev3', function (a) {
return a.substring(0,3);
})
Handlebars.registerHelper('valueAtIndex', function (arr, idx) {
return arr[idx];
})
Handlebars.registerHelper('includesKey', function (items, type, key) {
// console.log(items);
return items.filter(i => i.type === type).map(i => i.system.key).includes(key);
})
Handlebars.registerHelper('includes', function (array, val) {
return array.includes(val);
})
Handlebars.registerHelper('eval', function (expr) {
return eval(expr);
})
Handlebars.registerHelper('isOwnerOrGM', function (actor) {
console.log("Testing actor", actor.isOwner, game.userId)
if (actor.isOwner || game.isGM) {
return true
}
return false
})
Handlebars.registerHelper('upperFirst', function (text) {
if (typeof text !== 'string') return text
return text.charAt(0).toUpperCase() + text.slice(1)
})
Handlebars.registerHelper('upperFirstOnly', function (text) {
if (typeof text !== 'string') return text
return text.charAt(0).toUpperCase()
})
Handlebars.registerHelper('add', function (a, b) {
return parseInt(a) + parseInt(b);
});
Handlebars.registerHelper('valueAtIndex', function (arr, idx) {
return arr[idx];
});
Handlebars.registerHelper('includesKey', function (items, type, key) {
// console.log(items);
return items.filter(i => i.type === type).map(i => i.data.key).includes(key);
});
Handlebars.registerHelper('includes', function (array, val) {
return array.includes(val);
});
}

View File

@ -1,202 +1,92 @@
import {BoLUtility} from "./bol-utility.js";
export default function registerHooks() {
// Hooks.on("getChatLogEntryContext", (html, options) => {
// let canApplyDamage = li => li.find("h2.damage").length;
// let canApplyHealing = li => li.find("h2.heal").length;
// options.push(
// {
// name: game.i18n.localize("COF.ui.applyDamage"),
// icon: '<i class="fas fa-user-minus"></i>',
// condition: canApplyDamage,
// callback: li => {
// const dmg = parseInt(li.find(".dice-total").text());
// Hitpoints.applyToTargets(-dmg);
// }
// },
// {
// name: game.i18n.localize("COF.ui.applyDamage"),
// icon: '<i class="fas fa-user-minus"></i>',
// condition: canApplyHealing,
// callback: li => {
// const dmg = parseInt(li.find(".dice-total").text());
// Hitpoints.applyToTargets(-dmg);
// }
// },
// {
// name: game.i18n.localize("COF.ui.applyHalfDamage"),
// icon: '<i class="fas fa-user-shield"></i>',
// condition: canApplyDamage,
// callback: li => {
// const dmg = Math.ceil(parseInt(li.find(".dice-total").text()) / 2);
// Hitpoints.applyToTargets(-dmg);
// }
// },
// {
// name: game.i18n.localize("COF.ui.applyDoubleDamage"),
// icon: '<i class="fas fa-user-injured"></i>',
// condition: canApplyDamage,
// callback: li => {
// const dmg = parseInt(li.find(".dice-total").text())*2;
// Hitpoints.applyToTargets(-dmg);
// }
// },
// {
// name: game.i18n.localize("COF.ui.applyHealing"),
// icon: '<i class="fas fa-user-plus"></i>',
// condition: canApplyDamage,
// callback: li => {
// const dmg = parseInt(li.find(".dice-total").text());
// Hitpoints.applyToTargets(dmg);
// }
// },
// {
// name: game.i18n.localize("COF.ui.applyHealing"),
// icon: '<i class="fas fa-user-plus"></i>',
// condition: canApplyHealing,
// callback: li => {
// const dmg = parseInt(li.find(".dice-total").text());
// Hitpoints.applyToTargets(dmg);
// }
// }
// );
// });
//
// /**
// * Create a macro when dropping an entity on the hotbar
// * Item - open roll dialog for item
// * Actor - open actor sheet
// * Journal - open journal sheet
// */
//
// Hooks.on("hotbarDrop", async (bar, data, slot) => {
// // Create item macro if rollable item - weapon, spell, prayer, trait, or skill
// if (data.type == "Item") {
// let item = data.data;
// let command = `let onlyDamage = false;\nlet customLabel = "";\nlet skillDescription = "";\nlet dmgDescription = "";\n\nif (event) {\n if (event.shiftKey) onlyDamage = true;\n}\n\ngame.cof.macros.rollItemMacro("${item._id}", "${item.name}", "${item.type}", 0, 0, 0, onlyDamage, customLabel, skillDescription, dmgDescription);`;
//
// let macro = game.macros.entities.find(m => (m.name === item.name) && (m.command === command));
// if (!macro) {
// macro = await Macro.create({
// name: item.name,
// type : "script",
// img: item.img,
// command : command
// }, {displaySheet: false})
// }
// game.user.assignHotbarMacro(macro, slot);
// }
// // Create a macro to open the actor sheet of the actor dropped on the hotbar
// else if (data.type == "Actor") {
// let actor = game.actors.get(data.id);
// let command = `game.actors.get("${data.id}").sheet.render(true)`
// let macro = game.macros.entities.find(m => (m.name === actor.name) && (m.command === command));
// if (!macro) {
// macro = await Macro.create({
// name: actor.data.name,
// type: "script",
// img: actor.data.img,
// command: command
// }, {displaySheet: false})
// game.user.assignHotbarMacro(macro, slot);
// }
// }
// // Create a macro to open the journal sheet of the journal dropped on the hotbar
// else if (data.type == "JournalEntry") {
// let journal = game.journal.get(data.id);
// let command = `game.journal.get("${data.id}").sheet.render(true)`
// let macro = game.macros.entities.find(m => (m.name === journal.name) && (m.command === command));
// if (!macro) {
// macro = await Macro.create({
// name: journal.data.name,
// type: "script",
// img: (journal.data.img) ? journal.data.img : "icons/svg/book.svg",
// command: command
// }, {displaySheet: false})
// game.user.assignHotbarMacro(macro, slot);
// }
// }
// return false;
// });
//
//
// /**
// * Intercepte les commandes de chat
// * /stat - Jet de caractéristique
// * /skill stat - Jet de caractéristique
// * /stats - Génère les caractéristiques d'un personnage
// */
//
// Hooks.on("chatMessage", (html, content, msg) => {
// let regExp;
// regExp = /(\S+)/g;
// let commands = content.match(regExp);
// let command = (commands.length>0 && commands[0].split("/").length > 0) ? commands[0].split("/")[1].trim() : null;
// let arg1 = (commands.length > 1) ? commands[1].trim() : null;
// const actor = game.cof.macros.getSpeakersActor();
//
// const validCommands = ["for", "str", "dex", "con", "int", "sag", "wis", "cha", "atc", "melee", "atd", "ranged", "atm", "magic"];
//
// if(command && validCommands.includes(command)) {
// game.cof.macros.rollStatMacro(actor, command, 0, 0, null);
// return false;
// }
// else if(command && command === "skill") {
// if(arg1 && validCommands.includes(arg1)) {
// game.cof.macros.rollStatMacro(actor, arg1, 0, 0, null);
// } else {
// ui.notifications.error("Vous devez préciser la caractéristique à tester, par exemple \"/skill str\".");
// }
// return false;
// }
// else if(command && command === "stats") {
// CharacterGeneration.statsCommand();
// return false;
// }
// });
//
// Hooks.on("renderChatMessage", (message, html, data) => {
// // Affiche ou non les boutons d'application des dommages
// if (game.settings.get("cof", "displayChatDamageButtonsToAll")) {
// html.find(".apply-dmg").click(ev => Hitpoints.onClickChatMessageApplyButton(ev, html, data));
// }
// else {
// if (game.user.isGM){
// html.find(".apply-dmg").click(ev => Hitpoints.onClickChatMessageApplyButton(ev, html, data));
// }
// else {
// html.find(".apply-dmg").each((i, btn) => {
// btn.style.display = "none"
// });
// }
// }
// });
/**
* Ready hook loads tables, and override's foundry's entity link functions to provide extension to pseudo entities
*/
// Hooks.on("preCreateChatMessage", (data, options, user) => {
// console.debug("preCreateChatMessage");
// // console.log(data,options,user);
// return true;
// });
// Hooks.on("createChatMessage", (message, options, user) => {
// console.debug("createChatMessage");
// // console.log(message,options,user);
// return true;
// });
// Hooks.on("updateChatMessage", (message, update, options, user) => {
// console.debug("updateChatMessage");
// // console.log(message,update,options,user);
// return true;
// });
Hooks.once("ready", async () => {
console.info("BOL | System Initialized.");
});
Hooks.on("renderPause", ((_app, html) => {
html.find("img").attr("src", "systems/bol/ui/pause2.webp")
}))
Hooks.on('renderChatLog', (log, html, data) => BoLUtility.chatListeners(html))
Hooks.on('renderChatMessage', (message, html, data) => BoLUtility.chatMessageHandler(message, html, data))
/**
* Create a macro when dropping an entity on the hotbar
* Item - open roll dialog for item
* Actor - open actor sheet
* Journal - open journal sheet
*/
Hooks.on("hotbarDrop", async (bar, data, slot) => {
console.log(data.type);
// Create item macro if rollable item - weapon, spell, prayer, trait, or skill
if (data.type == "Item") {
let item = data.data;
console.log(item);
// let command = `let onlyDamage = false;\nlet customLabel = "";\nlet skillDescription = "";\nlet dmgDescription = "";\n\nif (event) {\n if (event.shiftKey) onlyDamage = true;\n}\n\ngame.cof.macros.rollItemMacro("${item._id}", "${item.name}", "${item.type}", 0, 0, 0, onlyDamage, customLabel, skillDescription, dmgDescription);`;
// let macro = game.macros.entities.find(m => (m.name === item.name) && (m.command === command));
// if (!macro) {
// macro = await Macro.create({
// name: item.name,
// type : "script",
// img: item.img,
// command : command
// }, {displaySheet: false})
// }
// game.user.assignHotbarMacro(macro, slot);
}
// Create a macro to open the actor sheet of the actor dropped on the hotbar
else if (data.type == "Actor") {
let actor = game.actors.get(data.id);
let command = `/*\nPersonnalisez la macro selon vos besoins en suivant les exemples suivants : \ngame.bol.macros.rollMacro('attribute', 'vigor|agility|mind|appeal', adv, mod);\ngame.bol.macros.rollMacro('aptitude', 'init|melee|ranged|def', adv, mod);\n*/\ngame.bol.macros.rollMacro('attribute', 'vigor', 0, 0);`;
let macro = game.macros.entities.find(m => (m.name === actor.name) && (m.command === command));
if (!macro) {
macro = await Macro.create({
name: actor.name,
type: "script",
img: "icons/svg/dice-target.svg",
command: command
}, {displaySheet: false})
game.user.assignHotbarMacro(macro, slot);
}
}
// Create a macro to open the journal sheet of the journal dropped on the hotbar
else if (data.type == "JournalEntry") {
let journal = game.journal.get(data.id);
console.log(journal);
let command = `game.journal.get("${data.id}").sheet.render(true)`
let macro = game.macros.entities.find(m => (m.name === journal.name) && (m.command === command));
if (!macro) {
macro = await Macro.create({
name: journal.name,
type: "script",
img: (journal.img) ? journal.img : "icons/svg/book.svg",
command: command
}, {displaySheet: false})
game.user.assignHotbarMacro(macro, slot);
}
}
return false;
});
/********************************************************************************** */
Hooks.on("renderActorDirectory", (app, html, data) => {
if (game.user.isGM) {
const button = document.createElement('button');
button.style.width = '95%';
button.innerHTML = game.i18n.localize("BOL.ui.pclistbutton")
button.addEventListener('click', () => {
game.bol.charSummary.render(true)
})
html.find('.header-actions').after(button)
}
})
// Hooks.on("renderItemSheet", (app, html, data) => {
// console.debug("renderItemSheet");
// return true;
// });
// Hooks.on("renderChatLog", (app, html, data) => {
// console.debug("renderChatLog");
// return true;
// });
// Hooks.on('dropCanvasData', function (canvas, dropData) {
// console.debug("dropCanvasData");
// return true;
// });
}

52
module/system/macros.js Normal file
View File

@ -0,0 +1,52 @@
import {BoLRoll} from "../controllers/bol-rolls.js";
export class Macros {
/**
* @name getSpeakersActor
* @description
*
* @returns
*/
static getSpeakersActor = function(){
// Vérifie qu'un seul token est sélectionné
const tokens = canvas.tokens.controlled;
if (tokens.length > 1) {
ui.notifications.warn(game.i18n.localize('BOL.notification.MacroMultipleTokensSelected'));
return null;
}
const speaker = ChatMessage.getSpeaker();
let actor;
// Si un token est sélectionné, le prendre comme acteur cible
if (speaker.token) actor = game.actors.tokens[speaker.token];
// Sinon prendre l'acteur par défaut pour l'utilisateur courrant
if (!actor) actor = game.actors.get(speaker.actor);
return actor;
}
static rollMacro = async function (rollType, key, adv, mod){
const actor = this.getSpeakersActor();
// Several tokens selected
if (actor === null) return;
// No token selected
if (actor === undefined) return ui.notifications.error(game.i18n.localize("BOL.notification.MacroNoTokenSelected"));
const actorData = {};
actorData.data = {
features : actor.buildFeatures()
};
if(rollType === "attribute") {
let attribute = eval(`actor.system.attributes.${key}`);
let rollLabel = (attribute.label) ? game.i18n.localize(attribute.label) : null;
let description = actor.name + " - " + game.i18n.localize('BOL.ui.attributeCheck') + " - " + game.i18n.localize(attribute.label) ;
BoLRoll.attributeRollDialog(actor, actorData, attribute, rollLabel, description, adv, mod);
}
else if(rollType === "aptitude") {
let aptitude = eval(`actor.system.aptitudes.${key}`);
let rollLabel = (aptitude.label) ? game.i18n.localize(aptitude.label) : null;
let description = actor.name + " - " + game.i18n.localize('BOL.ui.aptitudeCheck') + " - " + game.i18n.localize(aptitude.label) ;
BoLRoll.aptitudeRollDialog(actor, actorData, aptitude, rollLabel, description, adv, mod);
}
}
}

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