5 Commits

Author SHA1 Message Date
0874507025 Fixes for damages + vehicle/ship ehancements
All checks were successful
Release Creation / build (release) Successful in 1m21s
2025-10-13 23:21:13 +02:00
2578ea4dc1 Fix bio + initiative
All checks were successful
Release Creation / build (release) Successful in 1m2s
2025-10-05 18:09:02 +02:00
d80e3e4658 Fix roll options
All checks were successful
Release Creation / build (release) Successful in 1m8s
2025-08-26 22:14:45 +02:00
188501423a Add new roll options
All checks were successful
Release Creation / build (release) Successful in 1m24s
2025-08-25 22:41:42 +02:00
668da28d2c Fix various issues with rolls and compendiums
All checks were successful
Release Creation / build (release) Successful in 57s
2025-08-24 16:19:35 +02:00
38 changed files with 660 additions and 201 deletions

View File

@@ -0,0 +1,112 @@
[
{
"name": "Autocannon, Light",
"tech_age": "Late Mechanical",
"cost": 10000,
"range": "heavy",
"damage": "5d6",
"mag": 100,
"ammo_cost": 1000,
"aspect": "Auto, AV 3d6+1.",
"description": "This weapon can fire bursts of shells at high rates of fire. It is common to find this mounted on aircraft as a dogfighting weapon, as well as on light armored vehicles as a support weapon for infantry."
},
{
"name": "Autocannon, Heavy",
"tech_age": "Late Mechanical",
"cost": 20000,
"range": "heavy",
"damage": "5d6",
"mag": 50,
"ammo_cost": 2000,
"aspect": "Auto, AV 3d6+2.",
"description": "A larger version of the light autocannon, often found on light armored vehicles, naval vessels, and ground attack aircraft."
},
{
"name": "Cannon, Light",
"tech_age": "Early Mechanical",
"cost": 15000,
"range": "heavy",
"damage": "5d6",
"mag": 40,
"ammo_cost": 2000,
"aspect": "AV 4d6+1.",
"description": "A multipurpose support weapon usually mounted on a vehicle or gun carriage."
},
{
"name": "Cannon, Heavy",
"tech_age": "Early Mechanical",
"cost": 30000,
"range": "heavy",
"damage": "6d6",
"mag": 20,
"ammo_cost": 3000,
"aspect": "AV 5d6.",
"description": "This cannon is a main battle tanks primary weapon. It is often used as field artillery as well."
},
{
"name": "Heavy Flamer",
"tech_age": "Late Mechanical",
"cost": 1000,
"range": "Rifle",
"damage": "3d6",
"mag": 5,
"ammo_cost": 25,
"aspect": "AV 2d6, Fire. ",
"description": "A brutal close-in anti-infantry weapon used to flush out fortifications and defend against infantry attack in built-up areas. Vehicles that carry flamethrowers are usually the first to be targeted by enemy infantry."
},
{
"name": "Grenade Launcher",
"tech_age": "Late Mechanical",
"cost": 400,
"range": "Rifle",
"damage": "According to grenade",
"mag": 50,
"ammo_cost": 0,
"aspect": "",
"description": "A light support weapon mounted on many vehicles. This version has a 50 round belt magazine. Many vehicles mount smoke grenade launchers as defensive weapons."
},
{
"name": "Guided Anti-Tank Missile",
"tech_age": "Early Atomic",
"cost": 4000,
"range": "heavy",
"damage": "5d6",
"mag": 4,
"ammo_cost": 200,
"aspect": "Blast, AV 5d6. ",
"description": "This vehicle mounted version of the portable anti-tank missile launcher has a magazine of four missiles. A system like this is often mounted on a light vehicle to give it significant anti-armor punch."
},
{
"name": "Laser Cannon",
"tech_age": "Early Space",
"cost": 10000,
"range": "heavy",
"damage": "5d6",
"mag": 100,
"ammo_cost": 100,
"aspect": "AV 4d6+2.",
"description": "The Early Space Ages replacement for all but the heaviest cannons, this vehicle weapon is highly efficient, and can be recharged from any power grid. This makes it the darling of logistics officers in any military where it is found."
},
{
"name": "Laser, Support",
"tech_age": "Early Space",
"cost": 5000,
"range": "heavy",
"damage": "5d6",
"mag": 100,
"ammo_cost": 100,
"aspect": "AV 3d6+1.",
"description": "This vehicle mounted version of the portable support laser lacks auto fire capabilities but has a nearly inexhaustible ammunition supply."
},
{
"name": "Rocket Launcher",
"tech_age": "Early Atomic",
"cost": 2000,
"range": "heavy",
"damage": "4d6",
"mag": 1,
"ammo_cost": 150,
"aspect": "Greater Blast, AV 3d6.",
"description": "A portable rocket launcher utilizing unguided munitions. Rocket payloads are considered high explosive and are not particularly effective against armored vehicles. Vehicle-mounted versions usually have 12 or 24 shots before requiring reloading."
}
]

View File

@@ -413,10 +413,10 @@ i.fvtt-ftl-nomad {
background-color: var(--color-light-1);
}
.fvtt-ftl-nomad .character-biography prose-mirror.inactive {
min-height: 40px;
min-height: 16rem;
}
.fvtt-ftl-nomad .character-biography prose-mirror.active {
min-height: 150px;
min-height: 16rem;
}
.fvtt-ftl-nomad .character-biography .field-label {
margin-left: 8px;
@@ -1104,6 +1104,9 @@ i.fvtt-ftl-nomad {
.fvtt-ftl-nomad .vehicle-description .field-label {
margin-left: 8px;
}
.fvtt-ftl-nomad .vehicle-description .section-editor {
min-height: 10rem;
}
.fvtt-ftl-nomad .vehicle-description .biodata {
display: grid;
grid-template-columns: repeat(2, 1fr);
@@ -1408,6 +1411,9 @@ i.fvtt-ftl-nomad {
.fvtt-ftl-nomad .starship-description .field-label {
margin-left: 8px;
}
.fvtt-ftl-nomad .starship-description .section-editor {
min-height: 10rem;
}
.fvtt-ftl-nomad .starship-description .biodata {
display: grid;
grid-template-columns: repeat(2, 1fr);

View File

@@ -31,6 +31,13 @@ Hooks.once("init", function () {
utils: FTLNomadUtils,
}
/* -------------------------------------------- */
// Set an initiative formula for the system
CONFIG.Combat.initiative = {
formula: "2d6 + @skills.combat.value",
decimals: 1
};
CONFIG.Actor.documentClass = documents.FTLNomadActor
CONFIG.Actor.dataModels = {
character: models.FTLNomadCharacter,

View File

@@ -351,7 +351,9 @@
}
},
"Label": {
"damages": "Damages",
"techAge": "Tech Age",
"formula": "Formula",
"damages": "Damage",
"modifications": "Modifications",
"abilities": "Abilities",
"Details": "Details",
@@ -362,11 +364,17 @@
"cargo": "Cargo",
"vehicle": "Vehicle",
"starship": "Starship",
"Easy4": "Easy (+4D)",
"Easy3": "Easy (+3D)",
"Easy2": "Easy (+2D)",
"Easy": "Easy (+1D)",
"Moderate": "Moderate (+0D)",
"Difficult": "Difficult (-1D)",
"Formidable": "Formidable (-2D)",
"Formidable3": "Formidable (-3D)",
"Impossible": "Impossible (-4D)",
"Impossible5": "Impossible (-5D)",
"Impossible6": "Impossible (-6D)",
"combat": "Combat",
"physical": "Physical",
"social": "Social",
@@ -505,6 +513,9 @@
"Carrier": "Carrier"
},
"FIELDS": {
"techAge": {
"label": "Tech Age"
},
"monthlyCost": {
"label": "Monthly Cost"
},
@@ -583,7 +594,7 @@
"addPsionic" : "Add Psionic",
"addCreatureAbility" : "Add Creature Ability",
"addCreatureTrait" : "Add Creature Trait",
"damages": "Enter current damages suffered"
"damages": "Enter current damage suffered"
},
"Vehicle": {
"FIELDS": {
@@ -619,6 +630,9 @@
},
"notes": {
"label": "Notes"
},
"techAge": {
"label": "Tech Age"
}
}
},
@@ -648,6 +662,12 @@
},
"weaponType": {
"label": "Type"
},
"ammoCost": {
"label": "Ammo Cost"
},
"magazine": {
"label": "Mag"
}
},
"Range": {

View File

@@ -12,6 +12,8 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
contentClasses: ["starship-content"],
},
actions: {
createEquipment: FTLNomadStarshipSheet.#onCreateEquipment,
createWeapon: FTLNomadStarshipSheet.#onCreateWeapon,
},
}
@@ -23,14 +25,17 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
tabs: {
template: "templates/generic/tab-navigation.hbs",
},
equipment: {
template: "systems/fvtt-ftl-nomad/templates/starship-equipment.hbs",
},
description: {
template: "systems/fvtt-ftl-nomad/templates/starship-description.hbs",
},
}
/** @override */
tabGroups = {
sheet: "description",
/** @override */
tabGroups = {
sheet: "equipment",
}
/**
@@ -39,6 +44,7 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
*/
#getTabs() {
const tabs = {
equipment: { id: "equipment", group: "sheet", icon: "fa-solid fa-shapes", label: "FTLNOMAD.Label.equipment" },
description: { id: "description", group: "sheet", icon: "fa-solid fa-book", label: "FTLNOMAD.Label.description" },
}
for (const v of Object.values(tabs)) {
@@ -69,6 +75,13 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
switch (partId) {
case "main":
break
case "equipment":
context.tab = context.tabs.equipment
context.weapons = doc.itemTypes.weapon
context.weapons.sort((a, b) => a.name.localeCompare(b.name))
context.equipments = doc.itemTypes.equipment
context.equipments.sort((a, b) => a.name.localeCompare(b.name))
break
case "description":
context.tab = context.tabs.description
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(doc.system.description, { async: true })
@@ -78,22 +91,31 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
return context
}
static #onCreateEquipment(event, target) {
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("FTLNOMAD.Label.newEquipment"), type: "equipment" }])
}
static #onCreateWeapon(event, target) {
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("FTLNOMAD.Label.newWeapon"), type: "weapon" }])
}
async _onRoll(event, target) {
const rollType = $(event.currentTarget).data("roll-type")
let rollType = $(event.currentTarget).data("roll-type")
let item
let formula
let roll
console.log("rollType", rollType)
switch (rollType) {
case "damage":
let li = $(event.currentTarget).parents(".item");
item = this.actor.items.get(li.data("item-id"));
break
case "starship-guns":
formula = this.actor.system.guns
// Rolll the damage
roll = new Roll(formula)
await roll.evaluate()
roll.toMessage( { flavor: `Starship ${this.actor.name} : Guns Damage` })
item = { name: "Starship Guns", type: "weapon", system: { damage: this.actor.system.guns, rangeType: "heavyweapon" } }
rollType = "damage"
break
default:
throw new Error(`Unknown roll type ${rollType}`)
}
await this.document.system.roll(rollType, item)
}

View File

@@ -33,8 +33,8 @@ export default class FTLNomadVehicleSheet extends FTLNomadActorSheet {
},
}
/** @override */
tabGroups = {
/** @override */
tabGroups = {
sheet: "equipment",
}

View File

@@ -2,15 +2,15 @@ export const SYSTEM_ID = "fvtt-ftl-nomad"
export const ASCII = `
░▒▓████████▓▒░▒▓████████▓▒░▒▓█▓▒░ ░▒▓███████▓▒░ ░▒▓██████▓▒░░▒▓██████████████▓▒░ ░▒▓██████▓▒░░▒▓███████▓▒░
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓██▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓██▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓██████▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓████████▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓██▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓██▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓████████▓▒░ ░▒▓█▓▒░░▒▓█▓▒░░▒▓██████▓▒░░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓███████▓▒░
░▒▓████████▓▒░▒▓████████▓▒░▒▓█▓▒░ ░▒▓███████▓▒░ ░▒▓██████▓▒░░▒▓██████████████▓▒░ ░▒▓██████▓▒░░▒▓███████▓▒░
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓██▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓██▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓██████▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓████████▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓██▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓██▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░
░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓████████▓▒░ ░▒▓█▓▒░░▒▓█▓▒░░▒▓██████▓▒░░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓███████▓▒░
`
@@ -52,12 +52,12 @@ export const WEAPON_TYPES = {
}
export const WEAPON_RANGE = {
"handgun": { id: "handgun", label: "FTLNOMAD.Weapon.Range.Handgun", range: {close: 0, near:0, far:-2} },
"assault": { id: "assault", label: "FTLNOMAD.Weapon.Range.Assault", range: {close: -2, near:0, far:-1, distant: -2} },
"rifle": { id: "rifle", label: "FTLNOMAD.Weapon.Range.Rifle", range: {close: -3, near:0, far:0, distant: -1} },
"melee": { id: "melee", label: "FTLNOMAD.Weapon.Range.Melee", range: {close: 0} },
"heavyweapon": { id: "heavyweapon", label: "FTLNOMAD.Weapon.Range.HeavyWeapon", range: {near:-1, far:0, distant: 0} },
"thrownweapon": { id: "thrownweapon", label: "FTLNOMAD.Weapon.Range.ThrownWeapon", range: {close: 0, near:-1} }
"handgun": { id: "handgun", label: "FTLNOMAD.Weapon.Range.Handgun", range: { close: 0, near: 0, far: -2 } },
"assault": { id: "assault", label: "FTLNOMAD.Weapon.Range.Assault", range: { close: -2, near: 0, far: -1, distant: -2 } },
"rifle": { id: "rifle", label: "FTLNOMAD.Weapon.Range.Rifle", range: { close: -3, near: 0, far: 0, distant: -1 } },
"melee": { id: "melee", label: "FTLNOMAD.Weapon.Range.Melee", range: { close: 0 } },
"heavyweapon": { id: "heavyweapon", label: "FTLNOMAD.Weapon.Range.HeavyWeapon", range: { near: -1, far: 0, distant: 0 } },
"thrownweapon": { id: "thrownweapon", label: "FTLNOMAD.Weapon.Range.ThrownWeapon", range: { close: 0, near: -1 } }
}
export const ATTACK_MODIFIERS = {
@@ -73,35 +73,35 @@ export const ATTACK_MODIFIERS = {
}
export const TRIAGE_RESULTS = {
"none": { id: "none", dice:0, label: "FTLNOMAD.TriageResults.None" },
"death": { id: "death", dice:3, label: "FTLNOMAD.TriageResults.Death" },
"critical": { id: "critical", dice:4, label: "FTLNOMAD.TriageResults.Critical" },
"severe": { id: "severe", dice:7, label: "FTLNOMAD.TriageResults.Severe" },
"moderate": { id: "moderate", dice:10, label: "FTLNOMAD.TriageResults.Moderate" },
"fleshwound": { id: "fleshwound", dice:12, label: "FTLNOMAD.TriageResults.FleshWound" }
"none": { id: "none", dice: 0, label: "FTLNOMAD.TriageResults.None" },
"death": { id: "death", dice: 3, label: "FTLNOMAD.TriageResults.Death" },
"critical": { id: "critical", dice: 4, label: "FTLNOMAD.TriageResults.Critical" },
"severe": { id: "severe", dice: 7, label: "FTLNOMAD.TriageResults.Severe" },
"moderate": { id: "moderate", dice: 10, label: "FTLNOMAD.TriageResults.Moderate" },
"fleshwound": { id: "fleshwound", dice: 12, label: "FTLNOMAD.TriageResults.FleshWound" }
}
export const CREATURE_TERRAIN_TYPES = {
"cave": { id: "cave", label: "FTLNOMAD.Creature.Terrain.Cave", niche:0, size: 0 },
"coast": { id: "coast", label: "FTLNOMAD.Creature.Terrain.Coast", niche:1, size: 0 },
"desert": { id: "desert", label: "FTLNOMAD.Creature.Terrain.Desert", niche:-1, size: -1 },
"forest": { id: "forest", label: "FTLNOMAD.Creature.Terrain.Forest", niche:1, size: 1 },
"jungle": { id: "jungle", label: "FTLNOMAD.Creature.Terrain.Jungle", niche:1, size: 1 },
"mixed": { id: "mixed", label: "FTLNOMAD.Creature.Terrain.Mixed", niche:0, size: 0 },
"mountain": { id: "mountain", label: "FTLNOMAD.Creature.Terrain.Mountain", niche:-1, size: -1 },
"ocean": { id: "ocean", label: "FTLNOMAD.Creature.Terrain.Ocean", niche:-1, size: 1 },
"river": { id: "river", label: "FTLNOMAD.Creature.Terrain.River", niche:1, size: 0 },
"ruins": { id: "ruins", label: "FTLNOMAD.Creature.Terrain.Ruins", niche:0, size: 1 },
"savannah": { id: "savannah", label: "FTLNOMAD.Creature.Terrain.Savannah", niche:0, size: 1 },
"shallows": { id: "shallows", label: "FTLNOMAD.Creature.Terrain.Shallows", niche:1, size: 0 },
"swamp": { id: "swamp", label: "FTLNOMAD.Creature.Terrain.Swamp", niche:1, size: 1 }
"cave": { id: "cave", label: "FTLNOMAD.Creature.Terrain.Cave", niche: 0, size: 0 },
"coast": { id: "coast", label: "FTLNOMAD.Creature.Terrain.Coast", niche: 1, size: 0 },
"desert": { id: "desert", label: "FTLNOMAD.Creature.Terrain.Desert", niche: -1, size: -1 },
"forest": { id: "forest", label: "FTLNOMAD.Creature.Terrain.Forest", niche: 1, size: 1 },
"jungle": { id: "jungle", label: "FTLNOMAD.Creature.Terrain.Jungle", niche: 1, size: 1 },
"mixed": { id: "mixed", label: "FTLNOMAD.Creature.Terrain.Mixed", niche: 0, size: 0 },
"mountain": { id: "mountain", label: "FTLNOMAD.Creature.Terrain.Mountain", niche: -1, size: -1 },
"ocean": { id: "ocean", label: "FTLNOMAD.Creature.Terrain.Ocean", niche: -1, size: 1 },
"river": { id: "river", label: "FTLNOMAD.Creature.Terrain.River", niche: 1, size: 0 },
"ruins": { id: "ruins", label: "FTLNOMAD.Creature.Terrain.Ruins", niche: 0, size: 1 },
"savannah": { id: "savannah", label: "FTLNOMAD.Creature.Terrain.Savannah", niche: 0, size: 1 },
"shallows": { id: "shallows", label: "FTLNOMAD.Creature.Terrain.Shallows", niche: 1, size: 0 },
"swamp": { id: "swamp", label: "FTLNOMAD.Creature.Terrain.Swamp", niche: 1, size: 1 }
}
export const CREATURE_NICHES = {
"prey": { id: "prey", label: "FTLNOMAD.Creature.Niche.Prey" },
"opportunist": { id: "opportunist", label: "FTLNOMAD.Creature.Niche.Opportunist" },
"herbivore": { id: "herbivore", label: "FTLNOMAD.Creature.Niche.Herbivore" },
"predator": { id: "predator", label: "FTLNOMAD.Creature.Niche.Predator" }
"predator": { id: "predator", label: "FTLNOMAD.Creature.Niche.Predator" }
}
export const CREATURE_SIZES = {
@@ -114,11 +114,17 @@ export const CREATURE_SIZES = {
}
export const MODIFIER_CHOICES = {
"easy": { id: "easy", label: "FTLNOMAD.Label.Easy", value :"1" },
"easy4": { id: "easy4", label: "FTLNOMAD.Label.Easy4", value: "4" },
"easy3": { id: "easy3", label: "FTLNOMAD.Label.Easy3", value: "3" },
"easy2": { id: "easy2", label: "FTLNOMAD.Label.Easy2", value: "2" },
"easy": { id: "easy", label: "FTLNOMAD.Label.Easy", value: "1" },
"moderate": { id: "moderate", label: "FTLNOMAD.Label.Moderate", value: "0" },
"difficult": { id: "difficult", label: "FTLNOMAD.Label.Difficult", value: "-1" },
"formidable": { id: "formidable", label: "FTLNOMAD.Label.Formidable", value: "-2" },
"impossible": { id: "impossible", label: "FTLNOMAD.Label.Impossible", value: "-4" }
"formidable3": { id: "formidable3", label: "FTLNOMAD.Label.Formidable3", value: "-3" },
"impossible": { id: "impossible", label: "FTLNOMAD.Label.Impossible", value: "-4" },
"impossible5": { id: "impossible5", label: "FTLNOMAD.Label.Impossible5", value: "-5" },
"impossible6": { id: "impossible6", label: "FTLNOMAD.Label.Impossible6", value: "-6" }
}
export const STARSHIP_HULL = {

View File

@@ -62,9 +62,14 @@ export default class FTLNomadRoll extends Roll {
static updateFullFormula(options) {
let fullFormula
fullFormula = `${options.formula} + ${options.rollItem.value} + ${options.skillModifier}D + ${options.rangeModifier}D + ${options.numericModifier}D`
if (options.rollType === "damage") {
fullFormula = `${options.formula} + ${options.skillModifier}D6 `
} else {
let mod = options.rollItem?.value || 0
fullFormula = `${options.formula} + ${options.skillModifier}D + ${mod} + ${options.rangeModifier}D + ${options.numericModifier}D`
}
// Replace all the "+ -" with "-"
fullFormula = fullFormula.replace(/\+\s*-/g, "- ")
fullFormula = fullFormula.replace(/\+\s*\-/g, "- ")
$('#roll-dialog-full-formula').text(fullFormula)
options.fullFormula = fullFormula
}
@@ -85,20 +90,16 @@ export default class FTLNomadRoll extends Roll {
*/
static async prompt(options = {}) {
let formula = "2d6"
let actor = game.actors.get(options.actorId)
switch (options.rollType) {
case "skill":
break
case "damage":
let formula = options.rollItem.system.damage
let damageRoll = new Roll(formula)
await damageRoll.evaluate()
await damageRoll.toMessage({
flavor: `${options.rollItem.name} - Damage Roll`
});
return
options.weapon = foundry.utils.duplicate(options.rollItem)
formula = options.weapon.system.damage
break
case "weapon":
let actor = game.actors.get(options.actorId)
options.weapon = foundry.utils.duplicate(options.rollItem)
options.rollItem = actor.system.skills.combat
break
@@ -106,6 +107,7 @@ export default class FTLNomadRoll extends Roll {
break
}
options.actor = actor
const rollModes = foundry.utils.duplicate(CONFIG.Dice.rollModes)
const fieldRollMode = new foundry.data.fields.StringField({
choices: rollModes,
@@ -116,7 +118,7 @@ export default class FTLNomadRoll extends Roll {
const choiceModifier = SYSTEM.MODIFIER_CHOICES
let choiceRangeModifier = {}
let rangeModifier = 0
if ( options.weapon) {
if (options.weapon) {
// Build the range modifiers
let range = SYSTEM.WEAPON_RANGE[options.weapon.system.rangeType]
for (let [key, value] of Object.entries(range.range)) {
@@ -192,7 +194,7 @@ export default class FTLNomadRoll extends Roll {
$(".select-combat-option").change(event => {
let field = $(event.target).data("field")
let modifier = SYSTEM.ATTACK_MODIFIERS[field]
if ( event.target.checked) {
if (event.target.checked) {
options.numericModifier += modifier
} else {
options.numericModifier -= modifier
@@ -212,13 +214,40 @@ export default class FTLNomadRoll extends Roll {
if (Hooks.call("fvtt-ftl-nomad.preRoll", options, rollData) === false) return
let diceFormula = `${2+Math.abs(options.numericModifier)}D6`
if ( options.numericModifier > 0 ) {
diceFormula += `kh2 + ${options.rollItem.value}`
options.numericModifier = Number(rollData.numericModifier) || 0
options.skillModifier = Number(rollData.skillModifier) || 0
options.rangeModifier = Number(rollData.rangeModifier) || 0
options.finalModifier = options.numericModifier + options.skillModifier + options.rangeModifier
let mod = options.rollItem?.value || 0
// Build the dice formula
let diceFormula = "2d6"
if (options.rollType === "damage") {
let damageFormula = options.weapon.system.damage.toUpperCase().replace(/D/g, "d")
// Extract the mod (if present), like in 3d6+1
let match = damageFormula.match(/([+-]\d+)$/)
if (match) {
mod += Number(match[1])
damageFormula = damageFormula.replace(match[1], "")
}
// Replace the D6 by the correct number of D6
damageFormula = damageFormula.replace(/(\d*)d6/gi, (match, p1) => {
let numDice = Number(p1) || 1
numDice += Number(options.skillModifier)
//numDice += options?.finalModifier || 0
return `${numDice}d6 + ${mod}`
})
diceFormula = damageFormula
} else {
diceFormula += `kl2 + ${options.rollItem.value}`
diceFormula = `${2 + Math.abs(options.finalModifier)}D6`
if (options.finalModifier > 0) {
diceFormula += `kh2 + ${mod}`
} else {
diceFormula += `kl2 + ${mod}`
}
}
console.log("FTLNomadRoll | Rolling ", diceFormula, options, rollData)
const roll = new this(diceFormula, options.data, rollData)
await roll.evaluate()
@@ -254,6 +283,8 @@ export default class FTLNomadRoll extends Roll {
*/
static createTitle(type, target) {
switch (type) {
case "damage":
return `${game.i18n.localize("FTLNOMAD.Label.titleDamage")}`
case "skill":
return `${game.i18n.localize("FTLNOMAD.Label.titleSkill")}`
case "weapon":

View File

@@ -35,8 +35,8 @@ export default class FTLNomadProtagonist extends foundry.abstract.TypeDataModel
schema.health = new fields.SchemaField({
staminaValue: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 }),
staminaMax: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 }),
wounds: new fields.NumberField({ ...requiredInteger, initial:0, min: 0 }),
triageResults: new fields.StringField({ required: true, nullable: false, initial: "none", choices: SYSTEM.TRIAGE_RESULTS })
wounds: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
triageResults: new fields.StringField({ required: true, nullable: false, initial: "none", choices: SYSTEM.TRIAGE_RESULTS })
})
schema.enc = new fields.SchemaField({
@@ -76,18 +76,18 @@ export default class FTLNomadProtagonist extends foundry.abstract.TypeDataModel
prepareDerivedData() {
super.prepareDerivedData();
let encMax = 10 + (2*this.skills.physical.value)
let encMax = 10 + (2 * this.skills.physical.value)
if (encMax !== this.enc.max) {
this.enc.max = encMax
}
let enc = 0
let armor = 0
for (let i of this.parent.items) {
for (let i of this.parent.items) {
if (i.system?.enc) {
enc += i.system.enc
}
if ( i.system?.protection) {
if (i.system?.protection) {
armor += i.system.protection
}
}
@@ -97,12 +97,12 @@ export default class FTLNomadProtagonist extends foundry.abstract.TypeDataModel
if (armor !== this.armor.value) {
this.armor.value = armor
}
let staminaMax = 14 + (3*this.skills.physical.value)
let staminaMax = 14 + (3 * this.skills.physical.value)
if (staminaMax !== this.health.staminaMax) {
this.health.staminaMax = staminaMax
}
}
isEncumbered() {
return this.enc.value > this.enc.max
}

View File

@@ -15,9 +15,10 @@ export default class FTLNomadStarship extends foundry.abstract.TypeDataModel {
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: "" })
schema.cost = new fields.NumberField({ required: true, initial: 0, min: 0 })
schema.monthlyCost = new fields.NumberField({ required: true, initial: 0, min: 0 })
schema.cost = new fields.StringField({ required: true, initial: "0" })
schema.monthlyCost = new fields.StringField({ required: true, initial: "0" })
schema.damages = new fields.StringField({ required: true, initial: "" })
schema.techAge = new fields.StringField({ required: true, choices: SYSTEM.TECH_AGES, initial: "lateatomic" })
schema.description = new fields.HTMLField({ required: true, textSearch: true })
schema.modifications = new fields.HTMLField({ required: true, textSearch: true })
@@ -33,4 +34,24 @@ export default class FTLNomadStarship extends foundry.abstract.TypeDataModel {
return false
}
async roll(rollType, rollItem) {
let opponentTarget
const hasTarget = opponentTarget !== undefined
let roll = await FTLNomadRoll.prompt({
rollType,
rollItem,
actorId: this.parent.id,
actorName: this.parent.name,
actorImage: this.parent.img,
isEncumbered: false,
hasTarget,
target: opponentTarget
})
if (!roll) return null
await roll.toMessage({}, { rollMode: roll.options.rollMode })
}
}

View File

@@ -14,11 +14,11 @@ export default class FTLNomadVehicle extends foundry.abstract.TypeDataModel {
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" })
schema.techAge = new fields.StringField({ required: true, initial: "1d6" })
schema.techAge = new fields.StringField({ required: true, choices: SYSTEM.TECH_AGES, initial: "lateatomic" })
schema.tonnage = new fields.StringField({ required: true, initial: "" })
schema.damages = new fields.StringField({ required: true, initial: "" })
schema.cost = new fields.NumberField({ required: true, initial: 0, min: 0 })
schema.cost = new fields.StringField({ required: true, initial: "0" })
schema.description = new fields.HTMLField({ required: true, textSearch: true })
schema.notes = new fields.HTMLField({ required: true, textSearch: true })
@@ -33,23 +33,23 @@ export default class FTLNomadVehicle extends foundry.abstract.TypeDataModel {
return false
}
async roll(rollType, rollItem) {
let opponentTarget
const hasTarget = opponentTarget !== undefined
async roll(rollType, rollItem) {
let opponentTarget
const hasTarget = opponentTarget !== undefined
let roll = await FTLNomadRoll.prompt({
rollType,
rollItem,
actorId: this.parent.id,
actorName: this.parent.name,
actorImage: this.parent.img,
isEncumbered: this.isEncumbered(),
hasTarget,
target: opponentTarget
})
if (!roll) return null
let roll = await FTLNomadRoll.prompt({
rollType,
rollItem,
actorId: this.parent.id,
actorName: this.parent.name,
actorImage: this.parent.img,
isEncumbered: this.isEncumbered(),
hasTarget,
target: opponentTarget
})
if (!roll) return null
await roll.toMessage({}, { rollMode: roll.options.rollMode })
}
await roll.toMessage({}, { rollMode: roll.options.rollMode })
}
}

View File

@@ -8,14 +8,14 @@ export default class FTLNomadWeapon extends foundry.abstract.TypeDataModel {
schema.description = new fields.HTMLField({ required: true, textSearch: true })
schema.techAge = new fields.StringField({ required: true, choices: SYSTEM.TECH_AGES, initial : "lateatomic" })
schema.techAge = new fields.StringField({ required: true, choices: SYSTEM.TECH_AGES, initial: "lateatomic" })
schema.weaponType = new fields.StringField({ required: true, initial: "melee", choices: SYSTEM.WEAPON_TYPES })
schema.rangeType = new fields.StringField({ required: true, initial: "melee", choices: SYSTEM.WEAPON_RANGE })
schema.damage = new fields.StringField({required: true, initial: "1d6"})
schema.damage = new fields.StringField({ required: true, initial: "1d6" })
schema.magazine = new fields.NumberField({ required: true, initial: 1, min: 0 })
schema.range = new fields.SchemaField({
schema.range = new fields.SchemaField({
close: new fields.NumberField({ ...requiredInteger, initial: 0 }),
near: new fields.NumberField({ ...requiredInteger, initial: 0 }),
far: new fields.NumberField({ ...requiredInteger, initial: 0 }),
@@ -23,7 +23,7 @@ export default class FTLNomadWeapon extends foundry.abstract.TypeDataModel {
})
schema.enc = new fields.NumberField({ required: true, initial: 1, min: 0 })
schema.aspect = new fields.StringField({ required: true, initial: ""})
schema.aspect = new fields.StringField({ required: true, initial: "" })
schema.cost = new fields.NumberField({ required: true, initial: 0, min: 0 })
schema.ammoCost = new fields.NumberField({ required: true, initial: 0, min: 0 })

View File

@@ -675,7 +675,7 @@ export default class FTLNomadUtils {
return [];
});
console.log("Melee Weapons Data", meleeWeaponsData);
console.log("Melee Weapons Data", meleeWeaponsData);
// Import each melee weapon
for (const weapon of meleeWeaponsData) {
// Check if the weapon already exists
@@ -705,4 +705,51 @@ export default class FTLNomadUtils {
}
}
static async importVehicleWeapons() {
// Create a melee weapons folder if it doesn't exist
const meleeWeaponsFolder = game.folders.getName("Vehicle Weapons") || await Folder.create({
name: "Vehicle Weapons", type: "Item"
})
if (!meleeWeaponsFolder) {
console.error("Failed to create Vehicle Weapons folder");
return;
}
// Load the melee weapons JSON file
const meleeWeaponsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/vehicleweapons.json")
.then(response => response.json())
.catch(error => {
console.error("Failed to load vehicle weapons data:", error);
return [];
});
console.log("vehicle Weapons Data", meleeWeaponsData);
// Import each melee weapon
for (const weapon of meleeWeaponsData) {
// Check if the weapon already exists
const existingWeapon = game.items.find(i => i.name === weapon.name && i.type === "weapon");
if (existingWeapon) {
console.warn(`Weapon ${weapon.name} already exists, skipping import.`);
}
// Create the weapon item
await Item.create({
name: weapon.name,
type: "weapon",
img: "systems/fvtt-ftl-nomad/assets/icons/icon_weapon.svg",
system: {
description: weapon.description,
damage: weapon.damage,
techAge: this.getTechAgeKeyFromLabel(weapon.tech_age),
weaponType: "vehicle", //SYSTEM.WEAPON_TYPES.melee.id,
rangeType: SYSTEM.WEAPON_RANGE.melee.id,
enc: 0,
aspect: weapon.aspects,
cost: weapon.cost || 0,
ammoCost: weapon.ammo_cost || 0,
magazine: weapon.mag || 1,
},
folder: meleeWeaponsFolder.id
});
}
}
}

Binary file not shown.

View File

@@ -1 +1 @@
MANIFEST-000035
MANIFEST-000069

View File

@@ -1,15 +1,11 @@
2025/07/13-19:19:55.407043 7f3fa77fe6c0 Recovering log #33
2025/07/13-19:19:55.417622 7f3fa77fe6c0 Delete type=3 #31
2025/07/13-19:19:55.417740 7f3fa77fe6c0 Delete type=0 #33
2025/07/13-19:30:09.138052 7f3fa57fa6c0 Level-0 table #38: started
2025/07/13-19:30:09.142514 7f3fa57fa6c0 Level-0 table #38: 69052 bytes OK
2025/07/13-19:30:09.149276 7f3fa57fa6c0 Delete type=0 #36
2025/07/13-19:30:09.149522 7f3fa57fa6c0 Manual compaction at level-0 from '!folders!AuBtSOj1mJmh88qx' @ 72057594037927935 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at (end)
2025/07/13-19:30:09.149572 7f3fa57fa6c0 Manual compaction at level-1 from '!folders!AuBtSOj1mJmh88qx' @ 72057594037927935 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at '!items!zv9dwgL3p7ThQn7j' @ 347 : 0
2025/07/13-19:30:09.149581 7f3fa57fa6c0 Compacting 1@1 + 1@2 files
2025/07/13-19:30:09.155375 7f3fa57fa6c0 Generated table #39@1: 273 keys, 107280 bytes
2025/07/13-19:30:09.155393 7f3fa57fa6c0 Compacted 1@1 + 1@2 files => 107280 bytes
2025/07/13-19:30:09.161181 7f3fa57fa6c0 compacted to: files[ 0 0 1 0 0 0 0 ]
2025/07/13-19:30:09.161294 7f3fa57fa6c0 Delete type=2 #14
2025/07/13-19:30:09.161440 7f3fa57fa6c0 Delete type=2 #38
2025/07/13-19:30:09.181330 7f3fa57fa6c0 Manual compaction at level-1 from '!items!zv9dwgL3p7ThQn7j' @ 347 : 0 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at (end)
2025/10/13-22:56:27.667573 7f189ffff6c0 Delete type=3 #1
2025/10/13-23:20:46.625534 7f189e7fc6c0 Level-0 table #72: started
2025/10/13-23:20:46.625575 7f189e7fc6c0 Level-0 table #72: 0 bytes OK
2025/10/13-23:20:46.631818 7f189e7fc6c0 Delete type=0 #70
2025/10/13-23:20:46.644541 7f189e7fc6c0 Manual compaction at level-0 from '!folders!AuBtSOj1mJmh88qx' @ 72057594037927935 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at '!items!zv9dwgL3p7ThQn7j' @ 385 : 1
2025/10/13-23:20:46.644551 7f189e7fc6c0 Compacting 1@0 + 0@1 files
2025/10/13-23:20:46.649604 7f189e7fc6c0 Generated table #73@0: 285 keys, 111653 bytes
2025/10/13-23:20:46.649622 7f189e7fc6c0 Compacted 1@0 + 0@1 files => 111653 bytes
2025/10/13-23:20:46.655618 7f189e7fc6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2025/10/13-23:20:46.655762 7f189e7fc6c0 Delete type=2 #67
2025/10/13-23:20:46.675801 7f189e7fc6c0 Manual compaction at level-0 from '!items!zv9dwgL3p7ThQn7j' @ 385 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at (end)

View File

@@ -1,8 +1,4 @@
2025/07/13-10:30:52.384204 7f3fa77fe6c0 Recovering log #29
2025/07/13-10:30:52.394989 7f3fa77fe6c0 Delete type=3 #27
2025/07/13-10:30:52.395058 7f3fa77fe6c0 Delete type=0 #29
2025/07/13-10:33:26.219686 7f3fa57fa6c0 Level-0 table #34: started
2025/07/13-10:33:26.219728 7f3fa57fa6c0 Level-0 table #34: 0 bytes OK
2025/07/13-10:33:26.225987 7f3fa57fa6c0 Delete type=0 #32
2025/07/13-10:33:26.233983 7f3fa57fa6c0 Manual compaction at level-0 from '!folders!AuBtSOj1mJmh88qx' @ 72057594037927935 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at (end)
2025/07/13-10:33:26.244796 7f3fa57fa6c0 Manual compaction at level-1 from '!folders!AuBtSOj1mJmh88qx' @ 72057594037927935 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at (end)
2025/10/13-22:56:27.556402 7f189ffff6c0 Log #65: 0 ops saved to Table #68 OK
2025/10/13-22:56:27.556458 7f189ffff6c0 Archiving /home/morr/foundry/foundrydata-v13/Data/systems/fvtt-ftl-nomad/packs/ftl-nomad-items/000065.log: OK
2025/10/13-22:56:27.556662 7f189ffff6c0 Table #67: 285 entries OK
2025/10/13-22:56:27.577220 7f189ffff6c0 **** Repaired leveldb /home/morr/foundry/foundrydata-v13/Data/systems/fvtt-ftl-nomad/packs/ftl-nomad-items; recovered 1 files; 111653 bytes. Some data may have been lost. ****

Binary file not shown.

View File

@@ -1 +1 @@
MANIFEST-000014
MANIFEST-000047

View File

@@ -1,8 +1,11 @@
2025/07/13-19:19:55.423004 7f3fa5ffb6c0 Recovering log #12
2025/07/13-19:19:55.432450 7f3fa5ffb6c0 Delete type=3 #10
2025/07/13-19:19:55.432507 7f3fa5ffb6c0 Delete type=0 #12
2025/07/13-19:30:09.131809 7f3fa57fa6c0 Level-0 table #17: started
2025/07/13-19:30:09.131855 7f3fa57fa6c0 Level-0 table #17: 0 bytes OK
2025/07/13-19:30:09.137925 7f3fa57fa6c0 Delete type=0 #15
2025/07/13-19:30:09.149491 7f3fa57fa6c0 Manual compaction at level-0 from '!actors!3pydTJsM73Z4o0V6' @ 72057594037927935 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at (end)
2025/07/13-19:30:09.149534 7f3fa57fa6c0 Manual compaction at level-1 from '!actors!3pydTJsM73Z4o0V6' @ 72057594037927935 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at (end)
2025/10/13-22:56:27.777302 7f189ffff6c0 Delete type=3 #1
2025/10/13-23:20:46.638242 7f189e7fc6c0 Level-0 table #50: started
2025/10/13-23:20:46.638279 7f189e7fc6c0 Level-0 table #50: 0 bytes OK
2025/10/13-23:20:46.644407 7f189e7fc6c0 Delete type=0 #48
2025/10/13-23:20:46.655963 7f189e7fc6c0 Manual compaction at level-0 from '!actors!3pydTJsM73Z4o0V6' @ 72057594037927935 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at '!folders!vRnrOJqSMlxbSgyX' @ 92 : 1
2025/10/13-23:20:46.655974 7f189e7fc6c0 Compacting 1@0 + 0@1 files
2025/10/13-23:20:46.659684 7f189e7fc6c0 Generated table #51@0: 51 keys, 49087 bytes
2025/10/13-23:20:46.659713 7f189e7fc6c0 Compacted 1@0 + 0@1 files => 49087 bytes
2025/10/13-23:20:46.665961 7f189e7fc6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2025/10/13-23:20:46.666034 7f189e7fc6c0 Delete type=2 #45
2025/10/13-23:20:46.682181 7f189e7fc6c0 Manual compaction at level-0 from '!folders!vRnrOJqSMlxbSgyX' @ 92 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at (end)

View File

@@ -1,8 +1,4 @@
2025/07/13-10:30:52.399161 7f3fa5ffb6c0 Recovering log #8
2025/07/13-10:30:52.409521 7f3fa5ffb6c0 Delete type=3 #6
2025/07/13-10:30:52.409646 7f3fa5ffb6c0 Delete type=0 #8
2025/07/13-10:33:26.202414 7f3fa57fa6c0 Level-0 table #13: started
2025/07/13-10:33:26.202485 7f3fa57fa6c0 Level-0 table #13: 0 bytes OK
2025/07/13-10:33:26.208789 7f3fa57fa6c0 Delete type=0 #11
2025/07/13-10:33:26.233915 7f3fa57fa6c0 Manual compaction at level-0 from '!actors!3pydTJsM73Z4o0V6' @ 72057594037927935 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at (end)
2025/07/13-10:33:26.234020 7f3fa57fa6c0 Manual compaction at level-1 from '!actors!3pydTJsM73Z4o0V6' @ 72057594037927935 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at (end)
2025/10/13-22:56:27.671453 7f189ffff6c0 Log #43: 0 ops saved to Table #46 OK
2025/10/13-22:56:27.671525 7f189ffff6c0 Archiving /home/morr/foundry/foundrydata-v13/Data/systems/fvtt-ftl-nomad/packs/ftl-nomad-vehicles/000043.log: OK
2025/10/13-22:56:27.671630 7f189ffff6c0 Table #45: 51 entries OK
2025/10/13-22:56:27.705153 7f189ffff6c0 **** Repaired leveldb /home/morr/foundry/foundrydata-v13/Data/systems/fvtt-ftl-nomad/packs/ftl-nomad-vehicles; recovered 1 files; 49087 bytes. Some data may have been lost. ****

View File

@@ -219,10 +219,10 @@
.character-biography {
background-color: var(--color-light-1);
prose-mirror.inactive {
min-height: 40px;
min-height: 16rem;
}
prose-mirror.active {
min-height: 150px;
min-height: 16rem;
}
.field-label {
margin-left: 8px;

View File

@@ -42,7 +42,6 @@
max-width: 4rem;
}
}
}
.starship-right {
@@ -99,10 +98,8 @@
select {
max-width: 5rem;
}
}
.starship-infos {
display: flex;
flex-direction: column;
@@ -169,23 +166,25 @@
margin-left: 8px;
}
.section-editor {
min-height: 10rem;
}
.biodata {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
label {
min-width: 3.0rem;
min-width: 3rem;
}
.feature {
display: flex;
align-items: center;
gap: 4px;
min-width: 18rem;
max-width: 18rem;
display: flex;
align-items: center;
gap: 4px;
min-width: 18rem;
max-width: 18rem;
}
}
}
.tab.starship-equipment {

View File

@@ -136,7 +136,9 @@
.field-label {
margin-left: 8px;
}
.section-editor {
min-height: 10rem;
}
.biodata {
display: grid;

View File

@@ -2,7 +2,7 @@
"id": "fvtt-ftl-nomad",
"title": "Faster Than Light : Nomad",
"description": "Faster Than Light : Nomad is a system for Foundry VTT, based on the FTL system. It is a system for playing in a universe of space opera, where the players are the crew of a spaceship, traveling from planet to planet, from system to system, in search of adventure and fortune.",
"manifest": "https://www.uberwald.me/gitea/public/fvtt-ftl-nomad/raw/branch/main/system.json",
"manifest": "https://www.uberwald.me/gitea/uberwald/fvtt-ftl-nomad/releases/download/latest/system.json",
"download": "#{DOWNLOAD}#",
"url": "https://www.uberwald.me/gitea/public/fvtt-ftl-nomad",
"license": "LICENSE",

View File

@@ -23,12 +23,12 @@
<fieldset>
<legend>{{localize "FTLNOMAD.Label.description"}}</legend>
{{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}}
{{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true class="character-description"}}
</fieldset>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.notes"}}</legend>
{{formInput systemFields.notes enriched=enrichedNotes value=system.notes name="system.notes" toggled=true}}
{{formInput systemFields.notes enriched=enrichedNotes value=system.notes name="system.notes" toggled=true class="character-notes"}}
</fieldset>
</div>
</section>

View File

@@ -12,18 +12,28 @@
{{/if}}
{{#if (eq rollType "damage")}}
<li class="result-success">Weapon Damage</li>
<li><strong>{{weapon.name}}</strong></li>
{{else}}
{{#if weapon}}
<li><strong>Weapon : {{weapon.name}}</strong></li>
{{/if}}
{{/if}}
<li><strong>{{localize rollItem.label}} : {{fullFormula}}</strong></li>
{{#if (eq rollType "damage")}}
{{else}}
{{#if isEncumbered}}
<li class="red-warning">Encumbered : -1D</li>
{{/if}}
<li>{{localize "FTLNOMAD.Label.modifier"}} : {{skillModifier}}D {{rangeModifier}}D {{numericModifier}}D</li>
{{/if}}
{{#if (eq rollType "damage")}}
{{else}}
{{#if isSuccess}}
<li class="result-success">
{{localize "FTLNOMAD.Label.success"}}
@@ -35,6 +45,8 @@
{{localize "FTLNOMAD.Label.failure"}}
</li>
{{/if}}
{{/if}}
</ul>
</div>
</div>

View File

@@ -6,9 +6,14 @@
<legend>{{localize "FTLNOMAD.Label.skill"}}</legend>
{{/if}}
{{#if (eq rollType "damage")}}
<div class="dialog-skill">Damage : {{weapon.system.damage}}</div>
<div class="dialog-skill">Weapon : {{weapon.name}}</div>
{{else}}
<div class="dialog-skill">{{localize rollItem.label}} : 2d6+{{rollItem.value}}</div>
{{/if}}
{{#if weapon}}
{{#if (eq rollType "weapon")}}
<div class="dialog-skill">Weapon : {{weapon.name}}</div>
{{/if}}
@@ -25,28 +30,29 @@
{{selectOptions choiceModifier selected=modifier localize=true}}
</select>
{{#if weapon}}
<select name="range-modifier" class="roll-skill-range-modifier">
{{selectOptions choiceRangeModifier selected=rangeModifier}}
</select>
<ul>
<li>Two Attacks : <input type="checkbox" name="isAiming" data-field="two-attacks" class="select-combat-option"></li>
<li>Aiming : <input type="checkbox" data-field="aiming" class="select-combat-option"></li>
<li>Dim Lightning : <input type="checkbox" data-field="dim" class="select-combat-option"></li>
<li>Darkness : <input type="checkbox" data-field="darkness" class="select-combat-option"></li>
<li>Target Prone/Obscured : <input type="checkbox" data-field="prone" class="select-combat-option"></li>
<li>Target Cover : <input type="checkbox" data-field="cover" class="select-combat-option"></li>
<li>1/2 Auto Fire Recoil : <input type="checkbox" data-field="recoil-first" class="select-combat-option"></li>
<li>2+ Auto Fire Recoil : <input type="checkbox" data-field="recoil-third" class="select-combat-option"></li>
<li>Target Aware : <input type="checkbox" data-field="aware" class="select-combat-option"></li>
</ul>
{{#if (eq rollType "weapon")}}
<select name="range-modifier" class="roll-skill-range-modifier">
{{selectOptions choiceRangeModifier selected=rangeModifier}}
</select>
<ul>
<li>Two Attacks : <input type="checkbox" name="isAiming" data-field="two-attacks" class="select-combat-option">
</li>
<li>Aiming : <input type="checkbox" data-field="aiming" class="select-combat-option"></li>
<li>Dim Lightning : <input type="checkbox" data-field="dim" class="select-combat-option"></li>
<li>Darkness : <input type="checkbox" data-field="darkness" class="select-combat-option"></li>
<li>Target Prone/Obscured : <input type="checkbox" data-field="prone" class="select-combat-option"></li>
<li>Target Cover : <input type="checkbox" data-field="cover" class="select-combat-option"></li>
<li>1/2 Auto Fire Recoil : <input type="checkbox" data-field="recoil-first" class="select-combat-option"></li>
<li>2+ Auto Fire Recoil : <input type="checkbox" data-field="recoil-third" class="select-combat-option"></li>
<li>Target Aware : <input type="checkbox" data-field="aware" class="select-combat-option"></li>
</ul>
{{/if}}
</fieldSet>
<fieldSet class="dialog-formula">
<legend>{{localize "FTLNOMAD.Label.formula"}}</legend>
<label name="fullFormula" id="roll-dialog-full-formula" >{{fullFormula}}</label>
<label name="fullFormula" id="roll-dialog-full-formula">{{fullFormula}}</label>
</fieldSet>
<fieldSet>

View File

@@ -1,22 +1,26 @@
<section class="tab starship-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}">
<fieldset>
{{formField systemFields.techAge value=system.techAge localize=true}}
</fieldset>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.damages"}}</legend>
<textarea class="form-control" cols="66" rows="5" name="system.damages"
data-tooltip="{{localize "FTLNOMAD.Tooltip.damages"}}">{{system.damages}}</textarea>
</fieldset>
<fieldset>
<fieldset class="section-editor">
<legend>{{localize "FTLNOMAD.Label.description"}}</legend>
{{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}}
</fieldset>
<fieldset>
<fieldset class="section-editor">
<legend>{{localize "FTLNOMAD.Label.modifications"}}</legend>
{{formInput systemFields.modifications enriched=enrichedModifications value=system.modifications name="system.modifications" toggled=true}}
</fieldset>
<fieldset>
<fieldset class="section-editor">
<legend>{{localize "FTLNOMAD.Label.notes"}}</legend>
{{formInput systemFields.notes enriched=enrichedNotes value=system.notes name="system.notes" toggled=true}}
</fieldset>

View File

@@ -0,0 +1,108 @@
<section
class="tab vehicle-{{tab.id}} {{tab.cssClass}}"
data-tab="{{tab.id}}"
data-group="{{tab.group}}"
>
<div class="main-div">
<fieldset>
<legend>{{localize "FTLNOMAD.Label.weapons"}}{{#if isEditMode}}
<a
class="action"
data-tooltip="{{localize ' FTLNOMAD.Tooltip.addWeapon'}}"
data-tooltip-direction="UP"
><i class="fas fa-plus" data-action="createWeapon"></i></a>{{/if}}
</legend>
<div class="weapons">
{{#each weapons as |item|}}
{{!log 'weapon' this}}
<div
class="weapon item"
data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"
data-drag="true"
>
<img
class="item-img"
src="{{item.img}}"
data-tooltip="{{item.name}}"
/>
<div
class="name rollable"
data-roll-type="weapon"
data-tooltip="{{{item.system.description}}}"
>
{{item.name}}
</div>
<a
class="damage rollable"
data-item-id="{{item.id}}"
data-action="roll"
data-roll-type="damage"
data-roll-value="{{item.system.damage}}"
>{{localize "FTLNOMAD.Label.damageShort"}}
:
{{item.system.damage}}</a>
<div class="controls">
<a
data-tooltip="{{localize 'FTLNOMAD.Edit'}}"
data-action="edit"
data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"
><i class="fas fa-edit"></i></a>
<a
data-tooltip="{{localize 'FTLNOMAD.Delete'}}"
data-action="delete"
data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"
><i class="fas fa-trash"></i></a>
</div>
</div>
{{/each}}
</div>
</fieldset>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.equipment"}}{{#if isEditMode}}
<a
class="action"
data-tooltip="{{localize ' FTLNOMAD.Tooltip.addEquipment'}}"
data-tooltip-direction="UP"
><i class="fas fa-plus" data-action="createEquipment"></i></a>{{/if}}
</legend>
<div class="equipments">
{{#each equipments as |item|}}
{{!log 'armor' this}}
<div
class="equipment"
data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"
>
<img
class="item-img"
src="{{item.img}}"
data-tooltip="{{item.name}}"
/>
<div class="name" data-tooltip="{{{item.system.description}}}">
{{item.name}}
</div>
<div class="controls">
<a
data-tooltip="{{localize 'FTLNOMAD.Edit'}}"
data-action="edit"
data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"
><i class="fas fa-edit"></i></a>
<a
data-tooltip="{{localize 'FTLNOMAD.Delete'}}"
data-action="delete"
data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"
><i class="fas fa-trash"></i></a>
</div>
</div>
{{/each}}
</div>
</fieldset>
</div>
</section>

View File

@@ -1,40 +1,72 @@
<section class="starship-main starship-main-{{ifThen isPlayMode 'play' 'edit'}}">
<section
class="starship-main starship-main-{{ifThen isPlayMode 'play' 'edit'}}"
>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.starship"}}</legend>
<div class="starship-pc starship-pc-{{ifThen isPlayMode 'play' 'edit'}}">
<div class="starship-left">
<div class="starship-left-image">
<img class="starship-img" src="{{actor.img}}" data-edit="img" data-action="editImage"
data-tooltip="{{actor.name}}" />
<img
class="starship-img"
src="{{actor.img}}"
data-edit="img"
data-action="editImage"
data-tooltip="{{actor.name}}"
/>
</div>
<fieldset class="spec">
{{formField systemFields.agility value=system.agility localize=true}}
{{formField systemFields.armor value=system.armor localize=true}}
{{formField systemFields.endurance value=system.endurance localize=true}}
{{formField
systemFields.endurance
value=system.endurance
localize=true
}}
</fieldset>
</div>
<div class="starship-right">
<div class="starship-name">
{{formInput fields.name value=source.name rootId=partId disabled=isPlayMode}}
<a class="control" data-action="toggleSheet" data-tooltip="FTLNOMAD.ToggleSheet"
data-tooltip-direction="UP">
{{formInput
fields.name
value=source.name
rootId=partId
disabled=isPlayMode
}}
<a
class="control"
data-action="toggleSheet"
data-tooltip="FTLNOMAD.ToggleSheet"
data-tooltip-direction="UP"
>
<i class="fa-solid fa-user-{{ifThen isPlayMode 'lock' 'pen'}}"></i>
</a>
</div>
<fieldset class="capacity ">
<fieldset class="capacity">
<legend>{{localize "FTLNOMAD.Label.capacity"}}</legend>
<div class="flexrow">
{{formField systemFields.hullType value=system.hullType localize=true}}
{{formField systemFields.cost value=system.cost- localize=true}}
{{formField
systemFields.hullType
value=system.hullType
localize=true
}}
{{formField systemFields.cost value=system.cost localize=true}}
</div>
<div class="flexrow">
{{formField systemFields.travelMultiplier value=system.travelMultiplier localize=true}}
{{formField systemFields.monthlyCost value=system.monthlyCost localize=true}}
{{formField
systemFields.travelMultiplier
value=system.travelMultiplier
localize=true
}}
{{formField
systemFields.monthlyCost
value=system.monthlyCost
localize=true
}}
</div>
<div class="flexrow-guns rollable" data-roll-type="starship-guns">

View File

@@ -1,21 +1,46 @@
<section class="tab vehicle-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}">
<section
class="tab vehicle-{{tab.id}} {{tab.cssClass}}"
data-tab="{{tab.id}}"
data-group="{{tab.group}}"
>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.techAge"}}</legend>
{{formField systemFields.techAge value=system.techAge localize=true}}
</fieldset>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.damages"}}</legend>
<div class="text-center">
<textarea class="form-control " cols="64" rows="5" name="system.damages"
data-tooltip="{{localize "FTLNOMAD.Tooltip.damages"}}">{{system.damages}}</textarea>
<textarea
class="form-control"
cols="64"
rows="5"
name="system.damages"
data-tooltip="{{localize 'FTLNOMAD.Tooltip.damages'}}"
>{{system.damages}}</textarea>
</div>
</fieldset>
<fieldset>
<fieldset class="section-editor">
<legend>{{localize "FTLNOMAD.Label.description"}}</legend>
{{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}}
{{formInput
systemFields.description
enriched=enrichedDescription
value=system.description
name="system.description"
toggled=true
}}
</fieldset>
<fieldset>
<fieldset class="section-editor">
<legend>{{localize "FTLNOMAD.Label.notes"}}</legend>
{{formInput systemFields.notes enriched=enrichedNotes value=system.notes name="system.notes" toggled=true}}
{{formInput
systemFields.notes
enriched=enrichedNotes
value=system.notes
name="system.notes"
toggled=true
}}
</fieldset>
</section>

View File

@@ -36,6 +36,9 @@
{{formField systemFields.range value=system.range localize=true}}
{{formField systemFields.speed value=system.speed localize=true}}
</div>
<div class="flexrow">
{{formField systemFields.cost value=system.cost localize=true}}
</div>
</fieldset>
<fieldset class="cargo">

View File

@@ -13,7 +13,12 @@
{{formField systemFields.damage value=system.damage}}
{{formField systemFields.enc value=system.enc}}
{{formField systemFields.cost value=system.cost}}
{{formField cost value=system.cost}}
{{#if (eq system.weaponType "vehicle")}}
{{formField systemFields.ammoCost value=system.ammoCost}}
{{formField systemFields.magazine value=system.magazine}}
{{/if}}
</fieldset>
<fieldset>