Compare commits
235 Commits
0.8.8.1
...
5c4c6d73ee
Author | SHA1 | Date | |
---|---|---|---|
5c4c6d73ee | |||
1a0049a3f5 | |||
5d30482ce3 | |||
3fb8e92428 | |||
7738746994 | |||
761179bc5a | |||
a4d7c13383 | |||
ee6bf1a4d4 | |||
469948e296 | |||
def271b8b9 | |||
c9ed514ed6 | |||
2ffd3f35c8 | |||
e3b281f195 | |||
29ecb04ec3 | |||
ca3064dc0a | |||
9fd8751124 | |||
2d63b63b86 | |||
b44250e728 | |||
63c3e24296 | |||
8a87f6deab | |||
759b099bdf | |||
ade88fb54b | |||
f1a3f2df36 | |||
a357c6ddfc | |||
26a6c7fc28 | |||
6fcac36580 | |||
34924b07c0 | |||
66bf299ea4 | |||
37ab0d01dc | |||
2e3a97de04 | |||
01dbe76f59 | |||
ca33defd75 | |||
2e616e3e31 | |||
3be7f4bf9f | |||
1b8e0840b0 | |||
2cdd096c98 | |||
8fcb17b566 | |||
ad79dbb015 | |||
73ccf44dd4 | |||
ec3649799f | |||
3f5f090bb9 | |||
268ac0a25a | |||
59ee6684ab | |||
41fbc094bb | |||
5b91041a3f | |||
e7f3851daa | |||
75d562f922 | |||
ba7e25e8c7 | |||
83d3f17dd0 | |||
0c502a2188 | |||
5df2b7e624 | |||
f6554f6945 | |||
fbe232266f | |||
4b9c3bcd1e | |||
05f09aa3f5 | |||
727db74545 | |||
ccb3a458c0 | |||
1ac9605f08 | |||
1bbefd3499 | |||
bcb377db7a | |||
7a8cf9f8fd | |||
d74f7784bb | |||
6d6fec99b0 | |||
884823a1bc | |||
399c22d623 | |||
085265df5d | |||
593db9ba5b | |||
ac96f3ca67 | |||
b2fe67ab05 | |||
47178d7359 | |||
e1c7304551 | |||
7b4e5bcbfa | |||
31bd83b0ab | |||
e35187433e | |||
5e7dc3ad9d | |||
add6893864 | |||
3a591e750a | |||
fe1cda67c4 | |||
985aba0318 | |||
5d8cc300e9 | |||
aa27168c2b | |||
1135e3aff2 | |||
30e316d34e | |||
f3bd84c5c9 | |||
985d393de5 | |||
815b5ff2ac | |||
edf8325109 | |||
895aa01419 | |||
9631e5e72a | |||
716cc53b29 | |||
44952d4410 | |||
a7991bce92 | |||
a1c20019e8 | |||
af8576a4a1 | |||
6c35ddfb0b | |||
0cbcaee45e | |||
904ff821e1 | |||
5c13cde07a | |||
51c1e205e9 | |||
90a83f4571 | |||
3311bc091a | |||
fa8f9869a6 | |||
36b905134e | |||
eeb0a906e7 | |||
c552411d61 | |||
d3ae59f70d | |||
cf7d76fdba | |||
89ec404ca8 | |||
8f60aa95ee | |||
d888c6a2eb | |||
165e41fef6 | |||
19bb0798c8 | |||
05f044bc7c | |||
996ac1c88d | |||
cc1964093d | |||
d27b78d1d2 | |||
7259d3dc21 | |||
ef5cf6f393 | |||
3e50a9135f | |||
82c902099f | |||
c26e43bac7 | |||
4159b6b181 | |||
45cb082d8e | |||
2637f698ad | |||
9b8762300e | |||
dfac102925 | |||
fad281a7b3 | |||
1191442f04 | |||
fe93888c1b | |||
127f200c27 | |||
b078ffa992 | |||
d713066b5c | |||
7adfbfe148 | |||
2186d986ca | |||
590fba0cbd | |||
0c9e598958 | |||
049604ce98 | |||
471a18cd14 | |||
58c781f2f2 | |||
c9722b9b04 | |||
44ce88dd17 | |||
a31fe251e0 | |||
76a050b023 | |||
b68a6dbd23 | |||
34c7024191 | |||
33da01707d | |||
70b5324198 | |||
89566b8e3a | |||
de206498e7 | |||
e2491b9f54 | |||
45e239b8e9 | |||
477c86db0e | |||
38025666e9 | |||
9e5e07b227 | |||
e5b8c8f2c7 | |||
a5ba6d5215 | |||
fff6b2a733 | |||
80725d57e1 | |||
1a69116c06 | |||
02b3dd5e0f | |||
eacd32927c | |||
f63692b6b5 | |||
83188e6aae | |||
caf990737e | |||
7fcaf22424 | |||
53d006ed3d | |||
02b2c84f9d | |||
ec6a1b23bc | |||
0ee9e41a50 | |||
cfdfa27f23 | |||
5a90db34d7 | |||
157dd07bb5 | |||
aa367657ca | |||
5621f7b27c | |||
1734ce87cd | |||
634e755846 | |||
7407e0b75d | |||
80d58403ab | |||
59218de935 | |||
1baa51b9de | |||
fd82c204d7 | |||
48ae0920b5 | |||
aeb7739879 | |||
5eb059a2fa | |||
ae78f7a381 | |||
814877100d | |||
a5e01f051d | |||
adfcce10fc | |||
87a5b36b0a | |||
4e7b8b9a78 | |||
1008c8afb1 | |||
e7898ec769 | |||
2a83ba027b | |||
831b192691 | |||
69b6fbca6b | |||
c2e3f34517 | |||
ad8827c6f5 | |||
7bf9dabf32 | |||
0b77238dc2 | |||
06cf860505 | |||
704f5faf34 | |||
e595a16289 | |||
54ba3225dd | |||
915b89a8c4 | |||
8538af1907 | |||
a57fb3d738 | |||
8a8f2450d4 | |||
0f20a66cd2 | |||
2f19ba1948 | |||
e9eb9e2cff | |||
b034a92541 | |||
1074a1d91c | |||
721cb08059 | |||
5915b4a0ac | |||
ad205f4669 | |||
420390eed7 | |||
3fe224f1b4 | |||
a8d4d40106 | |||
498b5bc4a6 | |||
048e989ac5 | |||
c2cdc4201d | |||
7f6f813734 | |||
7531937e52 | |||
d5a5990faa | |||
4c349d89a8 | |||
0c24f49470 | |||
b6ad8a846e | |||
5d40642726 | |||
2c8d040881 | |||
4820039325 | |||
7bfeb96d5e | |||
954c95e606 | |||
ea034953a6 | |||
4452f3826a | |||
1992d618a9 |
54
.gitea/workflows/main.yml
Normal 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
@ -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
|
||||
|
45
README.md
@ -1 +1,44 @@
|
||||
# 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 s’est basée pour l’ essentiel sur celle
|
||||
de la première édition française de Barbarians of Lemuria, publiée aux Livres de l’Ours,
|
||||
et ce avec l’aimable autorisation de Kobayashi. Qu’il en soit ici vivement remercié.
|
||||
|
||||
Maps : Emmanuel Roudier.
|
||||
|
||||
# Developmement
|
||||
|
||||
LeRatierBretonnien, Zigmund (historical)
|
||||
|
BIN
assets/bol_monnaies_v1_2.pdf
Executable file
After Width: | Height: | Size: 253 KiB |
After Width: | Height: | Size: 287 KiB |
After Width: | Height: | Size: 104 KiB |
After Width: | Height: | Size: 265 KiB |
After Width: | Height: | Size: 127 KiB |
After Width: | Height: | Size: 541 KiB |
After Width: | Height: | Size: 207 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 131 KiB |
After Width: | Height: | Size: 227 KiB |
After Width: | Height: | Size: 174 KiB |
38
changelog.md
Normal 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é
|
||||
|
876
css/bol.css
@ -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
@ -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 qu’il risque de ne pas y couper, vous souhaiterez peut-être qu’il bénéficie au moins d’une petite protection. La catégorie des armures légères comprend les différentes sortes d’armures 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 qu’il soit vêtu d’une légère chemise de mailles et de rien d’autre.</p><p>Une armure légère est généralement dissimulable (à moins d’être inspecté de près ou d’avoir affaire à l’œil exercé d’un 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 d’une 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 d’armure, compromis entre la maniabilité de l’armure légère et la protection de l’armure lourde, est le choix favori des aventuriers qui s’attendent à affronter des combats de manière régulière. Il peut s’agir d’une armure de cuir couvrant la majeure partie du corps, avec des parties en cuir bouilli pour protéger les points vitaux, ou d’une armure mêlant le cuir et la cotte de mailles, ou encore d’une 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 s’il 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 d’une armure moyenne s’accompagne d’un malus de -1 en agilité du fait de l’encombrement ;</li><li>le port d’une 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 d’armure 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 l’on peut porter la journée entière, et encore moins pour voyager ou s’adonner aux activités ordinaires du quotidien. Il peut s’agir d’un haubert de mailles descendant jusqu’aux genoux ou d’une cuirasse en acier, complétée de grèves et de gantelets, ou encore d’une 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 s’il le souhaite.</p><p>Les personnages ayant moins de 0 en vigueur ne peuvent pas porter d’armure 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 d’une armure lourde s’accompagne d’un malus de -2 en agilité du fait de l’ encombrement ;</li><li>le port d’une 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é d’un 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 à l’initiative (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 lorsqu’il 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 s’il est conscient de l’attaque qui le vise, et donc s’il 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 s’il est conscient de l’attaque qui le vise, et donc s’il 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
@ -0,0 +1,533 @@
|
||||
[
|
||||
{
|
||||
"name": "Agilité de l’homme-oiseau",
|
||||
"type": "feature",
|
||||
"img": "/systems/bol/ui/icons/boon.webp",
|
||||
"data": {
|
||||
"subtype": "boon",
|
||||
"description": "<h1>Agilité de l’homme-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 d’un 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 d’un 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 s’ils ne seront pas en général disposés à risquer leur tête pour vous, ils pourront vous apporter de l’aide (comme vous obtenir une audience auprès d’un 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 d’une arme de qualité (une grande épée valgardienne, un arc long de Tyrus, une fronde d’Axos, un kriss halakhi, un khastok de Malakut, une hache d’abordage 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 l’enfance. Vous bénéficiez d’un 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é d’artiste. Vous bénéficiez d’un dé de bonus pour créer ou estimer des objets d’art.</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 d’un 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 d’un dé de bonus dans les situations où l’apparence 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 d’un dé de bonus à l’attaque 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 qu’un pagne ou un bikini en cotte de mailles et un simple baudrier (l’équivalent d’une armure légère au mieux), tout en considérant qu’il s’agit d’une armure moyenne en terme de protection, et ce sans subir le moindre malus d’armure.</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 d’un dé de bonus quand vous voulez mentir, escroquer, baratiner ou tromper quelqu’un.</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 d’une bibliothèque de qualité pour mener vos recherches. Vous bénéficiez d’un 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 à l’aventure pour trouver les moyens d’acqué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 d’un 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 d’un dé de bonus pour briser, lever, tirer ou pousser des objets.</p>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Combat à l’aveugle",
|
||||
"type": "feature",
|
||||
"img": "/systems/bol/ui/icons/boon.webp",
|
||||
"data": {
|
||||
"subtype": "boon",
|
||||
"description": "<h1>Combat à l’aveugle</h1><p>pas de lumière ? Aucun problème. En vous basant sur les odeurs, les bruits, les déplacements d’air, vous ne faites plus qu’un avec le monde qui vous entoure. Votre personnage ignore les malus imposés par le MJ pour combattre dans l’obscurité.</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 d’attaque durant le round qui suit le cri de guerre. Cet avantage ne peut être utilisé gratuitement qu’une fois par jour ; toute utilisation supplémentaire exigera la dépense de 1 point d’hé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 d’un 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 d’un dé de bonus pour toutes les tâches exigeant une grande dextérité, comme le vol à la tire, la fabrication d’objets, 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 d’un 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 d’un fait relevant de votre domaine de compétence, vous bénéficiez d’un 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 s’agit de lever le coude. Vous bénéficiez d’un 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 l’alcool et bénéficiez également d’un 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 d’un dé de bonus pour pister, piéger ou chasser, ainsi que pour d’autres 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 d’une source de revenus ou d’un héritage. Vous bénéficiez d’un dé de bonus quand vous cherchez à acquérir des biens ou des services dans votre cité d’origine.</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 d’un dé de bonus quand vous interagissez avec les gens des bas-fonds de la cité, ou pour des activités comme filer quelqu’un 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 d’une invocation aux dieux, d’un discours enflammé ou d’une musique inspirante, à moins que cela ne vienne simplement de votre présence charismatique. Pour le round qui suit l’utilisation de cet avantage, vos compagnons bénéficient d’un dé de bonus à tous leurs jets d’attaque (à condition d’être à portée de voix). Cet avantage ne peut être utilisé gratuitement qu’une fois par jour ; toute utilisation supplémentaire exigera la dépense de 1 point d’hé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 d’un dé de bonus à chaque fois que vous essayez de forcer quelqu’un à 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 n’a 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 d’un laboratoire de qualité pour mener vos expériences. Vous bénéficiez d’un 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 à l’aventure 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 d’un 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 d’un dé de bonus sur les tests destinés à aider un blessé à récupérer de ses blessures, d’un 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 d’un 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 d’hé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 d’hé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 d’un dé de bonus pour pister, piéger ou chasser, ainsi que pour d’autres 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 d’un 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 d’action sous esprit pour percevoir quelque chose grâce à votre odorat, vous bénéficiez d’un 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 d’action sous esprit pour percevoir quelque chose grâce à votre ouïe, vous bénéficiez d’un 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 d’outils adaptés à votre métier ou votre artisanat. Vous bénéficiez d’un dé de bonus quand vous entreprenez une action où l’emploi 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 d’armure.</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 quelqu’un tente de vous mentir ou de vous entourlouper, vous bénéficiez d’un 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 qu’on 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 d’un dé de bonus pour manœuvrer une embarcation ou entreprendre des activités physiques à bord d’un 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 d’un dé de bonus pour pister, piéger ou chasser, ainsi que pour d’autres activités similaires de survie (mais pas pour combattre).</p>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Poings d’acier",
|
||||
"type": "feature",
|
||||
"img": "/systems/bol/ui/icons/boon.webp",
|
||||
"data": {
|
||||
"subtype": "boon",
|
||||
"description": "<h1>Poings d’acier</h1><p>vous avez les poings durs comme la pierre après des années d’entraî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 l’abî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 d’une constitution hors norme. Lorsque vous récupérez après un combat, vous regagnez 1 point de vitalité supplémentaire (qui s’ajoute à 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 d’un dé de bonus pour pister, piéger ou chasser, ainsi que pour d’autres 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 n’a 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 d’un dé de bonus pour résister aux effets des drogues, des venins, des toxines, ainsi que de l’alcool.</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 d’un dé de bonus pour pister, piéger ou chasser, ainsi que pour d’autres 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 d’un 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 d’origine 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 d’un 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 d’un dé de bonus pour pister, piéger ou chasser, ainsi que pour d’autres 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 d’arme à 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 d’une excellente capacité de réaction face au danger. Vous bénéficiez d’un 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 d’un dé de bonus quand l’obscurité 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 d’action sous esprit pour percevoir quelque chose grâce à votre vue, vous bénéficiez d’un dé de bonus.</p>"
|
||||
}
|
||||
}
|
||||
]
|
236
data/fr/json/careers.json
Normal 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 qu’ils 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 d’assembler des morceaux issus de différentes créatures vivantes pour créer d’horribles chimères. Quand ils conçoivent des machines, les alchimistes travaillent souvent en étroite collaboration avec des forgerons. Vous trouverez davantage d’informations sur l’alchimie au chapitre 6.</p><h2>Attributs</h2><p>à l’évidence l’esprit est l’attribut 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>À l’aventure</h2><p>ce n’ est pas une carrière très courante chez les héros, car elle impose d’austères recherches et beaucoup de patience. Il arrive cependant que des alchimistes audacieux s’aventurent à explorer d’antiques ruines dans l’ espoir d’y découvrir d’anciennes reliques dont la véritable valeur pourrait échapper à des héros moins instruits qu’eux.</p><h2>Combat</h2><p>les circonstances où des rangs dans la carrière d’alchimiste pourraient se révéler utiles au combat sont particulièrement rares.</p><h2>Idées d’Avantages</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 d’alchimiste 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 s’ils veulent pouvoir utiliser les puissantes créations magiques et alchimiques de l’antique 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 d’un souverain, les espions et les assassins ont élevé le meurtre et le vol au rang d’art. Ce sont des experts de la collecte secrète d’informations et de rumeurs, de l’attaque sournoise et du meurtre discret, parfois maquillé en mort naturelle (par l’usage 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 (qu’il s’agisse 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 l’occasion parfaite de frapper. Il est de notoriété publique que les meilleurs assassins de Lémurie proviennent de la cité d’Halakh.</p><h2>Attributs</h2><p>tous les attributs sont importants pour un assassin.</p><h2>À l’aventure</h2><p>les assassins et les espions sont généralement des solitaires, ce qui n’en fait pas des candidats évidents pour rejoindre un groupe d’aventuriers. En revanche, d’anciens 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 s’il attaque par surprise, en frappant un adversaire qui ne l’a pas vu approcher, ou en utilisant une arme dissimulée, par exemple.</p><h2>Idées d’Avantages</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 l’Axos, des toundras glacées de Valgard, du désert de Beshaar ou d’autres 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 d’instincts aussi aiguisés que ceux d’un 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 d’intimider 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 qu’il ne doive pas non plus négliger l’agilité.</p><h2>Idées de Désavantages</h2><p>arrogant, gars de la ville, mauvaise réputation, obsession (achever la mission), traqué.</p><h2>À l’aventure</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 d’un combat particulièrement violent et sans pitié.</p><h2>Idées d’Avantages</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 d’eau 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 s’occupent 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 d’extirper des informations aux prisonniers récalcitrants et aux ennemis des rois qui les emploient. Passés maîtres dans l’art de l’intimidation et de l’interrogatoire, ils possèdent de bonnes connaissances de base en anatomie et en premiers soins (des savoirs indispensables pour briser un prisonnier sans qu’il meure avant d’avoir parlé).</p><p>Les esclavagistes mènent des raids dans des terres lointaines pour capturer ou acheter des « sauvages » qu’ils 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 d’aura élevé, tandis que la vigueur reste un attribut indispensable pour accomplir une décapitation dans les règles de l’art ou pour maintenir le calme parmi leurs prisonniers.</p><h2>À l’aventure</h2><p>les geôliers quittent rarement leurs cachots humides, mais il peut arriver qu’un bourreau se retrouve frappé d’exil et contraint de mener une vie d’errance et d’aventure. 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 d’Avantages</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 d’oreille, 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 l’art de pister et de traquer les animaux. Une fois qu’il a localisé sa proie, il utilise des techniques d’approche discrète, la pose de pièges, ou son habileté à l’arc pour l’abattre. Les chasseurs sont parfaitement à leur aise dans la nature sauvage et sont capables d’y survivre sur de longues périodes, pour ne retourner vers les zones civilisées qu’une fois qu’ils 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>l’agilité est importante pour un chasseur, tout comme la vigueur et l’esprit, encore qu’à un moindre degré.</p><h2>À l’aventure</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 d’anciennes 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 d’aventuriers.</p><h2>Combat</h2><p>un chasseur pourra recevoir un bonus de carrière ponctuel s’il affronte une créature sauvage qu’il connaît bien. En revanche, cette carrière est rarement utile contre des adversaires humains.</p><h2>Idées d’Avantages</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 d’eau 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, d’agilité 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 qu’ils 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 qu’ils n’y paraissent.</p><h2>À l’aventure</h2><p>les saltimbanques voyagent de ville en ville au sein de troupes itinérantes. Cela peut les confronter aux dangers de la route, qu’il s’agisse de bêtes féroces ou de brigands.</p><h2>Combat</h2><p>cette carrière n’a rien d’une 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 d’Avantages</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 d’ours)",
|
||||
"img": "/systems/bol/ui/icons/career.webp",
|
||||
"type": "feature",
|
||||
"data": {
|
||||
"subtype": "career",
|
||||
"description": "<h1>Dresseur (maître des bêtes/montreur d’ours)</h1><p>Les maîtres des bêtes sont demandés dans toute la Lémurie pour leur capacité à s’occuper des animaux, envers lesquels ils manifestent généralement une forme particulière d’empathie. 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 d’attaquer. En général, ce sont également des cavaliers émérites et de remarquables conducteurs d’attelage. 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 n’est pas toujours le cas). L’aura est donc l’attribut le plus important pour un dresseur, suivi de près par l’esprit.</p><h2>À l’aventure</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 d’arènes, ou par des aventuriers qui s’attendent à 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 d’Avantages</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>L’esclavage 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 d’apprendre à 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 d’une bonne vigueur ou d’une bonne agilité. Les femmes esclaves voient leur situation s’améliorer (ou empirer !) si elles ont un bon score d’aura. Les esclaves trop intelligents sont généralement considérés comme des fauteurs de trouble.</p><h2>À l’aventure</h2><p>les esclaves à l’esprit 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 d’esclave fugitif mène tout naturellement à l’aventure.</p><h2>Combat</h2><p>cette carrière n’ est pas d’un grand intérêt au combat. Toutefois des guerriers pourraient négliger de s’occuper d’un esclave, ne le considérant pas comme une menace, ce qui risque d’être une grave erreur.</p><h2>Idées d’Avantages</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 d’eau 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 à l’extérieur de l’enceinte de la cité, mais généralement à moins d’une 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 n’y a pas d’attribut plus important qu’un autre, encore que l’aura soit sans doute celui qui lui sera le moins utile.</p><h2>À l’aventure</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 d’errance.</p><h2>Combat</h2><p>en général, les fermiers ne sont pas des combattants aguerris et ils ne recevront qu’exceptionnellement un avantage au combat en raison de cette carrière, par exemple s’ils défendent leurs terres contre des pillards ou utilisent un outil agricole comme arme improvisée.</p><h2>Idées d’Avantages</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 d’eau 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 s’agit d’estimer et de marchander le prix d’objets 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>À l’aventure</h2><p>les forgerons ne sont pas vraiment des aventuriers, mais certains s’engagent parfois dans une troupe de mercenaires pour s’occuper de l’ entretien des armes et des armures.</p><h2>Combat</h2><p>bien qu’un forgeron ne soit pas à proprement parler un combattant, il pourra recevoir ponctuellement un bonus de mêlée s’il 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 d’Avantages</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 d’armes et capables d’affronter 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 d’une dette impayée ou en punition d’un 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 l’arène, et qui peut aussi bien jouer à leur avantage qu’à leur détriment.</p><h2>Attributs</h2><p>pour un gladiateur, la vigueur et l’agilité sont essentielles, mais les plus populaires des guerriers de l’arène possèdent aussi beaucoup d’aura.</p><h2>À l’aventure</h2><p>la vie de gladiateur ne conduit pas d’elle-même à l’aventure, 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 l’adversaire, mais de faire de la passe d’armes 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 l’approbation du MJ.</p><h2>Idées d’Avantages</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 l’art 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 d’abord à un marchand !</p><h2>Attributs</h2><p>les marchands ont besoin d’un esprit vif et d’un certain degré d’aura pour marchander et faire des affaires.</p><h2>À l’aventure</h2><p>une vie itinérante est forcément une vie d’aventure, 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 d’Avantages</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, s’orienter 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 qu’un capitaine refuse d’accepter à 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, qu’on appelle l’argot des mers.</p><h2>Attributs</h2><p>les marins ont besoin d’une bonne vigueur et d’une bonne agilité.</p><h2>À l’aventure</h2><p>la vie en mer ne manque pas d’aventures. 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 d’affrontements en mer, et peut-être aussi contre des créatures marines qu’il aurait déjà combattues ou dont il aurait entendu parler.</p><h2>Idées d’Avantages</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 d’un grand respect au sein des villes de Lémurie. La population sait reconnaître l’importance de leur mission et l’étendue de leur savoir, même si les petites gens n’ont pas forcément les moyens de s’offrir les services d’un vrai médecin et s’en 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 n’ont 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>l’esprit est l’attribut essentiel pour un médecin.</p><h2>À l’aventure</h2><p>la carrière de médecin n’ est pas en elle-même propice à une vie d’aventure, 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 d’un grand secours. Ce n’ est qu’après le combat qu’elle révèle tout son intérêt !</p><h2>Idées d’Avantages</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 d’un lieu à l’autre avec pour seul objectif de réussir à survivre. Ils peuvent à l’occasion 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 s’adonnent à 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é d’une difformité, d’un handicap, ou d’une maladie repoussante (ou simplement le simuler) peut cependant se révéler utile quand il s’agit de faire appel à la compassion des passants.</p><h2>À l’aventure</h2><p>la vie d’un vagabond implique des rencontres en tous genres sur les routes, ce qui peut mener à l’aventure sans même la rechercher.</p><h2>Combat</h2><p>en général, un mendiant n’a rien d’un combattant. Cette carrière ne pourra donc se révéler utile dans le cadre d’un combat, sauf quand le personnage fait de son mieux pour ne pas être remarqué.</p><h2>Idées d’Avantages</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 d’apporter 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 d’aura, ainsi qu’une bonne dose d’agilité et un esprit aiguisé.</p><h2>À l’aventure</h2><p>les ménestrels sont itinérants, ce qui les expose forcément aux dangers de la route. Certains choisissent d’accompagner des soldats et des aventuriers afin de connaître eux-mêmes l’excitation de l’aventure et de créer des récits épiques basés sur ce qu’ils 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 n’accordera 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 d’Avantages</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 s’assemblent en troupes sous l’autorité d’un chef respecté, tandis que d’autres voyagent seuls ou en petits groupes à la recherche d’un 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 s’adonner au métier des armes, les mercenaires doivent posséder de bonnes prédispositions en vigueur et en agilité.</p><h2>À l’aventure</h2><p>par nature, les mercenaires sont des vagabonds qui parcourent la Lémurie en quête d’un nouvel engagement. Même en temps de paix, ils trouvent à s’employer 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 d’autant mieux que la paie est bonne, et pour mettre peu de cœur à l’ouvrage (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 d’Avantages</h2><p>arme favorite, bagarreur, baudrier de guerre, combat à l’aveugle, 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 d’une 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 d’obtenir des prêts monétaires, disposent de contacts haut placés, connaissent les règles de l’étiquette et savent s’habiller avec élégance. La vie de courtisan développe également leurs talents pour ce qui est du mensonge, du chantage et de l’intimidation.</p><h2>Attributs</h2><p>les nobles ont besoin d’une aura forte ainsi que d’un esprit vif, même si, en fin de compte, c’est bien souvent la richesse qui dicte sa loi.</p><h2>À l’aventure</h2><p>les nobles n’ont pas de goût particulier pour l’aventure, même s’il arrive qu’ils financent des expéditions lointaines à la recherche d’artefacts anciens ou montent des opérations de négoce. Certains nobles audacieux se joignent parfois à ces expéditions afin d’en 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 à s’en prendre à un de leurs supérieurs. Les nobles se retrouvent souvent comme commandants à la tête d’armées, qu’ils en aient les qualités ou pas.</p><h2>Idées d’Avantages</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 l’alcool et s’y entendent en intimidation. Certaines des tâches qu’effectuent 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>À l’aventure</h2><p>le labeur des ouvriers est monotone et pas vraiment propice à l’aventure. Un personnage qui possède cette carrière n’a pas dû l’exercer très longtemps.</p><h2>Combat</h2><p>les ouvriers ne sont pas vraiment des combattants, même s’ils ont tendance à régler les disputes à coups de poing. Ils peuvent recevoir un bonus lors d’une bagarre, notamment quand il s’agit de saisir ou d’étrangler leur adversaire.</p><h2>Idées d’Avantages</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 d’oreille, 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 à l’entretien 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 d’anciens soldats, souvent d’origine 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>À l’aventure</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 l’aventure.</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 l’affrontement ait lieu en plein ciel.</p><h2>Idées d’Avantages</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 l’on 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 d’une forte influence sur les affaires politiques, mais aussi sur l’armé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 qu’ils pratiquent les sacrifices humains.</p><p>Vous trouverez davantage d’informations sur les prêtres au chapitre 6.</p><h2>Attributs</h2><p>les prêtres ont surtout besoin d’un esprit aiguisé, mais les meilleurs d’entre eux ont également l’aura nécessaire pour attirer les fidèles en nombre.</p><h2>À l’aventure</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. D’autres 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 n’apporte aucun avantage au combat, si ce n’est éventuellement lors d’un affrontement face à des adversaires superstitieux qui hésiteront à s’en prendre à un serviteur des dieux.</p><h2>Idées d’Avantages</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 s’ils veulent pouvoir utiliser les puissantes créations magiques et alchimiques de l’antique 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 d’une 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>l’esprit est l’attribut essentiel pour un scribe.</p><h2>À l’aventure</h2><p>les scribes font d’ordinaire de piètres aventuriers, mais il peut être très utile pour un groupe d’avoir 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 d’une quelconque utilité au combat.</p><h2>Idées d’Avantages</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 d’une 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 d’une certaine autorité, surtout quand ils sont officiers. Ils connaissent bien la cité qu’ils servent, ainsi que la rude vie des camps militaires.</p><h2>Attributs</h2><p>la vigueur est normalement l’attribut essentiel pour un soldat, mais les archers et les cavaliers auront besoin d’une bonne agilité. Les officiers doivent avoir de l’aura pour diriger leurs hommes et un esprit aiguisé pour établir de solides plans de bataille.</p><h2>À l’aventure</h2><p>la plupart des soldats manquent d’inspiration et de fantaisie pour faire de bons aventuriers. En revanche, le temps passé à l’armée permet à un personnage d’affûter ses talents martiaux en attendant de repartir à l’aventure.</p><h2>Combat</h2><p>les soldats pourront parfois bénéficier d’un bonus de carrière au combat, notamment s’ils se battent selon une tactique établie, au sein d’une unité bien commandée.</p><h2>Idées d’Avantages</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 d’oreille, 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 d’une 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 d’un apprenti. Ils s’adonnent à l’étude de sciences ésotériques comme l’astrologie, l’astronomie et la démonologie, recherchent fiévreusement d’antiques manuscrits interdits renfermant un savoir occulte, quand ils ne concluent pas des pactes avec les démons afin d’apprendre 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 d’informations sur les sorciers au chapitre 6.</p><h2>Attributs</h2><p>les sorciers ont besoin d’un esprit fort, à la fois pour mener leurs études et pour être en mesure de lancer des sorts puissants.</p><h2>À l’aventure</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 qu’ils quittent leur antre pour prendre part eux-mêmes à une expédition dont ils espèrent quelque gain mystique d’importance.</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 n’ont pas besoin de savoir manier une épée pour venir à bout d’un adversaire.</p><h2>Carrière dangereuse</h2><p>la sorcellerie est un moyen rapide d’obtenir 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 s’applique également si vous choisissez d’augmenter votre rang de sorcier plus tard dans le jeu, par l’utilisation de points d’expérience.</p><h2>Idées d’Avantages</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 s’ils veulent pouvoir utiliser les puissantes créations magiques et alchimiques de l’antique 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 d’art. La tentatrice peut être la maîtresse d’un 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 qu’elle est belle, car c’est le genre de femme pour laquelle les hommes se battent et les guerres éclatent. Une tentatrice est passée maîtresse dans l’art de la manipulation et de la séduction.</p><p>N.B. Barbarians of Lemuria étant conçu pour évoquer les thèmes et l’ambiance 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>l’aura est l’attribut le plus important pour une tentatrice. L’agilité et l’esprit sont également utiles.</p><h2>À l’aventure</h2><p>les tentatrices ne sont d’habitude pas très aventureuses (du moins en dehors d’un lit !), et il faudra donc que d’autres carrières viennent expliquer ce choix peu probable d’une vie itinérante à courir le danger.</p><h2>Combat</h2><p>cette carrière est rarement utile au combat, encore qu’une tentatrice puisse utiliser son rang dans cette carrière pour distraire des gardes, par exemple.</p><h2>Idées d’Avantages</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 qu’il n’ait commencé sa vie comme gamin des rues obligé de voler pour survivre. Quoi qu’il 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 d’une bonne agilité, mais aussi d’un esprit aiguisé.</p><h2>À l’aventure</h2><p>les bons voleurs font des recrues de choix pour les aventuriers prévoyant d’explorer 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 d’un bonus de carrière quand ils cherchent à prendre la poudre d’escampette, surtout face aux gardes de la cité.</p><h2>Idées d’Avantages</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
@ -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 qu’il risque de ne pas y couper, vous souhaiterez peut-être qu’il bénéficie au moins d’une petite protection. La catégorie des armures légères comprend les différentes sortes d’armures 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 qu’il soit vêtu d’une légère chemise de mailles et de rien d’autre.</p><p>Une armure légère est généralement dissimulable (à moins d’être inspecté de près ou d’avoir affaire à l’œil exercé d’un 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 d’une 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 d’armure, compromis entre la maniabilité de l’armure légère et la protection de l’armure lourde, est le choix favori des aventuriers qui s’attendent à affronter des combats de manière régulière. Il peut s’agir d’une armure de cuir couvrant la majeure partie du corps, avec des parties en cuir bouilli pour protéger les points vitaux, ou d’une armure mêlant le cuir et la cotte de mailles, ou encore d’une 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 s’il 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 d’une armure moyenne s’accompagne d’un malus de -1 en agilité du fait de l’encombrement ;</li><li>le port d’une 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 d’armure 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 l’on peut porter la journée entière, et encore moins pour voyager ou s’adonner aux activités ordinaires du quotidien. Il peut s’agir d’un haubert de mailles descendant jusqu’aux genoux ou d’une cuirasse en acier, complétée de grèves et de gantelets, ou encore d’une 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 s’il le souhaite.</p><p>Les personnages ayant moins de 0 en vigueur ne peuvent pas porter d’armure 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 d’une armure lourde s’accompagne d’un malus de -2 en agilité du fait de l’ encombrement ;</li><li>le port d’une 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é d’un 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 à l’initiative (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 lorsqu’il 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 s’il est conscient de l’attaque qui le vise, et donc s’il 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 s’il est conscient de l’attaque qui le vise, et donc s’il est prêt à la parer.</p>",
|
||||
"properties": {
|
||||
"equipable": true,
|
||||
"protection": true,
|
||||
"shield": true,
|
||||
"modifiers": {
|
||||
"agility": -1
|
||||
},
|
||||
"blocking": {
|
||||
"malus": -1,
|
||||
"nbAttacksPerRound": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Arme d’hast",
|
||||
"type": "item",
|
||||
"img": "/systems/bol/ui/icons/axe.webp",
|
||||
"data": {
|
||||
"subtype": "weapon",
|
||||
"description": "<h1>Arme d’hast</h1><p>ce nom recouvre une catégorie d’armes possédant toutes un fer destiné à frapper, fixé au bout d’une 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 d’arme.</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 qu’utilisées au corps à corps. Facilement dissimulable, la dague est l’arme 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>l’arme favorite des héros. Elle se décline en différents modèles utilisés un peu partout en Lémurie, comme les sabres d’abordage, les tulwars, les cimeterres ou les épées longues. Inscrivez le nom de l’arme que vous voulez sur la fiche de votre personnage en fonction de l’image que vous vous faites de ce dernier. Mais au final, une épée reste une longue lame utilisée pour tuer l’ennemi.</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 s’utilisant à 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 s’utilisant à 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é d’une chaîne, à l’extré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 l’emploi d’un 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>c’est l’arme 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 d’utiliser 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 d’une 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 d’armes",
|
||||
"type": "item",
|
||||
"img": "/systems/bol/ui/icons/mace.webp",
|
||||
"data": {
|
||||
"subtype": "weapon",
|
||||
"description": "<h1>Masse d’armes</h1><p>cette arme a la même forme qu’un gourdin, mais possède une tête en métal, souvent agrémentée de pointes ou d’ailettes pour plus d’efficacité. Les masses d’armes à 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 l’extrémité, plus volumineuse, sert à fracasser le crâne de ses adversaires, d’où 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 à l’extrémité d’une 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 l’escrime a été élevé au rang d’art. La rapière s’utilise 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 d’entraî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 qu’une arbalète normale, l’arbalè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 d’arcs.</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 d’un 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. C’est une arme peu coûteuse et facile à fabriquer. Il existe une version plus puissante, montée au bout d’un 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 d’une courte hampe surmontée d’une 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 l’Axos.</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
@ -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 n’a plus vingt ans. S’il ne dispose pas chaque jour d’une 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 d’autres 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 d’une 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 quelqu’un essaie de vous convaincre qu’une idée est bonne, alors qu’elle ne l’est 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. S’il 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 à l’arc ou à l’arbalè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-l’air, incapable de vous souvenir de vos obligations ou du nom des gens. Un défaut que le MJ se fera un plaisir d’exploiter de temps à autre au détriment de votre personnage…</p>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Dur d’oreille",
|
||||
"type": "feature",
|
||||
"img": "/systems/bol/ui/icons/flaw.webp",
|
||||
"data": {
|
||||
"subtype": "flaw",
|
||||
"description": "<h1>Dur d’oreille</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 d’hommes 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 à d’autres 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 d’indé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 d’indécision. Lancez un d3</h1><p>c’est le nombre de rounds où vous restez paralysé par la situation, incapable d’agir autrement qu’en 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 d’agir rationnellement, par exemple pour éviter de faire un esclandre en plein bal au palais, ou pour ignorer la raillerie d’un 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 d’un code de l’honneur 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 à quelqu’un 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 quelqu’un 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 d’amadouer 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 d’eau douce",
|
||||
"type": "feature",
|
||||
"img": "/systems/bol/ui/icons/flaw.webp",
|
||||
"data": {
|
||||
"subtype": "flaw",
|
||||
"description": "<h1>Marin d’eau douce</h1><p>vous subissez un dé de malus pour toute activité entreprise à bord d’un 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 c’est 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 d’autres termes, vous commencez le jeu avec 1 point d’hé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 d’agir comme vous l’avez fait, vous êtes précédé par votre mauvaise réputation. Vous subissez un dé de malus dans les interactions sociales où il s’agit 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 d’expé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 s’agir d’un but, d’une personne ou d’un objet. Vous consacrez beaucoup de temps, d’énergie et d’argent à cette obsession. À chaque fois que vous vous trouvez en présence de l’objet de votre obsession, vous subissez un dé de malus sur tous les jets qui impliquent que vous l’ignoriez. 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 n’avez 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é d’une peur irrationnelle. Vous subissez un dé de malus en présence de l’objet de votre phobie. Il peut s’agir par exemple de la peur du feu, des reptiles, des araignées, des hauteurs, de la foule, de la mort, de l’obscurité, 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 n’est 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 l’intimidation. 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ù l’apparence 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 s’oublie pas. Il peut s’agir d’une cicatrice particulière ou d’un 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 d’une 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é d’une 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 d’une 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 c’est 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 d’une pierre blanche, et il est très rare qu’il engage de lui-même la conversation. Son extrême réticence à parler implique malheureusement qu’il 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 qu’il 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
@ -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é d’influences diverses. Il n’en 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>l’axien est la langue des tribus barbares qui vivent dans la chaîne de l’Axos. Cette langue reste plutôt confinée à cette région montagneuse, mais on raconte que d’anciens textes datant de l’époque lointaine où l’axien é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 d’Halakh 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 n’a pas de forme écrite. Les marchands d’Oomis 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>c’est l’ancienne 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 s’ils 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>à l’origine, le festreli était un dialecte du lémurien, mais il s’en est tellement éloigné qu’il 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 s’agit pas d’une langue à proprement parler, mais plutôt d’un langage rudimentaire fait de grognements, de grimaces, de tapements du pied et de grands mouvements simiesques. Ce langage n’a 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 qu’un voyageur aura parfois du mal à comprendre les gens du coin. Le MJ pourra à l’occasion vous demander de réussir un jet d’esprit pour communiquer avec des gens d’autres 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 s’engouffrant 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>c’est le nom de l’ancienne langue des hommes (aussi appelée langue des Anciens). Peu d’individus la parlent aujourd’hui, et encore moins peuvent la lire. Il arrive cependant que d’antiques textes soient retrouvés dans les ruines d’Ygddar, de Qiddesh, de Qeb, de Qar ou d’Oosal, mais leur traduction requiert généralement les services d’un scribe particulièrement compétent.</p>"
|
||||
}
|
||||
}
|
||||
]
|
232
data/fr/json/melee.json
Normal file
@ -0,0 +1,232 @@
|
||||
[
|
||||
{
|
||||
"name": "Arme d’hast",
|
||||
"type": "item",
|
||||
"img": "/systems/bol/ui/icons/weapon.webp",
|
||||
"data": {
|
||||
"subtype": "weapon",
|
||||
"description": "<h1>Arme d’hast</h1><p>ce nom recouvre une catégorie d’armes possédant toutes un fer destiné à frapper, fixé au bout d’une 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 d’arme.</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 qu’utilisées au corps à corps. Facilement dissimulable, la dague est l’arme 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>l’arme favorite des héros. Elle se décline en différents modèles utilisés un peu partout en Lémurie, comme les sabres d’abordage, les tulwars, les cimeterres ou les épées longues. Inscrivez le nom de l’arme que vous voulez sur la fiche de votre personnage en fonction de l’image que vous vous faites de ce dernier. Mais au final, une épée reste une longue lame utilisée pour tuer l’ennemi.</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 s’utilisant à 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 s’utilisant à 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é d’une chaîne, à l’extré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 l’emploi d’un 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>c’est l’arme 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 d’utiliser 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 d’une 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 d’armes",
|
||||
"type": "item",
|
||||
"img": "/systems/bol/ui/icons/weapon.webp",
|
||||
"data": {
|
||||
"subtype": "weapon",
|
||||
"description": "<h1>Masse d’armes</h1><p>cette arme a la même forme qu’un gourdin, mais possède une tête en métal, souvent agrémentée de pointes ou d’ailettes pour plus d’efficacité. Les masses d’armes à 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 l’extrémité, plus volumineuse, sert à fracasser le crâne de ses adversaires, d’où 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 à l’extrémité d’une 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 l’escrime a été élevé au rang d’art. La rapière s’utilise 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
@ -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 d’en faire un kalukan, à condition que le MJ l’autorise. 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 qu’ailleurs 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 qu’ils 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>L’exotique 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 d’un homme impétueux a perdu la vie en se battant pour les faveurs d’une 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 à s’armer de longs javelots qu’ils 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 d’eau 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 c’est à Halakh que l’on 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 d’eau 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 : l’appel 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 d’abord l’accord 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 d’une de ces tribus, utilisez la liste d’avantages/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 s’ils restaient insensibles à l’agitation 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 s’enorgueillit 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 s’opposent à 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 à l’aveugle, 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 d’eau 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 n’ont pas envie de se montrer aux étrangers, sont très difficiles à trouver. Petits et trapus, ils font preuve d’une 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 d’Oomis.</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 l’art d’utiliser leur environnement pour se camoufler et masquer leur odeur, afin d’approcher les créatures du marais qu’ils 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, T’kala, T’kouna.</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, Z’kala, Z’kouna.</p>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Montagnes de l’Axos",
|
||||
"type": "feature",
|
||||
"img": "/systems/bol/ui/icons/origin.webp",
|
||||
"data": {
|
||||
"subtype": "origin",
|
||||
"description": "<h1>Montagnes de l’Axos</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 d’excellents chasseurs et des grimpeurs réputés. Les hommes des tribus de l’Axos mènent une vie fruste ; leur artisanat et leur art n’utilisent que les matériaux que leurs offrent leurs montagnes, et c’est également le cas pour leurs armes de chasse et de guerre.</p><p>Si vous êtes originaire des montagnes de l’Axos, votre première carrière doit être barbare, et il ne serait pas étonnant que vous soyez aussi chasseur. Les tribus de l’Axos sont réputées pour leur habileté à la fronde.</p><p>Les cimes de la chaîne de l’Axos sont la demeure d’un énigmatique peuple d’hommesoiseaux (cf. chapitre 5).</p><h2>Avantages</h2><p>arme favorite (fronde de l’Axos), 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 d’eau 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 d’un 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 jusqu’où va l’amitié qui les lie aux nomades bleus…</p><p>C’est un peuple d’habiles négociants, et un personnage originaire d’Oomis 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 d’oreille, 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 l’on 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 d’abordage 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 qu’on 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 d’excellents 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 l’art du négoce. Les carrières d’alchimiste, 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, qu’on 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 s’installent ici ont tôt fait d’adopter 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 d’adopter 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 d’excellents 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 d’eau douce, méfiance envers la sorcellerie.</p><h2>Noms masculins</h2><p>Akri, Badran, Bello, Diallo, Donkor, Eze, Jaafar, Juma, Kamouzou, M’Boutou, M’Dogo, 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, M’Lala, 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, s’il faut en croire les récits de chasseurs et d’explorateurs qui ont relevé des traces de présence. Mais à ce jour, personne n’a découvert le moindre village ou hameau, et on ignore tout de l’apparence 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 qu’il soit toujours considéré comme un étranger, où qu’il 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 d’Urceb sont des risque-tout, des joueurs et des opportunistes. Habitués à s’aventurer 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 à l’aveugle, 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 d’eau 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 qu’ailleurs) et aiment à se raser le crâne. Ils cultivent leur isolement et la légende prétend qu’ils 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. D’autres 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, Ar’siuqqu, 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
@ -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 qu’eux. 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. C’est 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 s’ils ne manquent pas d’atouts pour le combat. Lorsque deux tribus s’affrontent, 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 d’Ygddar 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 d’expériences alchimiques menées par les Rois-Sorciers.</p><p>L’Edda pourpre et d’autres chroniques anciennes indiquent sans l’ombre d’un 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 d’Hyrdral, le géant bleu Chunak mena ses frères à la révolte contre leurs maîtres reptiliens, qu’ils 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 n’ont 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 d’eau 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 d’hommes 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 jusqu’au 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 s’arment de solides gourdins ainsi que de lances à pointe en silex, et se ceignent les reins d’un pagne en peau d’animal, seuls signes chez eux d’un 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 d’eau 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 l’Axos. 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 d’oiseaux, qui leur permettent de grimper les parois rocheuses avec une grande aisance. Ce ne sont pas de grands guerriers et ils se servent essentiellement d’armes de jet légères qu’ils 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 d’entre eux s’équipent en cas de danger de brassards, d’un harnais et de jambières en cuir (l’équivalent d’une armure légère), ou utilisent un petit bouclier.</p><p>Si vous jouez un homme-oiseau, vous pouvez choisir n’importe 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 l’homme-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 d’eunuques 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 d’antiques rituels alchimiques afin de servir de gardes à leurs maîtres (notamment contre d’autres magiciens), ces êtres possèdent une force surhumaine et n’ont besoin ni de manger, ni de dormir.</p><p>Leur corps est couvert de tatouages investis d’une puissante sorcellerie qui les maintient en vie. Ils sont asexués, même s’ils possèdent des corps musclés et proportionnés comme ceux d’hommes 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 n’ont 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 d’une grande capacité d’apprentissage 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 qu’ils sont eux-mêmes issus d’une création alchimique, les kalukans manifestent parfois un grand talent pour la création de potions, d’objets et d’instruments quand ils ont l’occasion d’apprendre cet art. Les kalukans ne peuvent pas être ménestrels, marchands ou courtisans, et d’autres carrières leur sont également difficiles d’accè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>D’ordinaire, les kalukans n’ont pas de nom, mais il arrive qu’ils 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 s’ils sont particulièrement grands et pâles de peau. Mais à mesure qu’ils 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 qu’un morgal ne prenne soin de les couper très régulièrement, il suffit d’une semaine pour que ses mains soient griffues comme celles d’une bête. Certains érudits pensent que les morgal seraient les rejetons d’une 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 l’homme. Ils possédaient une force et une robustesse exceptionnelles, même s’ils 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 d’Hadron et des autres seigneurs du Néant.</p><p>Les Rois-Sorciers furent détruits à la bataille du gouffre d’Hyrdral. Seuls quelques-uns d’entre eux parvinrent à s’enfuir 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é d’une 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
@ -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 d’entraî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 qu’une arbalète normale, l’arbalè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 d’arcs.</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 d’un 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. C’est une arme peu coûteuse et facile à fabriquer. Il existe une version plus puissante, montée au bout d’un 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 d’une courte hampe surmontée d’une 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 l’Axos.</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
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
BIN
fonts/IMFellDWPicaSC-Regular.ttf
Normal file
BIN
fonts/rpgawesome-webfont.eot
Normal file
523
fonts/rpgawesome-webfont.svg
Normal file
After Width: | Height: | Size: 634 KiB |
BIN
fonts/rpgawesome-webfont.ttf
Normal file
BIN
fonts/rpgawesome-webfont.woff
Normal file
BIN
fonts/skullz.ttf
Normal file
4
images/.directory
Normal 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
|
BIN
images/background_screen_01.webp
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
images/bol_alchimie.webp
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
images/bol_armes.webp
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
images/bol_armes_bonus.webp
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
images/bol_armures.webp
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
images/bol_creature.webp
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
images/bol_demon.webp
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
images/bol_difficulte.webp
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
images/bol_init.webp
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
images/bol_jetaction.webp
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
images/bol_pnj.webp
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
images/bol_portee.webp
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
images/bol_sorts.webp
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
images/langues_lemurie.webp
Normal file
After Width: | Height: | Size: 82 KiB |
BIN
images/map_lemurie.webp
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
images/plan_halakh.webp
Normal file
After Width: | Height: | Size: 2.1 MiB |
BIN
images/plan_satarla.webp
Normal file
After Width: | Height: | Size: 2.6 MiB |
BIN
images/plan_ucerb.webp
Normal file
After Width: | Height: | Size: 2.2 MiB |
BIN
images/plans_scenarios/camp_upscaled_01.jpg
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
images/plans_scenarios/echoppe_valtriz_upscaled_01.jpg
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
images/plans_scenarios/ennui_mortel_she_lang.webp
Normal file
After Width: | Height: | Size: 592 KiB |
BIN
images/plans_scenarios/lom.webp
Normal file
After Width: | Height: | Size: 240 KiB |
BIN
images/plans_scenarios/mariage_amer_sanctuaire.webp
Normal file
After Width: | Height: | Size: 312 KiB |
BIN
images/plans_scenarios/mariage_amer_temple_01.webp
Normal file
After Width: | Height: | Size: 298 KiB |
BIN
images/plans_scenarios/mariage_amer_temple_02.webp
Normal file
After Width: | Height: | Size: 255 KiB |
BIN
images/plans_scenarios/taverne_petit_toad_upscaled_01.jpg
Normal file
After Width: | Height: | Size: 1.9 MiB |
BIN
images/plans_scenarios/temple_upscaled_01.jpg
Normal file
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 904 KiB |
After Width: | Height: | Size: 556 KiB |
After Width: | Height: | Size: 546 KiB |
After Width: | Height: | Size: 574 KiB |
BIN
images/plans_scenarios/tour_ajaskhar_antre.webp
Normal file
After Width: | Height: | Size: 438 KiB |
BIN
images/plans_scenarios/tour_ajhaskar_MJ.webp
Normal file
After Width: | Height: | Size: 417 KiB |
BIN
images/plans_scenarios/trois_coffres_jardin.webp
Normal file
After Width: | Height: | Size: 472 KiB |
BIN
images/plans_scenarios/trois_coffres_puits.webp
Normal file
After Width: | Height: | Size: 940 KiB |
BIN
images/plans_scenarios/trois_coffres_roseraie.webp
Normal file
After Width: | Height: | Size: 520 KiB |
BIN
images/plans_scenarios/village_pygmee_rescaled_01.jpg
Normal file
After Width: | Height: | Size: 1.9 MiB |
BIN
images/vademecum.webp
Normal file
After Width: | Height: | Size: 78 KiB |
490
lang/de.json
Normal 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)"
|
||||
}
|
487
lang/en.json
@ -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)"
|
||||
}
|
600
lang/fr.json
@ -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)"
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
229
module/actor/vehicle-sheet.js
Normal 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;
|
||||
}
|
||||
}
|
181
module/bol.js
@ -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.");
|
||||
});
|
||||
|
803
module/controllers/bol-rolls.js
Normal 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)
|
||||
}
|
||||
|
||||
}
|
@ -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()]);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
620
module/system/adventure_data.json
Normal 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": "d’attaquer un lieu."
|
||||
},
|
||||
{
|
||||
"name": "de détruire un certain objet."
|
||||
},
|
||||
{
|
||||
"name": "de kidnapper quelqu’un."
|
||||
},
|
||||
{
|
||||
"name": "d’obtenir une certaine chose."
|
||||
},
|
||||
{
|
||||
"name": "d’explorer un lieu."
|
||||
},
|
||||
{
|
||||
"name": "de sauver une personne."
|
||||
},
|
||||
{
|
||||
"name": "d’échapper à quelqu’un."
|
||||
},
|
||||
{
|
||||
"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": "d’escorter 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": [
|
||||
"c’est le genre de choses que fait Krongar.",
|
||||
"sinon il finira en prison.",
|
||||
"il est victime d’un 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",
|
||||
"Sa’Tel",
|
||||
"Morgazzon",
|
||||
"Hurm",
|
||||
"Afyra",
|
||||
"Grondil",
|
||||
"Zaggath",
|
||||
"Zalkyr",
|
||||
"Fillana",
|
||||
"Lilandra",
|
||||
"Zylidith",
|
||||
"Quathoomar",
|
||||
"Iondal",
|
||||
"Piandra",
|
||||
"Nemmereth",
|
||||
"Charkond",
|
||||
"Karyzon",
|
||||
"Zarymphyxos",
|
||||
"Kryphondus"
|
||||
],
|
||||
"complique1": [
|
||||
"c’est 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 d’un 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 à l’accomplissement 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": [
|
||||
"d’un ancien secret.",
|
||||
"d’un long voyage.",
|
||||
"d’une malédiction.",
|
||||
"d’un voleur rusé.",
|
||||
"d’une forte troupe de soldats.",
|
||||
"d’un énorme monstre.",
|
||||
"d’une horde de monstres.",
|
||||
"d’un manque de temps.",
|
||||
"de gardes et de pièges magiques.",
|
||||
"d’une catastrophe naturelle sur le point de se produire.",
|
||||
"d’une énigme à résoudre.",
|
||||
"d’une bataille à gagner."
|
||||
],
|
||||
"retournement": [
|
||||
"L’ennemi est en fait Krongar lui-même, venu d’une autre réalité !",
|
||||
"Toute cette histoire était un piège machiavélique !",
|
||||
"L’ennemi est en fait un vieil ami ou un allié qui a comploté dans l’ombre !",
|
||||
"Krongar est contraint de s’associer à un rival pour accomplir la mission !",
|
||||
"Tout ce qui semblait ordinaire se révèle en fait surnaturel !",
|
||||
"L’ennemi 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 n’y a pas de retournement de situation !",
|
||||
"i la mission est accomplie, cela entraînera de terribles répercussions !",
|
||||
"Le destin offre à Krongar une chance d’améliorer les choses, et il est renvoyé dans le temps au début de l’aventure. 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 s’est joué de lui !",
|
||||
"Beaucoup moins qu’escompté.",
|
||||
"Beaucoup moins qu’escompté, mais il gagne au moins la reconnaissance d’une personne haut placée.",
|
||||
"Beaucoup moins qu’escompté, 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 d’une personne haut placée.",
|
||||
"Plus qu’escompté.",
|
||||
"Plus qu’escompté, ainsi que la reconnaissance d’une personne haut placée.",
|
||||
"Plus qu’escompté, et il est marqué par les dieux (avantage).",
|
||||
"Plus qu’escompté, ainsi que la reconnaissance d’une personne haut placée, et il est marqué par les dieux (avantage).",
|
||||
"Une promotion... Longue vie au roi Krongar !"
|
||||
]
|
||||
}
|
96
module/system/bol-action-hud.js
Normal 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'))
|
||||
}
|
||||
}
|
86
module/system/bol-adventure-generator.js
Normal 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})
|
||||
})
|
||||
|
||||
}
|
||||
}
|
466
module/system/bol-calendar.js
Normal 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
162
module/system/bol-character-summary.js
Normal 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 )
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
84
module/system/bol-combat.js
Normal 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()
|
||||
}
|
||||
|
||||
}
|
||||
|
110
module/system/bol-commands.js
Normal 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;
|
||||
}
|
||||
|
||||
}
|
67
module/system/bol-hotbar.js
Normal 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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
756
module/system/bol-utility.js
Normal 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()
|
||||
}
|
||||
}
|
@ -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;
|
@ -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);
|
||||
});
|
||||
|
||||
}
|
@ -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
@ -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);
|
||||
}
|
||||
}
|
||||
}
|