Compare commits
24 Commits
f487908ecd
...
13.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
| e7a6c15bf7 | |||
| 1909ff443d | |||
| c72c9d8b02 | |||
| 536812e871 | |||
| 66fe1418f0 | |||
| 901df5b395 | |||
| f5d84832f3 | |||
| 216360e0d8 | |||
| a0502dc467 | |||
| c8b94b74a1 | |||
| c9e4f125b4 | |||
| e840b70ac9 | |||
| 03b8779862 | |||
| 580a2ccaba | |||
| 699dba5511 | |||
| aac552102a | |||
| 4762dc33ac | |||
| 0a030460e4 | |||
| ed2dc58680 | |||
| 9c20f277ea | |||
| 2a8617d781 | |||
| 91ad26730a | |||
| e1816b3dd7 | |||
| c48401a199 |
63
.gitea/workflows/release.yaml
Normal file
63
.gitea/workflows/release.yaml
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
# 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 system.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/${{gitea.repository}}
|
||||||
|
manifest: https://www.uberwald.me/gitea/public/fvtt-mournblade/releases/download/latest/system.json
|
||||||
|
download: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/fvtt-mournblade.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 ./fvtt-mournblade.zip system.json README.md LICENSE assets/ lang/ modules/ packs/ styles/ templates/ template.json
|
||||||
|
|
||||||
|
- 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: |-
|
||||||
|
./fvtt-mournblade.zip
|
||||||
|
system.json
|
||||||
|
api_key: '${{secrets.ALLOW_PUSH_RELEASE}}'
|
||||||
|
|
||||||
|
- name: Publish to Foundry server
|
||||||
|
uses: https://github.com/djlechuck/foundryvtt-publish-package-action@v1
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.FOUNDRYVTT_RELEASE_TOKEN }}
|
||||||
|
id: 'fvtt-mournblade'
|
||||||
|
version: ${{github.event.release.tag_name}}
|
||||||
|
manifest: 'https://www.uberwald.me/gitea/public/fvtt-mournblade/releases/download/latest/system.json'
|
||||||
|
notes: 'https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/fvtt-mournblade.zip'
|
||||||
|
compatibility-minimum: '13'
|
||||||
|
compatibility-verified: '13'
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
.history/
|
.history/
|
||||||
|
node_modules
|
||||||
|
|||||||
BIN
assets/ui/landing_page_mournblade.webp
Normal file
BIN
assets/ui/landing_page_mournblade.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 380 KiB |
35
gulpfile.js
Normal file
35
gulpfile.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
const gulp = require('gulp');
|
||||||
|
const less = require('gulp-less');
|
||||||
|
const sourcemaps = require('gulp-sourcemaps');
|
||||||
|
|
||||||
|
// Paths
|
||||||
|
const paths = {
|
||||||
|
styles: {
|
||||||
|
src: 'less/**/*.less',
|
||||||
|
dest: 'styles/'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Compile LESS to CSS
|
||||||
|
function styles() {
|
||||||
|
return gulp.src('less/mournblade.less')
|
||||||
|
.pipe(sourcemaps.init())
|
||||||
|
.pipe(less())
|
||||||
|
.pipe(sourcemaps.write('.'))
|
||||||
|
.pipe(gulp.dest(paths.styles.dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch files
|
||||||
|
function watchFiles() {
|
||||||
|
gulp.watch(paths.styles.src, styles);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define complex tasks
|
||||||
|
const build = gulp.series(styles);
|
||||||
|
const watch = gulp.series(build, watchFiles);
|
||||||
|
|
||||||
|
// Export tasks
|
||||||
|
exports.styles = styles;
|
||||||
|
exports.build = build;
|
||||||
|
exports.watch = watch;
|
||||||
|
exports.default = build;
|
||||||
203
lang/en.json
Normal file
203
lang/en.json
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
{
|
||||||
|
"Adresse": "Agility",
|
||||||
|
"Clairvoyance": "Clarity",
|
||||||
|
"MNBL.abilities": "Gifts/Pacts",
|
||||||
|
"MNBL.activatedrunes": "Activated Runes",
|
||||||
|
"MNBL.addpredilection": "Add a specialization",
|
||||||
|
"MNBL.aimingbonus": "Aiming Bonus",
|
||||||
|
"MNBL.alignement": "Alignment",
|
||||||
|
"MNBL.all": "All",
|
||||||
|
"MNBL.allegiance": "Allegiance",
|
||||||
|
"MNBL.applydamage": "Apply damage/bonus/penalty",
|
||||||
|
"MNBL.aspect": "Aspect",
|
||||||
|
"MNBL.Assaut": "Smite",
|
||||||
|
"MNBL.attack": "Attack",
|
||||||
|
"MNBL.attackcapacity": "Offensive Ability",
|
||||||
|
"MNBL.attackmountbonus": "Mounted attacker vs ground defender (+5)",
|
||||||
|
"MNBL.attacks": "Attacks",
|
||||||
|
"MNBL.attribut": "Attribute",
|
||||||
|
"MNBL.attributes": "Attributes",
|
||||||
|
"MNBL.automalus": "Auto Penalty",
|
||||||
|
"MNBL.base": "Base",
|
||||||
|
"MNBL.beastslords": "Beast Lords",
|
||||||
|
"MNBL.bio": "Bio & Notes",
|
||||||
|
"MNBL.bonus": "Bonus",
|
||||||
|
"MNBL.candoublebonusskill": "Bonuses can be doubled (cf. Profession)",
|
||||||
|
"MNBL.chaos": "Chaos",
|
||||||
|
"MNBL.chaotictraits": "Chaotic Traits",
|
||||||
|
"MNBL.charge": "Charge",
|
||||||
|
"MNBL.consumed": "Consumed",
|
||||||
|
"MNBL.contain": "Contain the opponent",
|
||||||
|
"MNBL.creatureresourcecost": "Resource Cost (creatures)",
|
||||||
|
"MNBL.current": "Current",
|
||||||
|
"MNBL.currentmax": "Current Max",
|
||||||
|
"MNBL.damage": "Damage",
|
||||||
|
"MNBL.damagebonus": "Damage Bonus",
|
||||||
|
"MNBL.defense": "Defense",
|
||||||
|
"MNBL.defensebonus": "Defense Bonus",
|
||||||
|
"MNBL.defensecapacity": "Defensive Ability",
|
||||||
|
"MNBL.dice": "Dice",
|
||||||
|
"MNBL.difficulty": "Difficulty",
|
||||||
|
"MNBL.dirtyattack": "Cheap Shot",
|
||||||
|
"MNBL.disadvantagepositions": "Disadvantageous positions (Max bonus +15)",
|
||||||
|
"MNBL.disarm": "Disarm",
|
||||||
|
"MNBL.doubleD20": "Double d20 (1 Shard Point)",
|
||||||
|
"MNBL.dramaticfailure": "Dramatic Failure",
|
||||||
|
"MNBL.duration": "Duration",
|
||||||
|
"MNBL.easy": "Easy (5)",
|
||||||
|
"MNBL.eclat": "Shard",
|
||||||
|
"MNBL.elementslords": "Elemental Lords",
|
||||||
|
"MNBL.equipmentactions": "Equipment/Actions",
|
||||||
|
"MNBL.equipments": "Equipments",
|
||||||
|
"MNBL.equipped": "Equipped",
|
||||||
|
"MNBL.exp": "Experience",
|
||||||
|
"MNBL.eyes": "Eyes",
|
||||||
|
"MNBL.failure": "Failure",
|
||||||
|
"MNBL.feint": "Feint",
|
||||||
|
"MNBL.flee": "Flee",
|
||||||
|
"MNBL.formula": "Formula",
|
||||||
|
"MNBL.genre": "Gender",
|
||||||
|
"MNBL.gifts": "Gifts",
|
||||||
|
"MNBL.goodadventure": "Good Adventure",
|
||||||
|
"MNBL.hair": "Hair",
|
||||||
|
"MNBL.hard": "Hard (15)",
|
||||||
|
"MNBL.hascover": "Cover",
|
||||||
|
"MNBL.hazardous": "Tricky (20)",
|
||||||
|
"MNBL.health": "Health",
|
||||||
|
"MNBL.healthmalus": "Health Penalty",
|
||||||
|
"MNBL.heavycover": "Almost complete (-10)",
|
||||||
|
"MNBL.heroicsuccess": "Heroic Success",
|
||||||
|
"MNBL.highlanguage": "High Melnibonéan",
|
||||||
|
"MNBL.ignorearmor": "Ignore Armor",
|
||||||
|
"MNBL.ignorehealthmalus": "Ignore Health Penalty",
|
||||||
|
"MNBL.ignoresoulmalus": "Ignore Soul Penalty",
|
||||||
|
"MNBL.immobilize": "Immobilize",
|
||||||
|
"MNBL.insane": "Ridiculous (25)",
|
||||||
|
"MNBL.isdefense": "Defensive",
|
||||||
|
"MNBL.knockout": "Knock Out",
|
||||||
|
"MNBL.law": "Law",
|
||||||
|
"MNBL.legacy": "Legacy",
|
||||||
|
"MNBL.lessthanshort": "Less than short (10)",
|
||||||
|
"MNBL.lethal": "Lethal",
|
||||||
|
"MNBL.level": "Level",
|
||||||
|
"MNBL.lightcover": "Buckler or light (-2)",
|
||||||
|
"MNBL.longmore": "Long and more (25)",
|
||||||
|
"MNBL.longrange": "Long Range",
|
||||||
|
"MNBL.malus": "Penalty",
|
||||||
|
"MNBL.margin": "Margin",
|
||||||
|
"MNBL.medium": "Average (10)",
|
||||||
|
"MNBL.mediumcover": "Pavise or half (-5)",
|
||||||
|
"MNBL.mediummore": "Medium and more (20)",
|
||||||
|
"MNBL.mediumrange": "Medium Range",
|
||||||
|
"MNBL.meleethrowweapon": "Melee and Throwing Weapon",
|
||||||
|
"MNBL.meleeweapon": "Melee Weapon",
|
||||||
|
"MNBL.mode": "Mode",
|
||||||
|
"MNBL.modifier": "Modifiers",
|
||||||
|
"MNBL.modifiertype": "Modifier Type",
|
||||||
|
"MNBL.mounted": "Mounted",
|
||||||
|
"MNBL.nextactionmalus": "Penalty for next action",
|
||||||
|
"MNBL.nextattackbonus": "Bonus for next attack",
|
||||||
|
"MNBL.none": "None",
|
||||||
|
"MNBL.noneunknwon": "None/Unknown",
|
||||||
|
"MNBL.nonlethal": "Non-Lethal",
|
||||||
|
"MNBL.nonlethaldamage": "Non-Lethal Damage",
|
||||||
|
"MNBL.notarget": "No designated target",
|
||||||
|
"MNBL.origin": "Origin",
|
||||||
|
"MNBL.pacts": "Pacts",
|
||||||
|
"MNBL.points": "Points",
|
||||||
|
"MNBL.preciseattack": "Precision Attack",
|
||||||
|
"MNBL.predilections": "Specializations",
|
||||||
|
"MNBL.preferredhand": "Preferred Hand",
|
||||||
|
"MNBL.prerequisites": "Prerequisites",
|
||||||
|
"MNBL.price": "Price",
|
||||||
|
"MNBL.profession": "Profession",
|
||||||
|
"MNBL.pronounced": "Spoken",
|
||||||
|
"MNBL.pronouncedrune": "Spoken Rune",
|
||||||
|
"MNBL.pronouncerune": "Speak the rune",
|
||||||
|
"MNBL.protections": "Protections",
|
||||||
|
"MNBL.puremadness": "Insane (30)",
|
||||||
|
"MNBL.quantity": "Quantity",
|
||||||
|
"MNBL.range": "Range",
|
||||||
|
"MNBL.rarity": "Rarity",
|
||||||
|
"MNBL.registeredmodifiers": "Registered Modifiers",
|
||||||
|
"MNBL.reloadduration": "Reload Time",
|
||||||
|
"MNBL.ressources": "Resources",
|
||||||
|
"MNBL.roll": "Roll",
|
||||||
|
"MNBL.runes": "Runes",
|
||||||
|
"MNBL.runningtarget": "Running target (-5/-10 depending on range)",
|
||||||
|
"MNBL.shootmodifier": "Shooting Modifiers",
|
||||||
|
"MNBL.shootweapon": "Shoot Weapon",
|
||||||
|
"MNBL.shortmore": "Short and more (10)",
|
||||||
|
"MNBL.shortrange": "Short Range",
|
||||||
|
"MNBL.size": "Size",
|
||||||
|
"MNBL.skill": "Skill",
|
||||||
|
"MNBL.skills": "Skills",
|
||||||
|
"MNBL.smallroomtarget": "Target in confined space (+5)",
|
||||||
|
"MNBL.soul": "Soul",
|
||||||
|
"MNBL.soulmalus": "Soul Penalty",
|
||||||
|
"MNBL.soulmultiplier": "Soul Multiplier",
|
||||||
|
"MNBL.soulpoints": "Soul Points",
|
||||||
|
"MNBL.specialactions": "Special Actions",
|
||||||
|
"MNBL.specialweapon": "Special (ability/gift)",
|
||||||
|
"MNBL.speciestrait": "Species Trait",
|
||||||
|
"MNBL.speed": "Speed",
|
||||||
|
"MNBL.success": "Success",
|
||||||
|
"MNBL.target": "Target",
|
||||||
|
"MNBL.targetbelow": "Target below (+5)",
|
||||||
|
"MNBL.targetcantmove": "Target immobilized (+5)",
|
||||||
|
"MNBL.targetdefense": "Opponent's Defense",
|
||||||
|
"MNBL.targetground": "Target on the ground (+5)",
|
||||||
|
"MNBL.targetseeshoot": "Target is aware of the shot",
|
||||||
|
"MNBL.tendancies": "Tendencies",
|
||||||
|
"MNBL.throwweapon": "Throwing Weapon",
|
||||||
|
"MNBL.totalprotection": "Total Protection",
|
||||||
|
"MNBL.traced": "Written",
|
||||||
|
"MNBL.tracedrune": "Written Rune",
|
||||||
|
"MNBL.tracerune": "Write the rune",
|
||||||
|
"MNBL.treasuremoney": "Treasures and Money",
|
||||||
|
"MNBL.twohands": "Two-handed",
|
||||||
|
"MNBL.type": "Type",
|
||||||
|
"MNBL.unarmedtarget": "Unarmed target (+5)",
|
||||||
|
"MNBL.unit": "Unit",
|
||||||
|
"MNBL.use": "Use",
|
||||||
|
"MNBL.usedpredilection": "Used Predilection",
|
||||||
|
"MNBL.value": "Value",
|
||||||
|
"MNBL.weapon": "Weapon",
|
||||||
|
"MNBL.weaponbonusattack": "Handling Bonus (offensive)",
|
||||||
|
"MNBL.weaponbonusdefense": "Handling Bonus (defensive)",
|
||||||
|
"MNBL.weapons": "Weapons",
|
||||||
|
"MNBL.weaponscapacities": "Weapons/Abilities",
|
||||||
|
"MNBL.weapontype": "Weapon Type",
|
||||||
|
"MNBL.weight": "Weight",
|
||||||
|
"MNBL.total": "Total",
|
||||||
|
|
||||||
|
"Présence": "Presence",
|
||||||
|
"Puissance": "Might",
|
||||||
|
"Trempe": "Mettle",
|
||||||
|
"TYPES": {
|
||||||
|
"Actor": {
|
||||||
|
"creature": "Creature",
|
||||||
|
"personnage": "Character"
|
||||||
|
},
|
||||||
|
"Item": {
|
||||||
|
"arme": "Weapon",
|
||||||
|
"bouclier": "Shield",
|
||||||
|
"capacite": "Ability",
|
||||||
|
"competence": "Skill",
|
||||||
|
"don": "Gifts",
|
||||||
|
"equipement": "Equipment",
|
||||||
|
"heritage": "Background",
|
||||||
|
"metier": "Profession",
|
||||||
|
"modifier": "Modifier",
|
||||||
|
"monnaie": "Currency",
|
||||||
|
"origine": "Origin",
|
||||||
|
"pacte": "Pacts",
|
||||||
|
"protection": "Protections",
|
||||||
|
"rune": "Rune",
|
||||||
|
"runeeffect": "Rune Effect",
|
||||||
|
"tendance": "Signs of Chaos",
|
||||||
|
"traitchaotique": "Background",
|
||||||
|
"traitespece": "Species Trait"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
241
lang/fr.json
241
lang/fr.json
@@ -1,27 +1,224 @@
|
|||||||
{
|
{
|
||||||
"ACTOR": {
|
"TYPES": {
|
||||||
"TypePersonnage": "Personnage",
|
"Actor": {
|
||||||
"TypePNJ": "PNJ"
|
"personnage": "Personnage",
|
||||||
|
"creature": "Créature"
|
||||||
},
|
},
|
||||||
|
"Item": {
|
||||||
|
"arme": "Arme",
|
||||||
|
"competence": "Compétence",
|
||||||
|
"protection": "Protection",
|
||||||
|
"pacte": "Pacte",
|
||||||
|
"traitchaotique": "Trait Chaotique",
|
||||||
|
"monnaie": "Monnaie",
|
||||||
|
"don": "Don",
|
||||||
|
"tendance": "Tendance",
|
||||||
|
"rune": "Rune",
|
||||||
|
"equipement": "Equipement",
|
||||||
|
"capacite": "Capacité",
|
||||||
|
"origine": "Origine",
|
||||||
|
"heritage": "Héritage",
|
||||||
|
"metier": "Métier",
|
||||||
|
"runeeffect": "Effet de Rune",
|
||||||
|
"bouclier": "Bouclier",
|
||||||
|
"modifier": "Modificateur",
|
||||||
|
"traitespece": "Trait d'Espèce"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Adresse": "Adresse",
|
||||||
|
"Puissance": "Puissance",
|
||||||
|
"Clairvoyance": "Clairvoyance",
|
||||||
|
"Présence": "Présence",
|
||||||
|
"Trempe": "Trempe",
|
||||||
|
|
||||||
"ITEM": {
|
"MNBL.assaut": "Assaut",
|
||||||
"TypeArme": "Arme",
|
"MNBL.preciseattack": "Attaque Précise",
|
||||||
"TypeCompetence": "Compétence",
|
"MNBL.feint": "Feinte",
|
||||||
"TypeProtection": "Protection",
|
"MNBL.dirtyattack": "Coup Bas",
|
||||||
"TypePacte": "Pacte",
|
"MNBL.charge": "Charger",
|
||||||
"TypeTraitchaotique": "Trait Chaotique",
|
"MNBL.contain": "Contenir l'adversaire",
|
||||||
"TypeMonnaie": "Monnaie",
|
"MNBL.disarm": "Désarmer",
|
||||||
"TypeDon": "Don",
|
|
||||||
"TypeTendance": "Tendance",
|
"MNBL.none": "Aucun",
|
||||||
"TypeRune": "Rune",
|
"MNBL.lightcover": "Rondache ou léger (-2)",
|
||||||
"TypeEquipement": "Equipement",
|
"MNBL.mediumcover": "Pavois ou à moitié (-5)",
|
||||||
"TypeCapacite": "Capacité",
|
"MNBL.heavycover": "Quasi complet (-10)",
|
||||||
"TypeOrigine": "Origine",
|
"MNBL.roll": "Jet",
|
||||||
"TypeHeritage": "Héritage",
|
"MNBL.defensecapacity": "Capacité défensive",
|
||||||
"TypeMetier": "Métier",
|
"MNBL.attackcapacity": "Capacité offensive",
|
||||||
"TypeRuneeffect": "Effet de Rune",
|
|
||||||
"TypeBouclier": "Bouclier"
|
"MNBL.lessthanshort": "Moins que courte (10)",
|
||||||
|
"MNBL.shortmore": "Courte et + (10)",
|
||||||
}
|
"MNBL.mediummore": "Moyenne et + (20)",
|
||||||
|
"MNBL.longmore": "Longue et + (25)",
|
||||||
|
|
||||||
|
"MNBL.noneunknwon": "Aucune/Inconnue",
|
||||||
|
"MNBL.easy": "Facile (5)",
|
||||||
|
"MNBL.medium": "Moyenne (10)",
|
||||||
|
"MNBL.hard": "Ardue (15)",
|
||||||
|
"MNBL.hazardous": "Hasardeuse (20)",
|
||||||
|
"MNBL.insane": "Insensée (25)",
|
||||||
|
"MNBL.puremadness": "Pure Folie (30)",
|
||||||
|
|
||||||
|
"MNBL.pronouncerune": "Prononcer la rune",
|
||||||
|
"MNBL.tracerune": "Tracer la rune",
|
||||||
|
"MNBL.pronounced": "Prononcée",
|
||||||
|
"MNBL.traced": "Tracée",
|
||||||
|
|
||||||
|
"MNBL.meleeweapon": "Arme de contact",
|
||||||
|
"MNBL.meleethrowweapon": "Arme de contact et de Jet",
|
||||||
|
"MNBL.throwweapon": "Arme de Lancer",
|
||||||
|
"MNBL.shootweapon": "Arme de Tir",
|
||||||
|
"MNBL.specialweapon": "Spécial (capacité/don)",
|
||||||
|
|
||||||
|
"MNBL.all": "Tous",
|
||||||
|
"MNBL.beastslords": "Seigneurs des Bêtes",
|
||||||
|
"MNBL.elementslords": "Seigneurs Elementaires",
|
||||||
|
|
||||||
|
"MNBL.law": "Loi",
|
||||||
|
"MNBL.chaos": "Chaos",
|
||||||
|
"MNBL.level": "Niveau",
|
||||||
|
"MNBL.points": "Points",
|
||||||
|
"MNBL.aspect": "Aspect",
|
||||||
|
"MNBL.margin": "Marge",
|
||||||
|
"MNBL.goodadventure" : "Bonne Aventure",
|
||||||
|
"MNBL.base": "Base",
|
||||||
|
"MNBL.current": "Actuelle",
|
||||||
|
"MNBL.alignement" : "Alignement",
|
||||||
|
"MNBL.eclat": "Eclat",
|
||||||
|
"MNBL.exp": "Expérience",
|
||||||
|
"MNBL.attributes": "Attributs",
|
||||||
|
"MNBL.skills": "Compétences",
|
||||||
|
"MNBL.abilities": "Dons/Pactes",
|
||||||
|
"MNBL.equipmentactions": "Equipements/Actions",
|
||||||
|
"MNBL.bio": "Bio&Notes",
|
||||||
|
"MNBL.health": "Santé",
|
||||||
|
"MNBL.bonus": "Bonus",
|
||||||
|
"MNBL.malus": "Malus",
|
||||||
|
"MNBL.nonlethal": "Non Létaux",
|
||||||
|
"MNBL.lethal": "Létaux",
|
||||||
|
"MNBL.automalus" : "Malus Auto",
|
||||||
|
"MNBL.soul": "Ame",
|
||||||
|
"MNBL.currentmax": "Max Actuel",
|
||||||
|
"MNBL.consumed": "Consommé",
|
||||||
|
"MNBL.damagebonus": "B. Dégats",
|
||||||
|
"MNBL.speed": "Vitesse",
|
||||||
|
"MNBL.defense": "Défense",
|
||||||
|
"MNBL.totalprotection": "Protection Totale",
|
||||||
|
"MNBL.modifier": "Modificateurs",
|
||||||
|
"MNBL.type": "Type",
|
||||||
|
"MNBL.value": "Valeur",
|
||||||
|
"MNBL.gifts": "Dons",
|
||||||
|
"MNBL.allegiance": "Allégeance",
|
||||||
|
"MNBL.pacts": "Pactes",
|
||||||
|
"MNBL.runes": "Runes",
|
||||||
|
"MNBL.highlanguage": "Haut Parler",
|
||||||
|
"MNBL.difficulty": "Difficulté",
|
||||||
|
"MNBL.tendancies": "Tendances",
|
||||||
|
"MNBL.chaotictraits": "Traits Chaotique",
|
||||||
|
"MNBL.activatedrunes": "Runes actives",
|
||||||
|
"MNBL.mode": "Mode",
|
||||||
|
"MNBL.duration": "Durée",
|
||||||
|
"MNBL.treasuremoney": "Richesses et Argent",
|
||||||
|
"MNBL.quantity": "Quantité",
|
||||||
|
"MNBL.unit": "Unité",
|
||||||
|
"MNBL.specialactions": "Actions spéciales",
|
||||||
|
"MNBL.knockout": "Assomer",
|
||||||
|
"MNBL.flee": "Fuir",
|
||||||
|
"MNBL.immobilize": "Immobiliser",
|
||||||
|
"MNBL.mounted": "Monté",
|
||||||
|
"MNBL.weapons": "Armes",
|
||||||
|
"MNBL.attack": "Attaque",
|
||||||
|
"MNBL.damage": "Dégats",
|
||||||
|
"MNBL.protections": "Protections",
|
||||||
|
"MNBL.equipments": "Equipements",
|
||||||
|
"MNBL.equipment": "Equipement",
|
||||||
|
"MNBL.origin": "Origine",
|
||||||
|
"MNBL.legacy": "Héritage",
|
||||||
|
"MNBL.profession": "Métier",
|
||||||
|
"MNBL.genre": "Genre",
|
||||||
|
"MNBL.size": "Taille",
|
||||||
|
"MNBL.hair": "Cheveux",
|
||||||
|
"MNBL.eyes": "Yeux",
|
||||||
|
"MNBL.preferredhand": "Main Préférée",
|
||||||
|
"MNBL.weight": "Poids",
|
||||||
|
"MNBL.soulmultiplier": "Multiplicateur d'âme",
|
||||||
|
"MNBL.ignorehealthmalus": "Ignore le malus de santé",
|
||||||
|
"MNBL.ignoresoulmalus": "Ignore le malus d'âme",
|
||||||
|
|
||||||
|
"MNBL.weapon": "Arme",
|
||||||
|
"MNBL.nextattackbonus": "Bonus pour prochaine attaque",
|
||||||
|
"MNBL.nextactionmalus": "Malus au défenseur pour prochaine action",
|
||||||
|
"MNBL.applydamage": "Appliquer les dégats/bonus/malus",
|
||||||
|
"MNBL.attribut": "Attribut",
|
||||||
|
"MNBL.skill": "Compétence",
|
||||||
|
"MNBL.target": "Cible",
|
||||||
|
"MNBL.usedpredilection": "Prédilection utilisée",
|
||||||
|
"MNBL.soulpoints": "Points d'âme",
|
||||||
|
"MNBL.formula": "Formule",
|
||||||
|
"MNBL.dice":"Dé",
|
||||||
|
"MNBL.success": "Succés",
|
||||||
|
"MNBL.failure": "Echec",
|
||||||
|
"MNBL.heroicsuccess": "Succés Héroïque",
|
||||||
|
"MNBL.dramaticfailure": "Echec Dramatique",
|
||||||
|
|
||||||
|
"MNBL.attackmountbonus": "Attaquant monté vs def. au sol (+5)",
|
||||||
|
"MNBL.targetdefense": "Défense adversaire",
|
||||||
|
"MNBL.shootmodifier": "Modificateurs de Tir",
|
||||||
|
"MNBL.aimingbonus": "Bonus de visée",
|
||||||
|
"MNBL.targetseeshoot": "La cible est consciente du tir",
|
||||||
|
"MNBL.notarget": "Pas de cible désignée",
|
||||||
|
"MNBL.runningtarget": "La cible court (-5/-10 selon portée)",
|
||||||
|
"MNBL.hascover": "Couvert",
|
||||||
|
"MNBL.range": "Portée",
|
||||||
|
"MNBL.disadvantagepositions": "Positions désavantageuses (Bonus max +15)",
|
||||||
|
"MNBL.targetground": "Cible au sol (+5)",
|
||||||
|
"MNBL.unarmedtarget": "Cible désarmée (+5)",
|
||||||
|
"MNBL.smallroomtarget": "Cible en espace restreint (+5)",
|
||||||
|
"MNBL.targetcantmove": "Cible immobilisée (+5)",
|
||||||
|
"MNBL.targetbelow": "Cible surplombée (+5)",
|
||||||
|
"MNBL.healthmalus": "Malus de santé",
|
||||||
|
"MNBL.soulmalus": "Malus d'âme",
|
||||||
|
"MNBL.registeredmodifiers": "Modificateurs enregistrés",
|
||||||
|
"MNBL.doubleD20": "Doubler le d20 (1 Point d'Eclat)",
|
||||||
|
|
||||||
|
"MNBL.pronouncedrune": "Rune prononcée",
|
||||||
|
"MNBL.tracedrune": "Rune tracée",
|
||||||
|
"MNBL.equipped": "Equipé",
|
||||||
|
"MNBL.rarity": "Rareté",
|
||||||
|
"MNBL.price": "Prix",
|
||||||
|
"MNBL.modifiertype": "Type de modificateur",
|
||||||
|
"MNBL.prerequisites": "Prérequis",
|
||||||
|
"MNBL.predilections": "Prédilections",
|
||||||
|
"MNBL.candoublebonusskill": "Les bonus de Bonne Aventure et d'Eclat peuvent être doublés (cf. Métier)",
|
||||||
|
"MNBL.addpredilection": "Ajouter une prédilection",
|
||||||
|
"MNBL.defensebonus": "Bonus de défense",
|
||||||
|
"MNBL.nonlethaldamage": "Dégâts non létaux",
|
||||||
|
"MNBL.weapontype": "Type d'arme",
|
||||||
|
"MNBL.weaponbonusattack": "Bonus de maniement (offensif)",
|
||||||
|
"MNBL.weaponbonusdefense": "Bonus de maniement (défensif)",
|
||||||
|
"MNBL.isdefense": "Défensive",
|
||||||
|
"MNBL.twohands": "A deux mains",
|
||||||
|
"MNBL.ignorearmor": "Ignore l'armure",
|
||||||
|
"MNBL.creatureresourcecost": "Cout en Ressources (créatures)",
|
||||||
|
"MNBL.shortrange": "Portée courte",
|
||||||
|
"MNBL.mediumrange":"Portée moyenne",
|
||||||
|
"MNBL.longrange":"Portée longue",
|
||||||
|
"MNBL.reloadduration": "Temps de rechargement",
|
||||||
|
"MNBL.attacks": "Attaques",
|
||||||
|
"MNBL.ressources": "Ressources",
|
||||||
|
"MNBL.weaponscapacities": "Armes/Capacités",
|
||||||
|
"MNBL.use": "Utiliser",
|
||||||
|
"MNBL.speciestrait": "Trait d'espèce",
|
||||||
|
|
||||||
|
"MNBL.attribute": "Attribut",
|
||||||
|
"MNBL.Protections": "Protections",
|
||||||
|
"MNBL.rune": "Rune",
|
||||||
|
"MNBL.total": "Total",
|
||||||
|
"MNBL.description": "Description",
|
||||||
|
"MNBL.details": "Détails",
|
||||||
|
"MNBL.sacrifice": "Sacrifice",
|
||||||
|
"MNBL.identity": "Identité",
|
||||||
|
"MNBL.gmtools": "Outils MJ"
|
||||||
|
|
||||||
}
|
}
|
||||||
874
less/actor-styles.less
Normal file
874
less/actor-styles.less
Normal file
@@ -0,0 +1,874 @@
|
|||||||
|
/* ==================== Actor Sheet Styles ==================== */
|
||||||
|
|
||||||
|
// NOTE: Ce fichier surcharge certaines règles de simple-converted.less
|
||||||
|
// Les sélecteurs .fvtt-mournblade.actor sont plus spécifiques et prennent priorité
|
||||||
|
|
||||||
|
.fvtt-mournblade.actor {
|
||||||
|
// Background pour toute la fiche d'acteur
|
||||||
|
background: url("../assets/ui/pc_sheet_bg.webp") repeat;
|
||||||
|
|
||||||
|
// AppV2 - Structure flex pour permettre le scroll
|
||||||
|
.window-content {
|
||||||
|
height: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main form structure
|
||||||
|
form,
|
||||||
|
.sheet-form-layout {
|
||||||
|
height: 100%;
|
||||||
|
background: url("../assets/ui/pc_sheet_bg.webp") repeat-y;
|
||||||
|
color: black;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
// La section racine du template (if nested inside form, or simple direct children handling)
|
||||||
|
> section {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SURCHARGE: simple-converted.less définit flex: 0 0 210px
|
||||||
|
.sheet-header {
|
||||||
|
background: url("../assets/ui/pc_sheet_bg.webp") repeat;
|
||||||
|
padding: 0.5rem;
|
||||||
|
margin: 0;
|
||||||
|
flex: 0 0 auto !important; // Override simple-converted
|
||||||
|
overflow: visible !important; // Override simple-converted
|
||||||
|
|
||||||
|
.background-sheet-header {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-main-content {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-stats-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 2fr 1fr 1fr;
|
||||||
|
gap: 0.75rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
background: rgba(0, 0, 0, 0.15);
|
||||||
|
border: 2px solid rgba(139, 69, 19, 0.5);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.3rem;
|
||||||
|
padding: 0.35rem 0.6rem;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
border: 1px solid rgba(139, 69, 19, 0.4);
|
||||||
|
border-radius: 3px;
|
||||||
|
|
||||||
|
&.stat-group-health {
|
||||||
|
border-left: 3px solid rgba(200, 0, 0, 0.6);
|
||||||
|
background: rgba(40, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-title {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #f5e6d3;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 0 0.3rem 0;
|
||||||
|
border-bottom: 1px solid rgba(139, 69, 19, 0.5);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
font-family: "CentaurMT", serif;
|
||||||
|
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-values {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 0.5rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.2rem;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
color: #d4c5b0;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: 600;
|
||||||
|
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #fff;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
border: 1px solid rgba(139, 69, 19, 0.6);
|
||||||
|
border-radius: 3px;
|
||||||
|
min-width: 2.5rem;
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-input {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 0.25rem 0.4rem;
|
||||||
|
background: rgba(40, 30, 20, 0.7);
|
||||||
|
border: 1px solid rgba(139, 69, 19, 0.7);
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 3px;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 2.5rem;
|
||||||
|
max-width: 100%;
|
||||||
|
width: 100%;
|
||||||
|
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
|
||||||
|
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||||
|
|
||||||
|
&.stat-input-single {
|
||||||
|
min-width: 3.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.stat-input-damage {
|
||||||
|
border-color: rgba(200, 0, 0, 0.8);
|
||||||
|
background: rgba(80, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(60, 45, 30, 0.8);
|
||||||
|
border-color: rgba(255, 102, 0, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: rgba(255, 102, 0, 1);
|
||||||
|
box-shadow: 0 0 6px rgba(255, 102, 0, 0.5), inset 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||||
|
background: rgba(70, 50, 35, 0.9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-fields {
|
||||||
|
h4.item-name-label.competence-name {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
padding-top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-name-label.competence-name {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
label.item-name-label.competence-name {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-field-label-short {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-small-label {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sheet navigation tabs
|
||||||
|
// SURCHARGE: simple-converted.less définit flex: 0
|
||||||
|
.sheet-tabs {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
flex: 0 0 auto !important; // Override simple-converted
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sheet body - section scrollable
|
||||||
|
// SURCHARGE CRITIQUE: simple-converted.less définit height: auto sur .sheet-body et .tab
|
||||||
|
// Ces surcharges permettent le scroll vertical
|
||||||
|
.sheet-body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0.5rem;
|
||||||
|
flex: 1 !important; // Override simple-converted
|
||||||
|
min-height: 0 !important; // Critique pour le scroll
|
||||||
|
overflow-y: auto !important; // Override simple-converted
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
padding: 0;
|
||||||
|
height: auto !important; // Override simple-converted qui met height: auto
|
||||||
|
|
||||||
|
&:not(.active) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assurer que les grilles peuvent scroller
|
||||||
|
.grid, .grid-2col {
|
||||||
|
height: auto;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-box {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listes compactes dans les sections
|
||||||
|
.compact-list {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
li.item {
|
||||||
|
padding: 0.2rem 0.4rem;
|
||||||
|
margin-bottom: 0.15rem;
|
||||||
|
background: rgba(0, 0, 0, 0.1);
|
||||||
|
border: 1px solid rgba(139, 69, 19, 0.3);
|
||||||
|
border-radius: 3px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.items-title-bg {
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
border-color: rgba(139, 69, 19, 0.5);
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 0.3rem;
|
||||||
|
|
||||||
|
.item-name-label-header {
|
||||||
|
color: #f5e6d3;
|
||||||
|
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contrôles d'items (edit, delete, equip, etc.)
|
||||||
|
.item-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.3rem;
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
.item-control {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
color: #5a3a1a;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 3px;
|
||||||
|
transition: all 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #2a1a0a;
|
||||||
|
background: rgba(139, 69, 19, 0.2);
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.item-edit {
|
||||||
|
color: #4a7c59;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #2d5a3a;
|
||||||
|
background: rgba(74, 124, 89, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.item-delete {
|
||||||
|
color: #a04040;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #802020;
|
||||||
|
background: rgba(160, 64, 64, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.item-equip {
|
||||||
|
color: #6b5b3a;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #4a3a1a;
|
||||||
|
background: rgba(107, 91, 58, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
i.fa-circle {
|
||||||
|
color: #4a7c59;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.fa-genderless {
|
||||||
|
color: #8a6a4a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.item-add {
|
||||||
|
color: #4a7c59;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #2d5a3a;
|
||||||
|
background: rgba(74, 124, 89, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-controls-fixed {
|
||||||
|
min-width: 3.2rem;
|
||||||
|
max-width: 3.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Couleurs pour les labels et textes dans les onglets
|
||||||
|
h4, h3, label, span.item-name-label, span.competence-name,
|
||||||
|
.label-name, .generic-label, .item-field-label-short,
|
||||||
|
.item-field-label-medium, .item-field-label-long,
|
||||||
|
.short-label, .items-title-text {
|
||||||
|
color: #3a2a1a !important;
|
||||||
|
text-shadow: 0px 0px 1px rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inputs dans le corps
|
||||||
|
input[type="text"], input[type="number"], select {
|
||||||
|
color: #2a1a0a;
|
||||||
|
background: rgba(255, 250, 240, 0.8);
|
||||||
|
border: 1px solid rgba(139, 69, 19, 0.5);
|
||||||
|
height: 24px;
|
||||||
|
padding: 0.15rem 0.3rem;
|
||||||
|
line-height: 1.2;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
background: rgba(255, 255, 245, 0.95);
|
||||||
|
border-color: rgba(139, 69, 19, 0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Titres de sections
|
||||||
|
h3, h4 {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #2a1a0a !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Titres de sections Santé, Âme, Combat
|
||||||
|
h4.item-name-label.competence-name {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
margin-top: 0.2rem;
|
||||||
|
margin-bottom: 0.3rem;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section grids pour Santé, Âme, Combat
|
||||||
|
.section-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.2rem;
|
||||||
|
padding: 0.3rem 0.4rem;
|
||||||
|
margin-bottom: 0.3rem;
|
||||||
|
background: rgba(0, 0, 0, 0.15);
|
||||||
|
border: 2px solid rgba(139, 69, 19, 0.5);
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #f5e6d3;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
margin: 0 0 0.2rem 0;
|
||||||
|
padding: 0.2rem 0.4rem;
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
border-left: 3px solid rgba(139, 69, 19, 0.8);
|
||||||
|
border-radius: 2px;
|
||||||
|
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.4rem;
|
||||||
|
padding: 0.25rem 0.4rem;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
border: 1px solid rgba(139, 69, 19, 0.4);
|
||||||
|
border-radius: 3px;
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 60px;
|
||||||
|
min-width: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.attr-row {
|
||||||
|
grid-template-columns: 40px 1fr auto;
|
||||||
|
gap: 0.5rem;
|
||||||
|
|
||||||
|
.item-name-img {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid rgba(139, 69, 19, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-name {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #f5e6d3;
|
||||||
|
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.7);
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 0 0 4px rgba(255, 200, 100, 0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-name {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #d4c5b0;
|
||||||
|
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #d4c5b0;
|
||||||
|
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.value-display {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #fff;
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
padding: 0.2rem 0.4rem;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid rgba(139, 69, 19, 0.6);
|
||||||
|
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.malus-value {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #ff9999;
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
padding: 0.2rem 0.4rem;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid rgba(200, 50, 50, 0.6);
|
||||||
|
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.damage-row {
|
||||||
|
grid-template-columns: 120px 1fr;
|
||||||
|
|
||||||
|
.damage-label {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.damage-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.4rem;
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 60px;
|
||||||
|
min-width: 60px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plus-minus-button {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 2px solid rgba(139, 69, 19, 0.5);
|
||||||
|
background: linear-gradient(to bottom, rgba(210, 180, 140, 0.9), rgba(180, 150, 110, 0.9));
|
||||||
|
color: #2a1a0a;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.15s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: linear-gradient(to bottom, rgba(230, 200, 160, 0.95), rgba(200, 170, 130, 0.95));
|
||||||
|
border-color: rgba(139, 69, 19, 0.8);
|
||||||
|
transform: scale(1.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.soul-consumed-row {
|
||||||
|
grid-template-columns: 120px 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.soul-malus-row {
|
||||||
|
grid-template-columns: 90px 1fr;
|
||||||
|
gap: 0.4rem;
|
||||||
|
|
||||||
|
.label-name {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.malus-value {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
padding: 0.2rem 0.3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.malus-row {
|
||||||
|
grid-template-columns: 55px 60px 75px 50px;
|
||||||
|
gap: 0.3rem;
|
||||||
|
|
||||||
|
.label-name {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 100%;
|
||||||
|
min-width: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.malus-value {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
padding: 0.2rem 0.3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.combat-grid {
|
||||||
|
.grid-row.combat-stat {
|
||||||
|
grid-template-columns: 85px 50px 60px 55px;
|
||||||
|
gap: 0.4rem;
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-base {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #fff;
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
padding: 0.2rem 0.3rem;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid rgba(139, 69, 19, 0.6);
|
||||||
|
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 50px;
|
||||||
|
min-width: 50px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-total {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #fff;
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
padding: 0.2rem 0.3rem;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid rgba(139, 69, 19, 0.6);
|
||||||
|
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-row.protection-row {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
|
||||||
|
.protection-value {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: #fff;
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
padding: 0.25rem 0.4rem;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid rgba(139, 69, 19, 0.6);
|
||||||
|
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Boutons d'actions spéciales
|
||||||
|
.action-buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.3rem;
|
||||||
|
padding: 0.3rem 0;
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-buttons-row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.3rem 0;
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin: 0;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mounted-checkbox {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.4rem;
|
||||||
|
padding: 0.3rem 0.6rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"] {
|
||||||
|
margin: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==================== Creature Sheet Specific Styles ==================== */
|
||||||
|
.fvtt-mournblade.actor.creature-sheet {
|
||||||
|
|
||||||
|
// Variant background pour creatures - teinte légèrement différente
|
||||||
|
.background-sheet-header-creature {
|
||||||
|
background: linear-gradient(135deg, rgba(0, 60, 0, 0.15) 0%, rgba(20, 80, 20, 0.1) 100%);
|
||||||
|
border: 2px solid rgba(34, 139, 34, 0.5);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Légère teinte verte pour les sections
|
||||||
|
.sheet-box {
|
||||||
|
&.color-bg-archetype {
|
||||||
|
background: linear-gradient(135deg, rgba(0, 40, 0, 0.08) 0%, rgba(20, 60, 20, 0.05) 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Header simplifié pour creatures
|
||||||
|
.sheet-header {
|
||||||
|
flex: 0 0 auto !important;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-img {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 2px solid rgba(34, 139, 34, 0.6);
|
||||||
|
object-fit: cover;
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tabs avec teinte verte
|
||||||
|
nav.tabs {
|
||||||
|
.item.active {
|
||||||
|
border-bottom-color: rgba(34, 139, 34, 0.8);
|
||||||
|
color: #228b22;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section titles avec teinte verte
|
||||||
|
.section-title {
|
||||||
|
color: #1a5a1a;
|
||||||
|
border-bottom-color: rgba(34, 139, 34, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Items headers
|
||||||
|
.items-title-bg {
|
||||||
|
background: linear-gradient(135deg, rgba(0, 60, 0, 0.15) 0%, rgba(20, 80, 20, 0.1) 100%);
|
||||||
|
border-bottom: 1px solid rgba(34, 139, 34, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// PNJ Sheet - Orange/Copper theme for visual distinction
|
||||||
|
.fvtt-mournblade.actor.pnj-sheet {
|
||||||
|
|
||||||
|
// Variant background pour PNJs - teinte orange/cuivre
|
||||||
|
.background-sheet-header-creature {
|
||||||
|
background: linear-gradient(135deg, rgba(80, 40, 0, 0.15) 0%, rgba(100, 50, 0, 0.1) 100%);
|
||||||
|
border: 2px solid rgba(205, 127, 50, 0.5);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Légère teinte orange/cuivre pour les sections
|
||||||
|
.sheet-box {
|
||||||
|
&.color-bg-archetype {
|
||||||
|
background: linear-gradient(135deg, rgba(60, 30, 0, 0.08) 0%, rgba(80, 40, 0, 0.05) 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Header simplifié pour PNJs
|
||||||
|
.sheet-header {
|
||||||
|
flex: 0 0 auto !important;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-img {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 2px solid rgba(205, 127, 50, 0.6);
|
||||||
|
object-fit: cover;
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tabs avec teinte orange/cuivre
|
||||||
|
nav.tabs {
|
||||||
|
.item.active {
|
||||||
|
border-bottom-color: rgba(205, 127, 50, 0.8);
|
||||||
|
color: #cd7f32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section titles avec teinte orange/cuivre
|
||||||
|
.section-title {
|
||||||
|
color: #b8734d;
|
||||||
|
border-bottom-color: rgba(205, 127, 50, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Items headers
|
||||||
|
.items-title-bg {
|
||||||
|
background: linear-gradient(135deg, rgba(80, 40, 0, 0.15) 0%, rgba(100, 50, 0, 0.1) 100%);
|
||||||
|
border-bottom: 1px solid rgba(205, 127, 50, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// GM Tools section - labels plus larges
|
||||||
|
.gm-tools-section {
|
||||||
|
.grid {
|
||||||
|
.item-list .flexrow.item {
|
||||||
|
.label-name {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 12rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alignment group in header
|
||||||
|
.stat-group-alignment {
|
||||||
|
.stat-values.alignment-values {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alignment-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.3rem;
|
||||||
|
|
||||||
|
.alignment-label {
|
||||||
|
font-weight: bold;
|
||||||
|
min-width: 4rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alignment-inputs {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.2rem;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label-mini {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
min-width: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-input-mini {
|
||||||
|
width: 2.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
padding: 0.1rem 0.2rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
select.stat-input-mini {
|
||||||
|
width: 3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.alignment-info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
margin-top: 0.2rem;
|
||||||
|
padding-top: 0.2rem;
|
||||||
|
border-top: 1px solid rgba(139, 69, 19, 0.3);
|
||||||
|
|
||||||
|
.info-label {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: #f5e6d3;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
color: #ffd700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
299
less/item-styles.less
Normal file
299
less/item-styles.less
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
/* ==================== Item Sheet Styles ==================== */
|
||||||
|
|
||||||
|
/* Item header with image and name */
|
||||||
|
.fvtt-mournblade.item {
|
||||||
|
/* Background pour toute la fiche d'item */
|
||||||
|
background: url("../assets/ui/pc_sheet_bg.webp") repeat;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
/* AppV2 - Remove window content padding */
|
||||||
|
.window-content {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AppV2 - Main section structure */
|
||||||
|
section {
|
||||||
|
background: url("../assets/ui/pc_sheet_bg.webp") repeat-y;
|
||||||
|
color: black;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AppV2 Item Sheets - Disabled inputs readability */
|
||||||
|
input:disabled,
|
||||||
|
select:disabled {
|
||||||
|
color: #000000;
|
||||||
|
opacity: 0.8;
|
||||||
|
background-color: rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inputs and selects styling */
|
||||||
|
input[type="text"],
|
||||||
|
input[type="number"],
|
||||||
|
select {
|
||||||
|
color: #000000;
|
||||||
|
background-color: rgba(255, 255, 255, 0.7);
|
||||||
|
border: 1px solid #999999;
|
||||||
|
margin: 0;
|
||||||
|
padding: 2px 4px;
|
||||||
|
font-family: "CentaurMT", serif;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
margin: 0;
|
||||||
|
padding: 2px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"] {
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
margin: 0 4px;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
border-bottom: 1px solid #999;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
background: url("../assets/ui/pc_sheet_bg.webp") repeat;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-sheet-img {
|
||||||
|
flex: 0 0 64px;
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
object-fit: cover;
|
||||||
|
border: 1px solid #999;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0 0 8px rgba(255, 102, 0, 0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-fields {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-actions {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
|
||||||
|
button {
|
||||||
|
background: rgba(0, 0, 0, 0.1);
|
||||||
|
border: 1px solid #999;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: "CentaurMT", serif;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(255, 102, 0, 0.2);
|
||||||
|
box-shadow: 0 0 5px rgba(255, 102, 0, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-card-button {
|
||||||
|
background: linear-gradient(to bottom, #21374afc 5%, #152833ab 100%);
|
||||||
|
border: 2px ridge #846109;
|
||||||
|
color: #d4b5a8;
|
||||||
|
padding: 0.3rem 0.5rem;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: linear-gradient(to bottom, #800000 5%, #3e0101 100%);
|
||||||
|
color: #ffffff;
|
||||||
|
box-shadow: 0 0 8px rgba(128, 0, 0, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-header h1.charname {
|
||||||
|
height: 50px;
|
||||||
|
padding: 0;
|
||||||
|
margin: 5px 0;
|
||||||
|
border-bottom: 0;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 2rem;
|
||||||
|
font-family: "CentaurMT";
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheet-header h1.charname input {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: bold;
|
||||||
|
font-family: "CentaurMT";
|
||||||
|
font-size: 2rem;
|
||||||
|
text-align: left;
|
||||||
|
border: 0 none;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: 1px solid #ff6600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tabs - Modern style matching actor sheets */
|
||||||
|
nav.tabs {
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 1px solid #7a7971;
|
||||||
|
margin: 0;
|
||||||
|
padding: 4px;
|
||||||
|
background-color: #1c1c1c;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav.tabs a.item {
|
||||||
|
padding: 6px 12px;
|
||||||
|
color: #d4af37;
|
||||||
|
text-decoration: none;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
margin-right: 4px;
|
||||||
|
transition: all 0.2s;
|
||||||
|
|
||||||
|
i {
|
||||||
|
display: none; // Hide icons to match actor sheets
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(212, 175, 55, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
border-bottom-color: #d4af37;
|
||||||
|
color: #f5f5f5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tab content */
|
||||||
|
.tab {
|
||||||
|
display: none;
|
||||||
|
padding: 4px 8px;
|
||||||
|
overflow-y: auto;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Item list in details tab */
|
||||||
|
.item-list {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
li.item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
padding: 2px 4px;
|
||||||
|
min-height: 24px;
|
||||||
|
border-bottom: none;
|
||||||
|
|
||||||
|
&.flexrow {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Labels */
|
||||||
|
.generic-label {
|
||||||
|
display: inline-block;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #464331c4;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-family: "CentaurMT", serif;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 4px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Field labels */
|
||||||
|
.item-field-label-short {
|
||||||
|
flex: 0 0 60px;
|
||||||
|
max-width: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-field-label-medium {
|
||||||
|
flex: 0 0 100px;
|
||||||
|
max-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-field-label-long {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-field-label-long1 {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-field-label-long2 {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 250px;
|
||||||
|
max-width: 250px;
|
||||||
|
}
|
||||||
|
.item-field-label-long3 {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 350px;
|
||||||
|
max-width: 350px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.numeric-input {
|
||||||
|
text-align: center;
|
||||||
|
width: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Editor fields */
|
||||||
|
.editor {
|
||||||
|
height: 300px;
|
||||||
|
border: 1px solid #999;
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
|
|
||||||
|
.editor-content {
|
||||||
|
height: 100%;
|
||||||
|
padding: 0.5rem;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6
less/mournblade.less
Normal file
6
less/mournblade.less
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
// Main LESS file for Mournblade system
|
||||||
|
// Importing base styles and component-specific styles
|
||||||
|
|
||||||
|
@import "simple-converted";
|
||||||
|
@import "item-styles";
|
||||||
|
@import "actor-styles";
|
||||||
2476
less/simple-converted.less
Normal file
2476
less/simple-converted.less
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,18 +1,18 @@
|
|||||||
/**
|
/**
|
||||||
* Extend the basic ActorSheet with some very simple modifications
|
* Extend the basic ActorSheet with some very simple modifications
|
||||||
* @extends {ActorSheet}
|
* @extends {ActorSheetV2}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { MournbladeUtility } from "./mournblade-utility.js";
|
import { MournbladeUtility } from "./mournblade-utility.js";
|
||||||
import { MournbladeRollDialog } from "./mournblade-roll-dialog.js";
|
import { MournbladeRollDialog } from "./mournblade-roll-dialog.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class MournbladeActorSheet extends ActorSheet {
|
export class MournbladeActorSheet extends foundry.applications.sheets.ActorSheetV2 {
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
|
|
||||||
return mergeObject(super.defaultOptions, {
|
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||||
classes: ["fvtt-mournblade", "sheet", "actor"],
|
classes: ["fvtt-mournblade", "sheet", "actor"],
|
||||||
template: "systems/fvtt-mournblade/templates/actor-sheet.html",
|
template: "systems/fvtt-mournblade/templates/actor-sheet.html",
|
||||||
width: 640,
|
width: 640,
|
||||||
@@ -25,7 +25,7 @@ export class MournbladeActorSheet extends ActorSheet {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async getData() {
|
async getData() {
|
||||||
const objectData = duplicate(this.object)
|
const objectData = foundry.utils.duplicate(this.object)
|
||||||
let actorData = objectData
|
let actorData = objectData
|
||||||
|
|
||||||
let formData = {
|
let formData = {
|
||||||
@@ -40,22 +40,30 @@ export class MournbladeActorSheet extends ActorSheet {
|
|||||||
effects: this.object.effects.map(e => foundry.utils.deepClone(e.data)),
|
effects: this.object.effects.map(e => foundry.utils.deepClone(e.data)),
|
||||||
limited: this.object.limited,
|
limited: this.object.limited,
|
||||||
skills: this.actor.getSkills(),
|
skills: this.actor.getSkills(),
|
||||||
armes: duplicate(this.actor.getWeapons()),
|
armes: foundry.utils.duplicate(this.actor.getWeapons()),
|
||||||
protections: duplicate(this.actor.getArmors()),
|
protections: foundry.utils.duplicate(this.actor.getArmors()),
|
||||||
dons: duplicate(this.actor.getDons()),
|
dons: foundry.utils.duplicate(this.actor.getDons()),
|
||||||
|
pactes: foundry.utils.duplicate(this.actor.getPactes()),
|
||||||
alignement: this.actor.getAlignement(),
|
alignement: this.actor.getAlignement(),
|
||||||
aspect: this.actor.getAspect(),
|
aspect: this.actor.getAspect(),
|
||||||
marge: this.actor.getMarge(),
|
marge: this.actor.getMarge(),
|
||||||
tendances:duplicate(this.actor.getTendances()),
|
tendances:foundry.utils.duplicate(this.actor.getTendances()),
|
||||||
runes:duplicate(this.actor.getRunes()),
|
runes:foundry.utils.duplicate(this.actor.getRunes()),
|
||||||
traitsChaotiques:duplicate(this.actor.getTraitsChaotiques()),
|
traitsChaotiques:foundry.utils.duplicate(this.actor.getTraitsChaotiques()),
|
||||||
origine: duplicate(this.actor.getOrigine() || {}),
|
traitsEspeces: foundry.utils.duplicate(this.actor.getTraitsEspeces()),
|
||||||
heritage: duplicate(this.actor.getHeritage() || {}),
|
origine: foundry.utils.duplicate(this.actor.getOrigine() || {}),
|
||||||
metier: duplicate(this.actor.getMetier() || {}),
|
heritage: foundry.utils.duplicate(this.actor.getHeritage() || {}),
|
||||||
|
metier: foundry.utils.duplicate(this.actor.getMetier() || {}),
|
||||||
combat: this.actor.getCombatValues(),
|
combat: this.actor.getCombatValues(),
|
||||||
equipements: duplicate(this.actor.getEquipments()),
|
equipements: foundry.utils.duplicate(this.actor.getEquipments()),
|
||||||
monnaies: duplicate(this.actor.getMonnaies()),
|
modifiers: foundry.utils.duplicate(this.actor.getModifiers()),
|
||||||
description: await TextEditor.enrichHTML(this.object.system.biodata.description, {async: true}),
|
monnaies: foundry.utils.duplicate(this.actor.getMonnaies()),
|
||||||
|
runeEffects: foundry.utils.duplicate(this.actor.getRuneEffects()),
|
||||||
|
config: game.system.mournblade.config,
|
||||||
|
protectionTotal: this.actor.getProtectionTotal(),
|
||||||
|
santeMalus: this.actor.getStatusMalus(),
|
||||||
|
ameMalus: this.actor.getAmeMalus(),
|
||||||
|
description: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.biodata.description, {async: true}),
|
||||||
options: this.options,
|
options: this.options,
|
||||||
owner: this.document.isOwner,
|
owner: this.document.isOwner,
|
||||||
editScore: this.options.editScore,
|
editScore: this.options.editScore,
|
||||||
@@ -128,6 +136,21 @@ export class MournbladeActorSheet extends ActorSheet {
|
|||||||
let armeId = li.data("item-id")
|
let armeId = li.data("item-id")
|
||||||
this.actor.rollArmeOffensif(armeId)
|
this.actor.rollArmeOffensif(armeId)
|
||||||
})
|
})
|
||||||
|
html.find('.roll-assomer').click((event) => {
|
||||||
|
this.actor.rollAssomer()
|
||||||
|
})
|
||||||
|
html.find('.roll-fuir').click((event) => {
|
||||||
|
this.actor.rollFuir()
|
||||||
|
})
|
||||||
|
html.find('.roll-immobiliser').click((event) => {
|
||||||
|
this.actor.rollImmobiliser()
|
||||||
|
})
|
||||||
|
html.find('.roll-arme-special').click((event) => {
|
||||||
|
const li = $(event.currentTarget).parents(".item")
|
||||||
|
let armeId = li.data("item-id")
|
||||||
|
this.actor.rollArmeSpecial(armeId)
|
||||||
|
})
|
||||||
|
|
||||||
html.find('.roll-arme-degats').click((event) => {
|
html.find('.roll-arme-degats').click((event) => {
|
||||||
const li = $(event.currentTarget).parents(".item")
|
const li = $(event.currentTarget).parents(".item")
|
||||||
let armeId = li.data("item-id")
|
let armeId = li.data("item-id")
|
||||||
@@ -142,6 +165,15 @@ export class MournbladeActorSheet extends ActorSheet {
|
|||||||
const itemType = $(event.currentTarget).data("type")
|
const itemType = $(event.currentTarget).data("type")
|
||||||
this.actor.createEmbeddedDocuments('Item', [{ name: `Nouveau ${itemType}`, type: itemType }], { renderSheet: true })
|
this.actor.createEmbeddedDocuments('Item', [{ name: `Nouveau ${itemType}`, type: itemType }], { renderSheet: true })
|
||||||
})
|
})
|
||||||
|
html.find('.sante-modify').click((event) => {
|
||||||
|
const santeType = $(event.currentTarget).data("type")
|
||||||
|
const value = $(event.currentTarget).data("value")
|
||||||
|
this.actor.incDecSante(santeType, value, false)
|
||||||
|
})
|
||||||
|
html.find('.ame-modify').click((event) => {
|
||||||
|
const value = $(event.currentTarget).data("value")
|
||||||
|
this.actor.incDecAme(value)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
html.find('.lock-unlock-sheet').click((event) => {
|
html.find('.lock-unlock-sheet').click((event) => {
|
||||||
25
modules/_deprecated/mournblade-creature-sheet.js
Normal file
25
modules/_deprecated/mournblade-creature-sheet.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Extend the basic ActorSheet with some very simple modifications
|
||||||
|
* @extends {ActorSheet}
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { MournbladeActorSheet } from "./mournblade-actor-sheet.js";
|
||||||
|
import { MournbladeUtility } from "./mournblade-utility.js";
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
export class MournbladeCreatureSheet extends MournbladeActorSheet {
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static get defaultOptions() {
|
||||||
|
|
||||||
|
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||||
|
classes: ["fvtt-mournblade", "sheet", "actor"],
|
||||||
|
template: "systems/fvtt-mournblade/templates/creature-sheet.html",
|
||||||
|
width: 640,
|
||||||
|
height: 720,
|
||||||
|
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "stats" }],
|
||||||
|
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
|
||||||
|
editScore: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
158
modules/applications/mournblade-roll-dialog.mjs
Normal file
158
modules/applications/mournblade-roll-dialog.mjs
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
import { MournbladeUtility } from "../mournblade-utility.js"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dialogue de jet de dé pour Mournblade - Version DialogV2
|
||||||
|
*/
|
||||||
|
export class MournbladeRollDialog {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and display the roll dialog
|
||||||
|
* @param {MournbladeActor} actor - The actor making the roll
|
||||||
|
* @param {Object} rollData - Data for the roll
|
||||||
|
* @returns {Promise<MournbladeRollDialog>}
|
||||||
|
*/
|
||||||
|
static async create(actor, rollData) {
|
||||||
|
// Préparer le contexte pour le template
|
||||||
|
const context = {
|
||||||
|
...rollData,
|
||||||
|
difficulte: String(rollData.difficulte || 0),
|
||||||
|
img: actor.img,
|
||||||
|
name: actor.name,
|
||||||
|
config: game.system.mournblade.config,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si attrKey est "tochoose", préparer la liste des attributs sélectionnables
|
||||||
|
if (rollData.attrKey === "tochoose") {
|
||||||
|
context.selectableAttributes = actor.system.attributs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rendre le template en HTML
|
||||||
|
const content = await foundry.applications.handlebars.renderTemplate(
|
||||||
|
"systems/fvtt-mournblade/templates/roll-dialog-v2.hbs",
|
||||||
|
context
|
||||||
|
)
|
||||||
|
|
||||||
|
// Utiliser DialogV2.wait avec le HTML rendu
|
||||||
|
return foundry.applications.api.DialogV2.wait({
|
||||||
|
window: { title: "Test de Capacité", icon: "fa-solid fa-dice-d20" },
|
||||||
|
classes: ["mournblade-roll-dialog"],
|
||||||
|
position: { width: 500 },
|
||||||
|
modal: false,
|
||||||
|
content,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
action: "rolld10",
|
||||||
|
label: "Lancer 1d10",
|
||||||
|
icon: "fa-solid fa-dice-d10",
|
||||||
|
default: true,
|
||||||
|
callback: (event, button, dialog) => {
|
||||||
|
this._updateRollDataFromForm(rollData, button.form.elements, actor)
|
||||||
|
rollData.mainDice = "1d10"
|
||||||
|
MournbladeUtility.rollMournblade(rollData)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: "rolld20",
|
||||||
|
label: "Lancer 1d20",
|
||||||
|
icon: "fa-solid fa-dice-d20",
|
||||||
|
callback: (event, button, dialog) => {
|
||||||
|
this._updateRollDataFromForm(rollData, button.form.elements, actor)
|
||||||
|
rollData.mainDice = "1d20"
|
||||||
|
MournbladeUtility.rollMournblade(rollData)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
rejectClose: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mettre à jour rollData avec les valeurs du formulaire
|
||||||
|
* @param {Object} rollData - L'objet rollData à mettre à jour
|
||||||
|
* @param {HTMLFormControlsCollection} formElements - Les éléments du formulaire
|
||||||
|
* @param {MournbladeActor} actor - L'acteur pour récupérer les attributs
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
static _updateRollDataFromForm(rollData, formElements, actor) {
|
||||||
|
// Attributs
|
||||||
|
if (formElements.attrKey) {
|
||||||
|
rollData.attrKey = formElements.attrKey.value
|
||||||
|
if (rollData.attrKey !== "tochoose" && actor) {
|
||||||
|
rollData.attr = foundry.utils.duplicate(actor.system.attributs[rollData.attrKey])
|
||||||
|
rollData.actionImg = "systems/fvtt-mournblade/assets/icons/" + actor.system.attributs[rollData.attrKey].labelnorm + ".webp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modificateurs de base
|
||||||
|
if (formElements.difficulte) {
|
||||||
|
rollData.difficulte = Number(formElements.difficulte.value)
|
||||||
|
}
|
||||||
|
if (formElements.modificateur) {
|
||||||
|
rollData.modificateur = Number(formElements.modificateur.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runes
|
||||||
|
if (formElements.runemode) {
|
||||||
|
rollData.runemode = String(formElements.runemode.value)
|
||||||
|
}
|
||||||
|
if (formElements.runeame) {
|
||||||
|
rollData.runeame = Number(formElements.runeame.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combat mêlée
|
||||||
|
if (formElements.typeAttaque) {
|
||||||
|
rollData.typeAttaque = String(formElements.typeAttaque.value)
|
||||||
|
}
|
||||||
|
if (formElements.isMonte !== undefined) {
|
||||||
|
rollData.isMonte = formElements.isMonte.checked
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combat distance
|
||||||
|
if (formElements.visee !== undefined) {
|
||||||
|
rollData.visee = formElements.visee.checked
|
||||||
|
}
|
||||||
|
if (formElements.cibleconsciente !== undefined) {
|
||||||
|
rollData.cibleconsciente = formElements.cibleconsciente.checked
|
||||||
|
}
|
||||||
|
if (formElements.ciblecourt !== undefined) {
|
||||||
|
rollData.ciblecourt = formElements.ciblecourt.checked
|
||||||
|
}
|
||||||
|
if (formElements.typeCouvert) {
|
||||||
|
rollData.typeCouvert = String(formElements.typeCouvert.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Désavantages
|
||||||
|
if (!rollData.desavantages) rollData.desavantages = {}
|
||||||
|
|
||||||
|
if (formElements.cibleausol !== undefined) {
|
||||||
|
rollData.desavantages.cibleausol = formElements.cibleausol.checked
|
||||||
|
}
|
||||||
|
if (formElements.cibledesarmee !== undefined) {
|
||||||
|
rollData.desavantages.cibledesarmee = formElements.cibledesarmee.checked
|
||||||
|
}
|
||||||
|
if (formElements.ciblerestreint !== undefined) {
|
||||||
|
rollData.desavantages.ciblerestreint = formElements.ciblerestreint.checked
|
||||||
|
}
|
||||||
|
if (formElements.cibleimmobilisée !== undefined) {
|
||||||
|
rollData.desavantages.cibleimmobilisée = formElements.cibleimmobilisée.checked
|
||||||
|
}
|
||||||
|
if (formElements.ciblesurplomb !== undefined) {
|
||||||
|
rollData.desavantages.ciblesurplomb = formElements.ciblesurplomb.checked
|
||||||
|
}
|
||||||
|
|
||||||
|
// Double D20
|
||||||
|
if (formElements.doubleD20 !== undefined) {
|
||||||
|
rollData.doubleD20 = formElements.doubleD20.checked
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modifiers
|
||||||
|
if (rollData.modifiers) {
|
||||||
|
rollData.modifiers.forEach((modifier, idx) => {
|
||||||
|
const checkbox = formElements[`apply-modifier-${idx}`]
|
||||||
|
if (checkbox) {
|
||||||
|
modifier.system.apply = checkbox.checked
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
29
modules/applications/sheets/_module.mjs
Normal file
29
modules/applications/sheets/_module.mjs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Index des applications AppV2 pour Mournblade
|
||||||
|
* Ce fichier centralise tous les exports des applications
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Applications de feuilles d'acteurs
|
||||||
|
export { default as MournbladePersonnageSheet } from './mournblade-personnage-sheet.mjs';
|
||||||
|
export { default as MournbladeCreatureSheet } from './mournblade-creature-sheet.mjs';
|
||||||
|
export { default as MournbladePnjSheet } from './mournblade-pnj-sheet.mjs';
|
||||||
|
|
||||||
|
// Applications de feuilles d'items
|
||||||
|
export { default as MournbladeArmeSheet } from './mournblade-arme-sheet.mjs';
|
||||||
|
export { default as MournbladeBouclierSheet } from './mournblade-bouclier-sheet.mjs';
|
||||||
|
export { default as MournbladeCapaciteSheet } from './mournblade-capacite-sheet.mjs';
|
||||||
|
export { default as MournbladeCompetenceSheet } from './mournblade-competence-sheet.mjs';
|
||||||
|
export { default as MournbladeDonSheet } from './mournblade-don-sheet.mjs';
|
||||||
|
export { default as MournbladeEquipementSheet } from './mournblade-equipement-sheet.mjs';
|
||||||
|
export { default as MournbladeHeritageSheet } from './mournblade-heritage-sheet.mjs';
|
||||||
|
export { default as MournbladeMetierSheet } from './mournblade-metier-sheet.mjs';
|
||||||
|
export { default as MournbladeModifierSheet } from './mournblade-modifier-sheet.mjs';
|
||||||
|
export { default as MournbladeMonnaieSheet } from './mournblade-monnaie-sheet.mjs';
|
||||||
|
export { default as MournbladeOrigineSheet } from './mournblade-origine-sheet.mjs';
|
||||||
|
export { default as MournbladePacteSheet } from './mournblade-pacte-sheet.mjs';
|
||||||
|
export { default as MournbladeProtectionSheet } from './mournblade-protection-sheet.mjs';
|
||||||
|
export { default as MournbladeRuneSheet } from './mournblade-rune-sheet.mjs';
|
||||||
|
export { default as MournbladeRuneEffectSheet } from './mournblade-runeeffect-sheet.mjs';
|
||||||
|
export { default as MournbladeTendanceSheet } from './mournblade-tendance-sheet.mjs';
|
||||||
|
export { default as MournbladeTraitChaotiqueSheet } from './mournblade-traitchaotique-sheet.mjs';
|
||||||
|
export { default as MournbladeTraitEspeceSheet } from './mournblade-traitespece-sheet.mjs';
|
||||||
406
modules/applications/sheets/base-actor-sheet.mjs
Normal file
406
modules/applications/sheets/base-actor-sheet.mjs
Normal file
@@ -0,0 +1,406 @@
|
|||||||
|
const { HandlebarsApplicationMixin } = foundry.applications.api
|
||||||
|
|
||||||
|
import { MournbladeUtility } from "../../mournblade-utility.js"
|
||||||
|
|
||||||
|
export default class MournbladeActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {
|
||||||
|
/**
|
||||||
|
* Different sheet modes.
|
||||||
|
* @enum {number}
|
||||||
|
*/
|
||||||
|
static SHEET_MODES = { EDIT: 0, PLAY: 1 }
|
||||||
|
|
||||||
|
constructor(options = {}) {
|
||||||
|
super(options)
|
||||||
|
this.#dragDrop = this.#createDragDropHandlers()
|
||||||
|
this._sheetMode = this.constructor.SHEET_MODES.PLAY // Commencer en mode visualisation
|
||||||
|
}
|
||||||
|
|
||||||
|
#dragDrop
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["fvtt-mournblade", "sheet", "actor"],
|
||||||
|
position: {
|
||||||
|
width: 650,
|
||||||
|
height: 720,
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
submitOnChange: true,
|
||||||
|
closeOnSubmit: false,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
resizable: true,
|
||||||
|
},
|
||||||
|
tabs: [
|
||||||
|
{
|
||||||
|
navSelector: 'nav[data-group="primary"]',
|
||||||
|
contentSelector: "section.sheet-body",
|
||||||
|
initial: "stats",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
|
||||||
|
actions: {
|
||||||
|
editImage: MournbladeActorSheet.#onEditImage,
|
||||||
|
toggleSheet: MournbladeActorSheet.#onToggleSheet,
|
||||||
|
editItem: MournbladeActorSheet.#onEditItem,
|
||||||
|
deleteItem: MournbladeActorSheet.#onDeleteItem,
|
||||||
|
createItem: MournbladeActorSheet.#onCreateItem,
|
||||||
|
equipItem: MournbladeActorSheet.#onEquipItem,
|
||||||
|
modifyQuantity: MournbladeActorSheet.#onModifyQuantity,
|
||||||
|
modifySante: MournbladeActorSheet.#onModifySante,
|
||||||
|
modifyAme: MournbladeActorSheet.#onModifyAme,
|
||||||
|
rollAttribut: MournbladeActorSheet.#onRollAttribut,
|
||||||
|
rollCompetence: MournbladeActorSheet.#onRollCompetence,
|
||||||
|
rollRune: MournbladeActorSheet.#onRollRune,
|
||||||
|
rollArmeOffensif: MournbladeActorSheet.#onRollArmeOffensif,
|
||||||
|
rollArmeSpecial: MournbladeActorSheet.#onRollArmeSpecial,
|
||||||
|
rollArmeDegats: MournbladeActorSheet.#onRollArmeDegats,
|
||||||
|
rollAssommer: MournbladeActorSheet.#onRollAssommer,
|
||||||
|
rollImmobiliser: MournbladeActorSheet.#onRollImmobiliser,
|
||||||
|
rollFuir: MournbladeActorSheet.#onRollFuir,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the sheet currently in 'Play' mode?
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
get isPlayMode() {
|
||||||
|
if (this._sheetMode === undefined) this._sheetMode = this.constructor.SHEET_MODES.PLAY
|
||||||
|
return this._sheetMode === this.constructor.SHEET_MODES.PLAY
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the sheet currently in 'Edit' mode?
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
get isEditMode() {
|
||||||
|
if (this._sheetMode === undefined) this._sheetMode = this.constructor.SHEET_MODES.PLAY
|
||||||
|
return this._sheetMode === this.constructor.SHEET_MODES.EDIT
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tab groups state
|
||||||
|
* @type {object}
|
||||||
|
*/
|
||||||
|
tabGroups = { primary: "stats" }
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const actor = this.document
|
||||||
|
|
||||||
|
const context = {
|
||||||
|
actor: actor,
|
||||||
|
system: actor.system,
|
||||||
|
source: actor.toObject(),
|
||||||
|
fields: actor.schema.fields,
|
||||||
|
systemFields: actor.system.schema.fields,
|
||||||
|
isEditable: this.isEditable,
|
||||||
|
isEditMode: this.isEditMode,
|
||||||
|
isPlayMode: this.isPlayMode,
|
||||||
|
isGM: game.user.isGM,
|
||||||
|
config: game.system.mournblade.config,
|
||||||
|
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(actor.system.biodata?.description || "", { async: true }),
|
||||||
|
}
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
_onRender(context, options) {
|
||||||
|
super._onRender(context, options)
|
||||||
|
this.#dragDrop.forEach((d) => d.bind(this.element))
|
||||||
|
|
||||||
|
// Handle edit-item-data changes
|
||||||
|
this.element.querySelectorAll('.edit-item-data').forEach(element => {
|
||||||
|
element.addEventListener('change', async (event) => {
|
||||||
|
const target = event.currentTarget
|
||||||
|
const itemElement = target.closest('[data-item-id]')
|
||||||
|
if (!itemElement) return
|
||||||
|
|
||||||
|
const itemId = itemElement.dataset.itemId
|
||||||
|
const itemType = itemElement.dataset.itemType
|
||||||
|
const itemField = target.dataset.itemField
|
||||||
|
const dataType = target.dataset.dtype
|
||||||
|
const value = target.value
|
||||||
|
|
||||||
|
await this.document.editItemField(itemId, itemType, itemField, dataType, value)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Activate tab navigation manually
|
||||||
|
const nav = this.element.querySelector('nav.tabs[data-group]')
|
||||||
|
if (nav) {
|
||||||
|
const group = nav.dataset.group
|
||||||
|
// Activate the current tab
|
||||||
|
const activeTab = this.tabGroups[group] || "stats"
|
||||||
|
nav.querySelectorAll('[data-tab]').forEach(link => {
|
||||||
|
const tab = link.dataset.tab
|
||||||
|
link.classList.toggle('active', tab === activeTab)
|
||||||
|
link.addEventListener('click', (event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
this.tabGroups[group] = tab
|
||||||
|
this.render()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Show/hide tab content
|
||||||
|
this.element.querySelectorAll('[data-group="' + group + '"][data-tab]').forEach(content => {
|
||||||
|
content.classList.toggle('active', content.dataset.tab === activeTab)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #region Drag-and-Drop Workflow
|
||||||
|
/**
|
||||||
|
* Create drag-and-drop workflow handlers for this Application
|
||||||
|
*/
|
||||||
|
#createDragDropHandlers() {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
// #region Actions
|
||||||
|
/** @override */
|
||||||
|
static ACTIONS = {
|
||||||
|
editImage: MournbladeActorSheet.#onEditImage,
|
||||||
|
toggleSheet: MournbladeActorSheet.#onToggleSheet,
|
||||||
|
editItem: MournbladeActorSheet.#onEditItem,
|
||||||
|
deleteItem: MournbladeActorSheet.#onDeleteItem,
|
||||||
|
createItem: MournbladeActorSheet.#onCreateItem,
|
||||||
|
equipItem: MournbladeActorSheet.#onEquipItem,
|
||||||
|
modifyQuantity: MournbladeActorSheet.#onModifyQuantity,
|
||||||
|
rollAttribut: MournbladeActorSheet.#onRollAttribut,
|
||||||
|
rollCompetence: MournbladeActorSheet.#onRollCompetence,
|
||||||
|
rollArmeOffensif: MournbladeActorSheet.#onRollArmeOffensif,
|
||||||
|
rollArmeDegats: MournbladeActorSheet.#onRollArmeDegats,
|
||||||
|
rollAssommer: MournbladeActorSheet.#onRollAssommer,
|
||||||
|
rollImmobiliser: MournbladeActorSheet.#onRollImmobiliser,
|
||||||
|
rollFuir: MournbladeActorSheet.#onRollFuir,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle editing the actor image
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
*/
|
||||||
|
static async #onEditImage(event) {
|
||||||
|
event.preventDefault()
|
||||||
|
const sheet = this
|
||||||
|
const filePicker = new FilePicker({
|
||||||
|
type: "image",
|
||||||
|
current: sheet.document.img,
|
||||||
|
callback: (path) => {
|
||||||
|
sheet.document.update({ img: path })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
filePicker.browse()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle toggling the sheet mode
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
*/
|
||||||
|
static async #onToggleSheet(event) {
|
||||||
|
event.preventDefault()
|
||||||
|
const sheet = this
|
||||||
|
sheet._sheetMode = sheet._sheetMode === sheet.constructor.SHEET_MODES.PLAY ? sheet.constructor.SHEET_MODES.EDIT : sheet.constructor.SHEET_MODES.PLAY
|
||||||
|
sheet.render()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle editing an item
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
* @param {HTMLElement} target - The target element
|
||||||
|
*/
|
||||||
|
static async #onEditItem(event, target) {
|
||||||
|
const li = target.closest(".item")
|
||||||
|
const itemId = li?.dataset.itemId
|
||||||
|
if (!itemId) return
|
||||||
|
const item = this.actor.items.get(itemId)
|
||||||
|
if (item) item.sheet.render(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle deleting an item
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
* @param {HTMLElement} target - The target element
|
||||||
|
*/
|
||||||
|
static async #onDeleteItem(event, target) {
|
||||||
|
const li = target.closest(".item")
|
||||||
|
await MournbladeUtility.confirmDelete(this, li)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle creating an item
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
* @param {HTMLElement} target - The target element
|
||||||
|
*/
|
||||||
|
static async #onCreateItem(event, target) {
|
||||||
|
const itemType = target.dataset.type
|
||||||
|
await this.actor.createEmbeddedDocuments("Item", [{ name: `Nouveau ${itemType}`, type: itemType }], { renderSheet: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle equipping an item
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
* @param {HTMLElement} target - The target element
|
||||||
|
*/
|
||||||
|
static async #onEquipItem(event, target) {
|
||||||
|
const li = target.closest(".item")
|
||||||
|
const itemId = li?.dataset.itemId
|
||||||
|
if (!itemId) return
|
||||||
|
const item = this.actor.items.get(itemId)
|
||||||
|
if (item) {
|
||||||
|
await item.update({ "system.equipped": !item.system.equipped })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle modifying the quantity of an item
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
* @param {HTMLElement} target - The target element
|
||||||
|
*/
|
||||||
|
static async #onModifyQuantity(event, target) {
|
||||||
|
const li = target.closest('[data-item-id]')
|
||||||
|
const itemId = li?.dataset.itemId
|
||||||
|
const value = Number.parseInt(target.dataset.quantiteValue)
|
||||||
|
const item = this.document.items.get(itemId)
|
||||||
|
if (item) {
|
||||||
|
const newQuantity = Math.max(0, (item.system.quantite || 0) + value)
|
||||||
|
await item.update({ "system.quantite": newQuantity })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle modifying santé (health) values
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
* @param {HTMLElement} target - The target element
|
||||||
|
*/
|
||||||
|
static async #onModifySante(event, target) {
|
||||||
|
const type = target.dataset.type
|
||||||
|
const value = Number.parseInt(target.dataset.value)
|
||||||
|
const actor = this.document
|
||||||
|
const currentValue = actor.system.sante[type] || 0
|
||||||
|
const newValue = Math.max(0, currentValue + value)
|
||||||
|
await actor.update({ [`system.sante.${type}`]: newValue })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle modifying âme (soul) value
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
* @param {HTMLElement} target - The target element
|
||||||
|
*/
|
||||||
|
static async #onModifyAme(event, target) {
|
||||||
|
const value = Number.parseInt(target.dataset.value)
|
||||||
|
const actor = this.document
|
||||||
|
const currentValue = actor.system.ame.value || 0
|
||||||
|
const newValue = Math.max(0, currentValue + value)
|
||||||
|
await actor.update({ "system.ame.value": newValue })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle rolling an attribut
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
*/
|
||||||
|
static async #onRollAttribut(event, target) {
|
||||||
|
event.preventDefault()
|
||||||
|
const sheet = this
|
||||||
|
const attrKey = target.dataset.attrKey
|
||||||
|
const actor = sheet.document
|
||||||
|
await actor.rollAttribut(attrKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle rolling a competence
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
*/
|
||||||
|
static async #onRollCompetence(event, target) {
|
||||||
|
event.preventDefault()
|
||||||
|
const sheet = this
|
||||||
|
const attrKey = target.dataset.attrKey
|
||||||
|
const li = target.closest('[data-item-id]')
|
||||||
|
const compId = li?.dataset.itemId
|
||||||
|
const actor = sheet.document
|
||||||
|
await actor.rollCompetence(attrKey, compId)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle rolling a rune
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
*/
|
||||||
|
static async #onRollRune(event, target) {
|
||||||
|
event.preventDefault()
|
||||||
|
const sheet = this
|
||||||
|
const li = target.closest('[data-item-id]')
|
||||||
|
const runeId = li?.dataset.itemId
|
||||||
|
const actor = sheet.document
|
||||||
|
await actor.rollRune(runeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle rolling an arme offensif
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
*/
|
||||||
|
static async #onRollArmeOffensif(event, target) {
|
||||||
|
event.preventDefault()
|
||||||
|
const sheet = this
|
||||||
|
const armeId = target.dataset.armeId
|
||||||
|
const actor = sheet.document
|
||||||
|
await actor.rollArmeOffensif(armeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle rolling an arme degats
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
*/
|
||||||
|
static async #onRollArmeDegats(event, target) {
|
||||||
|
event.preventDefault()
|
||||||
|
const sheet = this
|
||||||
|
const armeId = target.dataset.armeId
|
||||||
|
const actor = sheet.document
|
||||||
|
await actor.rollArmeDegats(armeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle rolling an arme special
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
*/
|
||||||
|
static async #onRollArmeSpecial(event, target) {
|
||||||
|
event.preventDefault()
|
||||||
|
const sheet = this
|
||||||
|
const armeId = target.dataset.armeId
|
||||||
|
const actor = sheet.document
|
||||||
|
await actor.rollArmeSpecial(armeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle rolling an assommer
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
*/
|
||||||
|
static async #onRollAssommer(event, target) {
|
||||||
|
event.preventDefault()
|
||||||
|
const sheet = this
|
||||||
|
const actor = sheet.document
|
||||||
|
await actor.rollAssomer()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle rolling an immobiliser
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
*/
|
||||||
|
static async #onRollImmobiliser(event, target) {
|
||||||
|
event.preventDefault()
|
||||||
|
const sheet = this
|
||||||
|
const actor = sheet.document
|
||||||
|
await actor.rollImmobiliser()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle rolling a fuir
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
*/
|
||||||
|
static async #onRollFuir(event, target) {
|
||||||
|
event.preventDefault()
|
||||||
|
const sheet = this
|
||||||
|
const actor = sheet.document
|
||||||
|
await actor.rollFuir()
|
||||||
|
}
|
||||||
|
}
|
||||||
142
modules/applications/sheets/base-item-sheet.mjs
Normal file
142
modules/applications/sheets/base-item-sheet.mjs
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
const { HandlebarsApplicationMixin } = foundry.applications.api
|
||||||
|
|
||||||
|
export default class MournbladeItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) {
|
||||||
|
constructor(options = {}) {
|
||||||
|
super(options)
|
||||||
|
this.#dragDrop = this.#createDragDropHandlers()
|
||||||
|
}
|
||||||
|
|
||||||
|
#dragDrop
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["fvtt-mournblade", "item"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
height: 600,
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
submitOnChange: true,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
resizable: true,
|
||||||
|
},
|
||||||
|
tabs: [
|
||||||
|
{
|
||||||
|
navSelector: 'nav[data-group="primary"]',
|
||||||
|
contentSelector: "section.sheet-body",
|
||||||
|
initial: "description",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
dragDrop: [{ dragSelector: "[data-drag]", dropSelector: null }],
|
||||||
|
actions: {
|
||||||
|
editImage: MournbladeItemSheet.#onEditImage,
|
||||||
|
postItem: MournbladeItemSheet.#onPostItem,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tab groups state
|
||||||
|
* @type {object}
|
||||||
|
*/
|
||||||
|
tabGroups = { primary: "description" }
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = {
|
||||||
|
fields: this.document.schema.fields,
|
||||||
|
systemFields: this.document.system.schema.fields,
|
||||||
|
item: this.document,
|
||||||
|
system: this.document.system,
|
||||||
|
source: this.document.toObject(),
|
||||||
|
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }),
|
||||||
|
isEditMode: true,
|
||||||
|
isEditable: this.isEditable,
|
||||||
|
isGM: game.user.isGM,
|
||||||
|
config: game.system.mournblade.config,
|
||||||
|
}
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
_onRender(context, options) {
|
||||||
|
super._onRender(context, options)
|
||||||
|
this.#dragDrop.forEach((d) => d.bind(this.element))
|
||||||
|
|
||||||
|
// Activate tab navigation manually
|
||||||
|
const nav = this.element.querySelector('nav.tabs[data-group]')
|
||||||
|
if (nav) {
|
||||||
|
const group = nav.dataset.group
|
||||||
|
// Activate the current tab
|
||||||
|
const activeTab = this.tabGroups[group] || "description"
|
||||||
|
nav.querySelectorAll('[data-tab]').forEach(link => {
|
||||||
|
const tab = link.dataset.tab
|
||||||
|
link.classList.toggle('active', tab === activeTab)
|
||||||
|
link.addEventListener('click', (event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
this.tabGroups[group] = tab
|
||||||
|
this.render()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Show/hide tab content
|
||||||
|
this.element.querySelectorAll('[data-group="' + group + '"][data-tab]').forEach(content => {
|
||||||
|
content.classList.toggle('active', content.dataset.tab === activeTab)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #region Drag-and-Drop Workflow
|
||||||
|
/**
|
||||||
|
* Create drag-and-drop workflow handlers for this Application
|
||||||
|
*/
|
||||||
|
#createDragDropHandlers() {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
// #region Actions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle editing the item image
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
*/
|
||||||
|
static async #onEditImage(event) {
|
||||||
|
event.preventDefault()
|
||||||
|
const filePicker = new FilePicker({
|
||||||
|
type: "image",
|
||||||
|
current: this.document.img,
|
||||||
|
callback: (path) => {
|
||||||
|
this.document.update({ img: path })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
filePicker.browse()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle posting the item to chat
|
||||||
|
* @param {Event} event - The triggering event
|
||||||
|
*/
|
||||||
|
static async #onPostItem(event) {
|
||||||
|
event.preventDefault()
|
||||||
|
let chatData = foundry.utils.duplicate(this.document)
|
||||||
|
if (this.document.actor) {
|
||||||
|
chatData.actor = { id: this.document.actor.id }
|
||||||
|
}
|
||||||
|
// Don't post any image for the item 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,
|
||||||
|
})
|
||||||
|
|
||||||
|
const html = await renderTemplate('systems/fvtt-mournblade/templates/post-item.hbs', chatData)
|
||||||
|
const chatOptions = {
|
||||||
|
user: game.user.id,
|
||||||
|
content: html,
|
||||||
|
}
|
||||||
|
ChatMessage.create(chatOptions)
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-arme-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-arme-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeArmeSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["arme"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["arme-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-arme-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-bouclier-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-bouclier-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeBouclierSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["bouclier"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["bouclier-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-bouclier-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-capacite-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-capacite-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeCapaciteSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["capacite"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["capacite-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-capacite-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-competence-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-competence-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeCompetenceSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["competence"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["competence-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-competence-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
43
modules/applications/sheets/mournblade-creature-sheet.mjs
Normal file
43
modules/applications/sheets/mournblade-creature-sheet.mjs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import MournbladeActorSheet from "./base-actor-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeCreatureSheet extends MournbladeActorSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
...super.DEFAULT_OPTIONS,
|
||||||
|
classes: [...super.DEFAULT_OPTIONS.classes],
|
||||||
|
window: {
|
||||||
|
...super.DEFAULT_OPTIONS.window,
|
||||||
|
title: "SHEETS.Actor.creature",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/creature-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "stats",
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
const actor = this.document
|
||||||
|
|
||||||
|
// Add creature-specific data
|
||||||
|
context.skills = actor.getSkills()
|
||||||
|
context.armes = foundry.utils.duplicate(actor.getWeapons())
|
||||||
|
context.protections = foundry.utils.duplicate(actor.getArmors())
|
||||||
|
context.runes = foundry.utils.duplicate(actor.getRunes())
|
||||||
|
context.combat = actor.getCombatValues()
|
||||||
|
context.equipements = foundry.utils.duplicate(actor.getEquipments())
|
||||||
|
context.protectionTotal = actor.getProtectionTotal()
|
||||||
|
context.santeMalus = actor.getStatusMalus()
|
||||||
|
context.ameMalus = actor.getAmeMalus()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
50
modules/applications/sheets/mournblade-don-sheet.mjs
Normal file
50
modules/applications/sheets/mournblade-don-sheet.mjs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeDonSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["don"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["don-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-don-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
context.enrichedSacrifice = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.sacrifice, { async: true })
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-equipement-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-equipement-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeEquipementSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["equipement"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["equipement-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-equipement-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-heritage-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-heritage-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeHeritageSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["heritage"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["heritage-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-heritage-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-metier-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-metier-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeMetierSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["metier"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["metier-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-metier-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-modifier-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-modifier-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeModifierSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["modifier"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["modifier-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-modifier-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-monnaie-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-monnaie-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeMonnaieSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["monnaie"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["monnaie-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-monnaie-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-origine-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-origine-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeOrigineSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["origine"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["origine-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-origine-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-pacte-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-pacte-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladePacteSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["pacte"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["pacte-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-pacte-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
57
modules/applications/sheets/mournblade-personnage-sheet.mjs
Normal file
57
modules/applications/sheets/mournblade-personnage-sheet.mjs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import MournbladeActorSheet from "./base-actor-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladePersonnageSheet extends MournbladeActorSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
...super.DEFAULT_OPTIONS,
|
||||||
|
classes: [...super.DEFAULT_OPTIONS.classes],
|
||||||
|
window: {
|
||||||
|
...super.DEFAULT_OPTIONS.window,
|
||||||
|
title: "SHEETS.Actor.personnage",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/actor-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "principal",
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
const actor = this.document
|
||||||
|
|
||||||
|
// Add personnage-specific data
|
||||||
|
context.skills = actor.getSkills()
|
||||||
|
context.armes = foundry.utils.duplicate(actor.getWeapons())
|
||||||
|
context.protections = foundry.utils.duplicate(actor.getArmors())
|
||||||
|
context.dons = foundry.utils.duplicate(actor.getDons())
|
||||||
|
context.pactes = foundry.utils.duplicate(actor.getPactes())
|
||||||
|
context.alignement = actor.getAlignement()
|
||||||
|
context.aspect = actor.getAspect()
|
||||||
|
context.marge = actor.getMarge()
|
||||||
|
context.tendances = foundry.utils.duplicate(actor.getTendances())
|
||||||
|
context.runes = foundry.utils.duplicate(actor.getRunes())
|
||||||
|
context.traitsChaotiques = foundry.utils.duplicate(actor.getTraitsChaotiques())
|
||||||
|
context.traitsEspeces = foundry.utils.duplicate(actor.getTraitsEspeces())
|
||||||
|
context.origine = foundry.utils.duplicate(actor.getOrigine() || {})
|
||||||
|
context.heritage = foundry.utils.duplicate(actor.getHeritage() || {})
|
||||||
|
context.metier = foundry.utils.duplicate(actor.getMetier() || {})
|
||||||
|
context.combat = actor.getCombatValues()
|
||||||
|
context.equipements = foundry.utils.duplicate(actor.getEquipments())
|
||||||
|
context.modifiers = foundry.utils.duplicate(actor.getModifiers())
|
||||||
|
context.monnaies = foundry.utils.duplicate(actor.getMonnaies())
|
||||||
|
context.runeEffects = foundry.utils.duplicate(actor.getRuneEffects())
|
||||||
|
context.protectionTotal = actor.getProtectionTotal()
|
||||||
|
context.santeMalus = actor.getStatusMalus()
|
||||||
|
context.ameMalus = actor.getAmeMalus()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
47
modules/applications/sheets/mournblade-pnj-sheet.mjs
Normal file
47
modules/applications/sheets/mournblade-pnj-sheet.mjs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* Application de feuille de PNJ pour Mournblade
|
||||||
|
*/
|
||||||
|
import MournbladeActorSheet from "./base-actor-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladePnjSheet extends MournbladeActorSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
...super.DEFAULT_OPTIONS,
|
||||||
|
classes: [...super.DEFAULT_OPTIONS.classes],
|
||||||
|
window: {
|
||||||
|
...super.DEFAULT_OPTIONS.window,
|
||||||
|
title: "SHEETS.Actor.pnj",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
sheet: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/actor-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "principal",
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
const actor = this.document
|
||||||
|
|
||||||
|
// Add pnj-specific data
|
||||||
|
context.skills = actor.getSkills()
|
||||||
|
context.armes = foundry.utils.duplicate(actor.getWeapons())
|
||||||
|
context.protections = foundry.utils.duplicate(actor.getArmors())
|
||||||
|
context.dons = foundry.utils.duplicate(actor.getDons())
|
||||||
|
context.pactes = foundry.utils.duplicate(actor.getPactes())
|
||||||
|
context.combat = actor.getCombatValues()
|
||||||
|
context.equipements = foundry.utils.duplicate(actor.getEquipments())
|
||||||
|
context.protectionTotal = actor.getProtectionTotal()
|
||||||
|
context.santeMalus = actor.getStatusMalus()
|
||||||
|
context.ameMalus = actor.getAmeMalus()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-protection-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-protection-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeProtectionSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["protection"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["protection-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-protection-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-rune-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-rune-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeRuneSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["rune"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["rune-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-rune-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-runeeffect-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-runeeffect-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeRuneEffectSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["runeeffect"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["runeeffect-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-runeeffect-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-tendance-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-tendance-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeTendanceSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["tendance"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["tendance-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-tendance-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeTraitChaotiqueSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["traitchaotique"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["traitchaotique-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-traitchaotique-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
49
modules/applications/sheets/mournblade-traitespece-sheet.mjs
Normal file
49
modules/applications/sheets/mournblade-traitespece-sheet.mjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import MournbladeItemSheet from "./base-item-sheet.mjs"
|
||||||
|
|
||||||
|
export default class MournbladeTraitEspeceSheet extends MournbladeItemSheet {
|
||||||
|
/** @override */
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ["traitespece"],
|
||||||
|
position: {
|
||||||
|
width: 620,
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
contentClasses: ["traitespece-content"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
main: {
|
||||||
|
template: "systems/fvtt-mournblade/templates/item-traitespece-sheet.hbs",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
tabGroups = {
|
||||||
|
primary: "description",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an array of form header tabs.
|
||||||
|
* @returns {Record<string, Partial<ApplicationTab>>}
|
||||||
|
*/
|
||||||
|
#getTabs() {
|
||||||
|
const tabs = {
|
||||||
|
details: { id: "details", group: "primary", label: "Détails" },
|
||||||
|
description: { id: "description", group: "primary", label: "Description" }
|
||||||
|
}
|
||||||
|
for (const v of Object.values(tabs)) {
|
||||||
|
v.active = this.tabGroups[v.group] === v.id
|
||||||
|
v.cssClass = v.active ? "active" : ""
|
||||||
|
}
|
||||||
|
return tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
async _prepareContext() {
|
||||||
|
const context = await super._prepareContext()
|
||||||
|
context.tabs = this.#getTabs()
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
27
modules/models/arme.mjs
Normal file
27
modules/models/arme.mjs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les armes
|
||||||
|
*/
|
||||||
|
export default class ArmeDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
typearme: new fields.StringField({ initial: "" }),
|
||||||
|
isdefense: new fields.BooleanField({ initial: false }),
|
||||||
|
bonusmaniementoff: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
bonusmaniementdef: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
ignorearmure: new fields.BooleanField({ initial: false }),
|
||||||
|
nbressources: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
degats: new fields.StringField({ initial: "" }),
|
||||||
|
nonletaux: new fields.BooleanField({ initial: false }),
|
||||||
|
deuxmains: new fields.BooleanField({ initial: false }),
|
||||||
|
courte: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
moyenne: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
longue: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
tr: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
rarete: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prix: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
equipped: new fields.BooleanField({ initial: false })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
11
modules/models/base-item.mjs
Normal file
11
modules/models/base-item.mjs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Data model de base pour les items Mournblade
|
||||||
|
*/
|
||||||
|
export default class BaseItemDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
17
modules/models/bouclier.mjs
Normal file
17
modules/models/bouclier.mjs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les boucliers
|
||||||
|
*/
|
||||||
|
export default class BouclierDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
bonusdefense: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
degats: new fields.StringField({ initial: "" }),
|
||||||
|
nonletaux: new fields.BooleanField({ initial: false }),
|
||||||
|
rarete: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prix: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
equipped: new fields.BooleanField({ initial: false })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
11
modules/models/capacite.mjs
Normal file
11
modules/models/capacite.mjs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les capacités
|
||||||
|
*/
|
||||||
|
export default class CapaciteDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
17
modules/models/competence.mjs
Normal file
17
modules/models/competence.mjs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les compétences
|
||||||
|
*/
|
||||||
|
export default class CompetenceDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
niveau: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
attribut1: new fields.StringField({ initial: "" }),
|
||||||
|
attribut2: new fields.StringField({ initial: "" }),
|
||||||
|
attribut3: new fields.StringField({ initial: "" }),
|
||||||
|
doublebonus: new fields.BooleanField({ initial: false }),
|
||||||
|
predilections: new fields.ArrayField(new fields.StringField(), { initial: [] })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
103
modules/models/creature.mjs
Normal file
103
modules/models/creature.mjs
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les créatures
|
||||||
|
*/
|
||||||
|
export default class CreatureDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
// Template biodata
|
||||||
|
biodata: new fields.SchemaField({
|
||||||
|
name: new fields.StringField({ initial: "" }),
|
||||||
|
age: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
alignement: new fields.StringField({ initial: "" }),
|
||||||
|
poids: new fields.StringField({ initial: "" }),
|
||||||
|
taille: new fields.StringField({ initial: "" }),
|
||||||
|
cheveux: new fields.StringField({ initial: "" }),
|
||||||
|
sexe: new fields.StringField({ initial: "" }),
|
||||||
|
yeux: new fields.StringField({ initial: "" }),
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
amemultiplier: new fields.NumberField({ initial: 2, integer: true }),
|
||||||
|
ignoreamemalus: new fields.BooleanField({ initial: false }),
|
||||||
|
ignoresantemalus: new fields.BooleanField({ initial: false }),
|
||||||
|
notes: new fields.HTMLField({ initial: "" }),
|
||||||
|
gmnotes: new fields.HTMLField({ initial: "" })
|
||||||
|
}),
|
||||||
|
// Template core
|
||||||
|
subactors: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
attributs: new fields.SchemaField({
|
||||||
|
adr: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Adresse" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "adresse" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "adr" }),
|
||||||
|
value: new fields.NumberField({ initial: 1, integer: true })
|
||||||
|
}),
|
||||||
|
pui: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Puissance" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "puissance" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "pui" }),
|
||||||
|
value: new fields.NumberField({ initial: 1, integer: true })
|
||||||
|
}),
|
||||||
|
cla: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Clairvoyance" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "clairvoyance" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "cla" }),
|
||||||
|
value: new fields.NumberField({ initial: 1, integer: true })
|
||||||
|
}),
|
||||||
|
pre: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Présence" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "presence" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "pre" }),
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
tre: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Trempe" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "trempe" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "tre" }),
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
bonneaventure: new fields.SchemaField({
|
||||||
|
base: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
actuelle: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
experience: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
eclat: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
sante: new fields.SchemaField({
|
||||||
|
base: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
bonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
nonletaux: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
letaux: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
malusmanuel: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
sequelles: new fields.StringField({ initial: "" })
|
||||||
|
}),
|
||||||
|
ame: new fields.SchemaField({
|
||||||
|
fullmax: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
currentmax: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
traumatismes: new fields.StringField({ initial: "" })
|
||||||
|
}),
|
||||||
|
combat: new fields.SchemaField({
|
||||||
|
initbonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
vitessebonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
bonusdegats: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
defensebonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
monte: new fields.BooleanField({ initial: false })
|
||||||
|
}),
|
||||||
|
balance: new fields.SchemaField({
|
||||||
|
loi: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
chaos: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
aspect: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
marge: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
pointschaos: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
pointsloi: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
ressources: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
14
modules/models/don.mjs
Normal file
14
modules/models/don.mjs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les dons
|
||||||
|
*/
|
||||||
|
export default class DonDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
allegeance: new fields.StringField({ initial: "" }),
|
||||||
|
prerequis: new fields.StringField({ initial: "" }),
|
||||||
|
sacrifice: new fields.HTMLField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
13
modules/models/equipement.mjs
Normal file
13
modules/models/equipement.mjs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les équipements
|
||||||
|
*/
|
||||||
|
export default class EquipementDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
rarete: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prix: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
11
modules/models/heritage.mjs
Normal file
11
modules/models/heritage.mjs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les héritages
|
||||||
|
*/
|
||||||
|
export default class HeritageDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
28
modules/models/index.mjs
Normal file
28
modules/models/index.mjs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Index des DataModels pour Mournblade
|
||||||
|
* Ce fichier centralise tous les exports des modèles de données
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Modèles d'items
|
||||||
|
export { default as ArmeDataModel } from './arme.mjs';
|
||||||
|
export { default as BouclierDataModel } from './bouclier.mjs';
|
||||||
|
export { default as CapaciteDataModel } from './capacite.mjs';
|
||||||
|
export { default as CompetenceDataModel } from './competence.mjs';
|
||||||
|
export { default as DonDataModel } from './don.mjs';
|
||||||
|
export { default as EquipementDataModel } from './equipement.mjs';
|
||||||
|
export { default as HeritageDataModel } from './heritage.mjs';
|
||||||
|
export { default as MetierDataModel } from './metier.mjs';
|
||||||
|
export { default as ModifierDataModel } from './modifier.mjs';
|
||||||
|
export { default as MonnaieDataModel } from './monnaie.mjs';
|
||||||
|
export { default as OrigineDataModel } from './origine.mjs';
|
||||||
|
export { default as PacteDataModel } from './pacte.mjs';
|
||||||
|
export { default as ProtectionDataModel } from './protection.mjs';
|
||||||
|
export { default as RuneDataModel } from './rune.mjs';
|
||||||
|
export { default as RuneEffectDataModel } from './runeeffect.mjs';
|
||||||
|
export { default as TendanceDataModel } from './tendance.mjs';
|
||||||
|
export { default as TraitChaotiqueDataModel } from './traitchaotique.mjs';
|
||||||
|
export { default as TraitEspeceDataModel } from './traitespece.mjs';
|
||||||
|
|
||||||
|
// Modèles d'acteurs
|
||||||
|
export { default as PersonnageDataModel } from './personnage.mjs';
|
||||||
|
export { default as CreatureDataModel } from './creature.mjs';
|
||||||
11
modules/models/metier.mjs
Normal file
11
modules/models/metier.mjs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les métiers
|
||||||
|
*/
|
||||||
|
export default class MetierDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
18
modules/models/modifier.mjs
Normal file
18
modules/models/modifier.mjs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les modificateurs
|
||||||
|
*/
|
||||||
|
export default class ModifierDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
modifiertype: new fields.StringField({ initial: "roll" }),
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
attribut: new fields.StringField({ initial: "aucun" }),
|
||||||
|
competence: new fields.StringField({ initial: "aucun" }),
|
||||||
|
permanent: new fields.BooleanField({ initial: true }),
|
||||||
|
once: new fields.BooleanField({ initial: false }),
|
||||||
|
duree: new fields.StringField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
13
modules/models/monnaie.mjs
Normal file
13
modules/models/monnaie.mjs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les monnaies
|
||||||
|
*/
|
||||||
|
export default class MonnaieDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
quantite: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
unite: new fields.StringField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
11
modules/models/origine.mjs
Normal file
11
modules/models/origine.mjs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les origines
|
||||||
|
*/
|
||||||
|
export default class OrigineDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
12
modules/models/pacte.mjs
Normal file
12
modules/models/pacte.mjs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les pactes
|
||||||
|
*/
|
||||||
|
export default class PacteDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
allegeance: new fields.StringField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
100
modules/models/personnage.mjs
Normal file
100
modules/models/personnage.mjs
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les personnages
|
||||||
|
*/
|
||||||
|
export default class PersonnageDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
// Template biodata
|
||||||
|
biodata: new fields.SchemaField({
|
||||||
|
name: new fields.StringField({ initial: "" }),
|
||||||
|
age: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
alignement: new fields.StringField({ initial: "" }),
|
||||||
|
poids: new fields.StringField({ initial: "" }),
|
||||||
|
taille: new fields.StringField({ initial: "" }),
|
||||||
|
cheveux: new fields.StringField({ initial: "" }),
|
||||||
|
sexe: new fields.StringField({ initial: "" }),
|
||||||
|
yeux: new fields.StringField({ initial: "" }),
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
amemultiplier: new fields.NumberField({ initial: 2, integer: true }),
|
||||||
|
ignoreamemalus: new fields.BooleanField({ initial: false }),
|
||||||
|
ignoresantemalus: new fields.BooleanField({ initial: false }),
|
||||||
|
notes: new fields.HTMLField({ initial: "" }),
|
||||||
|
gmnotes: new fields.HTMLField({ initial: "" })
|
||||||
|
}),
|
||||||
|
// Template core
|
||||||
|
subactors: new fields.ArrayField(new fields.StringField(), { initial: [] }),
|
||||||
|
attributs: new fields.SchemaField({
|
||||||
|
adr: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Adresse" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "adresse" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "adr" }),
|
||||||
|
value: new fields.NumberField({ initial: 1, integer: true })
|
||||||
|
}),
|
||||||
|
pui: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Puissance" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "puissance" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "pui" }),
|
||||||
|
value: new fields.NumberField({ initial: 1, integer: true })
|
||||||
|
}),
|
||||||
|
cla: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Clairvoyance" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "clairvoyance" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "cla" }),
|
||||||
|
value: new fields.NumberField({ initial: 1, integer: true })
|
||||||
|
}),
|
||||||
|
pre: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Présence" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "presence" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "pre" }),
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
tre: new fields.SchemaField({
|
||||||
|
label: new fields.StringField({ initial: "Trempe" }),
|
||||||
|
labelnorm: new fields.StringField({ initial: "trempe" }),
|
||||||
|
abbrev: new fields.StringField({ initial: "tre" }),
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
bonneaventure: new fields.SchemaField({
|
||||||
|
base: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
actuelle: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
experience: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
eclat: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
}),
|
||||||
|
sante: new fields.SchemaField({
|
||||||
|
base: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
bonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
nonletaux: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
letaux: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
malusmanuel: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
sequelles: new fields.StringField({ initial: "" })
|
||||||
|
}),
|
||||||
|
ame: new fields.SchemaField({
|
||||||
|
fullmax: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
currentmax: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
value: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
traumatismes: new fields.StringField({ initial: "" })
|
||||||
|
}),
|
||||||
|
combat: new fields.SchemaField({
|
||||||
|
initbonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
vitessebonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
bonusdegats: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
defensebonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
monte: new fields.BooleanField({ initial: false })
|
||||||
|
}),
|
||||||
|
balance: new fields.SchemaField({
|
||||||
|
loi: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
chaos: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
aspect: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
marge: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
pointschaos: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
pointsloi: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
17
modules/models/protection.mjs
Normal file
17
modules/models/protection.mjs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les protections
|
||||||
|
*/
|
||||||
|
export default class ProtectionDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
typeprotection: new fields.StringField({ initial: "" }),
|
||||||
|
protection: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
degats: new fields.StringField({ initial: "" }),
|
||||||
|
rarete: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prix: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
equipped: new fields.BooleanField({ initial: false })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
15
modules/models/rune.mjs
Normal file
15
modules/models/rune.mjs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les runes
|
||||||
|
*/
|
||||||
|
export default class RuneDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
formule: new fields.StringField({ initial: "" }),
|
||||||
|
seuil: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
prononcee: new fields.StringField({ initial: "" }),
|
||||||
|
tracee: new fields.StringField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
15
modules/models/runeeffect.mjs
Normal file
15
modules/models/runeeffect.mjs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les effets de runes
|
||||||
|
*/
|
||||||
|
export default class RuneEffectDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
rune: new fields.StringField({ initial: "" }),
|
||||||
|
mode: new fields.StringField({ initial: "" }),
|
||||||
|
duree: new fields.StringField({ initial: "" }),
|
||||||
|
pointame: new fields.NumberField({ initial: 0, integer: true })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
12
modules/models/tendance.mjs
Normal file
12
modules/models/tendance.mjs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les tendances
|
||||||
|
*/
|
||||||
|
export default class TendanceDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" }),
|
||||||
|
allegeance: new fields.StringField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
11
modules/models/traitchaotique.mjs
Normal file
11
modules/models/traitchaotique.mjs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les traits chaotiques
|
||||||
|
*/
|
||||||
|
export default class TraitChaotiqueDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
11
modules/models/traitespece.mjs
Normal file
11
modules/models/traitespece.mjs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Data model pour les traits d'espèce
|
||||||
|
*/
|
||||||
|
export default class TraitEspeceDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
return {
|
||||||
|
description: new fields.HTMLField({ initial: "" })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
import { MournbladeUtility } from "./mournblade-utility.js";
|
import { MournbladeUtility } from "./mournblade-utility.js";
|
||||||
import { MournbladeRollDialog } from "./mournblade-roll-dialog.js";
|
import { MournbladeRollDialog } from "./applications/mournblade-roll-dialog.mjs";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
|
const __degatsBonus = [-2, -2, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10]
|
||||||
@@ -12,6 +12,28 @@ const __vitesseBonus = [-2, -2, -1, -1, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6
|
|||||||
* @extends {Actor}
|
* @extends {Actor}
|
||||||
*/
|
*/
|
||||||
export class MournbladeActor extends Actor {
|
export class MournbladeActor extends Actor {
|
||||||
|
prepareData() {
|
||||||
|
super.prepareData();
|
||||||
|
|
||||||
|
// Calculate derived attributes
|
||||||
|
const data = this.system;
|
||||||
|
|
||||||
|
// Calculate total health
|
||||||
|
data.sante.total = data.sante.base + data.sante.bonus;
|
||||||
|
|
||||||
|
// Calculate current health
|
||||||
|
data.sante.current = data.sante.total - data.sante.nonletaux - data.sante.letaux;
|
||||||
|
|
||||||
|
// Calculate total ame
|
||||||
|
data.ame.total = data.ame.fullmax;
|
||||||
|
|
||||||
|
// Calculate balance
|
||||||
|
data.balance.total = data.balance.loi + data.balance.chaos;
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareDerivedData() {
|
||||||
|
this.prepareData();
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/**
|
/**
|
||||||
@@ -31,7 +53,7 @@ export class MournbladeActor extends Actor {
|
|||||||
if (data instanceof Array) {
|
if (data instanceof Array) {
|
||||||
return super.create(data, options);
|
return super.create(data, options);
|
||||||
}
|
}
|
||||||
// If the created actor has items (only applicable to duplicated actors) bypass the new actor creation logic
|
// If the created actor has items (only applicable to foundry.utils.duplicated actors) bypass the new actor creation logic
|
||||||
if (data.items) {
|
if (data.items) {
|
||||||
let actor = super.create(data, options);
|
let actor = super.create(data, options);
|
||||||
return actor;
|
return actor;
|
||||||
@@ -41,47 +63,84 @@ export class MournbladeActor extends Actor {
|
|||||||
const skills = await MournbladeUtility.loadCompendium("fvtt-mournblade.skills")
|
const skills = await MournbladeUtility.loadCompendium("fvtt-mournblade.skills")
|
||||||
data.items = skills.map(i => i.toObject())
|
data.items = skills.map(i => i.toObject())
|
||||||
}
|
}
|
||||||
if (data.type == 'pnj') {
|
if (data.type == 'creature') {
|
||||||
|
const skills = await MournbladeUtility.loadCompendium("fvtt-mournblade.skills-creatures")
|
||||||
|
data.items = skills.map(i => i.toObject())
|
||||||
|
data.items.push({ name: "Arme naturelle 1", type: 'arme', img: "systems/fvtt-mournblade/assets/icons/arme.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
|
||||||
|
data.items.push({ name: "Arme naturelle 2", type: 'arme', img: "systems/fvtt-mournblade/assets/icons/arme.webp", system: { typearme: "contact", bonusmaniementoff: 0, seuildefense: 0, degats: "0" } })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return super.create(data, options);
|
return super.create(data, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
setModifier(name, type, value) {
|
||||||
|
this.createEmbeddedDocuments("Item", [{ type: "modifier", name: name, system: { modifiertype: type, value: value } }])
|
||||||
|
ui.notifications.info("Le modificateur " + name + " a été ajouté à " + this.name + ".")
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
prepareArme(arme) {
|
prepareArme(arme) {
|
||||||
arme = duplicate(arme)
|
arme = foundry.utils.duplicate(arme)
|
||||||
let combat = this.getCombatValues()
|
let combat = this.getCombatValues()
|
||||||
if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
|
if (arme.system.typearme == "contact" || arme.system.typearme == "contactjet") {
|
||||||
arme.system.competence = duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
|
arme.system.isMelee = true
|
||||||
|
let competence = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée")
|
||||||
|
if (competence) {
|
||||||
|
arme.system.competence = foundry.utils.duplicate(competence)
|
||||||
arme.system.attrKey = "pui"
|
arme.system.attrKey = "pui"
|
||||||
arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
|
arme.system.totalDegats = arme.system.degats + "+" + combat.bonusDegatsTotal
|
||||||
arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
|
arme.system.totalOffensif = this.system.attributs.pui.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + combat.attaqueModifier
|
||||||
if (arme.system.isdefense) {
|
if (arme.system.isdefense) {
|
||||||
arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.bonusmaniementdef
|
arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.bonusmaniementdef
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
arme.system.competence = null
|
||||||
|
arme.system.totalOffensif = 0
|
||||||
|
arme.system.totalDegats = arme.system.degats
|
||||||
|
arme.system.totalDefensif = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
|
if (arme.system.typearme == "jet" || arme.system.typearme == "tir") {
|
||||||
arme.system.competence = duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance"))
|
arme.system.isDistance = true
|
||||||
|
let competence = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "armes à distance")
|
||||||
|
if (competence) {
|
||||||
|
arme.system.competence = foundry.utils.duplicate(competence)
|
||||||
arme.system.attrKey = "adr"
|
arme.system.attrKey = "adr"
|
||||||
arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff
|
arme.system.totalOffensif = this.system.attributs.adr.value + arme.system.competence.system.niveau + arme.system.bonusmaniementoff + combat.attaqueModifier
|
||||||
arme.system.totalDegats = arme.system.degats
|
arme.system.totalDegats = arme.system.degats
|
||||||
if (arme.system.isdefense) {
|
if (arme.system.isdefense) {
|
||||||
arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.bonusmaniementdef
|
arme.system.totalDefensif = combat.defenseTotal + arme.system.competence.system.niveau + arme.system.bonusmaniementdef
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
arme.system.competence = null
|
||||||
|
arme.system.totalOffensif = 0
|
||||||
|
arme.system.totalDegats = arme.system.degats
|
||||||
|
arme.system.totalDefensif = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return arme
|
return arme
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
prepareBouclier(bouclier) {
|
prepareBouclier(bouclier) {
|
||||||
bouclier = duplicate(bouclier)
|
bouclier = foundry.utils.duplicate(bouclier)
|
||||||
let combat = this.getCombatValues()
|
let combat = this.getCombatValues()
|
||||||
bouclier.system.competence = duplicate(this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée"))
|
let competence = this.items.find(item => item.type == "competence" && item.name.toLowerCase() == "mêlée")
|
||||||
|
if (competence) {
|
||||||
|
bouclier.system.competence = foundry.utils.duplicate(competence)
|
||||||
bouclier.system.attrKey = "pui"
|
bouclier.system.attrKey = "pui"
|
||||||
bouclier.system.totalDegats = bouclier.system.degats + "+" + combat.bonusDegatsTotal
|
bouclier.system.totalDegats = bouclier.system.degats + "+" + combat.bonusDegatsTotal
|
||||||
bouclier.system.totalOffensif = this.system.attributs.pui.value + bouclier.system.competence.system.niveau
|
bouclier.system.totalOffensif = this.system.attributs.pui.value + bouclier.system.competence.system.niveau
|
||||||
bouclier.system.isdefense = true
|
bouclier.system.isdefense = true
|
||||||
bouclier.system.bonusmaniementoff = 0
|
bouclier.system.bonusmaniementoff = 0
|
||||||
bouclier.system.totalDefensif = combat.defenseTotal + bouclier.system.competence.system.niveau + bouclier.system.bonusdefense
|
bouclier.system.totalDefensif = combat.defenseTotal + bouclier.system.competence.system.niveau + bouclier.system.bonusdefense
|
||||||
|
} else {
|
||||||
|
bouclier.system.competence = null
|
||||||
|
bouclier.system.totalOffensif = 0
|
||||||
|
bouclier.system.totalDegats = bouclier.system.degats
|
||||||
|
bouclier.system.totalDefensif = 0
|
||||||
|
}
|
||||||
return bouclier
|
return bouclier
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +159,20 @@ export class MournbladeActor extends Actor {
|
|||||||
return armes
|
return armes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getModifiersForRoll() {
|
||||||
|
let modifiers = []
|
||||||
|
for (let mod of this.items) {
|
||||||
|
if (mod.type == "modifier" && mod.system.modifiertype == "roll") {
|
||||||
|
let modObj = mod.toObject()
|
||||||
|
modObj.system.apply = true
|
||||||
|
modifiers.push(modObj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MournbladeUtility.sortArrayObjectsByName(modifiers)
|
||||||
|
return modifiers
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getItemSorted(types) {
|
getItemSorted(types) {
|
||||||
let items = this.items.filter(item => types.includes(item.type)) || []
|
let items = this.items.filter(item => types.includes(item.type)) || []
|
||||||
@@ -109,6 +182,9 @@ export class MournbladeActor extends Actor {
|
|||||||
getDons() {
|
getDons() {
|
||||||
return this.getItemSorted(["don"])
|
return this.getItemSorted(["don"])
|
||||||
}
|
}
|
||||||
|
getPactes() {
|
||||||
|
return this.getItemSorted(["pacte"])
|
||||||
|
}
|
||||||
getTendances() {
|
getTendances() {
|
||||||
return this.getItemSorted(["tendance"])
|
return this.getItemSorted(["tendance"])
|
||||||
}
|
}
|
||||||
@@ -118,15 +194,24 @@ export class MournbladeActor extends Actor {
|
|||||||
getEquipments() {
|
getEquipments() {
|
||||||
return this.getItemSorted(["equipement"])
|
return this.getItemSorted(["equipement"])
|
||||||
}
|
}
|
||||||
|
getModifiers() {
|
||||||
|
return this.getItemSorted(["modifier"])
|
||||||
|
}
|
||||||
getTraitsChaotiques() {
|
getTraitsChaotiques() {
|
||||||
return this.getItemSorted(["traitchaotique"])
|
return this.getItemSorted(["traitchaotique"])
|
||||||
}
|
}
|
||||||
|
getTraitsEspeces() {
|
||||||
|
return this.getItemSorted(["traitespece"])
|
||||||
|
}
|
||||||
getMonnaies() {
|
getMonnaies() {
|
||||||
return this.getItemSorted(["monnaie"])
|
return this.getItemSorted(["monnaie"])
|
||||||
}
|
}
|
||||||
getArmors() {
|
getArmors() {
|
||||||
return this.getItemSorted(["protection"])
|
return this.getItemSorted(["protection"])
|
||||||
}
|
}
|
||||||
|
getRuneEffects() {
|
||||||
|
return this.getItemSorted(["runeeffect"])
|
||||||
|
}
|
||||||
getOrigine() {
|
getOrigine() {
|
||||||
return this.items.find(item => item.type == "origine")
|
return this.items.find(item => item.type == "origine")
|
||||||
}
|
}
|
||||||
@@ -140,7 +225,7 @@ export class MournbladeActor extends Actor {
|
|||||||
getSkills() {
|
getSkills() {
|
||||||
let comp = []
|
let comp = []
|
||||||
for (let item of this.items) {
|
for (let item of this.items) {
|
||||||
item = duplicate(item)
|
item = foundry.utils.duplicate(item)
|
||||||
if (item.type == "competence") {
|
if (item.type == "competence") {
|
||||||
item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
|
item.system.attribut1total = item.system.niveau + (this.system.attributs[item.system.attribut1]?.value || 0)
|
||||||
item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
|
item.system.attribut2total = item.system.niveau + (this.system.attributs[item.system.attribut2]?.value || 0)
|
||||||
@@ -160,6 +245,17 @@ export class MournbladeActor extends Actor {
|
|||||||
return comp
|
return comp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getProtectionTotal() {
|
||||||
|
let protection = 0
|
||||||
|
for (let item of this.items) {
|
||||||
|
if (item.type == "protection" && item.system.equipped) {
|
||||||
|
protection += item.system.protection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return protection
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getAspect() {
|
getAspect() {
|
||||||
return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
|
return (this.system.balance.loi > this.system.balance.chaos) ? this.system.balance.loi : this.system.balance.chaos
|
||||||
@@ -183,7 +279,14 @@ export class MournbladeActor extends Actor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getCombatValues() {
|
getCombatValues() {
|
||||||
|
let defenserModifier = 0
|
||||||
|
this.items.filter(item => item.type == "modifier" && item.system.modifiertype == "defense").map(e => defenserModifier += e.system.value)
|
||||||
|
let attaqueModifier = 0
|
||||||
|
this.items.filter(item => item.type == "modifier" && item.system.modifiertype == "attaque").map(e => attaqueModifier += e.system.value)
|
||||||
|
|
||||||
let combat = {
|
let combat = {
|
||||||
|
defenserModifier,
|
||||||
|
attaqueModifier,
|
||||||
initBase: this.system.attributs.adr.value,
|
initBase: this.system.attributs.adr.value,
|
||||||
initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
|
initTotal: this.system.attributs.adr.value + this.system.combat.initbonus,
|
||||||
bonusDegats: this.getBonusDegats(),
|
bonusDegats: this.getBonusDegats(),
|
||||||
@@ -191,30 +294,23 @@ export class MournbladeActor extends Actor {
|
|||||||
vitesseBase: this.getVitesseBase(),
|
vitesseBase: this.getVitesseBase(),
|
||||||
vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
|
vitesseTotal: this.getVitesseBase() + this.system.combat.vitessebonus,
|
||||||
defenseBase: this.getDefenseBase(),
|
defenseBase: this.getDefenseBase(),
|
||||||
defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus
|
defenseTotal: this.getDefenseBase() + this.system.combat.defensebonus + defenserModifier
|
||||||
}
|
}
|
||||||
return combat
|
return combat
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
prepareBaseData() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async prepareData() {
|
|
||||||
super.prepareData();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
prepareDerivedData() {
|
prepareDerivedData() {
|
||||||
|
|
||||||
if (this.type == 'personnage') {
|
if (this.type == 'personnage') {
|
||||||
let newSante = this.system.sante.bonus + (this.system.attributs.pui.value + this.system.attributs.tre.value) * 2 + 5
|
let newSante = this.system.sante.bonus + (this.system.attributs.pui.value + this.system.attributs.tre.value) * 2 + 5
|
||||||
if (this.system.sante.base != newSante) {
|
if (this.system.sante.base != newSante && this._id) {
|
||||||
|
// Only update if the actor already exists (has an _id)
|
||||||
this.update({ 'system.sante.base': newSante })
|
this.update({ 'system.sante.base': newSante })
|
||||||
}
|
}
|
||||||
let newAme = (this.system.attributs.cla.value + this.system.attributs.tre.value) * this.system.biodata.amemultiplier + 5
|
let newAme = (this.system.attributs.cla.value + this.system.attributs.tre.value) * this.system.biodata.amemultiplier + 5
|
||||||
if (this.system.ame.fullmax != newAme) {
|
if (this.system.ame.fullmax != newAme && this._id) {
|
||||||
|
// Only update if the actor already exists (has an _id)
|
||||||
this.update({ 'system.ame.fullmax': newAme })
|
this.update({ 'system.ame.fullmax': newAme })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,7 +328,7 @@ export class MournbladeActor extends Actor {
|
|||||||
getItemById(id) {
|
getItemById(id) {
|
||||||
let item = this.items.find(item => item.id == id);
|
let item = this.items.find(item => item.id == id);
|
||||||
if (item) {
|
if (item) {
|
||||||
item = duplicate(item)
|
item = foundry.utils.duplicate(item)
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@@ -240,12 +336,49 @@ export class MournbladeActor extends Actor {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async equipItem(itemId) {
|
async equipItem(itemId) {
|
||||||
let item = this.items.find(item => item.id == itemId)
|
let item = this.items.find(item => item.id == itemId)
|
||||||
if (item && item.system) {
|
if (item?.system) {
|
||||||
let update = { _id: item.id, "system.equipped": !item.system.equipped }
|
let update = { _id: item.id, "system.equipped": !item.system.equipped }
|
||||||
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
|
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getStatusMalus() {
|
||||||
|
if (this.system.biodata.ignoresantemalus) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
let malusL = 0
|
||||||
|
let malusNL = 0
|
||||||
|
if (this.system.sante.base - this.system.sante.letaux < 10) {
|
||||||
|
malusL = -2
|
||||||
|
}
|
||||||
|
if (this.system.sante.base - this.system.sante.letaux < 5) {
|
||||||
|
malusL = -5
|
||||||
|
}
|
||||||
|
if (this.system.sante.base - this.system.sante.nonletaux < 10) {
|
||||||
|
malusNL = -2
|
||||||
|
}
|
||||||
|
if (this.system.sante.base - this.system.sante.nonletaux < 5) {
|
||||||
|
malusNL = -5
|
||||||
|
}
|
||||||
|
return Math.min(malusL, malusNL)
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
getAmeMalus() {
|
||||||
|
if (this.system.biodata.ignoreamemalus) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
let malusA = 0
|
||||||
|
if (this.system.ame.currentmax - this.system.ame.value < 10) {
|
||||||
|
malusA = -2
|
||||||
|
}
|
||||||
|
if (this.system.ame.currentmax - this.system.ame.value < 5) {
|
||||||
|
malusA = -5
|
||||||
|
}
|
||||||
|
return malusA
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
editItemField(itemId, itemType, itemField, dataType, value) {
|
editItemField(itemId, itemType, itemField, dataType, value) {
|
||||||
let item = this.items.find(item => item.id == itemId)
|
let item = this.items.find(item => item.id == itemId)
|
||||||
@@ -261,6 +394,44 @@ export class MournbladeActor extends Actor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
incDecSante(type, value, applyArmure = true) {
|
||||||
|
value = Number(value)
|
||||||
|
if (value && applyArmure) {
|
||||||
|
let protection = this.getProtectionTotal()
|
||||||
|
value -= protection
|
||||||
|
value = Math.max(0, Number(value))
|
||||||
|
}
|
||||||
|
if (value) {
|
||||||
|
let newSante = foundry.utils.duplicate(this.system.sante)
|
||||||
|
newSante[type] += Number(value)
|
||||||
|
newSante[type] = Math.max(0, newSante[type])
|
||||||
|
if (newSante[type] > this.system.sante.base) {
|
||||||
|
value -= this.system.sante.base - newSante[type]
|
||||||
|
newSante[type] = this.system.sante.base
|
||||||
|
} else {
|
||||||
|
value = 0
|
||||||
|
}
|
||||||
|
newSante[type] = Math.min(newSante[type], newSante.base)
|
||||||
|
if (value && type == "nonletaux") {
|
||||||
|
newSante["letaux"] += value
|
||||||
|
}
|
||||||
|
this.update({ 'system.sante': newSante })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
incDecAme(value) {
|
||||||
|
value = Number(value)
|
||||||
|
if (value) {
|
||||||
|
let newAme = foundry.utils.duplicate(this.system.ame)
|
||||||
|
newAme.value += Number(value)
|
||||||
|
newAme.value = Math.max(0, newAme.value)
|
||||||
|
newAme.value = Math.min(newAme.value, newAme.currentmax)
|
||||||
|
this.update({ 'system.ame': newAme })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getBonneAventure() {
|
getBonneAventure() {
|
||||||
return this.system.bonneaventure.actuelle
|
return this.system.bonneaventure.actuelle
|
||||||
@@ -291,9 +462,9 @@ export class MournbladeActor extends Actor {
|
|||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
subPointsAme(runeMode, value) {
|
subPointsAme(runeMode, value) {
|
||||||
let ame = duplicate(this.system.ame)
|
let ame = foundry.utils.duplicate(this.system.ame)
|
||||||
if (runeMode == "prononcer") {
|
if (runeMode == "prononcer") {
|
||||||
ame.value -= value
|
ame.value += value
|
||||||
} else {
|
} else {
|
||||||
ame.currentmax -= value
|
ame.currentmax -= value
|
||||||
}
|
}
|
||||||
@@ -318,6 +489,9 @@ export class MournbladeActor extends Actor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getBonusDegats() {
|
getBonusDegats() {
|
||||||
|
if (this.type == "creature") {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
return __degatsBonus[this.system.attributs.pui.value]
|
return __degatsBonus[this.system.attributs.pui.value]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,13 +508,13 @@ export class MournbladeActor extends Actor {
|
|||||||
getSubActors() {
|
getSubActors() {
|
||||||
let subActors = [];
|
let subActors = [];
|
||||||
for (let id of this.system.subactors) {
|
for (let id of this.system.subactors) {
|
||||||
subActors.push(duplicate(game.actors.get(id)));
|
subActors.push(foundry.utils.duplicate(game.actors.get(id)));
|
||||||
}
|
}
|
||||||
return subActors;
|
return subActors;
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async addSubActor(subActorId) {
|
async addSubActor(subActorId) {
|
||||||
let subActors = duplicate(this.system.subactors);
|
let subActors = foundry.utils.duplicate(this.system.subactors);
|
||||||
subActors.push(subActorId);
|
subActors.push(subActorId);
|
||||||
await this.update({ 'system.subactors': subActors });
|
await this.update({ 'system.subactors': subActors });
|
||||||
}
|
}
|
||||||
@@ -371,7 +545,7 @@ export class MournbladeActor extends Actor {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async setPredilectionUsed(compId, predIdx) {
|
async setPredilectionUsed(compId, predIdx) {
|
||||||
let comp = this.items.get(compId)
|
let comp = this.items.get(compId)
|
||||||
let pred = duplicate(comp.system.predilections)
|
let pred = foundry.utils.duplicate(comp.system.predilections)
|
||||||
pred[predIdx].used = true
|
pred[predIdx].used = true
|
||||||
await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
|
await this.updateEmbeddedDocuments('Item', [{ _id: compId, 'system.predilections': pred }])
|
||||||
}
|
}
|
||||||
@@ -394,11 +568,32 @@ export class MournbladeActor extends Actor {
|
|||||||
}
|
}
|
||||||
if (arme.system.totalDefensif > maxDef) {
|
if (arme.system.totalDefensif > maxDef) {
|
||||||
maxDef = arme.system.totalDefensif
|
maxDef = arme.system.totalDefensif
|
||||||
bestArme = duplicate(arme)
|
bestArme = foundry.utils.duplicate(arme)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bestArme
|
return bestArme
|
||||||
}
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
depenseRessources(arme) {
|
||||||
|
if (arme.system.nbressources && Number(arme.system.nbressources) > 0) {
|
||||||
|
if (this.type == "creature") {
|
||||||
|
let ressources = foundry.utils.duplicate(this.system.ressources)
|
||||||
|
if (Number(ressources.value) >= Number(arme.system.nbressources)) {
|
||||||
|
ressources.value -= arme.system.nbressources
|
||||||
|
this.update({ 'system.ressources': ressources })
|
||||||
|
ChatMessage.create({
|
||||||
|
content: "L'utilisation de la capacité/arme a dépensé " + arme.system.nbressources + " ressources.",
|
||||||
|
whisper: game.user._id,
|
||||||
|
user: game.user._id
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ui.notifications.warn("Points de ressources insuffisants.")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ui.notifications.warn("Les ressources ne sont pas disponibles pour les personnages.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
|
getCommonRollData(attrKey = undefined, compId = undefined, compName = undefined) {
|
||||||
@@ -411,20 +606,29 @@ export class MournbladeActor extends Actor {
|
|||||||
rollData.canEclatDoubleD20 = this.canEclatDoubleD20()
|
rollData.canEclatDoubleD20 = this.canEclatDoubleD20()
|
||||||
rollData.doubleD20 = false
|
rollData.doubleD20 = false
|
||||||
rollData.attributs = MournbladeUtility.getAttributs()
|
rollData.attributs = MournbladeUtility.getAttributs()
|
||||||
|
rollData.selectDifficulte = true
|
||||||
|
rollData.malusSante = this.getStatusMalus() + this.system.sante.malusmanuel
|
||||||
|
rollData.malusAme = this.getAmeMalus()
|
||||||
|
rollData.modifiers = this.getModifiersForRoll()
|
||||||
|
rollData.desavantages = {}
|
||||||
|
rollData.isMonte = this.system.combat.monte
|
||||||
|
if (rollData.isMonte) {
|
||||||
|
rollData.config.attaques["chargecavalerie"] = "Charge de cavalerie"
|
||||||
|
}
|
||||||
|
|
||||||
if (attrKey) {
|
if (attrKey) {
|
||||||
rollData.attrKey = attrKey
|
rollData.attrKey = attrKey
|
||||||
if (attrKey != "tochoose") {
|
if (attrKey != "tochoose") {
|
||||||
rollData.actionImg = "systems/fvtt-mournblade/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
|
rollData.actionImg = "systems/fvtt-mournblade/assets/icons/" + this.system.attributs[attrKey].labelnorm + ".webp"
|
||||||
rollData.attr = duplicate(this.system.attributs[attrKey])
|
rollData.attr = foundry.utils.duplicate(this.system.attributs[attrKey])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compId) {
|
if (compId) {
|
||||||
rollData.competence = duplicate(this.items.get(compId) || {})
|
rollData.competence = foundry.utils.duplicate(this.items.get(compId) || {})
|
||||||
rollData.actionImg = rollData.competence?.img
|
rollData.actionImg = rollData.competence?.img
|
||||||
}
|
}
|
||||||
if (compName) {
|
if (compName) {
|
||||||
rollData.competence = duplicate(this.items.find( item => item.name.toLowerCase() == compName.toLowerCase()) || {})
|
rollData.competence = foundry.utils.duplicate(this.items.find(item => item.name.toLowerCase() == compName.toLowerCase()) || {})
|
||||||
rollData.actionImg = rollData.competence?.img
|
rollData.actionImg = rollData.competence?.img
|
||||||
}
|
}
|
||||||
return rollData
|
return rollData
|
||||||
@@ -433,16 +637,14 @@ export class MournbladeActor extends Actor {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async rollAttribut(attrKey) {
|
async rollAttribut(attrKey) {
|
||||||
let rollData = this.getCommonRollData(attrKey)
|
let rollData = this.getCommonRollData(attrKey)
|
||||||
let rollDialog = await MournbladeRollDialog.create(this, rollData)
|
await MournbladeRollDialog.create(this, rollData)
|
||||||
rollDialog.render(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async rollCompetence(attrKey, compId) {
|
async rollCompetence(attrKey, compId) {
|
||||||
let rollData = this.getCommonRollData(attrKey, compId)
|
let rollData = this.getCommonRollData(attrKey, compId)
|
||||||
console.log("RollDatra", rollData)
|
console.log("RollDatra", rollData)
|
||||||
let rollDialog = await MournbladeRollDialog.create(this, rollData)
|
await MournbladeRollDialog.create(this, rollData)
|
||||||
rollDialog.render(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -453,13 +655,12 @@ export class MournbladeActor extends Actor {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
let rollData = this.getCommonRollData("cla", undefined, "Savoir : Runes")
|
let rollData = this.getCommonRollData("cla", undefined, "Savoir : Runes")
|
||||||
rollData.rune = duplicate(this.items.get(runeId) || {})
|
rollData.rune = foundry.utils.duplicate(this.items.get(runeId) || {})
|
||||||
rollData.difficulte = rollData.rune?.system?.seuil || 0
|
rollData.difficulte = rollData.rune?.system?.seuil || 0
|
||||||
rollData.runemode = "prononcer"
|
rollData.runemode = "prononcer"
|
||||||
rollData.runeame = 1
|
rollData.runeame = 1
|
||||||
console.log("runeData", rollData)
|
console.log("runeData", rollData)
|
||||||
let rollDialog = await MournbladeRollDialog.create(this, rollData)
|
await MournbladeRollDialog.create(this, rollData)
|
||||||
rollDialog.render(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -473,9 +674,71 @@ export class MournbladeActor extends Actor {
|
|||||||
}
|
}
|
||||||
let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
|
let rollData = this.getCommonRollData(arme.system.attrKey, arme.system.competence._id)
|
||||||
rollData.arme = arme
|
rollData.arme = arme
|
||||||
|
rollData.typeAttaque = "assaut"
|
||||||
|
rollData.typeCouvert = "aucun"
|
||||||
|
rollData.hasDesavantageBonus = true
|
||||||
|
rollData.visee = false
|
||||||
|
rollData.ciblecourt = false
|
||||||
|
rollData.cibleconsciente = false
|
||||||
|
// Do not display difficulte if defense weapon or distance
|
||||||
|
if (rollData.armeDefense || rollData.arme.system.isDistance) {
|
||||||
|
rollData.selectDifficulte = false
|
||||||
|
rollData.difficulte = (rollData.arme.system.isDistance) ? 0 : rollData.difficulte
|
||||||
|
}
|
||||||
console.log("ARME!", rollData)
|
console.log("ARME!", rollData)
|
||||||
let rollDialog = await MournbladeRollDialog.create(this, rollData)
|
this.depenseRessources(arme)
|
||||||
rollDialog.render(true)
|
await MournbladeRollDialog.create(this, rollData)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async rollAssomer() {
|
||||||
|
let rollData = this.getCommonRollData("adr", undefined, "Filouterie")
|
||||||
|
rollData.typeAttaque = "assomer"
|
||||||
|
rollData.typeCouvert = "aucun"
|
||||||
|
rollData.hasDesavantageBonus = true
|
||||||
|
if (rollData.defender) {
|
||||||
|
rollData.selectDifficulte = false
|
||||||
|
rollData.difficulte = rollData.defender.system.attributs.tre.value * 2
|
||||||
|
}
|
||||||
|
console.log("Assomer!", rollData)
|
||||||
|
await MournbladeRollDialog.create(this, rollData)
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async rollFuir() {
|
||||||
|
let rollData = this.getCommonRollData("adr", undefined, "Mouvements")
|
||||||
|
rollData.typeAttaque = "fuir"
|
||||||
|
rollData.typeCouvert = "aucun"
|
||||||
|
rollData.hasDesavantageBonus = true
|
||||||
|
if (rollData.defender) {
|
||||||
|
rollData.selectDifficulte = false
|
||||||
|
let comp = rollData.defender.items.find(it => it.type == "competence" && it.name.toLowerCase() == "mouvements")
|
||||||
|
rollData.difficulte = rollData.defender.system.attributs.adr.value + ((comp) ? comp.system.niveau : rollData.defender.system.attributs.adr.value)
|
||||||
|
}
|
||||||
|
console.log("Fuir!", rollData)
|
||||||
|
await MournbladeRollDialog.create(this, rollData)
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async rollImmobiliser() {
|
||||||
|
let rollData = this.getCommonRollData("pui", undefined, "Mêlée")
|
||||||
|
rollData.typeAttaque = "immobiliser"
|
||||||
|
rollData.typeCouvert = "aucun"
|
||||||
|
rollData.hasDesavantageBonus = true
|
||||||
|
if (rollData.defender) {
|
||||||
|
rollData.selectDifficulte = false
|
||||||
|
rollData.difficulte = rollData.defenderCombatValues.defenseTotal
|
||||||
|
}
|
||||||
|
console.log("Immobiliser!", rollData)
|
||||||
|
await MournbladeRollDialog.create(this, rollData)
|
||||||
|
}
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
async rollArmeSpecial(armeId) {
|
||||||
|
let arme = this.items.get(armeId)
|
||||||
|
if (arme) {
|
||||||
|
MournbladeUtility.createChatWithRollMode("GM", {
|
||||||
|
content: await renderTemplate(`systems/fvtt-mournblade/templates/chat-display-description.hbs`, arme)
|
||||||
|
}, arme)
|
||||||
|
this.depenseRessources(arme)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -487,9 +750,11 @@ export class MournbladeActor extends Actor {
|
|||||||
if (arme.type == "bouclier") {
|
if (arme.type == "bouclier") {
|
||||||
arme = this.prepareBouclier(arme)
|
arme = this.prepareBouclier(arme)
|
||||||
}
|
}
|
||||||
let roll = new Roll(arme.system.totalDegats).roll({ async: false })
|
//Unused rollData.degatsFormula = arme.system.totalDegats
|
||||||
|
let roll = await new Roll(arme.system.totalDegats).roll()
|
||||||
await MournbladeUtility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
|
await MournbladeUtility.showDiceSoNice(roll, game.settings.get("core", "rollMode"));
|
||||||
let rollData = {
|
let rollData = {
|
||||||
|
degatsFormula:arme.system.totalDegats,
|
||||||
arme: arme,
|
arme: arme,
|
||||||
finalResult: roll.total,
|
finalResult: roll.total,
|
||||||
alias: this.name,
|
alias: this.name,
|
||||||
@@ -498,7 +763,7 @@ export class MournbladeActor extends Actor {
|
|||||||
actionImg: arme.img,
|
actionImg: arme.img,
|
||||||
}
|
}
|
||||||
MournbladeUtility.createChatWithRollMode(rollData.alias, {
|
MournbladeUtility.createChatWithRollMode(rollData.alias, {
|
||||||
content: await renderTemplate(`systems/fvtt-mournblade/templates/chat-degats-result.html`, rollData)
|
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-mournblade/templates/chat-degats-result-v2.hbs`, rollData)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,8 +116,7 @@ export class MournbladeCommands {
|
|||||||
rollData.mode = "generic"
|
rollData.mode = "generic"
|
||||||
rollData.title = `Dice Pool Roll`;
|
rollData.title = `Dice Pool Roll`;
|
||||||
|
|
||||||
let rollDialog = await MournbladeRollDialog.create( this, rollData);
|
await MournbladeRollDialog.create( this, rollData);
|
||||||
rollDialog.render( true );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
81
modules/mournblade-config.js
Normal file
81
modules/mournblade-config.js
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
|
||||||
|
export class MournbladeConfig {
|
||||||
|
|
||||||
|
static getConfig() {
|
||||||
|
let MOURNBLADE_CONFIG = {
|
||||||
|
|
||||||
|
attaques: {
|
||||||
|
assaut: game.i18n.localize("MNBL.assaut"),
|
||||||
|
precise: game.i18n.localize("MNBL.preciseattack"),
|
||||||
|
feinte: game.i18n.localize("MNBL.feint"),
|
||||||
|
coupbas: game.i18n.localize("MNBL.dirtyattack"),
|
||||||
|
charger: game.i18n.localize("MNBL.charge"),
|
||||||
|
contenir: game.i18n.localize("MNBL.contain"),
|
||||||
|
desarmer: game.i18n.localize("MNBL.disarm")
|
||||||
|
},
|
||||||
|
couverts: {
|
||||||
|
aucun: { name: game.i18n.localize("MNBL.none"), value: 0 },
|
||||||
|
rondache: { name: game.i18n.localize("MNBL.lightcover"), value: -2 },
|
||||||
|
pavois: { name: game.i18n.localize("MNBL.mediumcover"), value: -5 },
|
||||||
|
complet: { name: game.i18n.localize("MNBL.heavycover"), value: -10 },
|
||||||
|
},
|
||||||
|
modifierTypes: {
|
||||||
|
aucun: { name: game.i18n.localize("MNBL.none"), value: 0 },
|
||||||
|
roll: { name: game.i18n.localize("MNBL.roll"), value: 0 },
|
||||||
|
degats: { name: game.i18n.localize("MNBL.damage"), value: 0 },
|
||||||
|
defense: { name: game.i18n.localize("MNBL.defensecapacity"), value: 0 },
|
||||||
|
attaque: { name: game.i18n.localize("MNBL.attackcapacity"), value: 0 },
|
||||||
|
},
|
||||||
|
listeNiveau: {
|
||||||
|
},
|
||||||
|
listeNiveauCreature: {
|
||||||
|
},
|
||||||
|
listePortees: {
|
||||||
|
"10": game.i18n.localize("MNBL.lessthanshort"),
|
||||||
|
"15": game.i18n.localize("MNBL.shortmore"),
|
||||||
|
"20": game.i18n.localize("MNBL.mediummore"),
|
||||||
|
"25": game.i18n.localize("MNBL.longmore")
|
||||||
|
},
|
||||||
|
modificateurOptions: {},
|
||||||
|
pointsAmeOptions: {},
|
||||||
|
difficulteOptions: {
|
||||||
|
"0": game.i18n.localize("MNBL.noneunknwon"),
|
||||||
|
"5": game.i18n.localize("MNBL.easy"),
|
||||||
|
"10": game.i18n.localize("MNBL.medium"),
|
||||||
|
"15": game.i18n.localize("MNBL.hard"),
|
||||||
|
"20": game.i18n.localize("MNBL.hazardous"),
|
||||||
|
"25": game.i18n.localize("MNBL.insane"),
|
||||||
|
"30": game.i18n.localize("MNBL.puremadness")
|
||||||
|
},
|
||||||
|
attributs: {
|
||||||
|
adr: game.i18n.localize("Adresse"), pui: game.i18n.localize("Puissance"),
|
||||||
|
cla: game.i18n.localize("Clairvoyance"), pre: game.i18n.localize("Présence"), tre: game.i18n.localize("Trempe")
|
||||||
|
},
|
||||||
|
lancementRuneOptions: {
|
||||||
|
prononcer: game.i18n.localize("MNBL.pronouncerune"),
|
||||||
|
inscrire: game.i18n.localize("MNBL.tracerune")
|
||||||
|
},
|
||||||
|
effetRuneOptions: {
|
||||||
|
prononcee: game.i18n.localize("MNBL.pronounced"),
|
||||||
|
inscrite: game.i18n.localize("MNBL.traced")
|
||||||
|
},
|
||||||
|
typeArmeOptions: {
|
||||||
|
contact: game.i18n.localize("MNBL.meleeweapon"),
|
||||||
|
contactjet: game.i18n.localize("MNBL.meleethrowweapon"),
|
||||||
|
jet: game.i18n.localize("MNBL.throwweapon"),
|
||||||
|
tir: game.i18n.localize("MNBL.shootweapon"),
|
||||||
|
special: game.i18n.localize("MNBL.specialweapon")
|
||||||
|
},
|
||||||
|
allegeanceOptions: {
|
||||||
|
tous: game.i18n.localize("MNBL.all"),
|
||||||
|
chaos: game.i18n.localize("MNBL.chaos"),
|
||||||
|
loi: game.i18n.localize("MNBL.law"),
|
||||||
|
betes: game.i18n.localize("MNBL.beastslords"),
|
||||||
|
elementaires: game.i18n.localize("MNBL.elementslords")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return MOURNBLADE_CONFIG;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
@@ -4,14 +4,14 @@ import { MournbladeUtility } from "./mournblade-utility.js";
|
|||||||
* Extend the basic ItemSheet with some very simple modifications
|
* Extend the basic ItemSheet with some very simple modifications
|
||||||
* @extends {ItemSheet}
|
* @extends {ItemSheet}
|
||||||
*/
|
*/
|
||||||
export class MournbladeItemSheet extends ItemSheet {
|
export class MournbladeItemSheet extends foundry.appv1.sheets.ItemSheet {
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
static get defaultOptions() {
|
static get defaultOptions() {
|
||||||
|
|
||||||
return mergeObject(super.defaultOptions, {
|
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||||
classes: ["fvtt-mournblade", "sheet", "item"],
|
classes: ["fvtt-mournblade", "sheet", "item"],
|
||||||
template: "systems/fvtt-mournblade/templates/item-sheet.html",
|
template: "systems/fvtt-mournblade/templates/item-sheet.hbs",
|
||||||
dragDrop: [{ dragSelector: null, dropSelector: null }],
|
dragDrop: [{ dragSelector: null, dropSelector: null }],
|
||||||
width: 620,
|
width: 620,
|
||||||
height: 550
|
height: 550
|
||||||
@@ -48,7 +48,7 @@ export class MournbladeItemSheet extends ItemSheet {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async getData() {
|
async getData() {
|
||||||
const objectData = duplicate(this.object)
|
const objectData = foundry.utils.duplicate(this.object)
|
||||||
let itemData = objectData
|
let itemData = objectData
|
||||||
let formData = {
|
let formData = {
|
||||||
title: this.title,
|
title: this.title,
|
||||||
@@ -63,13 +63,14 @@ export class MournbladeItemSheet extends ItemSheet {
|
|||||||
limited: this.object.limited,
|
limited: this.object.limited,
|
||||||
options: this.options,
|
options: this.options,
|
||||||
owner: this.document.isOwner,
|
owner: this.document.isOwner,
|
||||||
description: await TextEditor.enrichHTML(this.object.system.description, {async: true}),
|
description: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.description, {async: true}),
|
||||||
|
config: game.system.mournblade.config,
|
||||||
mr: (this.object.type == 'specialisation'),
|
mr: (this.object.type == 'specialisation'),
|
||||||
isGM: game.user.isGM
|
isGM: game.user.isGM
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( objectData.type == "don") {
|
if ( objectData.type == "don") {
|
||||||
formData.sacrifice = await TextEditor.enrichHTML(this.object.system.sacrifice, {async: true})
|
formData.sacrifice = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.object.system.sacrifice, {async: true})
|
||||||
}
|
}
|
||||||
//this.options.editable = !(this.object.origin == "embeddedItem");
|
//this.options.editable = !(this.object.origin == "embeddedItem");
|
||||||
console.log("ITEM DATA", formData, this);
|
console.log("ITEM DATA", formData, this);
|
||||||
@@ -90,7 +91,7 @@ export class MournbladeItemSheet extends ItemSheet {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
postItem() {
|
postItem() {
|
||||||
let chatData = duplicate(MournbladeUtility.data(this.item));
|
let chatData = foundry.utils.duplicate(MournbladeUtility.data(this.item));
|
||||||
if (this.actor) {
|
if (this.actor) {
|
||||||
chatData.actor = { id: this.actor.id };
|
chatData.actor = { id: this.actor.id };
|
||||||
}
|
}
|
||||||
@@ -105,7 +106,7 @@ export class MournbladeItemSheet extends ItemSheet {
|
|||||||
payload: chatData,
|
payload: chatData,
|
||||||
});
|
});
|
||||||
|
|
||||||
renderTemplate('systems/fvtt-Mournblade-rpg/templates/post-item.html', chatData).then(html => {
|
renderTemplate('systems/fvtt-mournblade/templates/post-item.hbs', chatData).then(html => {
|
||||||
let chatOptions = MournbladeUtility.chatDataSetup(html);
|
let chatOptions = MournbladeUtility.chatDataSetup(html);
|
||||||
ChatMessage.create(chatOptions)
|
ChatMessage.create(chatOptions)
|
||||||
});
|
});
|
||||||
@@ -133,28 +134,28 @@ export class MournbladeItemSheet extends ItemSheet {
|
|||||||
html.find('.edit-prediction').change(ev => {
|
html.find('.edit-prediction').change(ev => {
|
||||||
const li = $(ev.currentTarget).parents(".prediction-item")
|
const li = $(ev.currentTarget).parents(".prediction-item")
|
||||||
let index = li.data("prediction-index")
|
let index = li.data("prediction-index")
|
||||||
let pred = duplicate(this.object.system.predilections)
|
let pred = foundry.utils.duplicate(this.object.system.predilections)
|
||||||
pred[index].name = ev.currentTarget.value
|
pred[index].name = ev.currentTarget.value
|
||||||
this.object.update( { 'data.predilections': pred })
|
this.object.update( { 'system.predilections': pred })
|
||||||
})
|
})
|
||||||
html.find('.delete-prediction').click(ev => {
|
html.find('.delete-prediction').click(ev => {
|
||||||
const li = $(ev.currentTarget).parents(".prediction-item")
|
const li = $(ev.currentTarget).parents(".prediction-item")
|
||||||
let index = li.data("prediction-index")
|
let index = li.data("prediction-index")
|
||||||
let pred = duplicate(this.object.system.predilections)
|
let pred = foundry.utils.duplicate(this.object.system.predilections)
|
||||||
pred.splice(index,1)
|
pred.splice(index,1)
|
||||||
this.object.update( { 'data.predilections': pred })
|
this.object.update( { 'system.predilections': pred })
|
||||||
})
|
})
|
||||||
html.find('.use-prediction').change(ev => {
|
html.find('.use-prediction').change(ev => {
|
||||||
const li = $(ev.currentTarget).parents(".prediction-item")
|
const li = $(ev.currentTarget).parents(".prediction-item")
|
||||||
let index = li.data("prediction-index")
|
let index = li.data("prediction-index")
|
||||||
let pred = duplicate(this.object.system.predilections)
|
let pred = foundry.utils.duplicate(this.object.system.predilections)
|
||||||
pred[index].used = ev.currentTarget.checked
|
pred[index].used = ev.currentTarget.checked
|
||||||
this.object.update( { 'data.predilections': pred })
|
this.object.update( { 'system.predilections': pred })
|
||||||
})
|
})
|
||||||
html.find('#add-predilection').click(ev => {
|
html.find('#add-predilection').click(ev => {
|
||||||
let pred = duplicate(this.object.system.predilections)
|
let pred = foundry.utils.duplicate(this.object.system.predilections)
|
||||||
pred.push( { name: "Nouvelle prédilection", used: false })
|
pred.push( { name: "Nouvelle prédilection", id: randomID(), used: false })
|
||||||
this.object.update( { 'data.predilections': pred })
|
this.object.update( { 'system.predilections': pred })
|
||||||
})
|
})
|
||||||
// Update Inventory Item
|
// Update Inventory Item
|
||||||
html.find('.item-delete').click(ev => {
|
html.find('.item-delete').click(ev => {
|
||||||
@@ -168,7 +169,7 @@ export class MournbladeItemSheet extends ItemSheet {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
get template() {
|
get template() {
|
||||||
let type = this.item.type;
|
let type = this.item.type;
|
||||||
return `systems/fvtt-mournblade/templates/item-${type}-sheet.html`;
|
return `systems/fvtt-mournblade/templates/item-${type}-sheet.hbs`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|||||||
@@ -11,8 +11,10 @@ export const defaultItemImg = {
|
|||||||
predilection: "systems/fvtt-mournblade/assets/icons/predilection.webp",
|
predilection: "systems/fvtt-mournblade/assets/icons/predilection.webp",
|
||||||
protection: "systems/fvtt-mournblade/assets/icons/protection.webp",
|
protection: "systems/fvtt-mournblade/assets/icons/protection.webp",
|
||||||
rune: "systems/fvtt-mournblade/assets/icons/rune.webp",
|
rune: "systems/fvtt-mournblade/assets/icons/rune.webp",
|
||||||
|
runeeffect: "systems/fvtt-mournblade/assets/icons/rune.webp",
|
||||||
tendance: "systems/fvtt-mournblade/assets/icons/tendance.webp",
|
tendance: "systems/fvtt-mournblade/assets/icons/tendance.webp",
|
||||||
traitchaotique: "systems/fvtt-mournblade/assets/icons/traitchaotique.webp",
|
traitchaotique: "systems/fvtt-mournblade/assets/icons/traitchaotique.webp",
|
||||||
|
traitespece: "systems/fvtt-mournblade/assets/icons/capacite.webp"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -10,11 +10,19 @@
|
|||||||
// Import Modules
|
// Import Modules
|
||||||
import { MournbladeActor } from "./mournblade-actor.js";
|
import { MournbladeActor } from "./mournblade-actor.js";
|
||||||
import { MournbladeItemSheet } from "./mournblade-item-sheet.js";
|
import { MournbladeItemSheet } from "./mournblade-item-sheet.js";
|
||||||
import { MournbladeActorSheet } from "./mournblade-actor-sheet.js";
|
// import { MournbladeActorSheet } from "./mournblade-actor-sheet.js";
|
||||||
//import { MournbladeNPCSheet } from "./mournblade-npc-sheet.js";
|
// import { MournbladeCreatureSheet } from "./mournblade-creature-sheet.js";
|
||||||
import { MournbladeUtility } from "./mournblade-utility.js";
|
import { MournbladeUtility } from "./mournblade-utility.js";
|
||||||
import { MournbladeCombat } from "./mournblade-combat.js";
|
import { MournbladeCombat } from "./mournblade-combat.js";
|
||||||
import { MournbladeItem } from "./mournblade-item.js";
|
import { MournbladeItem } from "./mournblade-item.js";
|
||||||
|
import { MournbladeConfig } from "./mournblade-config.js";
|
||||||
|
|
||||||
|
// Import DataModels
|
||||||
|
import * as models from "./models/index.mjs";
|
||||||
|
|
||||||
|
// Import AppV2 Item Sheets
|
||||||
|
import * as sheets from "./applications/sheets/_module.mjs";
|
||||||
|
import { MournbladeRollDialog } from "./mournblade-roll-dialog.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/* Foundry VTT Initialization */
|
/* Foundry VTT Initialization */
|
||||||
@@ -44,58 +52,90 @@ Hooks.once("init", async function () {
|
|||||||
// Define custom Entity classes
|
// Define custom Entity classes
|
||||||
CONFIG.Combat.documentClass = MournbladeCombat
|
CONFIG.Combat.documentClass = MournbladeCombat
|
||||||
CONFIG.Actor.documentClass = MournbladeActor
|
CONFIG.Actor.documentClass = MournbladeActor
|
||||||
|
CONFIG.Actor.dataModels = {
|
||||||
|
personnage: models.PersonnageDataModel,
|
||||||
|
creature: models.CreatureDataModel,
|
||||||
|
}
|
||||||
|
|
||||||
CONFIG.Item.documentClass = MournbladeItem
|
CONFIG.Item.documentClass = MournbladeItem
|
||||||
game.system.mournblade = { }
|
CONFIG.Item.dataModels = {
|
||||||
|
arme: models.ArmeDataModel,
|
||||||
|
bouclier: models.BouclierDataModel,
|
||||||
|
capacite: models.CapaciteDataModel,
|
||||||
|
competence: models.CompetenceDataModel,
|
||||||
|
don: models.DonDataModel,
|
||||||
|
equipement: models.EquipementDataModel,
|
||||||
|
heritage: models.HeritageDataModel,
|
||||||
|
metier: models.MetierDataModel,
|
||||||
|
modifier: models.ModifierDataModel,
|
||||||
|
monnaie: models.MonnaieDataModel,
|
||||||
|
origine: models.OrigineDataModel,
|
||||||
|
pacte: models.PacteDataModel,
|
||||||
|
protection: models.ProtectionDataModel,
|
||||||
|
rune: models.RuneDataModel,
|
||||||
|
runeeffect: models.RuneEffectDataModel,
|
||||||
|
tendance: models.TendanceDataModel,
|
||||||
|
traitchaotique: models.TraitChaotiqueDataModel,
|
||||||
|
traitespece: models.TraitEspeceDataModel
|
||||||
|
}
|
||||||
|
|
||||||
|
game.system.mournblade = {
|
||||||
|
config : MournbladeConfig.getConfig(),
|
||||||
|
models,
|
||||||
|
sheets,
|
||||||
|
MournbladeRollDialog
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
// Register sheet application classes
|
// Register sheet application classes
|
||||||
Actors.unregisterSheet("core", ActorSheet);
|
foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet);
|
||||||
Actors.registerSheet("fvtt-mournblade", MournbladeActorSheet, { types: ["personnage"], makeDefault: true })
|
foundry.documents.collections.Actors.registerSheet("fvtt-mournblade", sheets.MournbladePersonnageSheet, { types: ["personnage"], makeDefault: true });
|
||||||
//Actors.registerSheet("fvtt-mournblade", MournbladeNPCSheet, { types: ["npc"], makeDefault: false });
|
foundry.documents.collections.Actors.registerSheet("fvtt-mournblade", sheets.MournbladeCreatureSheet, { types: ["creature"], makeDefault: true });
|
||||||
|
|
||||||
Items.unregisterSheet("core", ItemSheet);
|
foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet);
|
||||||
Items.registerSheet("fvtt-mournblade", MournbladeItemSheet, { makeDefault: true })
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeArmeSheet, { types: ["arme"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeBouclierSheet, { types: ["bouclier"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeCapaciteSheet, { types: ["capacite"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeCompetenceSheet, { types: ["competence"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeDonSheet, { types: ["don"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeEquipementSheet, { types: ["equipement"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeHeritageSheet, { types: ["heritage"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeMetierSheet, { types: ["metier"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeModifierSheet, { types: ["modifier"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeMonnaieSheet, { types: ["monnaie"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeOrigineSheet, { types: ["origine"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladePacteSheet, { types: ["pacte"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeProtectionSheet, { types: ["protection"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeRuneSheet, { types: ["rune"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeRuneEffectSheet, { types: ["runeeffect"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeTendanceSheet, { types: ["tendance"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeTraitChaotiqueSheet, { types: ["traitchaotique"], makeDefault: true });
|
||||||
|
foundry.documents.collections.Items.registerSheet("fvtt-mournblade", sheets.MournbladeTraitEspeceSheet, { types: ["traitespece"], makeDefault: true });
|
||||||
|
|
||||||
MournbladeUtility.init();
|
MournbladeUtility.init();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
function welcomeMessage() {
|
async function welcomeMessage() {
|
||||||
|
const templateData = {};
|
||||||
|
const html = await renderTemplate("systems/fvtt-mournblade/templates/chat-welcome-message.hbs", templateData);
|
||||||
|
|
||||||
ChatMessage.create({
|
ChatMessage.create({
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
whisper: [game.user.id],
|
whisper: [game.user.id],
|
||||||
content: `<div id="welcome-message-Mournblade"><span class="rdd-roll-part">
|
content: html
|
||||||
<strong>Bienvenue dans les Jeunes Royaumes de Mournblade !</strong>
|
});
|
||||||
<p>Les livres de Mournblade sont nécessaires pour jouer : https://www.titam-france.fr</p>
|
|
||||||
<p>Mournblade est jeu de rôle publié par Titam France/Sombres projets, tout les droits leur appartiennent.</p>
|
|
||||||
<p>Système développé par LeRatierBretonnien, support sur le <a href="https://discord.gg/pPSDNJk">Discord FR de Foundry</a>.</p>
|
|
||||||
` });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
// Register world usage statistics
|
async function importDefaultScene() {
|
||||||
function registerUsageCount( registerKey ) {
|
let exists = game.scenes.find(j => j.name == "Accueil");
|
||||||
if ( game.user.isGM ) {
|
if (!exists) {
|
||||||
game.settings.register(registerKey, "world-key", {
|
const scenes = await MournbladeUtility.loadCompendium("fvtt-mournblade.scenes")
|
||||||
name: "Unique world key",
|
let newDocuments = scenes.filter(i => i.name == "Accueil");
|
||||||
scope: "world",
|
await game.scenes.documentClass.create(newDocuments);
|
||||||
config: false,
|
game.scenes.find(i => i.name == "Accueil").activate();
|
||||||
default: "",
|
|
||||||
type: String
|
|
||||||
});
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,6 +144,10 @@ function registerUsageCount( registerKey ) {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
Hooks.once("ready", function () {
|
Hooks.once("ready", function () {
|
||||||
|
|
||||||
|
game.system.mournblade = {
|
||||||
|
config : MournbladeConfig.getConfig(),
|
||||||
|
}
|
||||||
|
|
||||||
MournbladeUtility.ready();
|
MournbladeUtility.ready();
|
||||||
// User warning
|
// User warning
|
||||||
if (!game.user.isGM && game.user.character == undefined) {
|
if (!game.user.isGM && game.user.character == undefined) {
|
||||||
@@ -113,8 +157,22 @@ Hooks.once("ready", function () {
|
|||||||
user: game.user._id
|
user: game.user._id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (!game.user.isGM && game.user.character && !game.user.character.prototypeToken.actorLink) {
|
||||||
|
ui.notifications.info("Le token de du joueur n'est pas connecté à l'acteur !");
|
||||||
|
ChatMessage.create({
|
||||||
|
content: "<b>ATTENTION</b> Le token du joueur " + game.user.name + " n'est pas connecté à l'acteur !",
|
||||||
|
user: game.user._id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
registerUsageCount('fvtt-mournblade')
|
import("https://www.uberwald.me/fvtt_appcount/count-class-ready.js").then(moduleCounter=>{
|
||||||
|
console.log("ClassCounter loaded", moduleCounter)
|
||||||
|
moduleCounter.ClassCounter.registerUsageCount()
|
||||||
|
}).catch(err=>
|
||||||
|
console.log("No stats available, giving up.")
|
||||||
|
)
|
||||||
|
|
||||||
|
importDefaultScene();
|
||||||
welcomeMessage();
|
welcomeMessage();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -131,4 +189,3 @@ Hooks.on("chatMessage", (html, content, msg) => {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,65 +1,73 @@
|
|||||||
import { MournbladeUtility } from "./mournblade-utility.js";
|
import { MournbladeUtility } from "./mournblade-utility.js";
|
||||||
|
|
||||||
export class MournbladeRollDialog extends Dialog {
|
export class MournbladeRollDialog extends Application {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async create(actor, rollData ) {
|
static async create(actor, rollData ) {
|
||||||
|
return new MournbladeRollDialog(actor, rollData);
|
||||||
let options = { classes: ["MournbladeDialog"], width: 340, height: 'fit-content', 'z-index': 99999 };
|
|
||||||
let html = await renderTemplate('systems/fvtt-mournblade/templates/roll-dialog-generic.html', rollData);
|
|
||||||
|
|
||||||
return new MournbladeRollDialog(actor, rollData, html, options );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
constructor(actor, rollData, html, options, close = undefined) {
|
constructor(actor, rollData, options = {}) {
|
||||||
let conf = {
|
super(options);
|
||||||
title: "Test de Capacité",
|
this.actor = actor;
|
||||||
content: html,
|
this.rollData = rollData;
|
||||||
buttons: {
|
|
||||||
rolld10: {
|
|
||||||
icon: '<i class="fas fa-check"></i>',
|
|
||||||
label: "Lancer 1d10",
|
|
||||||
callback: () => { this.roll("1d10") }
|
|
||||||
},
|
|
||||||
rolld20: {
|
|
||||||
icon: '<i class="fas fa-check"></i>',
|
|
||||||
label: "Lancer 1d20",
|
|
||||||
callback: () => { this.roll("1d20") }
|
|
||||||
},
|
|
||||||
cancel: {
|
|
||||||
icon: '<i class="fas fa-times"></i>',
|
|
||||||
label: "Annuler",
|
|
||||||
callback: () => { this.close() }
|
|
||||||
} },
|
|
||||||
close: close
|
|
||||||
}
|
}
|
||||||
|
|
||||||
super(conf, options);
|
static get defaultOptions() {
|
||||||
|
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||||
|
classes: ["fvtt-mournblade", "sheet", "item"],
|
||||||
|
template: "systems/fvtt-mournblade/templates/roll-dialog-generic.hbs",
|
||||||
|
width: 400,
|
||||||
|
height: "auto",
|
||||||
|
title: "Test de Capacité"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.actor = actor
|
getData() {
|
||||||
this.rollData = rollData
|
const data = foundry.utils.duplicate(this.rollData);
|
||||||
|
if (!data.config) {
|
||||||
|
data.config = game.system.mournblade.config;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
_onCancel() {
|
||||||
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
roll ( dice) {
|
_onRoll(dice) {
|
||||||
this.rollData.mainDice = dice
|
this.rollData.mainDice = dice;
|
||||||
MournbladeUtility.rollMournblade( this.rollData )
|
MournbladeUtility.rollMournblade(this.rollData);
|
||||||
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
activateListeners(html) {
|
activateListeners(html) {
|
||||||
super.activateListeners(html);
|
super.activateListeners(html);
|
||||||
|
|
||||||
var dialog = this;
|
// Roll buttons
|
||||||
|
html.find(".rolld10").click(this._onRoll.bind(this, "1d10"));
|
||||||
|
html.find(".rolld20").click(this._onRoll.bind(this, "1d20"));
|
||||||
|
html.find(".cancel").click(this._onCancel.bind(this));
|
||||||
|
|
||||||
function onLoad() {
|
function onLoad() {
|
||||||
}
|
}
|
||||||
$(function () { onLoad(); });
|
$(function () { onLoad(); });
|
||||||
|
|
||||||
|
html.find('.apply-modifier').change(async (event) => {
|
||||||
|
let modifierIdx = $(event.currentTarget).data("modifier-idx")
|
||||||
|
let modifier = this.rollData.modifiers[modifierIdx]
|
||||||
|
modifier.system.apply = event.currentTarget.checked
|
||||||
|
})
|
||||||
|
|
||||||
html.find('#modificateur').change(async (event) => {
|
html.find('#modificateur').change(async (event) => {
|
||||||
this.rollData.modificateur = Number(event.currentTarget.value)
|
this.rollData.modificateur = Number(event.currentTarget.value)
|
||||||
})
|
})
|
||||||
|
html.find('#typeAttaque').change(async (event) => {
|
||||||
|
this.rollData.typeAttaque = String(event.currentTarget.value)
|
||||||
|
})
|
||||||
html.find('#difficulte').change(async (event) => {
|
html.find('#difficulte').change(async (event) => {
|
||||||
this.rollData.difficulte = Number(event.currentTarget.value)
|
this.rollData.difficulte = Number(event.currentTarget.value)
|
||||||
})
|
})
|
||||||
@@ -72,8 +80,41 @@ export class MournbladeRollDialog extends Dialog {
|
|||||||
html.find('#runeame').change(async (event) => {
|
html.find('#runeame').change(async (event) => {
|
||||||
this.rollData.runeame = Number(event.currentTarget.value)
|
this.rollData.runeame = Number(event.currentTarget.value)
|
||||||
})
|
})
|
||||||
|
html.find('#isMonte').change(async (event) => {
|
||||||
|
this.rollData.desavantages.isMonte = event.currentTarget.checked
|
||||||
|
})
|
||||||
|
|
||||||
|
html.find('#cibleausol').change(async (event) => {
|
||||||
|
this.rollData.desavantages.cibleausol = event.currentTarget.checked
|
||||||
|
})
|
||||||
|
html.find('#cibledesarmee').change(async (event) => {
|
||||||
|
this.rollData.desavantages.cibledesarmee = event.currentTarget.checked
|
||||||
|
})
|
||||||
|
html.find('#ciblerestreint').change(async (event) => {
|
||||||
|
this.rollData.desavantages.ciblerestreint = event.currentTarget.checked
|
||||||
|
})
|
||||||
|
html.find('#cibleimmobilisée').change(async (event) => {
|
||||||
|
this.rollData.desavantages.cibleimmobilisée = event.currentTarget.checked
|
||||||
|
})
|
||||||
|
html.find('#ciblesurplomb').change(async (event) => {
|
||||||
|
this.rollData.desavantages.ciblesurplomb = event.currentTarget.checked
|
||||||
|
})
|
||||||
|
|
||||||
html.find('#doubleD20').change(async (event) => {
|
html.find('#doubleD20').change(async (event) => {
|
||||||
this.rollData.doubleD20 = event.currentTarget.checked
|
this.rollData.doubleD20 = event.currentTarget.checked
|
||||||
})
|
})
|
||||||
|
html.find('#visee').change(async (event) => {
|
||||||
|
this.rollData.visee = event.currentTarget.checked
|
||||||
|
})
|
||||||
|
html.find('#cibleconsciente').change(async (event) => {
|
||||||
|
this.rollData.cibleconsciente = event.currentTarget.checked
|
||||||
|
})
|
||||||
|
html.find('#ciblecourt').change(async (event) => {
|
||||||
|
this.rollData.ciblecourt = event.currentTarget.checked
|
||||||
|
})
|
||||||
|
html.find('#typeCouvert').change(async (event) => {
|
||||||
|
this.rollData.typeCouvert = String(event.currentTarget.value)
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,15 +8,13 @@ export class MournbladeUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async init() {
|
static async init() {
|
||||||
Hooks.on('renderChatLog', (log, html, data) => MournbladeUtility.chatListeners(html))
|
Hooks.on('renderChatMessageHTML', (log, html, data) => MournbladeUtility.chatListeners(html))
|
||||||
Hooks.on("getChatLogEntryContext", (html, options) => MournbladeUtility.chatRollMenu(html, options))
|
Hooks.on("getChatMessageContextOptions", (html, options) => MournbladeUtility.chatRollMenu(html, options))
|
||||||
|
Hooks.on('renderChatMessageHTML', (message, html, data) => MournbladeUtility.chatMessageHandler(message, html, data))
|
||||||
|
|
||||||
Hooks.on("getCombatTrackerEntryContext", (html, options) => {
|
Hooks.on("getCombatTrackerEntryContext", (html, options) => {
|
||||||
MournbladeUtility.pushInitiativeOptions(html, options);
|
MournbladeUtility.pushInitiativeOptions(html, options);
|
||||||
})
|
})
|
||||||
Hooks.on("dropCanvasData", (canvas, data) => {
|
|
||||||
MournbladeUtility.dropItemOnToken(canvas, data)
|
|
||||||
});
|
|
||||||
|
|
||||||
this.rollDataStore = {}
|
this.rollDataStore = {}
|
||||||
this.defenderStore = {}
|
this.defenderStore = {}
|
||||||
@@ -58,15 +56,6 @@ export class MournbladeUtility {
|
|||||||
return actor
|
return actor
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static getModificateurOptions() {
|
|
||||||
let opt = []
|
|
||||||
for (let i = -15; i <= 15; i++) {
|
|
||||||
opt.push(`<option value="${i}">${i}</option>`)
|
|
||||||
}
|
|
||||||
return opt.concat("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static sortArrayObjectsByName(myArray) {
|
static sortArrayObjectsByName(myArray) {
|
||||||
myArray.sort((a, b) => {
|
myArray.sort((a, b) => {
|
||||||
@@ -74,18 +63,9 @@ export class MournbladeUtility {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static getPointAmeOptions() {
|
|
||||||
let opt = []
|
|
||||||
for (let i = 1; i <= 20; i++) {
|
|
||||||
opt.push(`<option value="${i}">${i}</option>`)
|
|
||||||
}
|
|
||||||
return opt.concat("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getAttributs() {
|
static getAttributs() {
|
||||||
return { adr: "Adresse", pui: "Puissance", cla: "Clairvoyance", pre: "Présence", tre: "Trempe" }
|
return game.system.mournblade.config.attributs
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static pushInitiativeOptions(html, options) {
|
static pushInitiativeOptions(html, options) {
|
||||||
@@ -100,6 +80,11 @@ export class MournbladeUtility {
|
|||||||
static async ready() {
|
static async ready() {
|
||||||
const skills = await MournbladeUtility.loadCompendium("fvtt-mournblade.skills")
|
const skills = await MournbladeUtility.loadCompendium("fvtt-mournblade.skills")
|
||||||
this.skills = skills.map(i => i.toObject())
|
this.skills = skills.map(i => i.toObject())
|
||||||
|
|
||||||
|
game.system.mournblade.config.listeNiveauSkill = MournbladeUtility.createDirectOptionList(0, 10)
|
||||||
|
game.system.mournblade.config.listeNiveauCreature = MournbladeUtility.createDirectOptionList(0, 35)
|
||||||
|
game.system.mournblade.config.modificateurOptions = MournbladeUtility.createArrayOptionList(-15, 15)
|
||||||
|
game.system.mournblade.config.pointsAmeOptions = MournbladeUtility.createDirectOptionList(0, 20)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -118,30 +103,72 @@ export class MournbladeUtility {
|
|||||||
static getOptionsStatusList() {
|
static getOptionsStatusList() {
|
||||||
return this.optionsStatusList;
|
return this.optionsStatusList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static getPredilection(comp, predIdx) {
|
||||||
|
let pred = foundry.utils.duplicate(comp.system.predilections)
|
||||||
|
return foundry.utils.duplicate(pred[predIdx] || { name: "Error!" })
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async chatMessageHandler(message, html, data) {
|
||||||
|
const chatCard = $(html).find('.action-section')
|
||||||
|
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)
|
||||||
|
// DEBUG : console.log("FOUND 1!!! ", actor, data.message)
|
||||||
|
if (actor?.isOwner || game.user.isGM) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
chatCard.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async chatListeners(html) {
|
static async chatListeners(html) {
|
||||||
|
|
||||||
html.on("click", '.predilection-reroll', async event => {
|
$(html).on("click", '.predilection-reroll', async event => {
|
||||||
let predIdx = $(event.currentTarget).data("predilection-index")
|
let predIdx = $(event.currentTarget).data("predilection-index")
|
||||||
let messageId = MournbladeUtility.findChatMessageId(event.currentTarget)
|
let messageId = MournbladeUtility.findChatMessageId(event.currentTarget)
|
||||||
let message = game.messages.get(messageId)
|
let message = game.messages.get(messageId)
|
||||||
let rollData = message.getFlag("world", "mournblade-roll")
|
let rollData = message.getFlag("world", "mournblade-roll")
|
||||||
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
||||||
await actor.setPredilectionUsed(rollData.competence._id, predIdx)
|
await actor.setPredilectionUsed(rollData.competence._id, predIdx)
|
||||||
rollData.competence = duplicate(actor.getCompetence(rollData.competence._id))
|
rollData.competence = foundry.utils.duplicate(actor.getCompetence(rollData.competence._id))
|
||||||
|
rollData.predilectionUsed = MournbladeUtility.getPredilection(rollData.competence, predIdx)
|
||||||
await MournbladeUtility.rollMournblade(rollData)
|
await MournbladeUtility.rollMournblade(rollData)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
$(html).on("click", '.arme-roll-degats', async event => {
|
||||||
|
let messageId = MournbladeUtility.findChatMessageId(event.currentTarget)
|
||||||
|
let message = game.messages.get(messageId)
|
||||||
|
let rollData = message.getFlag("world", "mournblade-roll")
|
||||||
|
MournbladeUtility.rollDegatsFromAttaque(rollData)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
$(html).on("click", '.arme-apply-degats', async event => {
|
||||||
|
let messageId = MournbladeUtility.findChatMessageId(event.currentTarget)
|
||||||
|
let message = game.messages.get(messageId)
|
||||||
|
let rollData = message.getFlag("world", "mournblade-roll")
|
||||||
|
if (game.user.isGM) {
|
||||||
|
MournbladeUtility.applyDegatsFromAttaque(rollData)
|
||||||
|
} else {
|
||||||
|
game.socket.emit("system.fvtt-mournblade", { name: "msg_apply_damage", data: { rolLData: rollData } })
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async preloadHandlebarsTemplates() {
|
static async preloadHandlebarsTemplates() {
|
||||||
|
|
||||||
const templatePaths = [
|
const templatePaths = [
|
||||||
'systems/fvtt-mournblade/templates/editor-notes-gm.html',
|
'systems/fvtt-mournblade/templates/editor-notes-gm.hbs',
|
||||||
'systems/fvtt-mournblade/templates/partial-item-description.html',
|
'systems/fvtt-mournblade/templates/partial-item-description.hbs',
|
||||||
'systems/fvtt-mournblade/templates/partial-list-niveau.html'
|
'systems/fvtt-mournblade/templates/partial-item-header.hbs',
|
||||||
|
'systems/fvtt-mournblade/templates/partial-item-nav.hbs'
|
||||||
]
|
]
|
||||||
return loadTemplates(templatePaths);
|
return foundry.applications.handlebars.loadTemplates(templatePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -181,12 +208,10 @@ export class MournbladeUtility {
|
|||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
static createArrayOptionList(min, max) {
|
||||||
/* -------------------------------------------- */
|
let options = [];
|
||||||
static buildListOptions(min, max) {
|
|
||||||
let options = ""
|
|
||||||
for (let i = min; i <= max; i++) {
|
for (let i = min; i <= max; i++) {
|
||||||
options += `<option value="${i}">${i}</option>`
|
options.push({ key: `${i}`, label: `${i}` });
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
@@ -201,22 +226,6 @@ export class MournbladeUtility {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static updateRollData(rollData) {
|
|
||||||
|
|
||||||
let id = rollData.rollId;
|
|
||||||
let oldRollData = this.rollDataStore[id] || {};
|
|
||||||
let newRollData = mergeObject(oldRollData, rollData);
|
|
||||||
this.rollDataStore[id] = newRollData;
|
|
||||||
}
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static saveRollData(rollData) {
|
|
||||||
game.socket.emit("system.fvtt-mournblade", {
|
|
||||||
name: "msg_update_roll", data: rollData
|
|
||||||
}); // Notify all other clients of the roll
|
|
||||||
this.updateRollData(rollData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getRollData(id) {
|
static getRollData(id) {
|
||||||
return this.rollDataStore[id];
|
return this.rollDataStore[id];
|
||||||
@@ -224,11 +233,10 @@ export class MournbladeUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static onSocketMesssage(msg) {
|
static onSocketMesssage(msg) {
|
||||||
if (msg.name == "msg_update_defense_state") {
|
if (msg.name == "msg_apply_damage") {
|
||||||
this.updateDefenseState(msg.data.defenderId, msg.data.rollId);
|
if (game.user.isGM) {
|
||||||
|
this.applyDegatsFromAttaque(msg.data.rollData);
|
||||||
}
|
}
|
||||||
if (msg.name == "msg_update_roll") {
|
|
||||||
this.updateRollData(msg.data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,12 +300,17 @@ export class MournbladeUtility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.computeQualityResult(rollData)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static computeQualityResult(rollData) {
|
||||||
//console.log("Result : ", rollData)
|
//console.log("Result : ", rollData)
|
||||||
if (rollData.difficulte > 0 && !rollData.isDramatique) {
|
if (rollData.difficulte > 0 && !rollData.isDramatique) {
|
||||||
rollData.isSuccess = (rollData.finalResult >= rollData.difficulte)
|
rollData.isSuccess = (rollData.finalResult >= rollData.difficulte)
|
||||||
rollData.isHeroique = ((rollData.finalResult - rollData.difficulte) >= 10)
|
rollData.isHeroique = ((rollData.finalResult - rollData.difficulte) >= 10)
|
||||||
rollData.isDramatique = ((rollData.finalResult - rollData.difficulte) <= -10)
|
rollData.isDramatique = ((rollData.finalResult - rollData.difficulte) <= -10)
|
||||||
|
rollData.isPureSuccess = (rollData.isSuccess && !rollData.isHeroique)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,7 +323,7 @@ export class MournbladeUtility {
|
|||||||
}
|
}
|
||||||
if (!rollData.attr) {
|
if (!rollData.attr) {
|
||||||
rollData.actionImg = "systems/fvtt-mournblade/assets/icons/" + actor.system.attributs[rollData.attrKey].labelnorm + ".webp"
|
rollData.actionImg = "systems/fvtt-mournblade/assets/icons/" + actor.system.attributs[rollData.attrKey].labelnorm + ".webp"
|
||||||
rollData.attr = duplicate(actor.system.attributs[rollData.attrKey])
|
rollData.attr = foundry.utils.duplicate(actor.system.attributs[rollData.attrKey])
|
||||||
}
|
}
|
||||||
|
|
||||||
rollData.diceFormula = rollData.mainDice
|
rollData.diceFormula = rollData.mainDice
|
||||||
@@ -322,17 +335,59 @@ export class MournbladeUtility {
|
|||||||
}
|
}
|
||||||
//console.log("BEFORE COMP", rollData)
|
//console.log("BEFORE COMP", rollData)
|
||||||
if (rollData.competence) {
|
if (rollData.competence) {
|
||||||
rollData.predilections = duplicate(rollData.competence.system.predilections.filter(pred => !pred.used) || [])
|
rollData.predilections = foundry.utils.duplicate(rollData.competence.system.predilections)
|
||||||
let compmod = (rollData.competence.system.niveau == 0) ? -3 : 0
|
let compmod = (rollData.competence.system.niveau == 0) ? -3 : 0
|
||||||
rollData.diceFormula += `+${rollData.attr.value}+${rollData.competence.system.niveau}+${rollData.modificateur}+${compmod}`
|
rollData.diceFormula += `+${rollData.attr.value}+${rollData.competence.system.niveau}+${rollData.modificateur}+${compmod}`
|
||||||
} else {
|
} else {
|
||||||
rollData.diceFormula += `+${rollData.attr.value}*2+${rollData.modificateur}`
|
rollData.diceFormula += `+${rollData.attr.value}*2+${rollData.modificateur}`
|
||||||
}
|
}
|
||||||
|
rollData.diceFormula += `+${rollData.malusSante}+${rollData.malusAme}`
|
||||||
|
|
||||||
if (rollData.arme && rollData.arme.type == "arme") {
|
if (rollData.arme?.type == "arme") {
|
||||||
rollData.diceFormula += `+${rollData.arme.system.bonusmaniementoff}`
|
rollData.diceFormula += `+${rollData.arme.system.bonusmaniementoff}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply modifiers
|
||||||
|
for (let modifier of rollData.modifiers) {
|
||||||
|
if (modifier.system.modifiertype == "roll" && modifier.system.apply) {
|
||||||
|
rollData.diceFormula += `+${modifier.system.value}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Apply desavantages
|
||||||
|
let desavantagesBonus = 0
|
||||||
|
for (let desavantage in rollData.desavantages) {
|
||||||
|
if (rollData.desavantages[desavantage]) {
|
||||||
|
desavantagesBonus += 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
desavantagesBonus = Math.min(15, desavantagesBonus)
|
||||||
|
rollData.diceFormula += `+${desavantagesBonus}`
|
||||||
|
|
||||||
|
// Monté ?
|
||||||
|
if (rollData.isMonte) {
|
||||||
|
rollData.diceFormula += "+5"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specific modifier for distance
|
||||||
|
if (rollData.arme?.system?.isDistance) {
|
||||||
|
if (rollData.visee) {
|
||||||
|
rollData.diceFormula += "+5"
|
||||||
|
}
|
||||||
|
if (rollData.cibleconsciente && rollData.defender) {
|
||||||
|
rollData.diceFormula += `-${rollData.defender.system.attributs.adr.value}`
|
||||||
|
}
|
||||||
|
if (rollData.ciblecourt) {
|
||||||
|
if (rollData.difficulte <= 15) { // Portée courte ou moins
|
||||||
|
rollData.diceFormula += `-5`
|
||||||
|
} else {
|
||||||
|
rollData.diceFormula += `-10`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rollData.typeCouvert && rollData.typeCouvert != "aucun" && rollData.config.couverts[rollData.typeCouvert]) {
|
||||||
|
rollData.diceFormula += `+${rollData.config.couverts[rollData.typeCouvert].value}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rollData.rune) {
|
if (rollData.rune) {
|
||||||
rollData.runeduree = Math.ceil((rollData.runeame + 3) / 3)
|
rollData.runeduree = Math.ceil((rollData.runeame + 3) / 3)
|
||||||
if (rollData.runemode == "inscrire") {
|
if (rollData.runemode == "inscrire") {
|
||||||
@@ -343,15 +398,16 @@ export class MournbladeUtility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let myRoll = new Roll(rollData.diceFormula).roll({ async: false })
|
let myRoll = await new Roll(rollData.diceFormula).evaluate();
|
||||||
await this.showDiceSoNice(myRoll, game.settings.get("core", "rollMode"))
|
await this.showDiceSoNice(myRoll, game.settings.get("core", "rollMode"))
|
||||||
rollData.roll = duplicate(myRoll)
|
rollData.roll = foundry.utils.duplicate(myRoll)
|
||||||
rollData.diceResult = myRoll.terms[0].results[0].result
|
rollData.diceResult = myRoll.terms[0].results[0].result
|
||||||
console.log(">>>> ", myRoll)
|
console.log(">>>> ", myRoll)
|
||||||
|
|
||||||
rollData.finalResult = myRoll.total
|
rollData.finalResult = myRoll.total
|
||||||
this.computeResult(rollData)
|
this.computeResult(rollData)
|
||||||
|
|
||||||
|
// Application immédiate selon type de jet
|
||||||
if (rollData.rune) {
|
if (rollData.rune) {
|
||||||
let subAme = rollData.runeame
|
let subAme = rollData.runeame
|
||||||
if (rollData.isEchec && !rollData.isDramatique) {
|
if (rollData.isEchec && !rollData.isDramatique) {
|
||||||
@@ -359,34 +415,176 @@ export class MournbladeUtility {
|
|||||||
}
|
}
|
||||||
actor.subPointsAme(rollData.runemode, subAme)
|
actor.subPointsAme(rollData.runemode, subAme)
|
||||||
}
|
}
|
||||||
|
if (rollData.typeAttaque == "assomer" && rollData.defenderTokenId && rollData.isPureSuccess) {
|
||||||
|
let defender = game.canvas.tokens.get(rollData?.defenderTokenId)?.actor
|
||||||
|
defender.setModifier("Assomer : Prochaine action", "roll", -5)
|
||||||
|
}
|
||||||
|
if (rollData.typeAttaque == "fuir" && rollData.difficulte > 0 && !rollData.isSuccess) {
|
||||||
|
actor.setModifier("Fuite échouée : -5 en défense ce round et suivant", "defense", -5)
|
||||||
|
}
|
||||||
|
if (rollData.typeAttaque == "immobiliser" && rollData.difficulte > 0 && rollData.isPureSuccess) {
|
||||||
|
actor.setModifier("Immobilisation en cours : -5 pour prochaine action", "roll", -5)
|
||||||
|
}
|
||||||
|
if (rollData.typeAttaque == "chargecavalerie") {
|
||||||
|
actor.setModifier("Charge de Cavalerie : -5 défense pour le tour", "defense", -5)
|
||||||
|
}
|
||||||
this.createChatWithRollMode(rollData.alias, {
|
this.createChatWithRollMode(rollData.alias, {
|
||||||
content: await renderTemplate(`systems/fvtt-mournblade/templates/chat-generic-result.html`, rollData)
|
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-mournblade/templates/chat-generic-result-v2.hbs`, rollData)
|
||||||
}, rollData)
|
}, rollData)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static async rollDegatsFromAttaque(rollData) {
|
||||||
|
let maximize = false
|
||||||
|
let degatsMessage = "Degats normaux"
|
||||||
|
|
||||||
|
if (rollData.arme?.system?.isMelee) {
|
||||||
|
rollData.degatsFormula = rollData.arme.system.totalDegats
|
||||||
|
if (rollData.isHeroique) { // Deux fois les dés de dégats
|
||||||
|
degatsMessage = "Dégats doublés"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rollData.typeAttaque == "assomer") {
|
||||||
|
rollData.degatsFormula = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rollData.typeAttaque == "charger") {
|
||||||
|
rollData.degatsFormula += "+2"
|
||||||
|
}
|
||||||
|
if (rollData.typeAttaque == "chargecavalerie") {
|
||||||
|
rollData.degatsFormula += "+5"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rollData.typeAttaque == "precise") {
|
||||||
|
degatsMessage = "Degats normaux"
|
||||||
|
if (rollData.isHeroique) { // Degats max
|
||||||
|
maximize = true
|
||||||
|
degatsMessage = "Dégats maximaux, ignore l'armure du défenseur";
|
||||||
|
rollData.ignoreDefenseArmor = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rollData.typeAttaque == "feinte") {
|
||||||
|
degatsMessage = "Pas de dégats, mais bonus pour prochaine attaque"
|
||||||
|
rollData.degatsFormula = false
|
||||||
|
rollData.nextBonus = 5
|
||||||
|
if (rollData.isHeroique) { // Bonus pour prochaine action
|
||||||
|
rollData.nextBonus = 10
|
||||||
|
rollData.nextBonusDegats = 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rollData.typeAttaque == "coupbas") {
|
||||||
|
degatsMessage = "Pas de dégats, mais malus pour prochaine action complexe du défenseur"
|
||||||
|
rollData.degatsFormula = false
|
||||||
|
rollData.nextMalus = 5
|
||||||
|
if (rollData.isHeroique) { // Malus pour prochaine action
|
||||||
|
rollData.nextMalus = 15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rollData.typeAttaque == "contenir") {
|
||||||
|
degatsMessage = "Pas de dégats, mais l'adversaire ne peut pas vous attaquer pour le reste du tour"
|
||||||
|
rollData.degatsFormula = false
|
||||||
|
if (rollData.isHeroique) { // Malus pour prochaine action
|
||||||
|
degatsMessage = "Pas de dégats, mais tout les adversaires avec une défense inférieure ou égale à " + rollData.finalResult - 10 +
|
||||||
|
" ne peuvent pas vous attaquer pour le reste du tour"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rollData.typeAttaque == "desarmer") {
|
||||||
|
degatsMessage = "Pas de dégats, mais l'adversaire reçoit un malus de -5 pour sa prochaine action"
|
||||||
|
rollData.degatsFormula = false
|
||||||
|
if (rollData.isHeroique) { // Malus pour prochaine action
|
||||||
|
rollData.defenderDesarme = true
|
||||||
|
degatsMessage = "Pas de dégats, mais l'arme de votre adversaire est arrachée de ses mains"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // Armes à distance
|
||||||
|
rollData.degatsFormula = rollData.arme.system.totalDegats
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the roll, show the dice
|
||||||
|
rollData.finalResult = 0
|
||||||
|
rollData.degatsMessage = degatsMessage
|
||||||
|
if (rollData.degatsFormula) {
|
||||||
|
console.log("Degats formula", rollData.degatsFormula)
|
||||||
|
// Twice!maximize
|
||||||
|
if (rollData.isHeroique && !maximize) {
|
||||||
|
rollData.degatsFormula += "+" + rollData.degatsFormula
|
||||||
|
}
|
||||||
|
// Latest modifiers
|
||||||
|
for (let mod of rollData.modifiers) {
|
||||||
|
if (mod.system.modifiertype == "degats") {
|
||||||
|
rollData.degatsFormula += `+${mod.system.value}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let degatsRoll = await new Roll(rollData.degatsFormula).evaluate({ maximize: maximize })
|
||||||
|
await this.showDiceSoNice(degatsRoll, game.settings.get("core", "rollMode"))
|
||||||
|
rollData.degatsRoll = foundry.utils.duplicate(degatsRoll)
|
||||||
|
rollData.finalResult = degatsRoll.total
|
||||||
|
}
|
||||||
|
|
||||||
|
this.createChatWithRollMode(rollData.alias, {
|
||||||
|
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-mournblade/templates/chat-degats-result-v2.hbs`, rollData)
|
||||||
|
}, rollData)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static applyDegatsFromAttaque(rollData) {
|
||||||
|
let defender = game.canvas.tokens.get(rollData?.defenderTokenId)?.actor
|
||||||
|
if (defender && rollData.arme) {
|
||||||
|
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
||||||
|
if (rollData.typeAttaque == "desarmer" && !rollData.isHeroique) {
|
||||||
|
defender.setModifier("Malus suite à désarmement", "roll", -5)
|
||||||
|
}
|
||||||
|
if (rollData.typeAttaque == "charger") {
|
||||||
|
actor.setModifier("Défense suite à charge", "roll", -5)
|
||||||
|
}
|
||||||
|
if (rollData.nextBonus) {
|
||||||
|
actor.setModifier("Prochaine attaque", "roll", rollData.nextBonus)
|
||||||
|
if (rollData.nextDegatsBonus) {
|
||||||
|
actor.setModifier("Prochaine attaque", "degats", rollData.nextDegatsBonus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rollData.nextMalus) {
|
||||||
|
defender.setModifier("Prochaine action complexe", "roll", -rollData.nextMalus)
|
||||||
|
}
|
||||||
|
if (rollData.defenderDesarme) {
|
||||||
|
ui.notifications.info("L'arme de " + defender.name + " est arrachée de ses mains (à gérer manuellement)")
|
||||||
|
}
|
||||||
|
let degats = rollData.finalResult
|
||||||
|
|
||||||
|
let type = (rollData.arme.system.nonletaux) ? "nonletaux" : "letaux"
|
||||||
|
if (rollData.arme.system.ignorearmure) {
|
||||||
|
rollData.ignoreDefenseArmor = true
|
||||||
|
}
|
||||||
|
defender.incDecSante(type, +degats, rollData.ignoreDefenseArmor)
|
||||||
|
ui.notifications.info(defender.name + "a subi " + degats + " points de santé " + type + ".")
|
||||||
|
} else {
|
||||||
|
ui.notifications.warn("Pas de cible sélectionnée ou pas d'arme de défense équipée.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async bonusRollMournblade(rollData) {
|
static async bonusRollMournblade(rollData) {
|
||||||
rollData.bonusFormula = rollData.addedBonus
|
rollData.bonusFormula = rollData.addedBonus
|
||||||
|
|
||||||
let bonusRoll = new Roll(rollData.bonusFormula).roll({ async: false })
|
let bonusRoll = await new Roll(rollData.bonusFormula).evaluate()
|
||||||
await this.showDiceSoNice(bonusRoll, game.settings.get("core", "rollMode"));
|
await this.showDiceSoNice(bonusRoll, game.settings.get("core", "rollMode"));
|
||||||
rollData.bonusRoll = duplicate(bonusRoll)
|
rollData.bonusRoll = foundry.utils.duplicate(bonusRoll)
|
||||||
|
|
||||||
rollData.finalResult += rollData.bonusRoll.total
|
rollData.finalResult += rollData.bonusRoll.total
|
||||||
|
|
||||||
this.computeResult(rollData)
|
this.computeQualityResult(rollData)
|
||||||
|
|
||||||
this.createChatWithRollMode(rollData.alias, {
|
this.createChatWithRollMode(rollData.alias, {
|
||||||
content: await renderTemplate(`systems/fvtt-mournblade/templates/chat-generic-result.html`, rollData)
|
content: await foundry.applications.handlebars.renderTemplate(`systems/fvtt-mournblade/templates/chat-generic-result-v2.hbs`, rollData)
|
||||||
}, rollData)
|
}, rollData)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getUsers(filter) {
|
static getUsers(filter) {
|
||||||
return game.users.filter(filter).map(user => user.data._id);
|
return game.users.filter(filter).map(user => user._id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@@ -406,7 +604,7 @@ export class MournbladeUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static blindMessageToGM(chatOptions) {
|
static blindMessageToGM(chatOptions) {
|
||||||
let chatGM = duplicate(chatOptions);
|
let chatGM = foundry.utils.duplicate(chatOptions);
|
||||||
chatGM.whisper = this.getUsers(user => user.isGM);
|
chatGM.whisper = this.getUsers(user => user.isGM);
|
||||||
chatGM.content = "Blinde message of " + game.user.name + "<br>" + chatOptions.content;
|
chatGM.content = "Blinde message of " + game.user.name + "<br>" + chatOptions.content;
|
||||||
console.log("blindMessageToGM", chatGM);
|
console.log("blindMessageToGM", chatGM);
|
||||||
@@ -459,7 +657,8 @@ export class MournbladeUtility {
|
|||||||
chatOptions.whisper = this.getWhisperRecipients(rollMode, name);
|
chatOptions.whisper = this.getWhisperRecipients(rollMode, name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
chatOptions.alias = chatOptions.alias || name
|
chatOptions.alias = chatOptions.alias || name;
|
||||||
|
chatOptions.speaker = ChatMessage.getSpeaker();
|
||||||
let msg = await ChatMessage.create(chatOptions)
|
let msg = await ChatMessage.create(chatOptions)
|
||||||
console.log("=======>", rollData)
|
console.log("=======>", rollData)
|
||||||
msg.setFlag("world", "mournblade-roll", rollData)
|
msg.setFlag("world", "mournblade-roll", rollData)
|
||||||
@@ -468,12 +667,11 @@ export class MournbladeUtility {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static getBasicRollData() {
|
static getBasicRollData() {
|
||||||
let rollData = {
|
let rollData = {
|
||||||
rollId: randomID(16),
|
rollId: foundry.utils.randomID(16),
|
||||||
rollMode: game.settings.get("core", "rollMode"),
|
rollMode: game.settings.get("core", "rollMode"),
|
||||||
modificateursOptions: this.getModificateurOptions(),
|
|
||||||
pointAmeOptions: this.getPointAmeOptions(),
|
|
||||||
difficulte: 0,
|
difficulte: 0,
|
||||||
modificateur: 0,
|
modificateur: 0,
|
||||||
|
config: foundry.utils.duplicate(game.system.mournblade.config),
|
||||||
}
|
}
|
||||||
MournbladeUtility.updateWithTarget(rollData)
|
MournbladeUtility.updateWithTarget(rollData)
|
||||||
return rollData
|
return rollData
|
||||||
@@ -485,6 +683,9 @@ export class MournbladeUtility {
|
|||||||
if (target) {
|
if (target) {
|
||||||
rollData.defenderTokenId = target.id
|
rollData.defenderTokenId = target.id
|
||||||
let defender = game.canvas.tokens.get(rollData.defenderTokenId).actor
|
let defender = game.canvas.tokens.get(rollData.defenderTokenId).actor
|
||||||
|
rollData.defenderCombatValues = defender.getCombatValues()
|
||||||
|
rollData.defender = defender.toObject() // Simpler
|
||||||
|
rollData.defenderDefense = defender.getBestDefenseValue()
|
||||||
rollData.armeDefense = defender.getBestDefenseValue()
|
rollData.armeDefense = defender.getBestDefenseValue()
|
||||||
if (rollData.armeDefense) {
|
if (rollData.armeDefense) {
|
||||||
rollData.difficulte = rollData.armeDefense.system.totalDefensif
|
rollData.difficulte = rollData.armeDefense.system.totalDefensif
|
||||||
@@ -501,7 +702,7 @@ export class MournbladeUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static applyBonneAventureRoll(li, changed, addedBonus) {
|
static applyBonneAventureRoll(li, changed, addedBonus) {
|
||||||
let msgId = li.data("message-id")
|
let msgId = $(li).data("message-id")
|
||||||
let msg = game.messages.get(msgId)
|
let msg = game.messages.get(msgId)
|
||||||
if (msg) {
|
if (msg) {
|
||||||
let rollData = msg.getFlag("world", "mournblade-roll")
|
let rollData = msg.getFlag("world", "mournblade-roll")
|
||||||
@@ -520,7 +721,7 @@ export class MournbladeUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static applyEclatRoll(li, changed, addedBonus) {
|
static applyEclatRoll(li, changed, addedBonus) {
|
||||||
let msgId = li.data("message-id")
|
let msgId = $(li).data("message-id")
|
||||||
let msg = game.messages.get(msgId)
|
let msg = game.messages.get(msgId)
|
||||||
if (msg) {
|
if (msg) {
|
||||||
let rollData = msg.getFlag("world", "mournblade-roll")
|
let rollData = msg.getFlag("world", "mournblade-roll")
|
||||||
@@ -537,51 +738,51 @@ export class MournbladeUtility {
|
|||||||
static chatRollMenu(html, options) {
|
static chatRollMenu(html, options) {
|
||||||
let canApply = li => canvas.tokens.controlled.length && li.find(".mournblade-roll").length
|
let canApply = li => canvas.tokens.controlled.length && li.find(".mournblade-roll").length
|
||||||
let canApplyBALoyal = function (li) {
|
let canApplyBALoyal = function (li) {
|
||||||
let message = game.messages.get(li.attr("data-message-id"))
|
let message = game.messages.get($(li).attr("data-message-id"))
|
||||||
let rollData = message.getFlag("world", "mournblade-roll")
|
let rollData = message.getFlag("world", "mournblade-roll")
|
||||||
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
||||||
return (!rollData.isReroll && actor.getBonneAventure() > 0 && actor.getAlignement() == "loyal")
|
return (!rollData.isReroll && actor.getBonneAventure() > 0 && actor.getAlignement() == "loyal")
|
||||||
}
|
}
|
||||||
let canApplyPELoyal = function (li) {
|
let canApplyPELoyal = function (li) {
|
||||||
let message = game.messages.get(li.attr("data-message-id"))
|
let message = game.messages.get($(li).attr("data-message-id"))
|
||||||
let rollData = message.getFlag("world", "mournblade-roll")
|
let rollData = message.getFlag("world", "mournblade-roll")
|
||||||
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
||||||
return (!rollData.isReroll && actor.getEclat() > 0 && actor.getAlignement() == "loyal")
|
return (!rollData.isReroll && actor.getEclat() > 0 && actor.getAlignement() == "loyal")
|
||||||
}
|
}
|
||||||
let canApplyBAChaotique = function (li) {
|
let canApplyBAChaotique = function (li) {
|
||||||
let message = game.messages.get(li.attr("data-message-id"))
|
let message = game.messages.get($(li).attr("data-message-id"))
|
||||||
let rollData = message.getFlag("world", "mournblade-roll")
|
let rollData = message.getFlag("world", "mournblade-roll")
|
||||||
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
||||||
return (!rollData.isReroll && actor.getBonneAventure() > 0 && actor.getAlignement() == "chaotique")
|
return (!rollData.isReroll && actor.getBonneAventure() > 0 && actor.getAlignement() == "chaotique")
|
||||||
}
|
}
|
||||||
let canApplyBAChaotique3 = function (li) {
|
let canApplyBAChaotique3 = function (li) {
|
||||||
let message = game.messages.get(li.attr("data-message-id"))
|
let message = game.messages.get($(li).attr("data-message-id"))
|
||||||
let rollData = message.getFlag("world", "mournblade-roll")
|
let rollData = message.getFlag("world", "mournblade-roll")
|
||||||
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
||||||
return (!rollData.isReroll && actor.getBonneAventure() > 2 && actor.getAlignement() == "chaotique")
|
return (!rollData.isReroll && actor.getBonneAventure() > 2 && actor.getAlignement() == "chaotique")
|
||||||
}
|
}
|
||||||
let canApplyPEChaotique = function (li) {
|
let canApplyPEChaotique = function (li) {
|
||||||
let message = game.messages.get(li.attr("data-message-id"))
|
let message = game.messages.get($(li).attr("data-message-id"))
|
||||||
let rollData = message.getFlag("world", "mournblade-roll")
|
let rollData = message.getFlag("world", "mournblade-roll")
|
||||||
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
||||||
return (!rollData.isReroll && actor.getEclat() > 0 && actor.getAlignement() == "chaotique")
|
return (!rollData.isReroll && actor.getEclat() > 0 && actor.getAlignement() == "chaotique")
|
||||||
}
|
}
|
||||||
let hasPredilection = function (li) {
|
let hasPredilection = function (li) {
|
||||||
let message = game.messages.get(li.attr("data-message-id"))
|
let message = game.messages.get($(li).attr("data-message-id"))
|
||||||
let rollData = message.getFlag("world", "mournblade-roll")
|
let rollData = message.getFlag("world", "mournblade-roll")
|
||||||
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
||||||
if (rollData.competence) {
|
if (rollData.competence) {
|
||||||
let nbPred = rollData.competence.data.predilections.filter(pred => !pred.used).length
|
let nbPred = rollData.competence.system.predilections.filter(pred => !pred.used).length
|
||||||
return (!rollData.isReroll && rollData.competence && nbPred > 0)
|
return (!rollData.isReroll && rollData.competence && nbPred > 0)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
let canCompetenceDouble = function (li) {
|
let canCompetenceDouble = function (li) {
|
||||||
let message = game.messages.get(li.attr("data-message-id"))
|
let message = game.messages.get($(li).attr("data-message-id"))
|
||||||
let rollData = message.getFlag("world", "mournblade-roll")
|
let rollData = message.getFlag("world", "mournblade-roll")
|
||||||
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
let actor = MournbladeUtility.getActorFromRollData(rollData)
|
||||||
if (rollData.competence) {
|
if (rollData.competence) {
|
||||||
return rollData.competence.data.doublebonus
|
return rollData.competence.system.doublebonus
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -646,25 +847,25 @@ export class MournbladeUtility {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async confirmDelete(actorSheet, li) {
|
static async confirmDelete(actorSheet, li) {
|
||||||
let itemId = li.data("item-id");
|
let itemId = li.dataset?.itemId || li.data("item-id");
|
||||||
let msgTxt = "<p>Are you sure to remove this Item ?";
|
let msgTxt = "<p>Voulez vous supprimer cet item ?";
|
||||||
let buttons = {
|
let buttons = {
|
||||||
delete: {
|
delete: {
|
||||||
icon: '<i class="fas fa-check"></i>',
|
icon: '<i class="fas fa-check"></i>',
|
||||||
label: "Yes, remove it",
|
label: "Oui !",
|
||||||
callback: () => {
|
callback: () => {
|
||||||
actorSheet.actor.deleteEmbeddedDocuments("Item", [itemId]);
|
actorSheet.actor.deleteEmbeddedDocuments("Item", [itemId]);
|
||||||
li.slideUp(200, () => actorSheet.render(false));
|
actorSheet.render(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
cancel: {
|
cancel: {
|
||||||
icon: '<i class="fas fa-times"></i>',
|
icon: '<i class="fas fa-times"></i>',
|
||||||
label: "Cancel"
|
label: "Non !"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
msgTxt += "</p>";
|
msgTxt += "</p>";
|
||||||
let d = new Dialog({
|
let d = new Dialog({
|
||||||
title: "Confirm removal",
|
title: "Confirmer la suppression",
|
||||||
content: msgTxt,
|
content: msgTxt,
|
||||||
buttons: buttons,
|
buttons: buttons,
|
||||||
default: "cancel"
|
default: "cancel"
|
||||||
|
|||||||
4968
package-lock.json
generated
Normal file
4968
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
package.json
Normal file
16
package.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "fvtt-mournblade",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Mournblade RPG for FoundryVTT - French",
|
||||||
|
"scripts": {
|
||||||
|
"build": "gulp build",
|
||||||
|
"watch": "gulp watch"
|
||||||
|
},
|
||||||
|
"author": "Uberwald/LeRatierBretonnien",
|
||||||
|
"license": "SEE LICENSE IN LICENCE.txt",
|
||||||
|
"devDependencies": {
|
||||||
|
"gulp": "^4.0.2",
|
||||||
|
"gulp-less": "^5.0.0",
|
||||||
|
"gulp-sourcemaps": "^3.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
BIN
packs/armes/000235.ldb
Normal file
BIN
packs/armes/000235.ldb
Normal file
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000014
|
MANIFEST-000304
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
2023/12/19-22:15:44.879816 7f3323fff6c0 Recovering log #12
|
2026/01/09-16:51:34.709189 7f1c56bff6c0 Recovering log #302
|
||||||
2023/12/19-22:15:44.890587 7f3323fff6c0 Delete type=3 #10
|
2026/01/09-16:51:34.720652 7f1c56bff6c0 Delete type=3 #300
|
||||||
2023/12/19-22:15:44.890683 7f3323fff6c0 Delete type=0 #12
|
2026/01/09-16:51:34.720827 7f1c56bff6c0 Delete type=0 #302
|
||||||
2023/12/19-22:15:56.534936 7f33223ff6c0 Level-0 table #17: started
|
2026/01/09-17:10:52.171232 7f1c54bfb6c0 Level-0 table #307: started
|
||||||
2023/12/19-22:15:56.535009 7f33223ff6c0 Level-0 table #17: 0 bytes OK
|
2026/01/09-17:10:52.171270 7f1c54bfb6c0 Level-0 table #307: 0 bytes OK
|
||||||
2023/12/19-22:15:56.541696 7f33223ff6c0 Delete type=0 #15
|
2026/01/09-17:10:52.181182 7f1c54bfb6c0 Delete type=0 #305
|
||||||
2023/12/19-22:15:56.548995 7f33223ff6c0 Manual compaction at level-0 from '!items!0swiE8k5zfUIqmXu' @ 72057594037927935 : 1 .. '!items!wv5EiePmPTpqFutt' @ 0 : 0; will stop at (end)
|
2026/01/09-17:10:52.181380 7f1c54bfb6c0 Manual compaction at level-0 from '!items!0swiE8k5zfUIqmXu' @ 72057594037927935 : 1 .. '!items!wv5EiePmPTpqFutt' @ 0 : 0; will stop at (end)
|
||||||
2023/12/19-22:15:56.555645 7f33223ff6c0 Manual compaction at level-1 from '!items!0swiE8k5zfUIqmXu' @ 72057594037927935 : 1 .. '!items!wv5EiePmPTpqFutt' @ 0 : 0; will stop at (end)
|
2026/01/09-17:10:52.181415 7f1c54bfb6c0 Manual compaction at level-1 from '!items!0swiE8k5zfUIqmXu' @ 72057594037927935 : 1 .. '!items!wv5EiePmPTpqFutt' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
2023/12/19-21:45:05.580403 7f3323fff6c0 Recovering log #8
|
2026/01/09-16:50:28.487537 7f1c56bff6c0 Recovering log #298
|
||||||
2023/12/19-21:45:05.635099 7f3323fff6c0 Delete type=3 #6
|
2026/01/09-16:50:28.498450 7f1c56bff6c0 Delete type=3 #296
|
||||||
2023/12/19-21:45:05.635255 7f3323fff6c0 Delete type=0 #8
|
2026/01/09-16:50:28.498515 7f1c56bff6c0 Delete type=0 #298
|
||||||
2023/12/19-21:45:32.368329 7f33223ff6c0 Level-0 table #13: started
|
2026/01/09-16:51:28.840653 7f1c54bfb6c0 Level-0 table #303: started
|
||||||
2023/12/19-21:45:32.368364 7f33223ff6c0 Level-0 table #13: 0 bytes OK
|
2026/01/09-16:51:28.840708 7f1c54bfb6c0 Level-0 table #303: 0 bytes OK
|
||||||
2023/12/19-21:45:32.374930 7f33223ff6c0 Delete type=0 #11
|
2026/01/09-16:51:28.847927 7f1c54bfb6c0 Delete type=0 #301
|
||||||
2023/12/19-21:45:32.386871 7f33223ff6c0 Manual compaction at level-0 from '!items!0swiE8k5zfUIqmXu' @ 72057594037927935 : 1 .. '!items!wv5EiePmPTpqFutt' @ 0 : 0; will stop at (end)
|
2026/01/09-16:51:28.868475 7f1c54bfb6c0 Manual compaction at level-0 from '!items!0swiE8k5zfUIqmXu' @ 72057594037927935 : 1 .. '!items!wv5EiePmPTpqFutt' @ 0 : 0; will stop at (end)
|
||||||
2023/12/19-21:45:32.393727 7f33223ff6c0 Manual compaction at level-1 from '!items!0swiE8k5zfUIqmXu' @ 72057594037927935 : 1 .. '!items!wv5EiePmPTpqFutt' @ 0 : 0; will stop at (end)
|
2026/01/09-16:51:28.868551 7f1c54bfb6c0 Manual compaction at level-1 from '!items!0swiE8k5zfUIqmXu' @ 72057594037927935 : 1 .. '!items!wv5EiePmPTpqFutt' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
BIN
packs/armes/MANIFEST-000304
Normal file
BIN
packs/armes/MANIFEST-000304
Normal file
Binary file not shown.
Binary file not shown.
BIN
packs/dons/000234.ldb
Normal file
BIN
packs/dons/000234.ldb
Normal file
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000014
|
MANIFEST-000303
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
2023/12/19-22:15:44.922363 7f3322ffd6c0 Recovering log #12
|
2026/01/09-16:51:34.750271 7f1c55bfd6c0 Recovering log #301
|
||||||
2023/12/19-22:15:44.933242 7f3322ffd6c0 Delete type=3 #10
|
2026/01/09-16:51:34.760726 7f1c55bfd6c0 Delete type=3 #299
|
||||||
2023/12/19-22:15:44.933334 7f3322ffd6c0 Delete type=0 #12
|
2026/01/09-16:51:34.760813 7f1c55bfd6c0 Delete type=0 #301
|
||||||
2023/12/19-22:15:56.541869 7f33223ff6c0 Level-0 table #17: started
|
2026/01/09-17:10:52.202603 7f1c54bfb6c0 Level-0 table #306: started
|
||||||
2023/12/19-22:15:56.541915 7f33223ff6c0 Level-0 table #17: 0 bytes OK
|
2026/01/09-17:10:52.202692 7f1c54bfb6c0 Level-0 table #306: 0 bytes OK
|
||||||
2023/12/19-22:15:56.548800 7f33223ff6c0 Delete type=0 #15
|
2026/01/09-17:10:52.216180 7f1c54bfb6c0 Delete type=0 #304
|
||||||
2023/12/19-22:15:56.555609 7f33223ff6c0 Manual compaction at level-0 from '!items!5dGXNiL3WN4cAk7X' @ 72057594037927935 : 1 .. '!items!zzz9JrtWjELdoAfK' @ 0 : 0; will stop at (end)
|
2026/01/09-17:10:52.229242 7f1c54bfb6c0 Manual compaction at level-0 from '!items!5dGXNiL3WN4cAk7X' @ 72057594037927935 : 1 .. '!items!zzz9JrtWjELdoAfK' @ 0 : 0; will stop at (end)
|
||||||
2023/12/19-22:15:56.555674 7f33223ff6c0 Manual compaction at level-1 from '!items!5dGXNiL3WN4cAk7X' @ 72057594037927935 : 1 .. '!items!zzz9JrtWjELdoAfK' @ 0 : 0; will stop at (end)
|
2026/01/09-17:10:52.229348 7f1c54bfb6c0 Manual compaction at level-1 from '!items!5dGXNiL3WN4cAk7X' @ 72057594037927935 : 1 .. '!items!zzz9JrtWjELdoAfK' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
2023/12/19-21:45:05.751995 7f33237fe6c0 Recovering log #8
|
2026/01/09-16:50:28.529034 7f1c56bff6c0 Recovering log #297
|
||||||
2023/12/19-21:45:05.802361 7f33237fe6c0 Delete type=3 #6
|
2026/01/09-16:50:28.539837 7f1c56bff6c0 Delete type=3 #295
|
||||||
2023/12/19-21:45:05.802459 7f33237fe6c0 Delete type=0 #8
|
2026/01/09-16:50:28.539910 7f1c56bff6c0 Delete type=0 #297
|
||||||
2023/12/19-21:45:32.401535 7f33223ff6c0 Level-0 table #13: started
|
2026/01/09-16:51:28.861880 7f1c54bfb6c0 Level-0 table #302: started
|
||||||
2023/12/19-21:45:32.401586 7f33223ff6c0 Level-0 table #13: 0 bytes OK
|
2026/01/09-16:51:28.861911 7f1c54bfb6c0 Level-0 table #302: 0 bytes OK
|
||||||
2023/12/19-21:45:32.408618 7f33223ff6c0 Delete type=0 #11
|
2026/01/09-16:51:28.868272 7f1c54bfb6c0 Delete type=0 #300
|
||||||
2023/12/19-21:45:32.416737 7f33223ff6c0 Manual compaction at level-0 from '!items!5dGXNiL3WN4cAk7X' @ 72057594037927935 : 1 .. '!items!zzz9JrtWjELdoAfK' @ 0 : 0; will stop at (end)
|
2026/01/09-16:51:28.868530 7f1c54bfb6c0 Manual compaction at level-0 from '!items!5dGXNiL3WN4cAk7X' @ 72057594037927935 : 1 .. '!items!zzz9JrtWjELdoAfK' @ 0 : 0; will stop at (end)
|
||||||
2023/12/19-21:45:32.416779 7f33223ff6c0 Manual compaction at level-1 from '!items!5dGXNiL3WN4cAk7X' @ 72057594037927935 : 1 .. '!items!zzz9JrtWjELdoAfK' @ 0 : 0; will stop at (end)
|
2026/01/09-16:51:28.868572 7f1c54bfb6c0 Manual compaction at level-1 from '!items!5dGXNiL3WN4cAk7X' @ 72057594037927935 : 1 .. '!items!zzz9JrtWjELdoAfK' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
BIN
packs/dons/MANIFEST-000303
Normal file
BIN
packs/dons/MANIFEST-000303
Normal file
Binary file not shown.
Binary file not shown.
BIN
packs/equipement/000234.ldb
Normal file
BIN
packs/equipement/000234.ldb
Normal file
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000014
|
MANIFEST-000303
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
2023/12/19-22:15:44.907560 7f33237fe6c0 Recovering log #12
|
2026/01/09-16:51:34.736494 7f1c563fe6c0 Recovering log #301
|
||||||
2023/12/19-22:15:44.919038 7f33237fe6c0 Delete type=3 #10
|
2026/01/09-16:51:34.746896 7f1c563fe6c0 Delete type=3 #299
|
||||||
2023/12/19-22:15:44.919177 7f33237fe6c0 Delete type=0 #12
|
2026/01/09-16:51:34.747053 7f1c563fe6c0 Delete type=0 #301
|
||||||
2023/12/19-22:15:56.527537 7f33223ff6c0 Level-0 table #17: started
|
2026/01/09-17:10:52.181524 7f1c54bfb6c0 Level-0 table #306: started
|
||||||
2023/12/19-22:15:56.527579 7f33223ff6c0 Level-0 table #17: 0 bytes OK
|
2026/01/09-17:10:52.181569 7f1c54bfb6c0 Level-0 table #306: 0 bytes OK
|
||||||
2023/12/19-22:15:56.534748 7f33223ff6c0 Delete type=0 #15
|
2026/01/09-17:10:52.192560 7f1c54bfb6c0 Delete type=0 #304
|
||||||
2023/12/19-22:15:56.548969 7f33223ff6c0 Manual compaction at level-0 from '!items!1cZd2hlTV9tykDED' @ 72057594037927935 : 1 .. '!items!y47dBO3Mf5Pn7tOd' @ 0 : 0; will stop at (end)
|
2026/01/09-17:10:52.229188 7f1c54bfb6c0 Manual compaction at level-0 from '!items!1cZd2hlTV9tykDED' @ 72057594037927935 : 1 .. '!items!y47dBO3Mf5Pn7tOd' @ 0 : 0; will stop at (end)
|
||||||
2023/12/19-22:15:56.555629 7f33223ff6c0 Manual compaction at level-1 from '!items!1cZd2hlTV9tykDED' @ 72057594037927935 : 1 .. '!items!y47dBO3Mf5Pn7tOd' @ 0 : 0; will stop at (end)
|
2026/01/09-17:10:52.229310 7f1c54bfb6c0 Manual compaction at level-1 from '!items!1cZd2hlTV9tykDED' @ 72057594037927935 : 1 .. '!items!y47dBO3Mf5Pn7tOd' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
2023/12/19-21:45:05.694845 7f3322ffd6c0 Recovering log #8
|
2026/01/09-16:50:28.515550 7f1c563fe6c0 Recovering log #297
|
||||||
2023/12/19-21:45:05.749080 7f3322ffd6c0 Delete type=3 #6
|
2026/01/09-16:50:28.525696 7f1c563fe6c0 Delete type=3 #295
|
||||||
2023/12/19-21:45:05.749173 7f3322ffd6c0 Delete type=0 #8
|
2026/01/09-16:50:28.525817 7f1c563fe6c0 Delete type=0 #297
|
||||||
2023/12/19-21:45:32.393743 7f33223ff6c0 Level-0 table #13: started
|
2026/01/09-16:51:28.848057 7f1c54bfb6c0 Level-0 table #302: started
|
||||||
2023/12/19-21:45:32.393776 7f33223ff6c0 Level-0 table #13: 0 bytes OK
|
2026/01/09-16:51:28.848089 7f1c54bfb6c0 Level-0 table #302: 0 bytes OK
|
||||||
2023/12/19-21:45:32.401345 7f33223ff6c0 Delete type=0 #11
|
2026/01/09-16:51:28.854366 7f1c54bfb6c0 Delete type=0 #300
|
||||||
2023/12/19-21:45:32.416703 7f33223ff6c0 Manual compaction at level-0 from '!items!1cZd2hlTV9tykDED' @ 72057594037927935 : 1 .. '!items!y47dBO3Mf5Pn7tOd' @ 0 : 0; will stop at (end)
|
2026/01/09-16:51:28.868495 7f1c54bfb6c0 Manual compaction at level-0 from '!items!1cZd2hlTV9tykDED' @ 72057594037927935 : 1 .. '!items!y47dBO3Mf5Pn7tOd' @ 0 : 0; will stop at (end)
|
||||||
2023/12/19-21:45:32.416767 7f33223ff6c0 Manual compaction at level-1 from '!items!1cZd2hlTV9tykDED' @ 72057594037927935 : 1 .. '!items!y47dBO3Mf5Pn7tOd' @ 0 : 0; will stop at (end)
|
2026/01/09-16:51:28.868541 7f1c54bfb6c0 Manual compaction at level-1 from '!items!1cZd2hlTV9tykDED' @ 72057594037927935 : 1 .. '!items!y47dBO3Mf5Pn7tOd' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
BIN
packs/equipement/MANIFEST-000303
Normal file
BIN
packs/equipement/MANIFEST-000303
Normal file
Binary file not shown.
Binary file not shown.
BIN
packs/heritages/000234.ldb
Normal file
BIN
packs/heritages/000234.ldb
Normal file
Binary file not shown.
@@ -1 +1 @@
|
|||||||
MANIFEST-000014
|
MANIFEST-000303
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
2023/12/19-22:15:44.951754 7f35b8bfa6c0 Recovering log #12
|
2026/01/09-16:51:34.777168 7f1c563fe6c0 Recovering log #301
|
||||||
2023/12/19-22:15:44.963535 7f35b8bfa6c0 Delete type=3 #10
|
2026/01/09-16:51:34.788037 7f1c563fe6c0 Delete type=3 #299
|
||||||
2023/12/19-22:15:44.964185 7f35b8bfa6c0 Delete type=0 #12
|
2026/01/09-16:51:34.788106 7f1c563fe6c0 Delete type=0 #301
|
||||||
2023/12/19-22:15:56.555768 7f33223ff6c0 Level-0 table #17: started
|
2026/01/09-17:10:52.240948 7f1c54bfb6c0 Level-0 table #306: started
|
||||||
2023/12/19-22:15:56.555799 7f33223ff6c0 Level-0 table #17: 0 bytes OK
|
2026/01/09-17:10:52.241037 7f1c54bfb6c0 Level-0 table #306: 0 bytes OK
|
||||||
2023/12/19-22:15:56.562320 7f33223ff6c0 Delete type=0 #15
|
2026/01/09-17:10:52.254088 7f1c54bfb6c0 Delete type=0 #304
|
||||||
2023/12/19-22:15:56.583577 7f33223ff6c0 Manual compaction at level-0 from '!items!2GaJZsqr2c2mcDRv' @ 72057594037927935 : 1 .. '!items!ui4JGsGwHNlSXVK3' @ 0 : 0; will stop at (end)
|
2026/01/09-17:10:52.274702 7f1c54bfb6c0 Manual compaction at level-0 from '!items!2GaJZsqr2c2mcDRv' @ 72057594037927935 : 1 .. '!items!ui4JGsGwHNlSXVK3' @ 0 : 0; will stop at (end)
|
||||||
2023/12/19-22:15:56.583652 7f33223ff6c0 Manual compaction at level-1 from '!items!2GaJZsqr2c2mcDRv' @ 72057594037927935 : 1 .. '!items!ui4JGsGwHNlSXVK3' @ 0 : 0; will stop at (end)
|
2026/01/09-17:10:52.274758 7f1c54bfb6c0 Manual compaction at level-1 from '!items!2GaJZsqr2c2mcDRv' @ 72057594037927935 : 1 .. '!items!ui4JGsGwHNlSXVK3' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
2023/12/19-21:45:05.858392 7f3323fff6c0 Recovering log #8
|
2026/01/09-16:50:28.558115 7f1c553fc6c0 Recovering log #297
|
||||||
2023/12/19-21:45:05.908553 7f3323fff6c0 Delete type=3 #6
|
2026/01/09-16:50:28.568519 7f1c553fc6c0 Delete type=3 #295
|
||||||
2023/12/19-21:45:05.908991 7f3323fff6c0 Delete type=0 #8
|
2026/01/09-16:50:28.568591 7f1c553fc6c0 Delete type=0 #297
|
||||||
2023/12/19-21:45:32.431375 7f33223ff6c0 Level-0 table #13: started
|
2026/01/09-16:51:28.868695 7f1c54bfb6c0 Level-0 table #302: started
|
||||||
2023/12/19-21:45:32.431443 7f33223ff6c0 Level-0 table #13: 0 bytes OK
|
2026/01/09-16:51:28.868789 7f1c54bfb6c0 Level-0 table #302: 0 bytes OK
|
||||||
2023/12/19-21:45:32.438078 7f33223ff6c0 Delete type=0 #11
|
2026/01/09-16:51:28.875865 7f1c54bfb6c0 Delete type=0 #300
|
||||||
2023/12/19-21:45:32.445311 7f33223ff6c0 Manual compaction at level-0 from '!items!2GaJZsqr2c2mcDRv' @ 72057594037927935 : 1 .. '!items!ui4JGsGwHNlSXVK3' @ 0 : 0; will stop at (end)
|
2026/01/09-16:51:28.896773 7f1c54bfb6c0 Manual compaction at level-0 from '!items!2GaJZsqr2c2mcDRv' @ 72057594037927935 : 1 .. '!items!ui4JGsGwHNlSXVK3' @ 0 : 0; will stop at (end)
|
||||||
2023/12/19-21:45:32.445367 7f33223ff6c0 Manual compaction at level-1 from '!items!2GaJZsqr2c2mcDRv' @ 72057594037927935 : 1 .. '!items!ui4JGsGwHNlSXVK3' @ 0 : 0; will stop at (end)
|
2026/01/09-16:51:28.896837 7f1c54bfb6c0 Manual compaction at level-1 from '!items!2GaJZsqr2c2mcDRv' @ 72057594037927935 : 1 .. '!items!ui4JGsGwHNlSXVK3' @ 0 : 0; will stop at (end)
|
||||||
|
|||||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user