Compare commits
2 Commits
a008543f61
...
14.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
| 552731bc3b | |||
| 0187daa1e5 |
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 143 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 214 KiB |
@@ -87,6 +87,43 @@
|
||||
--lo-control-height: 1.95rem;
|
||||
--lo-number-width: 4.75rem;
|
||||
}
|
||||
body.system-fvtt-les-oublies #pause {
|
||||
font-size: 2rem;
|
||||
}
|
||||
body.system-fvtt-les-oublies #pause.paused {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
body.system-fvtt-les-oublies #pause > figcaption {
|
||||
color: #d9d4ca;
|
||||
text-shadow: 0 0 10px rgba(255, 255, 255, 0.22);
|
||||
}
|
||||
body.system-fvtt-les-oublies #pause > img {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
body.system-fvtt-les-oublies #pause::before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin-bottom: 0.75rem;
|
||||
background: url("../assets/ui/pause_oublie.webp") center / contain no-repeat;
|
||||
animation: lo-pause-logo 4.2s ease-in-out infinite;
|
||||
transform-origin: 50% 50%;
|
||||
filter: drop-shadow(0 10px 20px rgba(0, 0, 0, 0.35));
|
||||
}
|
||||
@keyframes lo-pause-logo {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(0.98) translateY(0);
|
||||
filter: drop-shadow(0 10px 20px rgba(0, 0, 0, 0.3));
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.03) translateY(-6px);
|
||||
filter: drop-shadow(0 16px 26px rgba(0, 0, 0, 0.45));
|
||||
}
|
||||
}
|
||||
.fvtt-les-oublies.sheet {
|
||||
color: var(--lo-ink);
|
||||
font-family: "Cormorant Garamond", Georgia, serif;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -34,6 +34,50 @@
|
||||
--lo-number-width: 4.75rem;
|
||||
}
|
||||
|
||||
body.system-fvtt-les-oublies #pause {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
body.system-fvtt-les-oublies #pause.paused {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
body.system-fvtt-les-oublies #pause > figcaption {
|
||||
color: #d9d4ca;
|
||||
text-shadow: 0 0 10px rgba(255, 255, 255, 0.22);
|
||||
}
|
||||
|
||||
body.system-fvtt-les-oublies #pause > img {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
body.system-fvtt-les-oublies #pause::before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin-bottom: 0.75rem;
|
||||
background: url("../assets/ui/pause_oublie.webp") center/contain no-repeat;
|
||||
animation: lo-pause-logo 4.2s ease-in-out infinite;
|
||||
transform-origin: 50% 50%;
|
||||
filter: drop-shadow(0 10px 20px rgba(0, 0, 0, 0.35));
|
||||
}
|
||||
|
||||
@keyframes lo-pause-logo {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(0.98) translateY(0);
|
||||
filter: drop-shadow(0 10px 20px rgba(0, 0, 0, 0.3));
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1.03) translateY(-6px);
|
||||
filter: drop-shadow(0 16px 26px rgba(0, 0, 0, 0.45));
|
||||
}
|
||||
}
|
||||
|
||||
.fvtt-les-oublies.sheet {
|
||||
color: var(--lo-ink);
|
||||
font-family: "Cormorant Garamond", Georgia, serif;
|
||||
|
||||
@@ -77,10 +77,27 @@ export default class LesOubliesActorSheet extends HandlebarsApplicationMixin(fou
|
||||
}
|
||||
}
|
||||
|
||||
_prepareWeaponEntries(items = []) {
|
||||
return items.map((item) => ({
|
||||
...item.toObject(),
|
||||
id: item.id,
|
||||
displayDamage: LesOubliesUtility.formatWeaponDamage(this.document, item),
|
||||
}))
|
||||
}
|
||||
|
||||
_onRender(context, options) {
|
||||
super._onRender(context, options)
|
||||
}
|
||||
|
||||
_onDragStart(event) {
|
||||
const itemElement = event.currentTarget?.closest?.("[data-item-id]") ?? event.target?.closest?.("[data-item-id]")
|
||||
const itemId = itemElement?.dataset?.itemId
|
||||
const item = itemId ? this.document.items.get(itemId) : null
|
||||
if (!item || !event.dataTransfer) return
|
||||
|
||||
event.dataTransfer.setData("text/plain", JSON.stringify(item.toDragData()))
|
||||
}
|
||||
|
||||
_canDragStart() {
|
||||
return this.isEditable
|
||||
}
|
||||
|
||||
@@ -105,6 +105,9 @@ export default class LesOubliesItemSheet extends HandlebarsApplicationMixin(foun
|
||||
choiceSets,
|
||||
enriched,
|
||||
enrichedDescription: foundry.utils.getProperty(enriched, "description") ?? "",
|
||||
weaponDamagePreview: this.document.type === "arme"
|
||||
? LesOubliesUtility.formatWeaponDamage(this.document.parent instanceof Actor ? this.document.parent : null, this.document)
|
||||
: "",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ export default class LesOubliesCreatureSheet extends LesOubliesActorSheet {
|
||||
context.derived = this.document.getDerivedOverview()
|
||||
context.skillGroups = this.document.getGroupedCompetences()
|
||||
context.spells = this.document.getEmbeddedItems("sortilege")
|
||||
context.weapons = this.document.getEmbeddedItems("arme")
|
||||
context.weapons = this._prepareWeaponEntries(this.document.getEmbeddedItems("arme"))
|
||||
context.armors = this.document.getEmbeddedItems("armure")
|
||||
context.equipment = this.document.getEmbeddedItems("equipement")
|
||||
return context
|
||||
|
||||
@@ -64,7 +64,7 @@ export default class LesOubliesPersonnageSheet extends LesOubliesActorSheet {
|
||||
context.skillGroups.slice(splitIndex),
|
||||
]
|
||||
context.spells = this.document.getEmbeddedItems("sortilege")
|
||||
context.weapons = this.document.getEmbeddedItems("arme")
|
||||
context.weapons = this._prepareWeaponEntries(this.document.getEmbeddedItems("arme"))
|
||||
context.equippedWeapons = context.weapons.filter((item) => item.system.equipped)
|
||||
context.armors = this.document.getEmbeddedItems("armure")
|
||||
context.equipment = this.document.getEmbeddedItems("equipement")
|
||||
|
||||
@@ -41,8 +41,9 @@ export class LesOubliesActor extends Actor {
|
||||
if (this.type !== "creature") return
|
||||
|
||||
const system = this.system
|
||||
const hpValue = Math.max(Number(system.hp?.value ?? 0), 0)
|
||||
const hpMax = Math.max(Number(system.hp?.max ?? hpValue), hpValue, 0)
|
||||
const sizeValue = Math.clamp(Number(system.size?.value ?? 1), 1, 8)
|
||||
const hpMax = Math.max(sizeValue * 4, 0)
|
||||
const hpValue = Math.max(Number(system.hp?.value ?? hpMax), 0)
|
||||
system.hp.max = hpMax
|
||||
system.hp.value = Math.min(hpValue, hpMax)
|
||||
const songesPoints = Math.max(Number(system.songes?.points ?? 0), 0)
|
||||
|
||||
@@ -60,12 +60,14 @@ export const SIZE_LABELS = {
|
||||
}
|
||||
|
||||
export const WEAPON_CATEGORY_LABELS = {
|
||||
corpsacorps: "Corps à corps",
|
||||
melee: "Mêlée",
|
||||
tir: "Tir",
|
||||
jet: "Jet",
|
||||
}
|
||||
|
||||
export const WEAPON_ORIGIN_LABELS = {
|
||||
animaux: "Animaux",
|
||||
geant: "Géant",
|
||||
petitPeuple: "Petit Peuple",
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import { LesOubliesRolls } from "./les-oublies-rolls.js"
|
||||
import * as models from "./models/index.mjs"
|
||||
import * as sheets from "./applications/sheets/_module.mjs"
|
||||
|
||||
const DEFAULT_PERSONNAGE_TOKEN_TEXTURE = "systems/fvtt-les-oublies/assets/tokens/border_token_oublies.webp"
|
||||
|
||||
function ensureSystemStyles() {
|
||||
const href = `systems/${game.system.id}/css/les-oublies.css`
|
||||
const existingLink = document.querySelector(`link[href$="${href}"]`)
|
||||
@@ -19,6 +21,13 @@ function ensureSystemStyles() {
|
||||
document.head.append(link)
|
||||
}
|
||||
|
||||
function usesFoundryDefaultTokenTexture(actor, data) {
|
||||
const tokenTexture = foundry.utils.getProperty(data, "prototypeToken.texture.src")
|
||||
?? foundry.utils.getProperty(actor, "prototypeToken.texture.src")
|
||||
?? ""
|
||||
return !tokenTexture || tokenTexture === CONST.DEFAULT_TOKEN || tokenTexture === "icons/svg/mystery-man.svg"
|
||||
}
|
||||
|
||||
Hooks.once("init", function () {
|
||||
console.info("Les Oubliés | Initialisation du système")
|
||||
ensureSystemStyles()
|
||||
@@ -67,3 +76,16 @@ Hooks.once("init", function () {
|
||||
|
||||
LesOubliesUtility.registerHandlebarsHelpers()
|
||||
})
|
||||
|
||||
Hooks.on("preCreateActor", function (actor, data) {
|
||||
if (actor.type !== "personnage") return
|
||||
if (!usesFoundryDefaultTokenTexture(actor, data)) return
|
||||
|
||||
actor.updateSource({
|
||||
prototypeToken: {
|
||||
texture: {
|
||||
src: DEFAULT_PERSONNAGE_TOKEN_TEXTURE,
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
@@ -289,10 +289,13 @@ export class LesOubliesRolls {
|
||||
|
||||
const result = await this.resolveTest(actor, data)
|
||||
if (!result) return null
|
||||
const initiativeScore = Math.min(Math.max(Math.ceil(result.final / 2), 0), 12)
|
||||
await this.#syncInitiativeToCombat(actor, initiativeScore)
|
||||
|
||||
return this.#createChatMessage(actor, {
|
||||
...result,
|
||||
mode: "initiative",
|
||||
initiativeScore: Math.min(Math.max(Math.ceil(result.final / 2), 0), 12),
|
||||
initiativeScore,
|
||||
successLabel: null,
|
||||
})
|
||||
}
|
||||
@@ -716,14 +719,7 @@ export class LesOubliesRolls {
|
||||
}
|
||||
|
||||
const pool = this.#buildPool(options.rollMode, options.extraDie)
|
||||
const dice = []
|
||||
for (let index = 0; index < pool.length; index += 1) {
|
||||
const spec = pool[index]
|
||||
dice.push(await this.#rollExplodingDie({
|
||||
...spec,
|
||||
index,
|
||||
}))
|
||||
}
|
||||
const dice = await this.#rollExplodingPool(pool)
|
||||
|
||||
const selectedIndex = this.#needsSelection(dice)
|
||||
? await this.#promptDieSelection(actor, options.label, dice)
|
||||
@@ -792,6 +788,23 @@ export class LesOubliesRolls {
|
||||
})
|
||||
}
|
||||
|
||||
static async #syncInitiativeToCombat(actor, initiativeScore) {
|
||||
if (!game.combat || !actor?.id) return false
|
||||
|
||||
const combatants = game.combat.combatants.filter((combatant) => combatant.actorId === actor.id)
|
||||
if (!combatants.length) {
|
||||
ui.notifications.warn(`${actor.name} n'est pas présent dans le combat actif.`)
|
||||
return false
|
||||
}
|
||||
|
||||
await game.combat.updateEmbeddedDocuments("Combatant", combatants.map((combatant) => ({
|
||||
_id: combatant.id,
|
||||
initiative: initiativeScore,
|
||||
})))
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
static async #createConfrontationMessage(actor, data, actionData = null) {
|
||||
const attacker = await this.resolveTest(actor, {
|
||||
label: data.attackerLabel,
|
||||
@@ -1507,38 +1520,82 @@ export class LesOubliesRolls {
|
||||
return dice
|
||||
}
|
||||
|
||||
static async #rollExplodingDie({ type, index, source = "base" }) {
|
||||
const faces = []
|
||||
const rolls = []
|
||||
let total = 0
|
||||
let lastFace = 12
|
||||
|
||||
while (lastFace === 12) {
|
||||
const roll = await this.#evaluateDisplayedRoll("1d12")
|
||||
lastFace = Number(roll.total ?? 0)
|
||||
rolls.push(roll)
|
||||
faces.push(lastFace)
|
||||
total += lastFace
|
||||
}
|
||||
|
||||
const typeLabel = game.i18n.localize(`LESOUBLIES.rolls.dice.${type}`)
|
||||
return {
|
||||
static async #rollExplodingPool(pool) {
|
||||
const dice = pool.map(({ type, source = "base" }, index) => ({
|
||||
index,
|
||||
type,
|
||||
typeLabel,
|
||||
typeLabel: game.i18n.localize(`LESOUBLIES.rolls.dice.${type}`),
|
||||
source,
|
||||
sourceLabel: source === "extra" ? game.i18n.localize("LESOUBLIES.rolls.extraDie") : null,
|
||||
faces,
|
||||
rolls,
|
||||
firstFace: faces[0] ?? 0,
|
||||
total,
|
||||
exploded: faces.length > 1,
|
||||
breakdown: faces.join(" + "),
|
||||
faces: [],
|
||||
rolls: [],
|
||||
total: 0,
|
||||
}))
|
||||
|
||||
let pendingDice = [...dice]
|
||||
while (pendingDice.length) {
|
||||
const roll = await this.#evaluateDisplayedRoll(
|
||||
Array.from({ length: pendingDice.length }, () => "1d12").join(" + "),
|
||||
(pendingRoll) => this.#applyDieAppearances(pendingRoll, pendingDice),
|
||||
)
|
||||
|
||||
const dieTerms = roll.terms.filter((term) => Number(term.faces ?? 0) === 12)
|
||||
const nextPendingDice = []
|
||||
|
||||
pendingDice.forEach((die, index) => {
|
||||
const face = Number(dieTerms[index]?.results?.[0]?.result ?? 0)
|
||||
die.rolls.push(roll)
|
||||
die.faces.push(face)
|
||||
die.total += face
|
||||
if (face === 12) nextPendingDice.push(die)
|
||||
})
|
||||
|
||||
pendingDice = nextPendingDice
|
||||
}
|
||||
|
||||
return dice.map((die) => ({
|
||||
...die,
|
||||
firstFace: die.faces[0] ?? 0,
|
||||
exploded: die.faces.length > 1,
|
||||
breakdown: die.faces.join(" + "),
|
||||
}))
|
||||
}
|
||||
|
||||
static #applyDieAppearances(roll, dice) {
|
||||
const dieTerms = roll.terms.filter((term) => Number(term.faces ?? 0) === 12)
|
||||
dieTerms.forEach((term, index) => {
|
||||
term.options ??= {}
|
||||
term.options.appearance = this.#getDieAppearance(dice[index]?.type)
|
||||
})
|
||||
}
|
||||
|
||||
static #getDieAppearance(type) {
|
||||
switch (type) {
|
||||
case "songes":
|
||||
return {
|
||||
foreground: "#111111",
|
||||
background: "#f3efe4",
|
||||
outline: "#b8aa87",
|
||||
}
|
||||
case "cauchemar":
|
||||
return {
|
||||
foreground: "#f4f0e8",
|
||||
background: "#111111",
|
||||
outline: "#5d5d5d",
|
||||
}
|
||||
default:
|
||||
return {
|
||||
foreground: "#201813",
|
||||
background: "#ddd0b0",
|
||||
outline: "#8d5c3b",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static async #evaluateDisplayedRoll(formula) {
|
||||
const roll = await (new Roll(formula)).evaluate()
|
||||
static async #evaluateDisplayedRoll(formula, configureRoll = null) {
|
||||
const roll = typeof formula === "string" ? new Roll(formula) : formula
|
||||
if (configureRoll) configureRoll(roll)
|
||||
await roll.evaluate()
|
||||
await this.#showDiceSoNice(roll)
|
||||
return roll
|
||||
}
|
||||
@@ -2059,16 +2116,7 @@ export class LesOubliesRolls {
|
||||
}
|
||||
|
||||
static #getWeaponBaseDamage(actor, weapon) {
|
||||
const damageText = String(weapon?.system?.damage || "")
|
||||
const parsed = this.#extractFirstInteger(damageText)
|
||||
if (parsed !== null) return parsed
|
||||
|
||||
const explicitValue = Number(weapon?.system?.sizeValue ?? 0)
|
||||
if (explicitValue > 0) return explicitValue
|
||||
|
||||
const actorSize = Number(actor?.system?.size?.value ?? 0)
|
||||
const sizeModifier = Number(weapon?.system?.sizeModifier ?? 0)
|
||||
return Math.max(actorSize + sizeModifier, 0)
|
||||
return LesOubliesUtility.getWeaponBaseDamage(actor, weapon)
|
||||
}
|
||||
|
||||
static #extractFirstInteger(text) {
|
||||
|
||||
@@ -97,6 +97,32 @@ export class LesOubliesUtility {
|
||||
return [...documents].sort((left, right) => left.name.localeCompare(right.name, "fr"))
|
||||
}
|
||||
|
||||
static getWeaponBaseDamage(actor, weapon) {
|
||||
const sizeMode = String(weapon?.system?.sizeMode || "").toLowerCase()
|
||||
if (sizeMode === "variable") {
|
||||
const actorSize = Number(actor?.system?.size?.value ?? 0)
|
||||
const sizeModifier = Number(weapon?.system?.sizeModifier ?? 0)
|
||||
return Math.max(actorSize + sizeModifier, 0)
|
||||
}
|
||||
|
||||
const explicitValue = Number(weapon?.system?.sizeValue ?? 0)
|
||||
if (explicitValue > 0) return explicitValue
|
||||
|
||||
const damageText = String(weapon?.system?.damage || "")
|
||||
const match = damageText.match(/-?\d+/)
|
||||
return match ? Number(match[0]) : 0
|
||||
}
|
||||
|
||||
static formatWeaponDamage(actor, weapon) {
|
||||
const baseLabel = String(weapon?.system?.damage || "").trim()
|
||||
const baseDamage = this.getWeaponBaseDamage(actor, weapon)
|
||||
const sizeMode = String(weapon?.system?.sizeMode || "").toLowerCase()
|
||||
if (sizeMode === "variable" || /taille/i.test(baseLabel)) {
|
||||
return baseLabel ? `${baseLabel} (${baseDamage})` : String(baseDamage)
|
||||
}
|
||||
return baseLabel || String(baseDamage)
|
||||
}
|
||||
|
||||
static uniqueStrings(values = []) {
|
||||
return [...new Set((Array.isArray(values) ? values : [])
|
||||
.map((value) => String(value ?? "").trim())
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+1
-1
@@ -1 +1 @@
|
||||
2026/05/04-09:46:56.090569 7fe6b57ed6c0 Delete type=3 #1
|
||||
2026/05/04-20:19:31.964617 7f037d7ed6c0 Delete type=3 #1
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
-1
@@ -1 +1 @@
|
||||
2026/05/04-09:46:56.106804 7fe6b4fec6c0 Delete type=3 #1
|
||||
2026/05/04-20:19:32.040110 7f037cfec6c0 Delete type=3 #1
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
2026/05/04-09:46:56.152550 7fe6b57ed6c0 Delete type=3 #1
|
||||
2026/05/04-20:19:32.300821 7f037d7ed6c0 Delete type=3 #1
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
2026/05/04-09:46:56.122237 7fe6b67ef6c0 Delete type=3 #1
|
||||
2026/05/04-20:19:32.128147 7f037e7ef6c0 Delete type=3 #1
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
-1
@@ -1 +1 @@
|
||||
2026/05/04-09:46:56.198341 7fe6b5fee6c0 Delete type=3 #1
|
||||
2026/05/04-20:19:32.576403 7f037dfee6c0 Delete type=3 #1
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
2026/05/04-09:46:56.137148 7fe6b5fee6c0 Delete type=3 #1
|
||||
2026/05/04-20:19:32.214437 7f037dfee6c0 Delete type=3 #1
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
-1
@@ -1 +1 @@
|
||||
2026/05/04-09:46:56.166829 7fe6b4fec6c0 Delete type=3 #1
|
||||
2026/05/04-20:19:32.413325 7f037cfec6c0 Delete type=3 #1
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
2026/05/04-09:46:56.214242 7fe6b57ed6c0 Delete type=3 #1
|
||||
2026/05/04-20:19:32.651585 7f037d7ed6c0 Delete type=3 #1
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
-1
@@ -1 +1 @@
|
||||
2026/05/04-09:46:56.182767 7fe6b67ef6c0 Delete type=3 #1
|
||||
2026/05/04-20:19:32.499232 7f037e7ef6c0 Delete type=3 #1
|
||||
|
||||
Binary file not shown.
+2
-1
@@ -5,7 +5,8 @@
|
||||
"manifest": "https://www.uberwald.me/gitea/public/fvtt-les-oublies/raw/branch/main/system.json",
|
||||
"download": "#{DOWNLOAD}#",
|
||||
"url": "https://www.uberwald.me/gitea/public/fvtt-les-oublies",
|
||||
"version": "0.1.0",
|
||||
"background": "systems/fvtt-les-oublies/assets/ui/banniere_les_oublies.webp",
|
||||
"version": "14.0.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Copilot",
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
</div>
|
||||
<div class="item-list">
|
||||
{{#each powers as |item|}}
|
||||
<article class="item-card">
|
||||
<article class="item-card" data-item-id="{{item.id}}" draggable="true">
|
||||
<div><strong>{{item.name}}</strong><div>{{item.system.activationCondition}}</div></div>
|
||||
<div class="item-controls"><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||
</article>
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
<h3>{{group.label}}</h3>
|
||||
<div class="item-list">
|
||||
{{#each group.items as |entry|}}
|
||||
<article class="item-card">
|
||||
<article class="item-card" data-item-id="{{entry.item.id}}" draggable="true">
|
||||
<div><strong>{{entry.item.name}}</strong><div>{{localize "LESOUBLIES.labels.valeurFinale"}} {{entry.finalValue}}</div></div>
|
||||
<div class="item-controls"><button type="button" data-action="rollSkill" data-item-id="{{entry.item.id}}">{{localize "LESOUBLIES.ui.roll"}}</button><button type="button" data-action="editItem" data-item-id="{{entry.item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{entry.item.id}}">Delete</button></div>
|
||||
</article>
|
||||
@@ -117,25 +117,25 @@
|
||||
</div>
|
||||
<div class="item-list">
|
||||
{{#each weapons as |item|}}
|
||||
<article class="item-card">
|
||||
<div><strong>{{item.name}}</strong><div>{{item.system.damage}}</div></div>
|
||||
<article class="item-card" data-item-id="{{item.id}}" draggable="true">
|
||||
<div><strong>{{item.name}}</strong><div>{{item.displayDamage}}</div></div>
|
||||
<div class="item-controls"><button type="button" data-action="useWeapon" data-item-id="{{item.id}}">Attaque</button><button type="button" data-action="resolveWeaponDamage" data-item-id="{{item.id}}">Dégâts</button><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||
</article>
|
||||
{{/each}}
|
||||
{{#each armors as |item|}}
|
||||
<article class="item-card">
|
||||
<article class="item-card" data-item-id="{{item.id}}" draggable="true">
|
||||
<div><strong>{{item.name}}</strong><div>Prot {{item.system.protection}}</div></div>
|
||||
<div class="item-controls"><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||
</article>
|
||||
{{/each}}
|
||||
{{#each equipment as |item|}}
|
||||
<article class="item-card">
|
||||
<article class="item-card" data-item-id="{{item.id}}" draggable="true">
|
||||
<div><strong>{{item.name}}</strong><div>{{localize "TYPES.Item.equipement"}} - {{item.system.category}}</div></div>
|
||||
<div class="item-controls"><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||
</article>
|
||||
{{/each}}
|
||||
{{#each spells as |item|}}
|
||||
<article class="item-card">
|
||||
<article class="item-card" data-item-id="{{item.id}}" draggable="true">
|
||||
<div><strong>{{item.name}}</strong><div>{{item.system.tradition}} / {{item.system.polarity}}</div></div>
|
||||
<div class="item-controls"><button type="button" data-action="useSpell" data-item-id="{{item.id}}">Activer</button><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||
</article>
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
</div>
|
||||
<div class="item-list skills-item-list">
|
||||
{{#each group.items as |entry|}}
|
||||
<article class="item-card skill-card">
|
||||
<article class="item-card skill-card" data-item-id="{{entry.item.id}}" draggable="true">
|
||||
<div class="skill-card-main">
|
||||
<strong>{{entry.item.name}}</strong>
|
||||
<span class="skill-summary">Base {{entry.item.system.base}} · {{group.label}} {{group.profileValue}} · {{localize "LESOUBLIES.labels.valeurFinale"}} {{entry.finalValue}}</span>
|
||||
@@ -187,8 +187,8 @@
|
||||
<div class="item-list">
|
||||
{{#if equippedWeapons.length}}
|
||||
{{#each equippedWeapons as |item|}}
|
||||
<article class="item-card">
|
||||
<div><strong>{{item.name}}</strong><div>{{localize "TYPES.Item.arme"}} - {{item.system.damage}}</div></div>
|
||||
<article class="item-card" data-item-id="{{item.id}}" draggable="true">
|
||||
<div><strong>{{item.name}}</strong><div>{{localize "TYPES.Item.arme"}} - {{item.displayDamage}}</div></div>
|
||||
<div class="item-controls"><button type="button" data-action="useWeapon" data-item-id="{{item.id}}">Attaque</button><button type="button" data-action="resolveWeaponDamage" data-item-id="{{item.id}}">Dégâts</button><button type="button" data-action="toggleEquipped" data-item-id="{{item.id}}">Retirer</button></div>
|
||||
</article>
|
||||
{{/each}}
|
||||
@@ -198,29 +198,6 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="sheet-grid sheet-grid-2">
|
||||
<section class="sheet-card ledger-card">
|
||||
<div class="section-title-row">
|
||||
<h2>{{localize "LESOUBLIES.ui.magie"}}</h2>
|
||||
<button type="button" data-action="createItem" data-type="sortilege">+ {{localize "TYPES.Item.sortilege"}}</button>
|
||||
</div>
|
||||
<div class="item-list">
|
||||
{{#each spells as |item|}}
|
||||
<article class="item-card">
|
||||
<div>
|
||||
<strong>{{item.name}}</strong>
|
||||
<div>{{item.system.tradition}} / {{item.system.polarity}} / coût {{item.system.cost}}</div>
|
||||
</div>
|
||||
<div class="item-controls">
|
||||
<button type="button" data-action="useSpell" data-item-id="{{item.id}}">Activer</button>
|
||||
<button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button>
|
||||
<button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button>
|
||||
</div>
|
||||
</article>
|
||||
{{/each}}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sheet-card ledger-card reserve-card">
|
||||
<div class="section-title-row">
|
||||
<h2>{{localize "LESOUBLIES.labels.threadReserves"}}</h2>
|
||||
@@ -292,7 +269,29 @@
|
||||
</div>
|
||||
<p class="help-text">Les dépenses en fils rendent automatiquement autant de globes vides à la réserve utilisée.</p>
|
||||
</section>
|
||||
|
||||
<section class="sheet-card ledger-card">
|
||||
<div class="section-title-row">
|
||||
<h2>{{localize "LESOUBLIES.ui.magie"}}</h2>
|
||||
<button type="button" data-action="createItem" data-type="sortilege">+ {{localize "TYPES.Item.sortilege"}}</button>
|
||||
</div>
|
||||
<div class="item-list">
|
||||
{{#each spells as |item|}}
|
||||
<article class="item-card" data-item-id="{{item.id}}" draggable="true">
|
||||
<div>
|
||||
<strong>{{item.name}}</strong>
|
||||
<div>{{item.system.tradition}} / {{item.system.polarity}} / coût {{item.system.cost}}</div>
|
||||
</div>
|
||||
<div class="item-controls">
|
||||
<button type="button" data-action="useSpell" data-item-id="{{item.id}}">Activer</button>
|
||||
<button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button>
|
||||
<button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button>
|
||||
</div>
|
||||
</article>
|
||||
{{/each}}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section class="sheet-tab {{tabs.equipment.cssClass}}" data-tab="equipment">
|
||||
@@ -307,19 +306,19 @@
|
||||
</div>
|
||||
<div class="item-list">
|
||||
{{#each weapons as |item|}}
|
||||
<article class="item-card">
|
||||
<div><strong>{{item.name}}</strong><div>{{localize "TYPES.Item.arme"}} - {{item.system.damage}}{{#if item.system.equipped}} - Équipée{{/if}}</div></div>
|
||||
<article class="item-card" data-item-id="{{item.id}}" draggable="true">
|
||||
<div><strong>{{item.name}}</strong><div>{{localize "TYPES.Item.arme"}} - {{item.displayDamage}}{{#if item.system.equipped}} - Équipée{{/if}}</div></div>
|
||||
<div class="item-controls"><button type="button" data-action="toggleEquipped" data-item-id="{{item.id}}">{{#if item.system.equipped}}Retirer{{else}}Équiper{{/if}}</button><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||
</article>
|
||||
{{/each}}
|
||||
{{#each armors as |item|}}
|
||||
<article class="item-card">
|
||||
<article class="item-card" data-item-id="{{item.id}}" draggable="true">
|
||||
<div><strong>{{item.name}}</strong><div>{{localize "TYPES.Item.armure"}} - Prot {{item.system.protection}}</div></div>
|
||||
<div class="item-controls"><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||
</article>
|
||||
{{/each}}
|
||||
{{#each equipment as |item|}}
|
||||
<article class="item-card">
|
||||
<article class="item-card" data-item-id="{{item.id}}" draggable="true">
|
||||
<div><strong>{{item.name}}</strong><div>{{localize "TYPES.Item.equipement"}} - {{item.system.category}}</div></div>
|
||||
<div class="item-controls"><button type="button" data-action="editItem" data-item-id="{{item.id}}">Edit</button><button type="button" data-action="deleteItem" data-item-id="{{item.id}}">Delete</button></div>
|
||||
</article>
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
<div class="field-row"><label>{{localize "LESOUBLIES.labels.quantite"}}</label><input name="system.quantity" type="number" value="{{system.quantity}}" {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||
<div class="field-row"><label>Équipée</label><input name="system.equipped" type="checkbox" {{checked system.equipped}} {{#if isPlayMode}}disabled{{/if}} /></div>
|
||||
<p><strong>Race restreinte :</strong> {{system.restrictedRace}}</p>
|
||||
{{#if weaponDamagePreview}}
|
||||
<p><strong>Dégâts calculés :</strong> {{weaponDamagePreview}}</p>
|
||||
{{/if}}
|
||||
</section>
|
||||
<section class="sheet-card notes-card">
|
||||
<h2>{{localize "LESOUBLIES.labels.description"}}</h2>
|
||||
|
||||
Reference in New Issue
Block a user