Crew member enhancements
All checks were successful
Release Creation / build (release) Successful in 59s

This commit is contained in:
2025-11-11 12:13:26 +01:00
parent 27b09d4546
commit 810271c2a2
27 changed files with 415 additions and 122 deletions

View File

@@ -17,6 +17,7 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
removeCrew: FTLNomadStarshipSheet.#onRemoveCrew,
viewCrew: FTLNomadStarshipSheet.#onViewCrew,
pilotCrew: FTLNomadStarshipSheet.#onPilotCrew,
rollNpcCrew: FTLNomadStarshipSheet.#onRollNpcCrew,
},
}
@@ -81,20 +82,25 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
// Get starship agility bonus
const starshipAgility = this.document.system.agility || 0
// Get the vehicles skill from the actor
const vehiclesSkill = actor.system.skills?.vehicles
if (!vehiclesSkill) {
ui.notifications.warn(game.i18n.localize("FTLNOMAD.Warning.noVehiclesSkill"))
// Get all skills from the actor
const actorSkills = actor.system.skills
if (!actorSkills) {
ui.notifications.warn(game.i18n.localize("FTLNOMAD.Warning.noSkills"))
return
}
// Default to vehicles skill
const defaultSkill = actorSkills.vehicles || Object.values(actorSkills)[0]
// Import the Roll class
const FTLNomadRoll = (await import("../../documents/roll.mjs")).default
// Call the roll prompt with the starship agility as a vehicle bonus
// Call the roll prompt with all skills available and starship agility as a vehicle bonus
let roll = await FTLNomadRoll.prompt({
rollType: "skill",
rollItem: vehiclesSkill,
rollItem: defaultSkill,
availableSkills: actorSkills,
selectedSkillId: "vehicles",
actorId: actor.id,
actorName: actor.name,
actorImage: actor.img,
@@ -108,6 +114,48 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
await roll.toMessage({}, { rollMode: roll.options.rollMode })
}
/**
* Roll a check for NPC crew with starship agility bonus
* @param {Event} event The initiating click event
* @param {HTMLElement} target The current target of the event listener
*/
static async #onRollNpcCrew(event, target) {
const npcCrewLevel = this.document.system.npcCrew || 0
if (npcCrewLevel < 0) {
ui.notifications.warn(game.i18n.localize("FTLNOMAD.Warning.noNpcCrew"))
return
}
// Get starship agility bonus
const starshipAgility = this.document.system.agility || 0
// Create a fake skill object for the NPC crew
const npcSkill = {
value: npcCrewLevel,
label: "FTLNOMAD.Label.npcCrewSkill"
}
// Import the Roll class
const FTLNomadRoll = (await import("../../documents/roll.mjs")).default
// Call the roll prompt with NPC crew level as skill
let roll = await FTLNomadRoll.prompt({
rollType: "skill",
rollItem: npcSkill,
actorId: this.document.id,
actorName: `${this.document.name} (NPC Crew)`,
actorImage: this.document.img,
talents: [],
isEncumbered: false,
hasTarget: false,
vehicleBonus: starshipAgility
})
if (!roll) return null
await roll.toMessage({}, { rollMode: roll.options.rollMode })
}
/** @override */
static PARTS = {
main: {

View File

@@ -5,8 +5,8 @@ export default class FTLNomadVehicleSheet extends FTLNomadActorSheet {
static DEFAULT_OPTIONS = {
classes: ["vehicle"],
position: {
width: 680,
height: 540,
width: 720,
height: 640,
},
window: {
contentClasses: ["vehicle-content"],
@@ -17,6 +17,7 @@ export default class FTLNomadVehicleSheet extends FTLNomadActorSheet {
removeCrew: FTLNomadVehicleSheet.#onRemoveCrew,
viewCrew: FTLNomadVehicleSheet.#onViewCrew,
pilotCrew: FTLNomadVehicleSheet.#onPilotCrew,
rollNpcCrew: FTLNomadVehicleSheet.#onRollNpcCrew,
},
}
@@ -81,20 +82,25 @@ export default class FTLNomadVehicleSheet extends FTLNomadActorSheet {
// Get vehicle agility bonus
const vehicleAgility = this.document.system.agility || 0
// Get the vehicles skill from the actor
const vehiclesSkill = actor.system.skills?.vehicles
if (!vehiclesSkill) {
ui.notifications.warn(game.i18n.localize("FTLNOMAD.Warning.noVehiclesSkill"))
// Get all skills from the actor
const actorSkills = actor.system.skills
if (!actorSkills) {
ui.notifications.warn(game.i18n.localize("FTLNOMAD.Warning.noSkills"))
return
}
// Default to vehicles skill
const defaultSkill = actorSkills.vehicles || Object.values(actorSkills)[0]
// Import the Roll class
const FTLNomadRoll = (await import("../../documents/roll.mjs")).default
// Call the roll prompt with the vehicle agility as a vehicle bonus
// Call the roll prompt with all skills available and vehicle agility as a vehicle bonus
let roll = await FTLNomadRoll.prompt({
rollType: "skill",
rollItem: vehiclesSkill,
rollItem: defaultSkill,
availableSkills: actorSkills,
selectedSkillId: "vehicles",
actorId: actor.id,
actorName: actor.name,
actorImage: actor.img,
@@ -108,6 +114,48 @@ export default class FTLNomadVehicleSheet extends FTLNomadActorSheet {
await roll.toMessage({}, { rollMode: roll.options.rollMode })
}
/**
* Roll a check for NPC crew with vehicle agility bonus
* @param {Event} event The initiating click event
* @param {HTMLElement} target The current target of the event listener
*/
static async #onRollNpcCrew(event, target) {
const npcCrewLevel = this.document.system.npcCrew || 0
if (npcCrewLevel < 0) {
ui.notifications.warn(game.i18n.localize("FTLNOMAD.Warning.noNpcCrew"))
return
}
// Get vehicle agility bonus
const vehicleAgility = this.document.system.agility || 0
// Create a fake skill object for the NPC crew
const npcSkill = {
value: npcCrewLevel,
label: "FTLNOMAD.Label.npcCrewSkill"
}
// Import the Roll class
const FTLNomadRoll = (await import("../../documents/roll.mjs")).default
// Call the roll prompt with NPC crew level as skill
let roll = await FTLNomadRoll.prompt({
rollType: "skill",
rollItem: npcSkill,
actorId: this.document.id,
actorName: `${this.document.name} (NPC Crew)`,
actorImage: this.document.img,
talents: [],
isEncumbered: false,
hasTarget: false,
vehicleBonus: vehicleAgility
})
if (!roll) return null
await roll.toMessage({}, { rollMode: roll.options.rollMode })
}
/** @override */
static PARTS = {
main: {

View File

@@ -67,7 +67,7 @@ export default class FTLNomadRoll extends Roll {
} else {
let mod = options.rollItem?.value || 0
fullFormula = `${options.formula} + ${options.skillModifier}D + ${mod} + ${options.rangeModifier}D + ${options.numericModifier}D + ${options.numericModifierSelect}`
if (options.vehicleBonus) {
if (options.vehicleBonus && options.useVehicleBonus) {
fullFormula += ` + ${options.vehicleBonus}`
}
}
@@ -140,16 +140,28 @@ export default class FTLNomadRoll extends Roll {
options.rangeModifier = rangeModifier
options.damageModifier = damageModifier
options.vehicleBonus = options.vehicleBonus || 0
options.useVehicleBonus = true // Par défaut, le bonus est activé
let fullFormula = `${formula} + ${options.rollItem.value}`
if (options.isEncumbered) {
fullFormula += ` - 1D`
}
if (options.vehicleBonus) {
if (options.vehicleBonus && options.useVehicleBonus) {
fullFormula += ` + ${options.vehicleBonus}`
}
options.fullFormula = fullFormula
options.formula = formula
// Prepare available skills if provided (for vehicle/starship piloting)
let availableSkills = null
if (options.availableSkills) {
availableSkills = Object.entries(options.availableSkills).map(([id, skill]) => ({
id: id,
label: skill.label,
value: skill.value,
selected: id === options.selectedSkillId
}))
}
let dialogContext = {
actorId: options.actorId,
actorName: options.actorName,
@@ -172,6 +184,7 @@ export default class FTLNomadRoll extends Roll {
modifier,
numericModifierSelect,
vehicleBonus: options.vehicleBonus,
availableSkills: availableSkills,
}
const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-ftl-nomad/templates/roll-dialog.hbs", dialogContext)
@@ -198,6 +211,14 @@ export default class FTLNomadRoll extends Roll {
rejectClose: false, // Click on Close button will not launch an error
render: (event, dialog) => {
FTLNomadRoll.updateFullFormula(options)
$(".roll-skill-selector").change(event => {
const skillId = event.target.value
if (options.availableSkills && options.availableSkills[skillId]) {
options.rollItem = foundry.utils.duplicate(options.availableSkills[skillId])
options.selectedSkillId = skillId
FTLNomadRoll.updateFullFormula(options)
}
})
$(".roll-skill-modifier").change(event => {
options.skillModifier = Number(event.target.value)
FTLNomadRoll.updateFullFormula(options)
@@ -224,6 +245,10 @@ export default class FTLNomadRoll extends Roll {
}
FTLNomadRoll.updateFullFormula(options)
})
$(".use-vehicle-bonus").change(event => {
options.useVehicleBonus = event.target.checked
FTLNomadRoll.updateFullFormula(options)
})
}
})
@@ -237,14 +262,22 @@ export default class FTLNomadRoll extends Roll {
if (Hooks.call("fvtt-ftl-nomad.preRoll", options, rollData) === false) return
// Update rollItem if a skill was selected from the dropdown
if (rollData.selectedSkill && options.availableSkills) {
options.rollItem = foundry.utils.duplicate(options.availableSkills[rollData.selectedSkill])
}
options.numericModifier = Number(rollData.numericModifier) || 0
options.skillModifier = Number(rollData.skillModifier) || 0
options.rangeModifier = Number(rollData.rangeModifier) || 0
options.numericModifierSelect = Number(rollData.numericModifierSelect) || 0
options.useVehicleBonus = rollData.useVehicleBonus !== "off" && rollData.useVehicleBonus !== false
options.finalModifier = options.numericModifier + options.skillModifier + options.rangeModifier
let mod = options.rollItem?.value || 0
mod += options.numericModifierSelect
mod += options.vehicleBonus || 0
if (options.useVehicleBonus) {
mod += options.vehicleBonus || 0
}
// Build the dice formula
let diceFormula = "2d6"

View File

@@ -11,8 +11,10 @@ export default class FTLNomadStarship extends foundry.abstract.TypeDataModel {
schema.hullType = new fields.StringField({ required: true, initial: "small", choices: SYSTEM.STARSHIP_HULL })
schema.endurance = new fields.StringField({ required: true, initial: "" })
schema.armor = new fields.StringField({ required: true, initial: "" })
schema.armorCritical = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
schema.crewList = new fields.ArrayField(new fields.StringField({ required: true }), { initial: [] })
schema.crewCapacity = new fields.StringField({ required: true, initial: "" })
schema.npcCrew = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
schema.cargo = new fields.StringField({ required: true, initial: "" })
schema.guns = new fields.StringField({ required: true, initial: "1d6" })
schema.travelMultiplier = new fields.StringField({ required: true, initial: "" })

View File

@@ -9,9 +9,11 @@ export default class FTLNomadVehicle extends foundry.abstract.TypeDataModel {
schema.agility = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
schema.armor = new fields.StringField({ required: true, initial: "" })
schema.armorCritical = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
schema.cargo = new fields.StringField({ required: true, initial: "" })
schema.crewList = new fields.ArrayField(new fields.StringField({ required: true }), { initial: [] })
schema.crewCapacity = new fields.StringField({ required: true, initial: "" })
schema.npcCrew = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
schema.force = new fields.NumberField({ ...requiredInteger, initial: 1, min: 1 })
schema.range = new fields.StringField({ required: true, initial: "1d6" })
schema.speed = new fields.StringField({ required: true, initial: "1d6" })