Migration vers le système officiel

This commit is contained in:
2026-05-01 00:57:50 +02:00
parent f31f8aba27
commit 386cf89d68
107 changed files with 1212 additions and 463 deletions
+99 -3
View File
@@ -8,6 +8,7 @@
import { calculatePassengers, calculateCargo, findAvailableGoods, calculatePrice, formatCredits } from './tradeHelper.js';
import { searchWorlds, fetchWorldDetail, fetchWorldCoordinates, calcParsecs } from './travellerMapApi.js';
import { buildActiveActorContext, COMMERCE_SKILLS, getActiveTravellerActor, rollActorSkillEffect, getActorSkillSummary } from './mgt2eSkills.js';
const MODULE_ID = 'mgt2-compendium-amiral-denisov';
@@ -33,9 +34,9 @@ export class CommerceDialog extends FormApplication {
}
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
return foundry.utils.mergeObject(super.defaultOptions, {
id: 'mgt2-commerce',
title: 'Commerce MGT2',
title: 'Commerce MgT2e',
template: `modules/${MODULE_ID}/templates/commerce-dialog.hbs`,
width: 780,
height: 'auto',
@@ -51,7 +52,10 @@ export class CommerceDialog extends FormApplication {
getData() {
_registerHandlebarsHelpers();
return foundry.utils.mergeObject(super.getData(), this._formData);
return foundry.utils.mergeObject(super.getData(), {
...this._formData,
activeActor: buildActiveActorContext(),
});
}
activateListeners(html) {
@@ -84,6 +88,31 @@ export class CommerceDialog extends FormApplication {
await this._handleBuyPrices();
});
html.find('[data-action="load-pax-actor"]').on('click', async (ev) => {
ev.preventDefault();
this._applyPassengerActorData(html);
});
html.find('[data-action="roll-pax-effect"]').on('click', async (ev) => {
ev.preventDefault();
await this._rollActorEffectIntoField(html, 'pax.skillEffect', COMMERCE_SKILLS.passengerEffect);
});
html.find('[data-action="load-cargo-actor"]').on('click', async (ev) => {
ev.preventDefault();
this._applyCargoActorData(html);
});
html.find('[data-action="roll-cargo-effect"]').on('click', async (ev) => {
ev.preventDefault();
await this._rollActorEffectIntoField(html, 'cargo.skillEffect', COMMERCE_SKILLS.cargoEffect);
});
html.find('[data-action="load-trade-actor"]').on('click', async (ev) => {
ev.preventDefault();
this._applyTradeActorData(html);
});
// ─── Recherche de monde (Traveller Map API) ───────────────────────────────
html.find('.world-search-widget').each((_, widget) => {
const $widget = $(widget);
@@ -205,6 +234,73 @@ export class CommerceDialog extends FormApplication {
this._formData.trade.blackMarket = html.find('[name="trade.blackMarket"]').is(':checked');
}
_getActiveActorOrWarn() {
const { actor } = getActiveTravellerActor();
if (!actor) {
ui.notifications.warn('Aucun token sélectionné ni personnage assigné pour lire les compétences mgt2e.');
return null;
}
return actor;
}
_applyPassengerActorData(html) {
const actor = this._getActiveActorOrWarn();
if (!actor) return;
const steward = getActorSkillSummary(actor, COMMERCE_SKILLS.steward);
this._setNumericSelectValue(html, 'pax.stewardLevel', steward.value);
this._readForm(html);
ui.notifications.info(`${actor.name} : Intendant ${steward.value} chargé dans le calcul passagers.`);
}
_applyCargoActorData(html) {
const actor = this._getActiveActorOrWarn();
if (!actor) return;
const socMod = Number(actor.system.characteristics?.SOC?.dm ?? 0);
this._setNumericSelectValue(html, 'cargo.socMod', socMod);
this._readForm(html);
ui.notifications.info(`${actor.name} : DM SOC ${socMod >= 0 ? '+' : ''}${socMod} chargé dans le calcul cargaison.`);
}
_applyTradeActorData(html) {
const actor = this._getActiveActorOrWarn();
if (!actor) return;
const broker = getActorSkillSummary(actor, COMMERCE_SKILLS.tradeBroker);
this._setNumericSelectValue(html, 'trade.brokerSkill', broker.value);
this._readForm(html);
ui.notifications.info(`${actor.name} : Courtier ${broker.value} chargé pour le commerce spéculatif.`);
}
async _rollActorEffectIntoField(html, fieldName, skillList) {
const actor = this._getActiveActorOrWarn();
if (!actor) return;
const rollResult = await rollActorSkillEffect(actor, skillList);
if (!rollResult) {
ui.notifications.warn(`${actor.name} ne possède aucune des compétences attendues pour ce calcul.`);
return;
}
this._setNumericSelectValue(html, fieldName, rollResult.effect);
this._readForm(html);
ui.notifications.info(`${actor.name} : ${rollResult.label} → 2D6 (${rollResult.diceTotal}) + ${rollResult.totalModifier >= 0 ? '+' : ''}${rollResult.totalModifier} = ${rollResult.total}, effet ${rollResult.effect >= 0 ? '+' : ''}${rollResult.effect}.`);
}
_setNumericSelectValue(html, fieldName, value) {
const select = html.find(`[name="${fieldName}"]`);
if (!select.length) return;
const normalized = Number(value ?? 0);
if (!select.find(`option[value="${normalized}"]`).length) {
const label = normalized > 0 ? `+${normalized}` : `${normalized}`;
select.append(`<option value="${normalized}">${label}</option>`);
}
select.val(`${normalized}`);
}
// ─── Passagers ─────────────────────────────────────────────────────────────
async _handlePassengers() {