Modifications suite beta 2

This commit is contained in:
2026-05-11 00:03:41 +02:00
parent 7542890232
commit 122cd29041
14 changed files with 159 additions and 34 deletions
+44 -2
View File
@@ -189,6 +189,9 @@ export class CharacterSheetL5r5e extends BaseCharacterSheetL5r5e {
this._tabs this._tabs
.find((e) => e._navSelector === ".advancements-tabs") .find((e) => e._navSelector === ".advancements-tabs")
.activate("advancement_rank_" + (this.actor.system.identity.school_rank || 0)); .activate("advancement_rank_" + (this.actor.system.identity.school_rank || 0));
// Arcane roll on name click
html.find(".dice-picker-arcane").on("click", this._openDicePickerForArcane.bind(this));
} }
/** /**
@@ -220,10 +223,49 @@ export class CharacterSheetL5r5e extends BaseCharacterSheetL5r5e {
} }
/** /**
* Override base dice picker to open Chiaroscuro d6 dialog. * Open the Chiaroscuro dice dialog for an arcane item.
* Parses `system.applicationDisplay` (comma-separated skill IDs and/or group names),
* expands groups, pre-selects the first skill, and passes the arcane bonus.
* @param {Event} event * @param {Event} event
*/ */
_openDicePickerForSkill(event) { _openDicePickerForArcane(event) {
event.preventDefault();
event.stopPropagation();
if (event.clientX === 0 && event.clientY === 0) return;
const itemId = $(event.currentTarget).closest("[data-item-id]").data("item-id") ?? $(event.currentTarget).data("item-id");
const item = this.actor.items.get(itemId);
if (!item) return;
// Parse application array (database field) → expand skill groups
const app = item.system.application || [];
const rawEntries = (Array.isArray(app) ? app : app.split(","))
.map((s) => s.trim().toLowerCase())
.filter(Boolean);
const allGroupIds = new Set(CONFIG.l5r5e.skills.values());
const skillIds = [];
for (const entry of rawEntries) {
if (allGroupIds.has(entry)) {
// Expand group → all skills belonging to that group
for (const [skillId, groupId] of CONFIG.l5r5e.skills.entries()) {
if (groupId === entry && !skillIds.includes(skillId)) skillIds.push(skillId);
}
} else if (CONFIG.l5r5e.skills.has(entry) && !skillIds.includes(entry)) {
skillIds.push(entry);
}
}
new game.l5r5e.ChiaroscuroDiceDialog({
actor: this.actor,
ringId: this.actor.system?.default_ring || "void",
skillsList: skillIds,
arcaneBonus: parseInt(item.system.bonus || 0),
itemUuid: item.uuid,
}).render(true);
}
/**
event.preventDefault(); event.preventDefault();
const el = $(event.currentTarget); const el = $(event.currentTarget);
const weapon = this._getWeaponInfos(el.data("weapon-id") || null); const weapon = this._getWeaponInfos(el.data("weapon-id") || null);
+28 -2
View File
@@ -24,6 +24,8 @@ export class ChiaroscuroDiceDialog extends FormApplication {
useAspectPoint: false, useAspectPoint: false,
aspectType: "solar", aspectType: "solar",
useAssistance: false, useAssistance: false,
skillsList: [],
arcaneBonus: 0,
}; };
static get defaultOptions() { static get defaultOptions() {
@@ -82,9 +84,17 @@ export class ChiaroscuroDiceDialog extends FormApplication {
this.ringId = ringId; this.ringId = ringId;
// Skill // Skill
if (options.skillId) { if (options.skillsList?.length > 0) {
this.object.skillsList = options.skillsList;
this.skillId = options.skillsList[0];
} else if (options.skillId) {
this.skillId = options.skillId; this.skillId = options.skillId;
} }
// Arcane bonus
if (options.arcaneBonus) {
this.object.arcaneBonus = parseInt(options.arcaneBonus) || 0;
}
} }
/** /**
@@ -139,6 +149,14 @@ export class ChiaroscuroDiceDialog extends FormApplication {
aspectsList, aspectsList,
isVoidRing: this.object.ring.id === "void", isVoidRing: this.object.ring.id === "void",
quickInfo: this._actor?.system?.quick_info ?? "", quickInfo: this._actor?.system?.quick_info ?? "",
hasMultipleSkills: this.object.skillsList.length > 1,
skillsChoices: this.object.skillsList.map((id) => {
const catId = CONFIG.l5r5e.skills.get(id.toLowerCase());
return {
id,
label: catId ? game.i18n.localize(`l5r5e.skills.${catId}.${id}`) : id,
};
}),
}; };
} }
@@ -182,6 +200,12 @@ export class ChiaroscuroDiceDialog extends FormApplication {
this.render(false); this.render(false);
}); });
// Skill selector (arcane)
html.find("select[name='skill.id']").on("change", (event) => {
this.skillId = event.target.value;
this.render(false);
});
// Roll button — explicit submit trigger // Roll button — explicit submit trigger
html.find("button[name='roll']").on("click", (event) => { html.find("button[name='roll']").on("click", (event) => {
event.preventDefault(); event.preventDefault();
@@ -207,8 +231,9 @@ export class ChiaroscuroDiceDialog extends FormApplication {
const wasAdjusted = diceAdjustedFlags.some(Boolean); const wasAdjusted = diceAdjustedFlags.some(Boolean);
// Compute total // Compute total
const arcaneBonus = this.object.arcaneBonus || 0;
const rawSum = adjustedResults.reduce((a, b) => a + b, 0); const rawSum = adjustedResults.reduce((a, b) => a + b, 0);
const total = rawSum + skillBonus + flatModifier; const total = rawSum + skillBonus + flatModifier + arcaneBonus;
const success = total >= difficultyValue; const success = total >= difficultyValue;
const bonus = success ? total - difficultyValue : 0; const bonus = success ? total - difficultyValue : 0;
@@ -228,6 +253,7 @@ export class ChiaroscuroDiceDialog extends FormApplication {
total, total,
skillBonus, skillBonus,
flatModifier, flatModifier,
arcaneBonus,
difficulty: difficultyObj, difficulty: difficultyObj,
success, success,
bonus, bonus,
File diff suppressed because one or more lines are too long
+12
View File
@@ -550,6 +550,18 @@ article.tab.notes {
border: 1px solid rgba($l5r5e-red, 0.3); border: 1px solid rgba($l5r5e-red, 0.3);
} }
} }
// ── Item infos (weapon/arcane link) ──────────────────────────────────────
.item-infos {
.profile {
flex: 0 0 auto;
.profile-img {
width: 2rem;
height: 2rem;
object-fit: cover;
}
}
}
} }
// ── Skill rank: bonus display ────────────────────────────────────────────── // ── Skill rank: bonus display ──────────────────────────────────────────────
+16
View File
@@ -78,6 +78,14 @@
&-skill { &-skill {
flex-grow: 3; flex-grow: 3;
.chat-actor-name {
display: block;
font-family: $font-secondary;
font-size: 0.9rem;
color: $l5r5e-title;
margin-bottom: 0.1rem;
}
} }
&:last-child { &:last-child {
flex-grow: 2; flex-grow: 2;
@@ -190,6 +198,14 @@
} }
.item-infos { .item-infos {
border: solid 1px rgba(0, 78, 100, 0.75); border: solid 1px rgba(0, 78, 100, 0.75);
.profile {
flex: 0 0 auto;
.profile-img {
width: 2rem;
height: 2rem;
object-fit: cover;
}
}
i { i {
font-size: var(--font-size-12); font-size: var(--font-size-12);
} }
+6
View File
@@ -662,6 +662,12 @@
width: 100%; width: 100%;
} }
} }
.attribute-third {
flex: 0 0 calc(33.33% - 0.5rem);
}
.attribute-full {
flex: 0 0 calc(100% - 0.5rem);
}
} }
&.infos, &.infos,
&.tab.infos { &.tab.infos {
@@ -35,7 +35,7 @@
<li class="item technique flexcol" data-item-id="{{item._id}}"> <li class="item technique flexcol" data-item-id="{{item._id}}">
<ul class="item-header technique-controls"> <ul class="item-header technique-controls">
<li class="item-img"><img src="{{item.img}}" title="{{item.name}}" width="32px" height="32px"/></li> <li class="item-img"><img src="{{item.img}}" title="{{item.name}}" width="32px" height="32px"/></li>
<li class="item-name dice-picker l5r5e-tooltip" data-item-id="{{item._id}}">{{item.name}}</li> <li class="item-name dice-picker-arcane l5r5e-tooltip" data-item-id="{{item._id}}">{{item.name}}</li>
{{#if ../data.editable_not_soft_locked}} {{#if ../data.editable_not_soft_locked}}
<li data-item-id="{{item._id}}" class="item-control item-edit" title="{{localize 'l5r5e.global.edit'}}"><i class="fas fa-edit"></i></li> <li data-item-id="{{item._id}}" class="item-control item-edit" title="{{localize 'l5r5e.global.edit'}}"><i class="fas fa-edit"></i></li>
<li data-item-id="{{item._id}}" class="item-control item-delete" title="{{localize 'Delete'}}"><i class="fas fa-trash"></i></li> <li data-item-id="{{item._id}}" class="item-control item-delete" title="{{localize 'Delete'}}"><i class="fas fa-trash"></i></li>
+3
View File
@@ -13,6 +13,9 @@
</span> </span>
<span class="chat-profil-element-skill"> <span class="chat-profil-element-skill">
{{#if l5r5e.actor.name}}
<strong class="chat-actor-name">{{l5r5e.actor.name}}</strong>
{{/if}}
{{#if l5r5e.skillId}} {{#if l5r5e.skillId}}
{{localizeSkillId l5r5e.skillId}} {{localizeSkillId l5r5e.skillId}}
{{else}} {{else}}
@@ -2,9 +2,15 @@
{{!-- Ring accent bar --}} {{!-- Ring accent bar --}}
<div class="chi-ring-bar {{ring.id}}"></div> <div class="chi-ring-bar {{ring.id}}"></div>
{{!-- Header: portrait + ring badge --}} {{!-- Header: portrait + actor name + ring badge --}}
<div class="chi-chat-header"> <div class="chi-chat-header">
<img class="profile-img" src="{{profileImg}}" alt="{{actor.name}}" /> <img class="profile-img" src="{{profileImg}}" alt="{{actor.name}}" />
{{#if actor.name}}
<div class="chi-chat-actor">
<strong>{{actor.name}}</strong>
{{#if quickInfo}}<span class="chi-chat-quick-info">{{quickInfo}}</span>{{/if}}
</div>
{{/if}}
<div class="chi-chat-badges"> <div class="chi-chat-badges">
<span class="chi-ring-badge {{ring.id}}" title="{{ring.label}}"> <span class="chi-ring-badge {{ring.id}}" title="{{ring.label}}">
<i class="i_{{ring.id}}"></i> <i class="i_{{ring.id}}"></i>
@@ -68,12 +74,15 @@
{{/each}} {{/each}}
</div> </div>
{{!-- Breakdown: sum [+bonus] [±mod] = total / diff --}} {{!-- Breakdown: sum [+bonus] [+arcaneBonus] [±mod] = total / diff --}}
<div class="chi-chat-breakdown"> <div class="chi-chat-breakdown">
<span class="chi-bd-part chi-bd-sum" title="{{localize 'chiaroscuro.dice.dice_result'}}">{{rawSum}}</span> <span class="chi-bd-part chi-bd-sum" title="{{localize 'chiaroscuro.dice.dice_result'}}">{{rawSum}}</span>
{{#if skill.bonus}} {{#if skill.bonus}}
<span class="chi-bd-part chi-bd-pos">+{{skill.bonus}}</span> <span class="chi-bd-part chi-bd-pos">+{{skill.bonus}}</span>
{{/if}} {{/if}}
{{#if arcaneBonus}}
<span class="chi-bd-part chi-bd-pos">+{{arcaneBonus}}</span>
{{/if}}
{{#if modifier}} {{#if modifier}}
<span class="chi-bd-part {{#ifCond modifier '>' 0}}chi-bd-pos{{else}}chi-bd-neg{{/ifCond}}">{{#ifCond modifier '>' 0}}+{{/ifCond}}{{modifier}}</span> <span class="chi-bd-part {{#ifCond modifier '>' 0}}chi-bd-pos{{else}}chi-bd-neg{{/ifCond}}">{{#ifCond modifier '>' 0}}+{{/ifCond}}{{modifier}}</span>
{{/if}} {{/if}}
@@ -31,12 +31,20 @@
</ul> </ul>
</fieldset> </fieldset>
{{!-- Skill info --}} {{!-- Skill info / selector --}}
{{#if data.skill.name}} {{#if data.skill.id}}
<fieldset class="chi-dice-section"> <fieldset class="chi-dice-section">
<legend>{{localize 'l5r5e.skills.title'}}</legend> <legend>{{localize 'l5r5e.skills.title'}}</legend>
<div class="chi-skill-row"> <div class="chi-skill-row">
{{#if hasMultipleSkills}}
<select name="skill.id">
{{#each skillsChoices}}
<option value="{{this.id}}" {{#ifCond this.id '==' ../data.skill.id}}selected{{/ifCond}}>{{this.label}}</option>
{{/each}}
</select>
{{else}}
<span class="chi-skill-name">{{data.skill.name}}</span> <span class="chi-skill-name">{{data.skill.name}}</span>
{{/if}}
<span class="chi-skill-rank">{{localize (concat 'chiaroscuro.skill_ranks.' data.skill.rank)}}</span> <span class="chi-skill-rank">{{localize (concat 'chiaroscuro.skill_ranks.' data.skill.rank)}}</span>
{{#ifCond data.skill.bonus '>' 0}}<span class="chi-skill-bonus skill-bonus">+{{data.skill.bonus}}</span>{{/ifCond}} {{#ifCond data.skill.bonus '>' 0}}<span class="chi-skill-bonus skill-bonus">+{{data.skill.bonus}}</span>{{/ifCond}}
</div> </div>
@@ -92,6 +100,7 @@
<span>{{localize 'chiaroscuro.dice.total_dice'}} :</span> <span>{{localize 'chiaroscuro.dice.total_dice'}} :</span>
<strong class="chi-total-dice">{{totalDice}}d6</strong> <strong class="chi-total-dice">{{totalDice}}d6</strong>
{{#if data.skill.bonus}}<span> + {{data.skill.bonus}} ({{localize 'chiaroscuro.dice.bonus'}})</span>{{/if}} {{#if data.skill.bonus}}<span> + {{data.skill.bonus}} ({{localize 'chiaroscuro.dice.bonus'}})</span>{{/if}}
{{#if data.arcaneBonus}}<span> + {{data.arcaneBonus}} ({{localize 'chiaroscuro.arcane.bonus'}})</span>{{/if}}
{{#if data.modifier}}<span> {{#ifCond data.modifier '>' 0}}+{{/ifCond}}{{data.modifier}} ({{localize 'chiaroscuro.dice.modifier_label'}})</span>{{/if}} {{#if data.modifier}}<span> {{#ifCond data.modifier '>' 0}}+{{/ifCond}}{{data.modifier}} ({{localize 'chiaroscuro.dice.modifier_label'}})</span>{{/if}}
</div> </div>
@@ -7,18 +7,20 @@
<section class="sheet-body"> <section class="sheet-body">
{{!-- Attributes --}} {{!-- Attributes --}}
<article class="attributes"> <article class="attributes">
<label class="attribute"> {{!-- Ligne 1 : Dépensée / Type / Compétences --}}
{{localize 'chiaroscuro.arcane.arcane_type'}} <label class="attribute attribute-third">
<input type="text" name="system.arcane_type" value="{{data.system.arcane_type}}" />
</label>
<label class="attribute">
{{localize 'chiaroscuro.arcane.xp_used'}} {{localize 'chiaroscuro.arcane.xp_used'}}
<input class="select-on-focus" type="number" name="system.xp_used" value="{{data.system.xp_used}}" data-dtype="Number" min="0" placeholder="0"/> <input class="select-on-focus" type="number" name="system.xp_used" value="{{data.system.xp_used}}" data-dtype="Number" min="0" placeholder="0"/>
</label> </label>
<label class="attribute"> <label class="attribute attribute-third">
{{localize 'chiaroscuro.arcane.arcane_type'}}
<input type="text" name="system.arcane_type" value="{{data.system.arcane_type}}" />
</label>
<label class="attribute attribute-third">
{{localize 'chiaroscuro.arcane.application'}} {{localize 'chiaroscuro.arcane.application'}}
<input type="text" name="system.applicationDisplay" value="{{data.system.applicationDisplay}}" placeholder="compétence1, compétence2" /> <input type="text" name="system.applicationDisplay" value="{{data.system.applicationDisplay}}" placeholder="compétence1, compétence2" />
</label> </label>
{{!-- Ligne 2 : Bonus / Progression --}}
<label class="attribute"> <label class="attribute">
{{localize 'chiaroscuro.arcane.bonus'}} {{localize 'chiaroscuro.arcane.bonus'}}
<input class="select-on-focus" type="number" name="system.bonus" value="{{data.system.bonus}}" data-dtype="Number" min="0" placeholder="2"/> <input class="select-on-focus" type="number" name="system.bonus" value="{{data.system.bonus}}" data-dtype="Number" min="0" placeholder="2"/>
@@ -7,20 +7,20 @@
<section class="sheet-body"> <section class="sheet-body">
{{!-- Attributes --}} {{!-- Attributes --}}
<article class="attributes"> <article class="attributes">
<label class="attribute"> <label class="attribute attribute-third">
{{localize 'chiaroscuro.arcane.xp_used'}}
<input class="select-on-focus" type="number" name="system.xp_used" value="{{data.system.xp_used}}" data-dtype="Number" min="0" placeholder="0"/>
</label>
<label class="attribute attribute-third">
{{localize 'chiaroscuro.technique.invocation_type'}} {{localize 'chiaroscuro.technique.invocation_type'}}
<select name="system.invocation_type" id="mot_invocation_type"> <select name="system.invocation_type" id="mot_invocation_type">
{{selectOptions data.invocationTypesList selected=data.system.invocation_type valueAttr='id' labelAttr='label'}} {{selectOptions data.invocationTypesList selected=data.system.invocation_type valueAttr='id' labelAttr='label'}}
</select> </select>
</label> </label>
<label class="attribute"> <label class="attribute attribute-third">
{{localize 'chiaroscuro.technique.mode_invocation'}} {{localize 'chiaroscuro.technique.mode_invocation'}}
<input class="select-on-focus" type="number" id="mot_invocation_mode" name="system.mode_invocation" value="{{data.system.mode_invocation}}" data-dtype="Number" placeholder="0" readonly /> <input class="select-on-focus" type="number" id="mot_invocation_mode" name="system.mode_invocation" value="{{data.system.mode_invocation}}" data-dtype="Number" placeholder="0" readonly />
</label> </label>
<label class="attribute">
{{localize 'chiaroscuro.arcane.xp_used'}}
<input class="select-on-focus" type="number" name="system.xp_used" value="{{data.system.xp_used}}" data-dtype="Number" min="0" placeholder="0"/>
</label>
</article> </article>
{{!-- Description --}} {{!-- Description --}}
<article class="tab infos active" data-group="primary" data-tab="infos"> <article class="tab infos active" data-group="primary" data-tab="infos">
@@ -5,21 +5,21 @@
</header> </header>
<section class="sheet-body"> <section class="sheet-body">
<article class="attributes"> <article class="attributes">
<label class="attribute">
{{localize 'chiaroscuro.arcane.xp_used'}}
<input class="select-on-focus" type="number" name="system.xp_used" value="{{data.system.xp_used}}" data-dtype="Number" min="0" placeholder="0"/>
</label>
<label class="attribute"> <label class="attribute">
{{localize 'chiaroscuro.mystere.mystere_type'}} {{localize 'chiaroscuro.mystere.mystere_type'}}
<select name="system.mystere_type"> <select name="system.mystere_type">
{{selectOptions data.mystereTypes selected=data.system.mystere_type valueAttr='id' labelAttr='label'}} {{selectOptions data.mystereTypes selected=data.system.mystere_type valueAttr='id' labelAttr='label'}}
</select> </select>
</label> </label>
<label class="attribute"> <label class="attribute attribute-full">
{{localize 'chiaroscuro.arcane.xp_used'}}
<input class="select-on-focus" type="number" name="system.xp_used" value="{{data.system.xp_used}}" data-dtype="Number" min="0" placeholder="0"/>
</label>
<label class="attribute">
{{localize 'chiaroscuro.mystere.prerequisite_skill'}} {{localize 'chiaroscuro.mystere.prerequisite_skill'}}
<input type="text" name="system.prerequisite_skill" value="{{data.system.prerequisite_skill}}" /> <input type="text" name="system.prerequisite_skill" value="{{data.system.prerequisite_skill}}" />
</label> </label>
<label class="attribute"> <label class="attribute attribute-full">
{{localize 'chiaroscuro.mystere.prerequisite_condition'}} {{localize 'chiaroscuro.mystere.prerequisite_condition'}}
<input type="text" name="system.prerequisite_condition" value="{{data.system.prerequisite_condition}}" /> <input type="text" name="system.prerequisite_condition" value="{{data.system.prerequisite_condition}}" />
</label> </label>
@@ -7,18 +7,18 @@
<section class="sheet-body"> <section class="sheet-body">
{{!-- Attributes --}} {{!-- Attributes --}}
<article class="attributes"> <article class="attributes">
<label class="attribute"> <label class="attribute attribute-third">
{{localize 'chiaroscuro.arcane.xp_used'}}
<input class="select-on-focus" type="number" name="system.xp_used" value="{{data.system.xp_used}}" data-dtype="Number" min="0" placeholder="0"/>
</label>
<label class="attribute attribute-third">
{{localize 'chiaroscuro.arcane.application'}} {{localize 'chiaroscuro.arcane.application'}}
<input type="text" name="system.application" value="{{data.system.application}}" placeholder="compétence1, catégorie2" /> <input type="text" name="system.application" value="{{data.system.application}}" placeholder="compétence1, catégorie2" />
</label> </label>
<label class="attribute"> <label class="attribute attribute-third">
{{localize 'chiaroscuro.arcane.bonus'}} {{localize 'chiaroscuro.arcane.bonus'}}
<input class="select-on-focus" type="number" name="system.bonus" value="{{data.system.bonus}}" data-dtype="Number" min="0" placeholder="3" readonly /> <input class="select-on-focus" type="number" name="system.bonus" value="{{data.system.bonus}}" data-dtype="Number" min="0" placeholder="3" readonly />
</label> </label>
<label class="attribute">
{{localize 'chiaroscuro.arcane.xp_used'}}
<input class="select-on-focus" type="number" name="system.xp_used" value="{{data.system.xp_used}}" data-dtype="Number" min="0" placeholder="0"/>
</label>
</article> </article>
{{!-- Description --}} {{!-- Description --}}
<article class="tab infos active" data-group="primary" data-tab="infos"> <article class="tab infos active" data-group="primary" data-tab="infos">