8 Commits

Author SHA1 Message Date
810271c2a2 Crew member enhancements
All checks were successful
Release Creation / build (release) Successful in 59s
2025-11-11 12:13:26 +01:00
27b09d4546 Add crew member option with pilot rolls integrated
All checks were successful
Release Creation / build (release) Successful in 48s
2025-11-09 22:12:00 +01:00
c180365a61 Add optionnal modifier
All checks were successful
Release Creation / build (release) Successful in 1m17s
2025-10-27 20:07:22 +00:00
ace607d05c Add optionnal modifier 2025-10-27 20:06:24 +00:00
8a5d1cc1d8 Sync robot enc
All checks were successful
Release Creation / build (release) Successful in 1m8s
2025-10-18 18:03:30 +02:00
99d9cb435f Fix robot stuff
All checks were successful
Release Creation / build (release) Successful in 57s
2025-10-16 20:00:03 +02:00
f57b016b46 Cosmetic fixes
All checks were successful
Release Creation / build (release) Successful in 51s
2025-10-15 22:19:35 +02:00
09907dbbf7 Cosmetic fixes 2025-10-15 22:19:20 +02:00
42 changed files with 1342 additions and 223 deletions

View File

@@ -24,6 +24,7 @@
body { body {
--color-text-secondary: #160303; --color-text-secondary: #160303;
--color-text-emphatic: #09610e; --color-text-emphatic: #09610e;
--input-height: 1.6rem;
} }
.d100 { .d100 {
width: 18px; width: 18px;
@@ -74,6 +75,11 @@ i.fvtt-ftl-nomad {
.application.dialog.fvtt-ftl-nomad .legend { .application.dialog.fvtt-ftl-nomad .legend {
font-family: var(--font-primary); font-family: var(--font-primary);
} }
.sheet-tabs {
background-color: var(--color-light-1);
font-family: Ethnocentric;
font-size: 0.7rem;
}
.chat-message, .chat-message,
.chat-message.whisper { .chat-message.whisper {
font-family: var(--font-primary); font-family: var(--font-primary);
@@ -99,8 +105,8 @@ i.fvtt-ftl-nomad {
.fvtt-ftl-nomad .vehicle-sheet-common .form-group label { .fvtt-ftl-nomad .vehicle-sheet-common .form-group label {
font-weight: bold; font-weight: bold;
margin-right: 8px; margin-right: 8px;
min-width: 4rem; min-width: 5rem;
max-width: 4rem; max-width: 5rem;
} }
.fvtt-ftl-nomad .starship-sheet-common label { .fvtt-ftl-nomad .starship-sheet-common label {
font-family: var(--font-secondary); font-family: var(--font-secondary);
@@ -343,24 +349,26 @@ i.fvtt-ftl-nomad {
min-width: 5.2rem; min-width: 5.2rem;
} }
.fvtt-ftl-nomad .character-main .character-pc .character-right .encumbrance { .fvtt-ftl-nomad .character-main .character-pc .character-right .encumbrance {
display: grid; display: flex;
grid-template-columns: repeat(3, 1fr);
gap: 4px; gap: 4px;
} }
.fvtt-ftl-nomad .character-main .character-pc .character-right .encumbrance .form-group { .fvtt-ftl-nomad .character-main .character-pc .character-right .encumbrance .form-group {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center;
margin-bottom: 4px; margin-bottom: 4px;
} }
.fvtt-ftl-nomad .character-main .character-pc .character-right .encumbrance label { .fvtt-ftl-nomad .character-main .character-pc .character-right .encumbrance label {
min-width: 4rem; min-width: 3rem;
max-width: 4rem; max-width: 3rem;
} }
.fvtt-ftl-nomad .character-main .character-pc .character-right .encumbrance input { .fvtt-ftl-nomad .character-main .character-pc .character-right .encumbrance input {
max-width: 3rem; max-width: 3rem;
min-width: 3rem; min-width: 3rem;
} }
.fvtt-ftl-nomad .character-main .character-pc .character-right .encumbrance .character-credit input {
max-width: 9rem;
min-width: 9rem;
}
.fvtt-ftl-nomad .character-main .character-pc .character-right .character-name { .fvtt-ftl-nomad .character-main .character-pc .character-right .character-name {
display: flex; display: flex;
} }
@@ -382,7 +390,7 @@ i.fvtt-ftl-nomad {
background-color: var(--color-light-1); background-color: var(--color-light-1);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 5px; justify-content: space-evenly;
flex: 1; flex: 1;
} }
.fvtt-ftl-nomad .character-main .character-skills .character-skill { .fvtt-ftl-nomad .character-main .character-skills .character-skill {
@@ -1000,8 +1008,8 @@ i.fvtt-ftl-nomad {
.fvtt-ftl-nomad .vehicle-content .form-group label { .fvtt-ftl-nomad .vehicle-content .form-group label {
font-weight: bold; font-weight: bold;
margin-right: 8px; margin-right: 8px;
min-width: 4rem; min-width: 5rem;
max-width: 4rem; max-width: 5rem;
} }
.fvtt-ftl-nomad .sheet-tabs { .fvtt-ftl-nomad .sheet-tabs {
background-color: var(--color-light-1); background-color: var(--color-light-1);
@@ -1031,6 +1039,12 @@ i.fvtt-ftl-nomad {
width: auto; width: auto;
border: none; border: none;
} }
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-left .spec label {
max-width: 4rem;
}
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-left .spec input {
max-width: 4rem;
}
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right { .fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -1046,8 +1060,7 @@ i.fvtt-ftl-nomad {
} }
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .cargo label, .fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .cargo label,
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .capacity label { .fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .capacity label {
min-width: 4rem; max-width: 7rem;
max-width: 4rem;
} }
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .cargo input, .fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .cargo input,
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .capacity input { .fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .capacity input {
@@ -1056,10 +1069,31 @@ i.fvtt-ftl-nomad {
} }
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .cargo .cargo-content, .fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .cargo .cargo-content,
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .capacity .cargo-content { .fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .capacity .cargo-content {
display: flex;
flex-direction: column;
gap: 4px;
}
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .cargo .cargo-content .cargo-line,
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .capacity .cargo-content .cargo-line {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
} }
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .cargo .npc-crew-field,
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .capacity .npc-crew-field {
display: flex;
align-items: center;
gap: 4px;
}
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .cargo .npc-crew-field .npc-crew-roll,
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .capacity .npc-crew-field .npc-crew-roll {
cursor: pointer;
color: var(--color-text-dark-primary);
}
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .cargo .npc-crew-field .npc-crew-roll:hover,
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .capacity .npc-crew-field .npc-crew-roll:hover {
color: var(--color-text-hyperlink);
}
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .vehicle-infos { .fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .vehicle-infos {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -1123,6 +1157,12 @@ i.fvtt-ftl-nomad {
.fvtt-ftl-nomad .vehicle-description .section-editor { .fvtt-ftl-nomad .vehicle-description .section-editor {
min-height: 10rem; min-height: 10rem;
} }
.fvtt-ftl-nomad .vehicle-description .section-editor .editor {
min-height: 10rem;
}
.fvtt-ftl-nomad .vehicle-description .section-editor .editor-content {
min-height: 10rem;
}
.fvtt-ftl-nomad .vehicle-description .biodata { .fvtt-ftl-nomad .vehicle-description .biodata {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
@@ -1147,6 +1187,65 @@ i.fvtt-ftl-nomad {
font-size: calc(var(--font-size-standard) * 1.4); font-size: calc(var(--font-size-standard) * 1.4);
padding-left: 5px; padding-left: 5px;
} }
.fvtt-ftl-nomad .tab.vehicle-equipment .main-div .crew .crew-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
padding: 4px;
}
.fvtt-ftl-nomad .tab.vehicle-equipment .main-div .crew .crew-member {
display: flex;
align-items: center;
gap: 4px;
padding: 4px;
border: 1px solid var(--color-border-dark);
border-radius: 4px;
background: var(--color-light-2);
}
.fvtt-ftl-nomad .tab.vehicle-equipment .main-div .crew .crew-member .crew-img {
width: 32px;
height: 32px;
border-radius: 50%;
border: 1px solid var(--color-border-dark);
cursor: pointer;
}
.fvtt-ftl-nomad .tab.vehicle-equipment .main-div .crew .crew-member .crew-img:hover {
opacity: 0.8;
box-shadow: 0 0 4px var(--color-shadow-primary);
}
.fvtt-ftl-nomad .tab.vehicle-equipment .main-div .crew .crew-member .crew-name {
flex: 1;
font-size: var(--font-size-small);
cursor: pointer;
}
.fvtt-ftl-nomad .tab.vehicle-equipment .main-div .crew .crew-member .crew-name:hover {
color: var(--color-text-dark-highlight);
text-shadow: 0 0 4px var(--color-shadow-primary);
}
.fvtt-ftl-nomad .tab.vehicle-equipment .main-div .crew .crew-member .controls {
display: flex;
gap: 4px;
min-width: 3rem;
}
.fvtt-ftl-nomad .tab.vehicle-equipment .main-div .crew .crew-member .controls a {
color: var(--color-text-dark-primary);
}
.fvtt-ftl-nomad .tab.vehicle-equipment .main-div .crew .crew-member .controls a:hover {
color: var(--color-text-dark-highlight);
}
.fvtt-ftl-nomad .tab.vehicle-equipment .main-div .crew .crew-member .controls .pilot-button {
color: var(--color-text-light-primary);
}
.fvtt-ftl-nomad .tab.vehicle-equipment .main-div .crew .crew-member .controls .pilot-button:hover {
color: var(--color-text-light-highlight);
}
.fvtt-ftl-nomad .tab.vehicle-equipment .main-div .crew .crew-empty {
grid-column: 1 / -1;
text-align: center;
padding: 8px;
font-style: italic;
color: var(--color-text-dark-secondary);
}
.fvtt-ftl-nomad .tab.vehicle-equipment .main-div .weapons { .fvtt-ftl-nomad .tab.vehicle-equipment .main-div .weapons {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
@@ -1301,6 +1400,7 @@ i.fvtt-ftl-nomad {
} }
.fvtt-ftl-nomad .robot-main .robot-pc .robot-left { .fvtt-ftl-nomad .robot-main .robot-pc .robot-left {
min-width: 180px; min-width: 180px;
max-width: 180px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
@@ -1315,6 +1415,14 @@ i.fvtt-ftl-nomad {
width: auto; width: auto;
border: none; border: none;
} }
.fvtt-ftl-nomad .robot-main .robot-pc .robot-left .robot-cost label {
min-width: 3rem;
max-width: 3rem;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-left .robot-cost input {
min-width: 6rem;
max-width: 6rem;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right { .fvtt-ftl-nomad .robot-main .robot-pc .robot-right {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -1326,12 +1434,26 @@ i.fvtt-ftl-nomad {
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .robot-name input { .fvtt-ftl-nomad .robot-main .robot-pc .robot-right .robot-name input {
font-family: var(--font-title); font-family: var(--font-title);
font-size: calc(var(--font-size-standard) * 1.4); font-size: calc(var(--font-size-standard) * 1.4);
width: 400px; width: 380px;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .robot-brain {
min-width: 25rem;
max-width: 25rem;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .robot-brain textarea {
min-width: 23rem;
max-width: 23rem;
background-color: rgba(0, 0, 0, 0.2);
color: var(--color-dark-3);
} }
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .main-stats { .fvtt-ftl-nomad .robot-main .robot-pc .robot-right .main-stats {
min-width: 25rem; min-width: 25rem;
max-width: 25rem; max-width: 25rem;
} }
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .main-stats .encumbered {
color: red;
font-weight: bold;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .cargo label, .fvtt-ftl-nomad .robot-main .robot-pc .robot-right .cargo label,
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .capacity label { .fvtt-ftl-nomad .robot-main .robot-pc .robot-right .capacity label {
min-width: 4rem; min-width: 4rem;
@@ -1390,7 +1512,7 @@ i.fvtt-ftl-nomad {
background-color: var(--color-light-1); background-color: var(--color-light-1);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 5px; justify-content: space-evenly;
flex: 1; flex: 1;
} }
.fvtt-ftl-nomad .robot-main .robot-skills .robot-skill { .fvtt-ftl-nomad .robot-main .robot-skills .robot-skill {
@@ -1462,6 +1584,12 @@ i.fvtt-ftl-nomad {
.fvtt-ftl-nomad .robot-description .section-editor { .fvtt-ftl-nomad .robot-description .section-editor {
min-height: 10rem; min-height: 10rem;
} }
.fvtt-ftl-nomad .robot-description .section-editor .editor {
min-height: 10rem;
}
.fvtt-ftl-nomad .robot-description .section-editor .editor-content {
min-height: 10rem;
}
.fvtt-ftl-nomad .robot-description .biodata { .fvtt-ftl-nomad .robot-description .biodata {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
@@ -1626,9 +1754,6 @@ i.fvtt-ftl-nomad {
min-width: 5rem; min-width: 5rem;
max-width: 5rem; max-width: 5rem;
} }
.fvtt-ftl-nomad .sheet-tabs {
background-color: var(--color-light-1);
}
.fvtt-ftl-nomad .starship-main { .fvtt-ftl-nomad .starship-main {
background-color: var(--color-light-1); background-color: var(--color-light-1);
display: flex; display: flex;
@@ -1682,6 +1807,10 @@ i.fvtt-ftl-nomad {
text-shadow: 0 0 8px var(--color-shadow-primary); text-shadow: 0 0 8px var(--color-shadow-primary);
cursor: pointer; cursor: pointer;
} }
.fvtt-ftl-nomad .starship-main .starship-pc .starship-right .capacity .hull-field select {
min-width: 10rem;
max-width: 10rem;
}
.fvtt-ftl-nomad .starship-main .starship-pc .starship-right .capacity label { .fvtt-ftl-nomad .starship-main .starship-pc .starship-right .capacity label {
margin-left: 0.2rem; margin-left: 0.2rem;
max-width: 7rem; max-width: 7rem;
@@ -1715,6 +1844,18 @@ i.fvtt-ftl-nomad {
.fvtt-ftl-nomad .starship-main .starship-pc .starship-right .cargo select { .fvtt-ftl-nomad .starship-main .starship-pc .starship-right .cargo select {
max-width: 5rem; max-width: 5rem;
} }
.fvtt-ftl-nomad .starship-main .starship-pc .starship-right .cargo .npc-crew-field {
display: flex;
align-items: center;
gap: 4px;
}
.fvtt-ftl-nomad .starship-main .starship-pc .starship-right .cargo .npc-crew-field .npc-crew-roll {
cursor: pointer;
color: var(--color-text-dark-primary);
}
.fvtt-ftl-nomad .starship-main .starship-pc .starship-right .cargo .npc-crew-field .npc-crew-roll:hover {
color: var(--color-text-hyperlink);
}
.fvtt-ftl-nomad .starship-main .starship-pc .starship-right .starship-infos { .fvtt-ftl-nomad .starship-main .starship-pc .starship-right .starship-infos {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -1774,6 +1915,12 @@ i.fvtt-ftl-nomad {
.fvtt-ftl-nomad .starship-description .section-editor { .fvtt-ftl-nomad .starship-description .section-editor {
min-height: 10rem; min-height: 10rem;
} }
.fvtt-ftl-nomad .starship-description .section-editor .editor {
min-height: 10rem;
}
.fvtt-ftl-nomad .starship-description .section-editor .editor-content {
min-height: 10rem;
}
.fvtt-ftl-nomad .starship-description .biodata { .fvtt-ftl-nomad .starship-description .biodata {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
@@ -1798,6 +1945,65 @@ i.fvtt-ftl-nomad {
font-size: calc(var(--font-size-standard) * 1.4); font-size: calc(var(--font-size-standard) * 1.4);
padding-left: 5px; padding-left: 5px;
} }
.fvtt-ftl-nomad .tab.starship-equipment .crew .crew-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
padding: 4px;
}
.fvtt-ftl-nomad .tab.starship-equipment .crew .crew-member {
display: flex;
align-items: center;
gap: 4px;
padding: 4px;
border: 1px solid var(--color-border-dark);
border-radius: 4px;
background: var(--color-light-2);
}
.fvtt-ftl-nomad .tab.starship-equipment .crew .crew-member .crew-img {
width: 32px;
height: 32px;
border-radius: 50%;
border: 1px solid var(--color-border-dark);
cursor: pointer;
}
.fvtt-ftl-nomad .tab.starship-equipment .crew .crew-member .crew-img:hover {
opacity: 0.8;
box-shadow: 0 0 4px var(--color-shadow-primary);
}
.fvtt-ftl-nomad .tab.starship-equipment .crew .crew-member .crew-name {
flex: 1;
font-size: var(--font-size-small);
cursor: pointer;
}
.fvtt-ftl-nomad .tab.starship-equipment .crew .crew-member .crew-name:hover {
color: var(--color-text-dark-highlight);
text-shadow: 0 0 4px var(--color-shadow-primary);
}
.fvtt-ftl-nomad .tab.starship-equipment .crew .crew-member .controls {
display: flex;
gap: 4px;
min-width: 3rem;
}
.fvtt-ftl-nomad .tab.starship-equipment .crew .crew-member .controls a {
color: var(--color-text-dark-primary);
}
.fvtt-ftl-nomad .tab.starship-equipment .crew .crew-member .controls a:hover {
color: var(--color-text-dark-highlight);
}
.fvtt-ftl-nomad .tab.starship-equipment .crew .crew-member .controls .pilot-button {
color: var(--color-text-light-primary);
}
.fvtt-ftl-nomad .tab.starship-equipment .crew .crew-member .controls .pilot-button:hover {
color: var(--color-text-light-highlight);
}
.fvtt-ftl-nomad .tab.starship-equipment .crew .crew-empty {
grid-column: 1 / -1;
text-align: center;
padding: 8px;
font-style: italic;
color: var(--color-text-dark-secondary);
}
.fvtt-ftl-nomad .tab.starship-equipment .weapons { .fvtt-ftl-nomad .tab.starship-equipment .weapons {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
@@ -2044,7 +2250,7 @@ i.fvtt-ftl-nomad {
background-color: var(--color-light-1); background-color: var(--color-light-1);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 5px; justify-content: space-evenly;
flex: 1; flex: 1;
} }
.fvtt-ftl-nomad .creature-main .creature-skills .creature-skill { .fvtt-ftl-nomad .creature-main .creature-skills .creature-skill {
@@ -2110,6 +2316,15 @@ i.fvtt-ftl-nomad {
.fvtt-ftl-nomad .creature-biography .rank input { .fvtt-ftl-nomad .creature-biography .rank input {
max-width: 4rem; max-width: 4rem;
} }
.fvtt-ftl-nomad .creature-biography .section-editor {
min-height: 10rem;
}
.fvtt-ftl-nomad .creature-biography .section-editor .editor {
min-height: 10rem;
}
.fvtt-ftl-nomad .creature-biography .section-editor .editor-content {
min-height: 10rem;
}
.fvtt-ftl-nomad .creature-biography .biodata { .fvtt-ftl-nomad .creature-biography .biodata {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);

View File

@@ -304,6 +304,15 @@
"Gargantuan": "Gargantuan" "Gargantuan": "Gargantuan"
}, },
"FIELDS": { "FIELDS": {
"enc": {
"label": "Enc",
"value": {
"label": "Enc Curr."
},
"max": {
"label": "Enc Max"
}
},
"brain": { "brain": {
"label": "Brain" "label": "Brain"
}, },
@@ -438,6 +447,7 @@
"capacity" : "Capacity", "capacity" : "Capacity",
"Agility" : "Agility", "Agility" : "Agility",
"Armor": "Armor", "Armor": "Armor",
"ArmorCritical": "Armor Critical",
"cargo": "Cargo", "cargo": "Cargo",
"vehicle": "Vehicle", "vehicle": "Vehicle",
"starship": "Starship", "starship": "Starship",
@@ -466,6 +476,7 @@
"Unarmed": "Unarmed", "Unarmed": "Unarmed",
"Vehicle": "Vehicle", "Vehicle": "Vehicle",
"armor": "Armor", "armor": "Armor",
"armorCritical": "Armor (Crit.)",
"armors": "Armors", "armors": "Armors",
"biodata": "Biodata", "biodata": "Biodata",
"biography": "Biography", "biography": "Biography",
@@ -486,6 +497,7 @@
"max": "Max", "max": "Max",
"maximum": "Maximum", "maximum": "Maximum",
"modifier": "Modifier", "modifier": "Modifier",
"numericModifier": "Additionnal Modifier",
"multiplier": "Multiplier", "multiplier": "Multiplier",
"newArmor": "New Armor", "newArmor": "New Armor",
"newWeapon": "New Weapon", "newWeapon": "New Weapon",
@@ -514,7 +526,12 @@
"titleWeapon": "Weapon Roll", "titleWeapon": "Weapon Roll",
"total": "Total", "total": "Total",
"totalScore": "Total Score", "totalScore": "Total Score",
"weapons": "Weapons" "weapons": "Weapons",
"crew": "Crew",
"noCrew": "No crew members assigned",
"vehicleBonus": "Vehicle/Starship Agility Bonus",
"selectSkill": "Select Skill",
"npcCrewSkill": "NPC Crew"
}, },
"Language": { "Language": {
"FIELDS": { "FIELDS": {
@@ -600,7 +617,10 @@
"label": "Hull Type" "label": "Hull Type"
}, },
"armor": { "armor": {
"label": "Armor" "label": "Armor (Reg.)"
},
"armorCritical": {
"label": "Armor (Crit.)"
}, },
"guns" : { "guns" : {
"label": "Guns" "label": "Guns"
@@ -623,6 +643,12 @@
"crew": { "crew": {
"label": "Crew" "label": "Crew"
}, },
"crewCapacity": {
"label": "Crew Capacity"
},
"npcCrew": {
"label": "NPC Skill"
},
"description": { "description": {
"label": "Description" "label": "Description"
}, },
@@ -697,11 +723,20 @@
"label": "Speed" "label": "Speed"
}, },
"armor": { "armor": {
"label": "Armor" "label": "Armor (Reg.)"
},
"armorCritical": {
"label": "Armor (Crit.)"
}, },
"crew": { "crew": {
"label": "Crew" "label": "Crew"
}, },
"crewCapacity": {
"label": "Crew Capacity"
},
"npcCrew": {
"label": "NPC Skill"
},
"description": { "description": {
"label": "Description" "label": "Description"
}, },
@@ -713,7 +748,21 @@
} }
} }
}, },
"Warning": {}, "Warning": {
"alreadyInCrew": "This actor is already a crew member",
"notACharacter": "Only characters can pilot vehicles",
"noVehiclesSkill": "This character does not have the vehicles skill",
"noSkills": "This character does not have any skills",
"noNpcCrew": "NPC Crew level is below 0",
"onlyCharactersAllowed": "Only characters can be added as crew members",
"noLinkedPrototype": "This character must be linked to his token to be added as crew member"
},
"RemoveCrew": "Remove from crew",
"RemoveCrewTitle": "Remove crew member?",
"RemoveCrewContent": "Are you sure you want to remove {name} from the crew?",
"PilotVehicle": "Pilot vehicle (with vehicle agility bonus)",
"PilotStarship": "Pilot starship (with starship agility bonus)",
"RollNpcCrew": "Roll for NPC Crew",
"Weapon": { "Weapon": {
"FIELDS": { "FIELDS": {
"cost": { "cost": {

View File

@@ -14,9 +14,148 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
actions: { actions: {
createEquipment: FTLNomadStarshipSheet.#onCreateEquipment, createEquipment: FTLNomadStarshipSheet.#onCreateEquipment,
createWeapon: FTLNomadStarshipSheet.#onCreateWeapon, createWeapon: FTLNomadStarshipSheet.#onCreateWeapon,
removeCrew: FTLNomadStarshipSheet.#onRemoveCrew,
viewCrew: FTLNomadStarshipSheet.#onViewCrew,
pilotCrew: FTLNomadStarshipSheet.#onPilotCrew,
rollNpcCrew: FTLNomadStarshipSheet.#onRollNpcCrew,
}, },
} }
/**
* Remove a crew member from the starship
* @param {Event} event The initiating click event
* @param {HTMLElement} target The current target of the event listener
*/
static async #onRemoveCrew(event, target) {
const crewUuid = target.dataset.crewUuid
const actor = await fromUuid(crewUuid)
// Show confirmation dialog
const confirmed = await foundry.applications.api.DialogV2.confirm({
window: { title: game.i18n.localize("FTLNOMAD.RemoveCrewTitle") },
content: game.i18n.format("FTLNOMAD.RemoveCrewContent", { name: actor?.name || "Unknown" }),
rejectClose: false,
modal: true
})
if (!confirmed) return
const currentCrew = this.document.system.crewList || []
const updatedCrew = currentCrew.filter(uuid => uuid !== crewUuid)
await this.document.update({ "system.crewList": updatedCrew })
}
/**
* Open the actor sheet of a crew member
* @param {Event} event The initiating click event
* @param {HTMLElement} target The current target of the event listener
*/
static async #onViewCrew(event, target) {
const actorUuid = target.closest('.crew-member').dataset.actorUuid
const actor = await fromUuid(actorUuid)
if (actor) {
actor.sheet.render(true)
}
}
/**
* Roll a piloting check for a crew member with starship agility bonus
* @param {Event} event The initiating click event
* @param {HTMLElement} target The current target of the event listener
*/
static async #onPilotCrew(event, target) {
const actorUuid = target.closest('.crew-member').dataset.actorUuid
const actor = await fromUuid(actorUuid)
console.log("Pilot crew - Actor:", actor, "Type:", actor?.type)
if (!actor) {
ui.notifications.warn("Actor not found")
return
}
if (actor.type !== "character") {
ui.notifications.warn(`This actor is of type "${actor.type}", not "character"`)
return
}
// Get starship agility bonus
const starshipAgility = this.document.system.agility || 0
// 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 all skills available and starship agility as a vehicle bonus
let roll = await FTLNomadRoll.prompt({
rollType: "skill",
rollItem: defaultSkill,
availableSkills: actorSkills,
selectedSkillId: "vehicles",
actorId: actor.id,
actorName: actor.name,
actorImage: actor.img,
talents: actor.items.filter(i => i.type === "talent" && i.system.isAdvantage),
isEncumbered: actor.system.isEncumbered(),
hasTarget: false,
vehicleBonus: starshipAgility
})
if (!roll) return null
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 */ /** @override */
static PARTS = { static PARTS = {
main: { main: {
@@ -63,9 +202,35 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes, { async: true }) context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes, { async: true })
context.enrichedModifications = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.modifications, { async: true }) context.enrichedModifications = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.modifications, { async: true })
// Prepare crew members data
context.crewMembers = await this.#prepareCrewMembers()
return context return context
} }
/**
* Prepare crew members data from stored UUIDs
* @returns {Promise<Array>}
*/
async #prepareCrewMembers() {
const crewUuids = this.document.system.crewList || []
const crewMembers = []
for (const uuid of crewUuids) {
const actor = await fromUuid(uuid)
if (actor) {
crewMembers.push({
uuid: uuid,
id: actor.id,
name: actor.name,
img: actor.img
})
}
}
return crewMembers
}
_generateTooltip(type, target) { _generateTooltip(type, target) {
} }
@@ -128,7 +293,41 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
case "Item": case "Item":
const item = await fromUuid(data.uuid) const item = await fromUuid(data.uuid)
return super._onDropItem(item) return super._onDropItem(item)
case "Actor":
const actor = await fromUuid(data.uuid)
return this.#onDropActor(actor)
} }
} }
/**
* Handle dropping an actor onto the starship sheet to add them to the crew
* @param {Actor} actor The actor being dropped
*/
async #onDropActor(actor) {
if (!actor) return
// Check if actor is of type "character"
if (actor.type !== "character") {
ui.notifications.info(game.i18n.localize("FTLNOMAD.Warning.onlyCharactersAllowed"))
return
}
// Check if the actor has a linked prototype
if (!actor.prototypeToken?.actorLink) {
ui.notifications.info(game.i18n.localize("FTLNOMAD.Warning.noLinkedPrototype"))
return
}
const currentCrew = this.document.system.crewList || []
// Check if actor is already in crew
if (currentCrew.includes(actor.uuid)) {
ui.notifications.warn(game.i18n.localize("FTLNOMAD.Warning.alreadyInCrew"))
return
}
// Add actor UUID to crew array
const updatedCrew = [...currentCrew, actor.uuid]
await this.document.update({ "system.crewList": updatedCrew })
}
} }

View File

@@ -5,8 +5,8 @@ export default class FTLNomadVehicleSheet extends FTLNomadActorSheet {
static DEFAULT_OPTIONS = { static DEFAULT_OPTIONS = {
classes: ["vehicle"], classes: ["vehicle"],
position: { position: {
width: 680, width: 720,
height: 540, height: 640,
}, },
window: { window: {
contentClasses: ["vehicle-content"], contentClasses: ["vehicle-content"],
@@ -14,9 +14,148 @@ export default class FTLNomadVehicleSheet extends FTLNomadActorSheet {
actions: { actions: {
createEquipment: FTLNomadVehicleSheet.#onCreateEquipment, createEquipment: FTLNomadVehicleSheet.#onCreateEquipment,
createWeapon: FTLNomadVehicleSheet.#onCreateWeapon, createWeapon: FTLNomadVehicleSheet.#onCreateWeapon,
removeCrew: FTLNomadVehicleSheet.#onRemoveCrew,
viewCrew: FTLNomadVehicleSheet.#onViewCrew,
pilotCrew: FTLNomadVehicleSheet.#onPilotCrew,
rollNpcCrew: FTLNomadVehicleSheet.#onRollNpcCrew,
}, },
} }
/**
* Remove a crew member from the vehicle
* @param {Event} event The initiating click event
* @param {HTMLElement} target The current target of the event listener
*/
static async #onRemoveCrew(event, target) {
const crewUuid = target.dataset.crewUuid
const actor = await fromUuid(crewUuid)
// Show confirmation dialog
const confirmed = await foundry.applications.api.DialogV2.confirm({
window: { title: game.i18n.localize("FTLNOMAD.RemoveCrewTitle") },
content: game.i18n.format("FTLNOMAD.RemoveCrewContent", { name: actor?.name || "Unknown" }),
rejectClose: false,
modal: true
})
if (!confirmed) return
const currentCrew = this.document.system.crewList || []
const updatedCrew = currentCrew.filter(uuid => uuid !== crewUuid)
await this.document.update({ "system.crewList": updatedCrew })
}
/**
* Open the actor sheet of a crew member
* @param {Event} event The initiating click event
* @param {HTMLElement} target The current target of the event listener
*/
static async #onViewCrew(event, target) {
const actorUuid = target.closest('.crew-member').dataset.actorUuid
const actor = await fromUuid(actorUuid)
if (actor) {
actor.sheet.render(true)
}
}
/**
* Roll a piloting check for a crew member with vehicle agility bonus
* @param {Event} event The initiating click event
* @param {HTMLElement} target The current target of the event listener
*/
static async #onPilotCrew(event, target) {
const actorUuid = target.closest('.crew-member').dataset.actorUuid
const actor = await fromUuid(actorUuid)
console.log("Pilot crew - Actor:", actor, "Type:", actor?.type)
if (!actor) {
ui.notifications.warn("Actor not found")
return
}
if (actor.type !== "character") {
ui.notifications.warn(`This actor is of type "${actor.type}", not "character"`)
return
}
// Get vehicle agility bonus
const vehicleAgility = this.document.system.agility || 0
// 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 all skills available and vehicle agility as a vehicle bonus
let roll = await FTLNomadRoll.prompt({
rollType: "skill",
rollItem: defaultSkill,
availableSkills: actorSkills,
selectedSkillId: "vehicles",
actorId: actor.id,
actorName: actor.name,
actorImage: actor.img,
talents: actor.items.filter(i => i.type === "talent" && i.system.isAdvantage),
isEncumbered: actor.system.isEncumbered(),
hasTarget: false,
vehicleBonus: vehicleAgility
})
if (!roll) return null
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 */ /** @override */
static PARTS = { static PARTS = {
main: { main: {
@@ -62,9 +201,35 @@ export default class FTLNomadVehicleSheet extends FTLNomadActorSheet {
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }) context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes, { async: true }) context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes, { async: true })
// Prepare crew members data
context.crewMembers = await this.#prepareCrewMembers()
return context return context
} }
/**
* Prepare crew members data from stored UUIDs
* @returns {Promise<Array>}
*/
async #prepareCrewMembers() {
const crewUuids = this.document.system.crewList || []
const crewMembers = []
for (const uuid of crewUuids) {
const actor = await fromUuid(uuid)
if (actor) {
crewMembers.push({
uuid: uuid,
id: actor.id,
name: actor.name,
img: actor.img
})
}
}
return crewMembers
}
_generateTooltip(type, target) { _generateTooltip(type, target) {
} }
@@ -128,7 +293,36 @@ export default class FTLNomadVehicleSheet extends FTLNomadActorSheet {
case "Item": case "Item":
const item = await fromUuid(data.uuid) const item = await fromUuid(data.uuid)
return super._onDropItem(item) return super._onDropItem(item)
case "Actor":
const actor = await fromUuid(data.uuid)
return this.#onDropActor(actor)
} }
} }
/**
* Handle dropping an actor onto the vehicle sheet to add them to the crew
* @param {Actor} actor The actor being dropped
*/
async #onDropActor(actor) {
if (!actor) return
// Check if actor is of type "character"
if (actor.type !== "character") {
ui.notifications.info(game.i18n.localize("FTLNOMAD.Warning.onlyCharactersAllowed"))
return
}
const currentCrew = this.document.system.crewList || []
// Check if actor is already in crew
if (currentCrew.includes(actor.uuid)) {
ui.notifications.warn(game.i18n.localize("FTLNOMAD.Warning.alreadyInCrew"))
return
}
// Add actor UUID to crew array
const updatedCrew = [...currentCrew, actor.uuid]
await this.document.update({ "system.crewList": updatedCrew })
}
} }

View File

@@ -144,6 +144,20 @@ export const MODIFIER_CHOICES = {
"impossible6": { id: "impossible6", label: "FTLNOMAD.Label.Impossible6", value: "-6" } "impossible6": { id: "impossible6", label: "FTLNOMAD.Label.Impossible6", value: "-6" }
} }
export const NUMERIC_MODIFIER_CHOICES = {
"-5": { label: "-5", value: -5 },
"-4": { label: "-4", value: -4 },
"-3": { label: "-3", value: -3 },
"-2": { label: "-2", value: -2 },
"-1": { label: "-1", value: -1 },
"0": { label: "0", value: 0 },
"+1": { label: "+1", value: 1 },
"+2": { label: "+2", value: 2 },
"+3": { label: "+3", value: 3 },
"+4": { label: "+4", value: 4 },
"+5": { label: "+5", value: 5 }
}
export const STARSHIP_HULL = { export const STARSHIP_HULL = {
"pod": { id: "pod", label: "FTLNOMAD.Starship.Hull.Pod" }, "pod": { id: "pod", label: "FTLNOMAD.Starship.Hull.Pod" },
"micro": { id: "micro", label: "FTLNOMAD.Starship.Hull.Micro" }, "micro": { id: "micro", label: "FTLNOMAD.Starship.Hull.Micro" },
@@ -163,6 +177,7 @@ export const STARSHIP_HULL = {
export const SYSTEM = { export const SYSTEM = {
id: SYSTEM_ID, id: SYSTEM_ID,
MODIFIER_CHOICES, MODIFIER_CHOICES,
NUMERIC_MODIFIER_CHOICES,
ATTACK_MODIFIERS, ATTACK_MODIFIERS,
TECH_AGES, TECH_AGES,
WEAPON_TYPES, WEAPON_TYPES,

View File

@@ -66,10 +66,13 @@ export default class FTLNomadRoll extends Roll {
fullFormula = `${options.formula} + ${options.damageModifier}D6 ` fullFormula = `${options.formula} + ${options.damageModifier}D6 `
} else { } else {
let mod = options.rollItem?.value || 0 let mod = options.rollItem?.value || 0
fullFormula = `${options.formula} + ${options.skillModifier}D + ${mod} + ${options.rangeModifier}D + ${options.numericModifier}D` fullFormula = `${options.formula} + ${options.skillModifier}D + ${mod} + ${options.rangeModifier}D + ${options.numericModifier}D + ${options.numericModifierSelect}`
if (options.vehicleBonus && options.useVehicleBonus) {
fullFormula += ` + ${options.vehicleBonus}`
}
} }
// Replace all the "+ -" with "-" // Replace all the "+ -" with "-"
fullFormula = fullFormula.replace(/\+\s*\-/g, "- ") fullFormula = fullFormula.replace(/\+\s*-/g, "- ")
$('#roll-dialog-full-formula').text(fullFormula) $('#roll-dialog-full-formula').text(fullFormula)
options.fullFormula = fullFormula options.fullFormula = fullFormula
} }
@@ -116,6 +119,7 @@ export default class FTLNomadRoll extends Roll {
}) })
const choiceModifier = SYSTEM.MODIFIER_CHOICES const choiceModifier = SYSTEM.MODIFIER_CHOICES
const choiceNumericModifier = SYSTEM.NUMERIC_MODIFIER_CHOICES
let choiceRangeModifier = {} let choiceRangeModifier = {}
let rangeModifier = 0 let rangeModifier = 0
if (options.weapon) { if (options.weapon) {
@@ -129,17 +133,35 @@ export default class FTLNomadRoll extends Roll {
let damageModifier = "0" let damageModifier = "0"
let modifier = "0" let modifier = "0"
let numericModifierSelect = 0
options.skillModifier = 0 options.skillModifier = 0
options.numericModifier = 0 options.numericModifier = 0
options.numericModifierSelect = 0
options.rangeModifier = rangeModifier options.rangeModifier = rangeModifier
options.damageModifier = damageModifier options.damageModifier = damageModifier
options.vehicleBonus = options.vehicleBonus || 0
options.useVehicleBonus = true // Par défaut, le bonus est activé
let fullFormula = `${formula} + ${options.rollItem.value}` let fullFormula = `${formula} + ${options.rollItem.value}`
if (options.isEncumbered) { if (options.isEncumbered) {
fullFormula += ` - 1D` fullFormula += ` - 1D`
} }
if (options.vehicleBonus && options.useVehicleBonus) {
fullFormula += ` + ${options.vehicleBonus}`
}
options.fullFormula = fullFormula options.fullFormula = fullFormula
options.formula = formula 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 = { let dialogContext = {
actorId: options.actorId, actorId: options.actorId,
actorName: options.actorName, actorName: options.actorName,
@@ -152,6 +174,7 @@ export default class FTLNomadRoll extends Roll {
rollModes, rollModes,
fieldRollMode, fieldRollMode,
choiceModifier, choiceModifier,
choiceNumericModifier,
choiceRangeModifier, choiceRangeModifier,
choiceDamageModifier, choiceDamageModifier,
rangeModifier, rangeModifier,
@@ -159,6 +182,9 @@ export default class FTLNomadRoll extends Roll {
formula, formula,
hasTarget: options.hasTarget, hasTarget: options.hasTarget,
modifier, modifier,
numericModifierSelect,
vehicleBonus: options.vehicleBonus,
availableSkills: availableSkills,
} }
const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-ftl-nomad/templates/roll-dialog.hbs", dialogContext) const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-ftl-nomad/templates/roll-dialog.hbs", dialogContext)
@@ -185,10 +211,22 @@ export default class FTLNomadRoll extends Roll {
rejectClose: false, // Click on Close button will not launch an error rejectClose: false, // Click on Close button will not launch an error
render: (event, dialog) => { render: (event, dialog) => {
FTLNomadRoll.updateFullFormula(options) 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 => { $(".roll-skill-modifier").change(event => {
options.skillModifier = Number(event.target.value) options.skillModifier = Number(event.target.value)
FTLNomadRoll.updateFullFormula(options) FTLNomadRoll.updateFullFormula(options)
}) })
$(".roll-numeric-modifier").change(event => {
options.numericModifierSelect = Number(event.target.value)
FTLNomadRoll.updateFullFormula(options)
})
$(".roll-damage-modifier").change(event => { $(".roll-damage-modifier").change(event => {
options.damageModifier = Number(event.target.value) options.damageModifier = Number(event.target.value)
FTLNomadRoll.updateFullFormula(options) FTLNomadRoll.updateFullFormula(options)
@@ -207,6 +245,10 @@ export default class FTLNomadRoll extends Roll {
} }
FTLNomadRoll.updateFullFormula(options) FTLNomadRoll.updateFullFormula(options)
}) })
$(".use-vehicle-bonus").change(event => {
options.useVehicleBonus = event.target.checked
FTLNomadRoll.updateFullFormula(options)
})
} }
}) })
@@ -220,11 +262,22 @@ export default class FTLNomadRoll extends Roll {
if (Hooks.call("fvtt-ftl-nomad.preRoll", options, rollData) === false) return 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.numericModifier = Number(rollData.numericModifier) || 0
options.skillModifier = Number(rollData.skillModifier) || 0 options.skillModifier = Number(rollData.skillModifier) || 0
options.rangeModifier = Number(rollData.rangeModifier) || 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 options.finalModifier = options.numericModifier + options.skillModifier + options.rangeModifier
let mod = options.rollItem?.value || 0 let mod = options.rollItem?.value || 0
mod += options.numericModifierSelect
if (options.useVehicleBonus) {
mod += options.vehicleBonus || 0
}
// Build the dice formula // Build the dice formula
let diceFormula = "2d6" let diceFormula = "2d6"

View File

@@ -49,7 +49,19 @@ export default class FTLNomadRobot extends foundry.abstract.TypeDataModel {
prepareDerivedData() { prepareDerivedData() {
super.prepareDerivedData(); super.prepareDerivedData();
let encMax = this.durability + (2 * this.skills.physical.value)
if (encMax !== this.enc.max) {
this.enc.max = encMax
}
let enc = 0
for (let i of this.parent.items) {
if (i.system?.enc) {
enc += i.system.enc
}
}
if (enc !== this.enc.value) {
this.enc.value = enc
}
} }
isEncumbered() { isEncumbered() {

View File

@@ -11,7 +11,10 @@ export default class FTLNomadStarship extends foundry.abstract.TypeDataModel {
schema.hullType = new fields.StringField({ required: true, initial: "small", choices: SYSTEM.STARSHIP_HULL }) schema.hullType = new fields.StringField({ required: true, initial: "small", choices: SYSTEM.STARSHIP_HULL })
schema.endurance = new fields.StringField({ required: true, initial: "" }) schema.endurance = new fields.StringField({ required: true, initial: "" })
schema.armor = new fields.StringField({ required: true, initial: "" }) schema.armor = new fields.StringField({ required: true, initial: "" })
schema.crew = 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.cargo = new fields.StringField({ required: true, initial: "" })
schema.guns = new fields.StringField({ required: true, initial: "1d6" }) schema.guns = new fields.StringField({ required: true, initial: "1d6" })
schema.travelMultiplier = new fields.StringField({ required: true, initial: "" }) schema.travelMultiplier = new fields.StringField({ required: true, initial: "" })

View File

@@ -9,8 +9,11 @@ export default class FTLNomadVehicle extends foundry.abstract.TypeDataModel {
schema.agility = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) schema.agility = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
schema.armor = 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.cargo = new fields.StringField({ required: true, initial: "" }) schema.cargo = new fields.StringField({ required: true, initial: "" })
schema.crew = 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.force = new fields.NumberField({ ...requiredInteger, initial: 1, min: 1 })
schema.range = new fields.StringField({ required: true, initial: "1d6" }) schema.range = new fields.StringField({ required: true, initial: "1d6" })
schema.speed = new fields.StringField({ required: true, initial: "1d6" }) schema.speed = new fields.StringField({ required: true, initial: "1d6" })

View File

@@ -1 +1 @@
MANIFEST-000086 MANIFEST-000132

View File

@@ -1,14 +1,7 @@
2025/10/15-13:50:39.028219 7f189f7fe6c0 Recovering log #84 2025/11/11-09:55:29.500472 7f0922ffd6c0 Recovering log #130
2025/10/15-13:50:39.038979 7f189f7fe6c0 Delete type=3 #82 2025/11/11-09:55:29.510925 7f0922ffd6c0 Delete type=3 #128
2025/10/15-13:50:39.039047 7f189f7fe6c0 Delete type=0 #84 2025/11/11-09:55:29.511008 7f0922ffd6c0 Delete type=0 #130
2025/10/15-15:26:39.732570 7f189e7fc6c0 Level-0 table #89: started 2025/11/11-12:13:09.876661 7f0920bff6c0 Level-0 table #135: started
2025/10/15-15:26:39.736109 7f189e7fc6c0 Level-0 table #89: 12073 bytes OK 2025/11/11-12:13:09.876709 7f0920bff6c0 Level-0 table #135: 0 bytes OK
2025/10/15-15:26:39.742312 7f189e7fc6c0 Delete type=0 #87 2025/11/11-12:13:09.882679 7f0920bff6c0 Delete type=0 #133
2025/10/15-15:26:39.748688 7f189e7fc6c0 Manual compaction at level-0 from '!folders!AuBtSOj1mJmh88qx' @ 72057594037927935 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at '!items!zoE4ITyfl3od6hYD' @ 721 : 1 2025/11/11-12:13:09.882804 7f0920bff6c0 Manual compaction at level-0 from '!folders!AuBtSOj1mJmh88qx' @ 72057594037927935 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at (end)
2025/10/15-15:26:39.748706 7f189e7fc6c0 Compacting 1@0 + 1@1 files
2025/10/15-15:26:39.753893 7f189e7fc6c0 Generated table #90@0: 316 keys, 126470 bytes
2025/10/15-15:26:39.753929 7f189e7fc6c0 Compacted 1@0 + 1@1 files => 126470 bytes
2025/10/15-15:26:39.760361 7f189e7fc6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2025/10/15-15:26:39.760492 7f189e7fc6c0 Delete type=2 #73
2025/10/15-15:26:39.760637 7f189e7fc6c0 Delete type=2 #89
2025/10/15-15:26:39.774069 7f189e7fc6c0 Manual compaction at level-0 from '!items!zoE4ITyfl3od6hYD' @ 721 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at (end)

View File

@@ -1,7 +1,7 @@
2025/10/15-10:02:54.141015 7f189f7fe6c0 Recovering log #80 2025/11/11-09:17:46.334216 7f0921ffb6c0 Recovering log #126
2025/10/15-10:02:54.151620 7f189f7fe6c0 Delete type=3 #78 2025/11/11-09:17:46.344001 7f0921ffb6c0 Delete type=3 #124
2025/10/15-10:02:54.151691 7f189f7fe6c0 Delete type=0 #80 2025/11/11-09:17:46.344052 7f0921ffb6c0 Delete type=0 #126
2025/10/15-10:23:16.651592 7f189e7fc6c0 Level-0 table #85: started 2025/11/11-09:53:31.537774 7f0920bff6c0 Level-0 table #131: started
2025/10/15-10:23:16.651628 7f189e7fc6c0 Level-0 table #85: 0 bytes OK 2025/11/11-09:53:31.537826 7f0920bff6c0 Level-0 table #131: 0 bytes OK
2025/10/15-10:23:16.657926 7f189e7fc6c0 Delete type=0 #83 2025/11/11-09:53:31.544859 7f0920bff6c0 Delete type=0 #129
2025/10/15-10:23:16.664228 7f189e7fc6c0 Manual compaction at level-0 from '!folders!AuBtSOj1mJmh88qx' @ 72057594037927935 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at (end) 2025/11/11-09:53:31.558512 7f0920bff6c0 Manual compaction at level-0 from '!folders!AuBtSOj1mJmh88qx' @ 72057594037927935 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

View File

@@ -1 +1 @@
MANIFEST-000064 MANIFEST-000110

View File

@@ -1,14 +1,7 @@
2025/10/15-13:50:39.042685 7f18a4ffa6c0 Recovering log #62 2025/11/11-09:55:29.516089 7f0921ffb6c0 Recovering log #108
2025/10/15-13:50:39.052767 7f18a4ffa6c0 Delete type=3 #60 2025/11/11-09:55:29.525977 7f0921ffb6c0 Delete type=3 #106
2025/10/15-13:50:39.052843 7f18a4ffa6c0 Delete type=0 #62 2025/11/11-09:55:29.526050 7f0921ffb6c0 Delete type=0 #108
2025/10/15-15:26:39.665250 7f189e7fc6c0 Level-0 table #67: started 2025/11/11-12:13:09.863976 7f0920bff6c0 Level-0 table #113: started
2025/10/15-15:26:39.668457 7f189e7fc6c0 Level-0 table #67: 12881 bytes OK 2025/11/11-12:13:09.864017 7f0920bff6c0 Level-0 table #113: 0 bytes OK
2025/10/15-15:26:39.674498 7f189e7fc6c0 Delete type=0 #65 2025/11/11-12:13:09.870509 7f0920bff6c0 Delete type=0 #111
2025/10/15-15:26:39.688322 7f189e7fc6c0 Manual compaction at level-0 from '!actors!0FQ6XaRi24OorI21' @ 72057594037927935 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at '!folders!HobFutlnH6HPTEfT' @ 93 : 1 2025/11/11-12:13:09.882783 7f0920bff6c0 Manual compaction at level-0 from '!actors!0FQ6XaRi24OorI21' @ 72057594037927935 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at (end)
2025/10/15-15:26:39.688334 7f189e7fc6c0 Compacting 1@0 + 1@1 files
2025/10/15-15:26:39.692347 7f189e7fc6c0 Generated table #68@0: 78 keys, 62826 bytes
2025/10/15-15:26:39.692380 7f189e7fc6c0 Compacted 1@0 + 1@1 files => 62826 bytes
2025/10/15-15:26:39.698356 7f189e7fc6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2025/10/15-15:26:39.698484 7f189e7fc6c0 Delete type=2 #51
2025/10/15-15:26:39.698645 7f189e7fc6c0 Delete type=2 #67
2025/10/15-15:26:39.709845 7f189e7fc6c0 Manual compaction at level-0 from '!folders!HobFutlnH6HPTEfT' @ 93 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at (end)

View File

@@ -1,7 +1,7 @@
2025/10/15-10:02:54.154455 7f18a4ffa6c0 Recovering log #58 2025/11/11-09:17:46.347112 7f09217fa6c0 Recovering log #104
2025/10/15-10:02:54.164920 7f18a4ffa6c0 Delete type=3 #56 2025/11/11-09:17:46.357554 7f09217fa6c0 Delete type=3 #102
2025/10/15-10:02:54.164970 7f18a4ffa6c0 Delete type=0 #58 2025/11/11-09:17:46.357636 7f09217fa6c0 Delete type=0 #104
2025/10/15-10:23:16.644379 7f189e7fc6c0 Level-0 table #63: started 2025/11/11-09:53:31.551245 7f0920bff6c0 Level-0 table #109: started
2025/10/15-10:23:16.644413 7f189e7fc6c0 Level-0 table #63: 0 bytes OK 2025/11/11-09:53:31.551306 7f0920bff6c0 Level-0 table #109: 0 bytes OK
2025/10/15-10:23:16.651461 7f189e7fc6c0 Delete type=0 #61 2025/11/11-09:53:31.558404 7f0920bff6c0 Delete type=0 #107
2025/10/15-10:23:16.664216 7f189e7fc6c0 Manual compaction at level-0 from '!actors!3pydTJsM73Z4o0V6' @ 72057594037927935 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at (end) 2025/11/11-09:53:31.558535 7f0920bff6c0 Manual compaction at level-0 from '!actors!0FQ6XaRi24OorI21' @ 72057594037927935 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

View File

@@ -123,23 +123,27 @@
} }
.encumbrance { .encumbrance {
display: grid; display: flex;
grid-template-columns: repeat(3, 1fr);
gap: 4px; gap: 4px;
.form-group { .form-group {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center;
margin-bottom: 4px; margin-bottom: 4px;
} }
label { label {
min-width: 4rem; min-width: 3rem;
max-width: 4rem; max-width: 3rem;
} }
input { input {
max-width: 3rem; max-width: 3rem;
min-width: 3rem; min-width: 3rem;
} }
.character-credit {
input {
max-width: 9rem;
min-width: 9rem;
}
}
} }
.character-name { .character-name {
@@ -168,7 +172,7 @@
background-color: var(--color-light-1); background-color: var(--color-light-1);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 5px; justify-content: space-evenly;
flex: 1; flex: 1;
.character-skill { .character-skill {

View File

@@ -129,7 +129,7 @@
background-color: var(--color-light-1); background-color: var(--color-light-1);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 5px; justify-content: space-evenly;
flex: 1; flex: 1;
.creature-skill { .creature-skill {
@@ -201,6 +201,16 @@
} }
} }
.section-editor {
min-height: 10rem;
.editor {
min-height: 10rem;
}
.editor-content {
min-height: 10rem;
}
}
.biodata { .biodata {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);

View File

@@ -1,7 +1,10 @@
:root { :root {
--font-size-standard: 0.9rem; --font-size-standard: 0.9rem;
--font-size-result: 1.4rem; --font-size-result: 1.4rem;
--background-image-base: linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.8)), --background-image-base: linear-gradient(
rgba(255, 255, 255, 0.8),
rgba(255, 255, 255, 0.8)
),
url("../assets/ui/ftl_nomad_background_01.webp"); url("../assets/ui/ftl_nomad_background_01.webp");
--font-primary: "Atkinson"; --font-primary: "Atkinson";
--font-secondary: "Atkinson"; --font-secondary: "Atkinson";
@@ -12,12 +15,14 @@
--color-warning: darkorange; --color-warning: darkorange;
--color-critical-success: rgb(21, 39, 204); --color-critical-success: rgb(21, 39, 204);
--color-critical-failure: rgb(141, 32, 231); --color-critical-failure: rgb(141, 32, 231);
/*--img-icon-color-filter: invert(60%) sepia(12%) saturate(6853%) hue-rotate(81deg) brightness(113%) contrast(104%);*/ /*--img-icon-color-filter: invert(60%) sepia(12%) saturate(6853%) hue-rotate(81deg) brightness(113%) contrast(104%);*/
} }
body { body {
--color-text-secondary: rgb(22, 3, 3); --color-text-secondary: rgb(22, 3, 3);
--color-text-emphatic: rgb(9, 97, 14); --color-text-emphatic: rgb(9, 97, 14);
--input-height: 1.6rem;
} }
.d100 { .d100 {
@@ -65,7 +70,7 @@ i.fvtt-ftl-nomad {
.application.dialog.fvtt-ftl-nomad { .application.dialog.fvtt-ftl-nomad {
font-family: var(--font-primary); font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1.0); font-size: calc(var(--font-size-standard) * 1);
background-image: var(--background-image-base); background-image: var(--background-image-base);
button:hover { button:hover {
background: var(--color-dark-6); background: var(--color-dark-6);
@@ -75,6 +80,12 @@ i.fvtt-ftl-nomad {
} }
} }
.sheet-tabs {
background-color: var(--color-light-1);
font-family: Ethnocentric;
font-size: 0.7rem;
}
.chat-message, .chat-message,
.chat-message.whisper { .chat-message.whisper {
font-family: var(--font-primary); font-family: var(--font-primary);

View File

@@ -77,8 +77,8 @@
label { label {
font-weight: bold; font-weight: bold;
margin-right: 8px; margin-right: 8px;
min-width: 4rem; min-width: 5rem;
max-width: 4rem; max-width: 5rem;
} }
} }
} }

View File

@@ -19,6 +19,7 @@
.robot-left { .robot-left {
min-width: 180px; min-width: 180px;
max-width: 180px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -33,6 +34,17 @@
border: none; border: none;
} }
} }
.robot-cost {
label {
min-width: 3rem;
max-width: 3rem;
}
input {
min-width: 6rem;
max-width: 6rem;
}
}
} }
.robot-right { .robot-right {
@@ -45,13 +57,28 @@
input { input {
font-family: var(--font-title); font-family: var(--font-title);
font-size: calc(var(--font-size-standard) * 1.4); font-size: calc(var(--font-size-standard) * 1.4);
width: 400px; width: 380px;
}
}
.robot-brain {
min-width: 25rem;
max-width: 25rem;
textarea {
min-width: 23rem;
max-width: 23rem;
background-color: rgba(0, 0, 0, 0.2);
color: var(--color-dark-3);
} }
} }
.main-stats { .main-stats {
min-width: 25rem; min-width: 25rem;
max-width: 25rem; max-width: 25rem;
.encumbered {
color: red;
font-weight: bold;
}
} }
.cargo, .cargo,
.capacity { .capacity {
@@ -119,7 +146,7 @@
background-color: var(--color-light-1); background-color: var(--color-light-1);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 5px; justify-content: space-evenly;
flex: 1; flex: 1;
.robot-skill { .robot-skill {
@@ -198,6 +225,12 @@
} }
.section-editor { .section-editor {
min-height: 10rem; min-height: 10rem;
.editor {
min-height: 10rem;
}
.editor-content {
min-height: 10rem;
}
} }
.biodata { .biodata {

View File

@@ -4,10 +4,6 @@
overflow: scroll; overflow: scroll;
} }
.sheet-tabs {
background-color: var(--color-light-1);
}
.starship-main { .starship-main {
background-color: var(--color-light-1); background-color: var(--color-light-1);
display: flex; display: flex;
@@ -68,6 +64,12 @@
text-shadow: 0 0 8px var(--color-shadow-primary); text-shadow: 0 0 8px var(--color-shadow-primary);
cursor: pointer; cursor: pointer;
} }
.hull-field {
select {
min-width: 10rem;
max-width: 10rem;
}
}
label { label {
margin-left: 0.2rem; margin-left: 0.2rem;
max-width: 7rem; max-width: 7rem;
@@ -103,6 +105,18 @@
select { select {
max-width: 5rem; max-width: 5rem;
} }
.npc-crew-field {
display: flex;
align-items: center;
gap: 4px;
.npc-crew-roll {
cursor: pointer;
color: var(--color-text-dark-primary);
&:hover {
color: var(--color-text-hyperlink);
}
}
}
} }
.starship-infos { .starship-infos {
@@ -173,6 +187,12 @@
.section-editor { .section-editor {
min-height: 10rem; min-height: 10rem;
.editor {
min-height: 10rem;
}
.editor-content {
min-height: 10rem;
}
} }
.biodata { .biodata {
@@ -202,6 +222,68 @@
padding-left: 5px; padding-left: 5px;
} }
} }
.crew {
.crew-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
padding: 4px;
}
.crew-member {
display: flex;
align-items: center;
gap: 4px;
padding: 4px;
border: 1px solid var(--color-border-dark);
border-radius: 4px;
background: var(--color-light-2);
.crew-img {
width: 32px;
height: 32px;
border-radius: 50%;
border: 1px solid var(--color-border-dark);
cursor: pointer;
&:hover {
opacity: 0.8;
box-shadow: 0 0 4px var(--color-shadow-primary);
}
}
.crew-name {
flex: 1;
font-size: var(--font-size-small);
cursor: pointer;
&:hover {
color: var(--color-text-dark-highlight);
text-shadow: 0 0 4px var(--color-shadow-primary);
}
}
.controls {
display: flex;
gap: 4px;
min-width: 3rem;
a {
color: var(--color-text-dark-primary);
&:hover {
color: var(--color-text-dark-highlight);
}
}
.pilot-button {
color: var(--color-text-light-primary);
&:hover {
color: var(--color-text-light-highlight);
}
}
}
}
.crew-empty {
grid-column: 1 / -1;
text-align: center;
padding: 8px;
font-style: italic;
color: var(--color-text-dark-secondary);
}
}
.weapons { .weapons {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);

View File

@@ -34,6 +34,14 @@
} }
} }
.spec {
label {
max-width: 4rem;
}
input {
max-width: 4rem;
}
}
} }
.vehicle-right { .vehicle-right {
@@ -53,19 +61,35 @@
.cargo, .cargo,
.capacity { .capacity {
label { label {
min-width: 4rem; max-width: 7rem;
max-width: 4rem;
} }
input { input {
max-width: 6rem; max-width: 6rem;
margin-right: 0.5rem; margin-right: 0.5rem;
} }
.cargo-content { .cargo-content {
display: flex;
flex-direction: column;
gap: 4px;
.cargo-line {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
} }
} }
.npc-crew-field {
display: flex;
align-items: center;
gap: 4px;
.npc-crew-roll {
cursor: pointer;
color: var(--color-text-dark-primary);
&:hover {
color: var(--color-text-hyperlink);
}
}
}
}
.vehicle-infos { .vehicle-infos {
display: flex; display: flex;
@@ -136,8 +160,15 @@
.field-label { .field-label {
margin-left: 8px; margin-left: 8px;
} }
.section-editor { .section-editor {
min-height: 10rem; min-height: 10rem;
.editor {
min-height: 10rem;
}
.editor-content {
min-height: 10rem;
}
} }
.biodata { .biodata {
@@ -145,7 +176,7 @@
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
gap: 8px; gap: 8px;
label { label {
min-width: 3.0rem; min-width: 3rem;
} }
.feature { .feature {
display: flex; display: flex;
@@ -155,7 +186,6 @@
max-width: 18rem; max-width: 18rem;
} }
} }
} }
.tab.vehicle-equipment .main-div { .tab.vehicle-equipment .main-div {
@@ -168,6 +198,68 @@
padding-left: 5px; padding-left: 5px;
} }
} }
.crew {
.crew-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
padding: 4px;
}
.crew-member {
display: flex;
align-items: center;
gap: 4px;
padding: 4px;
border: 1px solid var(--color-border-dark);
border-radius: 4px;
background: var(--color-light-2);
.crew-img {
width: 32px;
height: 32px;
border-radius: 50%;
border: 1px solid var(--color-border-dark);
cursor: pointer;
&:hover {
opacity: 0.8;
box-shadow: 0 0 4px var(--color-shadow-primary);
}
}
.crew-name {
flex: 1;
font-size: var(--font-size-small);
cursor: pointer;
&:hover {
color: var(--color-text-dark-highlight);
text-shadow: 0 0 4px var(--color-shadow-primary);
}
}
.controls {
display: flex;
gap: 4px;
min-width: 3rem;
a {
color: var(--color-text-dark-primary);
&:hover {
color: var(--color-text-dark-highlight);
}
}
.pilot-button {
color: var(--color-text-light-primary);
&:hover {
color: var(--color-text-light-highlight);
}
}
}
}
.crew-empty {
grid-column: 1 / -1;
text-align: center;
padding: 8px;
font-style: italic;
color: var(--color-text-dark-secondary);
}
}
.weapons { .weapons {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);

View File

@@ -113,7 +113,14 @@
rootId=partId rootId=partId
disabled=isPlayMode disabled=isPlayMode
}} }}
{{formField systemFields.credits value=system.credits rootId=partId}} <span class="character-credit">
{{formField
systemFields.credits
value=system.credits
rootId=partId
disabled=isPlayMode
}}
</span>
</fieldset> </fieldset>
</div> </div>

View File

@@ -1,16 +1,31 @@
<section class="tab creature-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}"> <section
class="tab creature-{{tab.id}} {{tab.cssClass}}"
data-tab="{{tab.id}}"
data-group="{{tab.group}}"
>
<div class="main-div"> <div class="main-div">
<fieldset> <fieldset class="section-editor">
<legend>{{localize "FTLNOMAD.Label.description"}}</legend> <legend>{{localize "FTLNOMAD.Label.description"}}</legend>
{{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" {{formInput
toggled=true}} systemFields.description
enriched=enrichedDescription
value=system.description
name="system.description"
toggled=true
}}
</fieldset> </fieldset>
<fieldset> <fieldset class="section-editor">
<legend>{{localize "FTLNOMAD.Label.notes"}}</legend> <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> </fieldset>
</div> </div>

View File

@@ -6,11 +6,16 @@
<fieldset> <fieldset>
<legend>Tech Age</legend> <legend>Tech Age</legend>
<div class="flexrow"> <div class="flexrow">
{{formField systemFields.techAge value=system.techAge localize=true}} {{formField
systemFields.techAge
value=system.techAge
localize=true
disabled=isPlayMode
}}
</div> </div>
</fieldset> </fieldset>
<fieldset> <!-- <fieldset>
<legend>{{localize "FTLNOMAD.Label.damages"}}</legend> <legend>{{localize "FTLNOMAD.Label.damages"}}</legend>
<div class="text-center"> <div class="text-center">
<textarea <textarea
@@ -21,7 +26,7 @@
data-tooltip="{{localize 'FTLNOMAD.Tooltip.damages'}}" data-tooltip="{{localize 'FTLNOMAD.Tooltip.damages'}}"
>{{system.damages}}</textarea> >{{system.damages}}</textarea>
</div> </div>
</fieldset> </fieldset> -->
<fieldset class="section-editor"> <fieldset class="section-editor">
<legend>{{localize "FTLNOMAD.Label.description"}}</legend> <legend>{{localize "FTLNOMAD.Label.description"}}</legend>

View File

@@ -3,6 +3,7 @@
<fieldset> <fieldset>
<legend>{{localize "FTLNOMAD.Label.robot"}}</legend> <legend>{{localize "FTLNOMAD.Label.robot"}}</legend>
<div class="robot-pc robot-pc-{{ifThen isPlayMode 'play' 'edit'}}"> <div class="robot-pc robot-pc-{{ifThen isPlayMode 'play' 'edit'}}">
<div class="robot-left"> <div class="robot-left">
<div class="robot-left-image"> <div class="robot-left-image">
<img <img
@@ -13,7 +14,19 @@
data-tooltip="{{actor.name}}" data-tooltip="{{actor.name}}"
/> />
</div> </div>
<div>
<fieldset class="robot-cost">
<legend>Cost</legend>
<div class="flexrow">
{{formField
systemFields.cost
value=system.cost
localize=true
disabled=isPlayMode
}}
</div>
</fieldset>
</div>
</div> </div>
<div class="robot-right"> <div class="robot-right">
@@ -67,21 +80,41 @@
}} }}
</div> </div>
<div class="flexrow"> <div class="flexrow">
{{#if isEncumbered}}
{{formField {{formField
systemFields.cost systemFields.enc.fields.value
value=system.cost value=system.enc.value
localize=true rootId=partId
disabled=true
classes="encumbered"
}}
{{else}}
{{formField
systemFields.enc.fields.value
value=system.enc.value
rootId=partId
disabled=true
}}
{{/if}}
&nbsp;
{{formField
systemFields.enc.fields.max
value=system.enc.max
rootId=partId
disabled=isPlayMode disabled=isPlayMode
}} }}
</div> </div>
</fieldset>
<fieldset class="robot-brain">
<legend>Brain</legend>
<div class="flexrow"> <div class="flexrow">
{{formField <textarea
systemFields.brain cols="64"
value=system.brain rows="2"
localize=true name="system.brain"
classes="robot-brain" data-tooltip="{{localize 'FTLNOMAD.Tooltip.brain'}}"
disabled=isPlayMode {{#if isPlayMode}}disabled{{/if}}>{{system.brain}}</textarea>
}}
</div> </div>
</fieldset> </fieldset>

View File

@@ -9,10 +9,22 @@
{{#if (eq rollType "damage")}} {{#if (eq rollType "damage")}}
<div class="dialog-skill">Damage : {{weapon.system.damage}}</div> <div class="dialog-skill">Damage : {{weapon.system.damage}}</div>
<div class="dialog-skill">Weapon : {{weapon.name}}</div> <div class="dialog-skill">Weapon : {{weapon.name}}</div>
{{else}}
{{#if availableSkills}}
<label>{{localize "FTLNOMAD.Label.selectSkill"}}</label>
<select name="selectedSkill" class="roll-skill-selector">
{{#each availableSkills as |skill|}}
<option
value="{{skill.id}}"
{{#if skill.selected}}selected{{/if}}
>{{localize skill.label}} (2d6+{{skill.value}})</option>
{{/each}}
</select>
{{else}} {{else}}
<div class="dialog-skill">{{localize rollItem.label}} <div class="dialog-skill">{{localize rollItem.label}}
: 2d6+{{rollItem.value}}</div> : 2d6+{{rollItem.value}}</div>
{{/if}} {{/if}}
{{/if}}
{{#if (eq rollType "weapon")}} {{#if (eq rollType "weapon")}}
<div class="dialog-skill">Weapon : {{weapon.name}}</div> <div class="dialog-skill">Weapon : {{weapon.name}}</div>
@@ -40,6 +52,24 @@
<select name="modifier" class="roll-skill-modifier"> <select name="modifier" class="roll-skill-modifier">
{{selectOptions choiceModifier selected=modifier localize=true}} {{selectOptions choiceModifier selected=modifier localize=true}}
</select> </select>
<label>{{localize "FTLNOMAD.Label.numericModifier"}}</label>
<select name="numericModifierSelect" class="roll-numeric-modifier">
{{selectOptions choiceNumericModifier selected=numericModifierSelect}}
</select>
{{#if vehicleBonus}}
<div class="vehicle-bonus-info">
<label>
<input
type="checkbox"
name="useVehicleBonus"
class="use-vehicle-bonus"
checked
/>
{{localize "FTLNOMAD.Label.vehicleBonus"}}
</label>
<span class="vehicle-bonus-value">+{{vehicleBonus}}</span>
</div>
{{/if}}
{{/if}} {{/if}}
{{#if (eq rollType "weapon")}} {{#if (eq rollType "weapon")}}

View File

@@ -4,63 +4,43 @@
data-group="{{tab.group}}" data-group="{{tab.group}}"
> >
<div class="main-div"> <div class="main-div">
<fieldset class="crew">
<!-- <div class="weapons"> <legend>{{localize "FTLNOMAD.Label.crew"}}
<fieldset> ({{crewMembers.length}}{{#if
<legend>{{localize "FTLNOMAD.Label.weapons"}}{{#if isEditMode}} system.crewCapacity
<a }}/{{system.crewCapacity}}{{/if}})</legend>
class="action" <div class="crew-list">
data-tooltip="{{localize ' FTLNOMAD.Tooltip.addWeapon'}}" {{#each crewMembers as |member|}}
data-tooltip-direction="UP"
><i class="fas fa-plus" data-action="createWeapon"></i></a>{{/if}}
</legend>
{{#each weapons as |item|}}
{{!log 'weapon' this}}
<div <div
class="weapon item" class="crew-member"
data-item-id="{{item.id}}" data-actor-uuid="{{member.uuid}}"
data-item-uuid="{{item.uuid}}"
data-drag="true" data-drag="true"
> >
<img <img
class="item-img" class="crew-img"
src="{{item.img}}" src="{{member.img}}"
data-tooltip="{{item.name}}" data-tooltip="{{member.name}}"
data-action="viewCrew"
/> />
<div <div class="crew-name" data-action="viewCrew">{{member.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"> <div class="controls">
<a <a
data-tooltip="{{localize 'FTLNOMAD.Edit'}}" class="pilot-button"
data-action="edit" data-tooltip="{{localize 'FTLNOMAD.PilotStarship'}}"
data-item-id="{{item.id}}" data-action="pilotCrew"
data-item-uuid="{{item.uuid}}" ><i class="fas fa-dice-d6"></i></a>
><i class="fas fa-edit"></i></a>
<a <a
data-tooltip="{{localize 'FTLNOMAD.Delete'}}" data-tooltip="{{localize 'FTLNOMAD.RemoveCrew'}}"
data-action="delete" data-action="removeCrew"
data-item-id="{{item.id}}" data-crew-uuid="{{member.uuid}}"
data-item-uuid="{{item.uuid}}" ><i class="fas fa-times"></i></a>
><i class="fas fa-trash"></i></a>
</div> </div>
</div> </div>
{{else}}
<div class="crew-empty">{{localize "FTLNOMAD.Label.noCrew"}}</div>
{{/each}} {{/each}}
</div> </div>
</fieldset> --> </fieldset>
<fieldset> <fieldset>
<legend>{{localize "FTLNOMAD.Label.equipment"}}{{#if isEditMode}} <legend>{{localize "FTLNOMAD.Label.equipment"}}{{#if isEditMode}}

View File

@@ -22,12 +22,21 @@
localize=true localize=true
disabled=isPlayMode disabled=isPlayMode
}} }}
{{formField {{formField
systemFields.armor systemFields.armor
value=system.armor value=system.armor
localize=true localize=true
disabled=isPlayMode disabled=isPlayMode
}} }}
{{formField
systemFields.armorCritical
value=system.armorCritical
localize=true
disabled=isPlayMode
}}
{{formField {{formField
systemFields.endurance systemFields.endurance
value=system.endurance value=system.endurance
@@ -58,20 +67,13 @@
<fieldset class="capacity"> <fieldset class="capacity">
<legend>{{localize "FTLNOMAD.Label.capacity"}}</legend> <legend>{{localize "FTLNOMAD.Label.capacity"}}</legend>
<div class="flexrow"> <div class="flexrow hull-field">
{{formField {{formField
systemFields.hullType systemFields.hullType
value=system.hullType value=system.hullType
localize=true localize=true
disabled=isPlayMode disabled=isPlayMode
}} }}
{{formField
systemFields.travelMultiplier
value=system.travelMultiplier
localize=true
disabled=isPlayMode
}}
</div> </div>
<div class="flexrow-guns"> <div class="flexrow-guns">
@@ -87,6 +89,14 @@
localize=true localize=true
disabled=isPlayMode disabled=isPlayMode
}} }}
{{formField
systemFields.travelMultiplier
value=system.travelMultiplier
localize=true
disabled=isPlayMode
}}
</div> </div>
</fieldset> </fieldset>
@@ -95,11 +105,26 @@
<legend>{{localize "FTLNOMAD.Label.cargo"}}</legend> <legend>{{localize "FTLNOMAD.Label.cargo"}}</legend>
<div class="flexrow"> <div class="flexrow">
{{formField {{formField
systemFields.crew systemFields.crewCapacity
value=system.crew value=system.crewCapacity
localize=true localize=true
disabled=isPlayMode disabled=isPlayMode
}} }}
<div class="npc-crew-field">
<a
class="npc-crew-roll rollable"
data-action="rollNpcCrew"
data-tooltip="{{localize 'FTLNOMAD.RollNpcCrew'}}"
><i class="fas fa-dice-d6"></i></a>
{{formField
systemFields.npcCrew
value=system.npcCrew
localize=true
disabled=isPlayMode
}}
</div>
</div>
<div class="flexrow">
{{formField {{formField
systemFields.cargo systemFields.cargo
value=system.cargo value=system.cargo

View File

@@ -6,7 +6,12 @@
<fieldset> <fieldset>
<legend>{{localize "FTLNOMAD.Label.techAge"}}</legend> <legend>{{localize "FTLNOMAD.Label.techAge"}}</legend>
<div class="flexrow"> <div class="flexrow">
{{formField systemFields.techAge value=system.techAge localize=true}} {{formField
systemFields.techAge
value=system.techAge
localize=true
disabled=isPlayMode
}}
&nbsp; &nbsp;
{{formField {{formField
systemFields.cost systemFields.cost

View File

@@ -4,6 +4,45 @@
data-group="{{tab.group}}" data-group="{{tab.group}}"
> >
<div class="main-div"> <div class="main-div">
<fieldset class="crew">
<legend>{{localize "FTLNOMAD.Label.crew"}}
({{crewMembers.length}}{{#if
system.crewCapacity
}}/{{system.crewCapacity}}{{/if}})</legend>
<div class="crew-list">
{{#each crewMembers as |member|}}
<div
class="crew-member"
data-actor-uuid="{{member.uuid}}"
data-drag="true"
>
<img
class="crew-img"
src="{{member.img}}"
data-tooltip="{{member.name}}"
data-action="viewCrew"
/>
<div class="crew-name" data-action="viewCrew">{{member.name}}</div>
<div class="controls">
<a
class="pilot-button"
data-tooltip="{{localize 'FTLNOMAD.PilotVehicle'}}"
data-action="pilotCrew"
><i class="fas fa-dice-d6"></i></a>
<a
data-tooltip="{{localize 'FTLNOMAD.RemoveCrew'}}"
data-action="removeCrew"
data-crew-uuid="{{member.uuid}}"
><i class="fas fa-times"></i></a>
</div>
</div>
{{else}}
<div class="crew-empty">{{localize "FTLNOMAD.Label.noCrew"}}</div>
{{/each}}
</div>
</fieldset>
<fieldset> <fieldset>
<legend>{{localize "FTLNOMAD.Label.weapons"}}{{#if isEditMode}} <legend>{{localize "FTLNOMAD.Label.weapons"}}{{#if isEditMode}}
<a <a

View File

@@ -13,16 +13,25 @@
data-tooltip="{{actor.name}}" data-tooltip="{{actor.name}}"
/> />
</div> </div>
<fieldset> <fieldset class="spec">
<legend>{{localize "FTLNOMAD.Label.Agility"}}</legend>
<div class="flexrow">
{{formField {{formField
systemFields.agility systemFields.agility
value=system.agility value=system.agility
localize=true localize=true
disabled=isPlayMode disabled=isPlayMode
}} }}
</div> {{formField
systemFields.armor
value=system.armor
localize=true
disabled=isPlayMode
}}
{{formField
systemFields.armorCritical
value=system.armorCritical
localize=true
disabled=isPlayMode
}}
</fieldset> </fieldset>
</div> </div>
@@ -48,12 +57,6 @@
<fieldset class="capacity"> <fieldset class="capacity">
<legend>{{localize "FTLNOMAD.Label.capacity"}}</legend> <legend>{{localize "FTLNOMAD.Label.capacity"}}</legend>
<div class="flexrow"> <div class="flexrow">
{{formField
systemFields.armor
value=system.armor
localize=true
disabled=isPlayMode
}}
{{formField {{formField
systemFields.force systemFields.force
value=system.force value=system.force
@@ -80,12 +83,28 @@
<fieldset class="cargo"> <fieldset class="cargo">
<legend>{{localize "FTLNOMAD.Label.cargo"}}</legend> <legend>{{localize "FTLNOMAD.Label.cargo"}}</legend>
<div class="cargo-content"> <div class="cargo-content">
<div class="cargo-line">
{{formField {{formField
systemFields.crew systemFields.crewCapacity
value=system.crew value=system.crewCapacity
localize=true localize=true
disabled=isPlayMode disabled=isPlayMode
}} }}
<div class="npc-crew-field">
<a
class="npc-crew-roll rollable"
data-action="rollNpcCrew"
data-tooltip="{{localize 'FTLNOMAD.RollNpcCrew'}}"
><i class="fas fa-dice-d6"></i></a>
{{formField
systemFields.npcCrew
value=system.npcCrew
localize=true
disabled=isPlayMode
}}
</div>
</div>
<div class="cargo-line">
{{formField {{formField
systemFields.cargo systemFields.cargo
value=system.cargo value=system.cargo
@@ -99,8 +118,8 @@
disabled=isPlayMode disabled=isPlayMode
}} }}
</div> </div>
</div>
</fieldset> </fieldset>
</div> </div>
</div> </div>
</fieldset> </fieldset>