14 Commits

Author SHA1 Message Date
21dca4446f Fix starship agility
All checks were successful
Release Creation / build (release) Successful in 51s
2025-11-16 13:49:33 +01:00
6aa0b3a58d Fix robot weapon, and rework encumbrance
All checks were successful
Release Creation / build (release) Successful in 53s
2025-11-15 21:59:42 +01:00
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
e65f0a1670 New robot stuff
All checks were successful
Release Creation / build (release) Successful in 1m15s
2025-10-15 15:27:58 +02:00
941db9436f Range distance fix + compendiums 2025-10-14 15:49:08 +02:00
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
59 changed files with 3550 additions and 430 deletions

View File

@@ -0,0 +1 @@
<svg style="height: 512px; width: 512px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><defs><filter id="shadow-1" height="300%" width="300%" x="-100%" y="-100%"><feFlood flood-color="rgba(255, 255, 255, 1)" result="flood"></feFlood><feComposite in="flood" in2="SourceGraphic" operator="atop" result="composite"></feComposite><feGaussianBlur in="composite" stdDeviation="15" result="blur"></feGaussianBlur><feOffset dx="0" dy="0" result="offset"></feOffset><feComposite in="SourceGraphic" in2="offset" operator="over"></feComposite></filter></defs><g class="" style="" transform="translate(0,0)"><path d="M265.344 18.563v302.863h-18.69V18.59c-61.403 3.005-115.44 34.412-149.238 81.336l35.022 60.658a46.633 46.633 0 0 1 12.11-1.598c25.747 0 46.62 20.872 46.62 46.62 0 22.556-16.02 41.37-37.3 45.687v174.084c13.712 21.43 27.6 41.98 40.712 60.754V369.01h122.838v117.117c13.11-18.773 27-39.324 40.713-60.754V251.294c-21.282-4.317-37.302-23.13-37.302-45.688 0-25.747 20.873-46.62 46.62-46.62 4.19 0 8.25.562 12.113 1.6l35.13-60.847c-33.74-47-87.758-78.375-149.346-81.175zM426.03 117.47l-29.74 51.52c10.824 8.537 17.782 21.76 17.782 36.615 0 22.54-15.995 41.343-37.254 45.68V395.38c9.833-16.237 19.31-32.676 28.014-48.927 27.3-50.976 46.564-100.37 46.564-132.36 0-35.127-9.22-68.104-25.365-96.622zm-339.973.157c-16.196 28.486-25.46 61.408-25.46 96.465 0 31.992 19.267 81.385 46.567 132.36 8.704 16.253 18.182 32.694 28.016 48.933v-144.1c-21.26-4.336-37.254-23.14-37.254-45.68 0-14.856 6.957-28.08 17.783-36.617l-29.653-51.36zm127.213 270.07V488.98h85.46V387.696h-85.46z" fill="#7ed321" fill-opacity="1" filter="url(#shadow-1)" stroke="#ffffff" stroke-opacity="1" stroke-width="8"></path></g></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -24,6 +24,7 @@
body {
--color-text-secondary: #160303;
--color-text-emphatic: #09610e;
--input-height: 1.6rem;
}
.d100 {
width: 18px;
@@ -74,6 +75,11 @@ i.fvtt-ftl-nomad {
.application.dialog.fvtt-ftl-nomad .legend {
font-family: var(--font-primary);
}
.sheet-tabs {
background-color: var(--color-light-1);
font-family: Ethnocentric;
font-size: 0.7rem;
}
.chat-message,
.chat-message.whisper {
font-family: var(--font-primary);
@@ -99,8 +105,8 @@ i.fvtt-ftl-nomad {
.fvtt-ftl-nomad .vehicle-sheet-common .form-group label {
font-weight: bold;
margin-right: 8px;
min-width: 4rem;
max-width: 4rem;
min-width: 5rem;
max-width: 5rem;
}
.fvtt-ftl-nomad .starship-sheet-common label {
font-family: var(--font-secondary);
@@ -118,6 +124,22 @@ i.fvtt-ftl-nomad {
min-width: 5rem;
max-width: 5rem;
}
.fvtt-ftl-nomad .robot-sheet-common label {
font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1);
}
.fvtt-ftl-nomad .robot-sheet-common .form-group {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 4px;
}
.fvtt-ftl-nomad .robot-sheet-common .form-group label {
font-weight: bold;
margin-right: 8px;
min-width: 5rem;
max-width: 5rem;
}
.fvtt-ftl-nomad .creature-sheet-common label {
font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1);
@@ -327,24 +349,26 @@ i.fvtt-ftl-nomad {
min-width: 5.2rem;
}
.fvtt-ftl-nomad .character-main .character-pc .character-right .encumbrance {
display: grid;
grid-template-columns: repeat(3, 1fr);
display: flex;
gap: 4px;
}
.fvtt-ftl-nomad .character-main .character-pc .character-right .encumbrance .form-group {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 4px;
}
.fvtt-ftl-nomad .character-main .character-pc .character-right .encumbrance label {
min-width: 4rem;
max-width: 4rem;
min-width: 3rem;
max-width: 3rem;
}
.fvtt-ftl-nomad .character-main .character-pc .character-right .encumbrance input {
max-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 {
display: flex;
}
@@ -366,7 +390,7 @@ i.fvtt-ftl-nomad {
background-color: var(--color-light-1);
display: flex;
flex-direction: column;
gap: 5px;
justify-content: space-evenly;
flex: 1;
}
.fvtt-ftl-nomad .character-main .character-skills .character-skill {
@@ -413,10 +437,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;
@@ -984,8 +1008,8 @@ i.fvtt-ftl-nomad {
.fvtt-ftl-nomad .vehicle-content .form-group label {
font-weight: bold;
margin-right: 8px;
min-width: 4rem;
max-width: 4rem;
min-width: 5rem;
max-width: 5rem;
}
.fvtt-ftl-nomad .sheet-tabs {
background-color: var(--color-light-1);
@@ -1015,6 +1039,12 @@ i.fvtt-ftl-nomad {
width: auto;
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 {
display: flex;
flex-direction: column;
@@ -1030,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 .capacity label {
min-width: 4rem;
max-width: 4rem;
max-width: 7rem;
}
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .cargo input,
.fvtt-ftl-nomad .vehicle-main .vehicle-pc .vehicle-right .capacity input {
@@ -1040,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 .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;
align-items: center;
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 {
display: flex;
flex-direction: column;
@@ -1104,6 +1154,15 @@ 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 .section-editor .editor {
min-height: 10rem;
}
.fvtt-ftl-nomad .vehicle-description .section-editor .editor-content {
min-height: 10rem;
}
.fvtt-ftl-nomad .vehicle-description .biodata {
display: grid;
grid-template-columns: repeat(2, 1fr);
@@ -1128,6 +1187,65 @@ i.fvtt-ftl-nomad {
font-size: calc(var(--font-size-standard) * 1.4);
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 {
display: grid;
grid-template-columns: repeat(2, 1fr);
@@ -1202,6 +1320,374 @@ i.fvtt-ftl-nomad {
.fvtt-ftl-nomad .tab.vehicle-equipment .main-div prose-mirror.active {
min-height: 150px;
}
.fvtt-ftl-nomad .robot-content {
font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1);
color: var(--color-dark-1);
background-color: var(--color-light-1);
/*background-image: var(--background-image-base);*/
background-repeat: no-repeat;
background-size: 100% 100%;
overflow: scroll;
}
.fvtt-ftl-nomad .robot-content input:disabled,
.fvtt-ftl-nomad .robot-content select:disabled {
background-color: rgba(0, 0, 0, 0.2);
border-color: transparent;
color: var(--color-dark-3);
}
.fvtt-ftl-nomad .robot-content input,
.fvtt-ftl-nomad .robot-content select {
background-color: rgba(0, 0, 0, 0.1);
border-color: var(--color-dark-6);
color: var(--color-dark-2);
}
.fvtt-ftl-nomad .robot-content input[name="name"] {
height: 40px;
margin-right: 10px;
font-family: var(--font-title);
font-size: calc(var(--font-size-standard) * 1.2);
font-weight: bold;
border: none;
margin-top: 4px;
}
.fvtt-ftl-nomad .robot-content fieldset {
margin-bottom: 4px;
border-radius: 4px;
}
.fvtt-ftl-nomad .robot-content .form-fields input,
.fvtt-ftl-nomad .robot-content .form-fields select {
text-align: center;
font-size: calc(var(--font-size-standard) * 1);
}
.fvtt-ftl-nomad .robot-content .form-fields select {
font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1);
}
.fvtt-ftl-nomad .robot-content legend {
font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1.2);
font-weight: bold;
letter-spacing: 1px;
}
.fvtt-ftl-nomad .robot-content label {
font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1);
}
.fvtt-ftl-nomad .robot-content .form-group {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 4px;
}
.fvtt-ftl-nomad .robot-content .form-group label {
font-weight: bold;
margin-right: 8px;
min-width: 5rem;
max-width: 5rem;
}
.fvtt-ftl-nomad .sheet-tabs {
background-color: var(--color-light-1);
}
.fvtt-ftl-nomad .robot-main {
background-color: var(--color-light-1);
display: flex;
}
.fvtt-ftl-nomad .robot-main .robot-pc {
display: flex;
gap: 4px;
flex: 1;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-left {
min-width: 180px;
max-width: 180px;
display: flex;
flex-direction: column;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-left .robot-left-image {
display: flex;
justify-content: center;
align-items: center;
padding-bottom: 8px;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-left .robot-left-image .robot-img {
height: 140px;
width: auto;
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 {
display: flex;
flex-direction: column;
gap: 5px;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .robot-name {
display: flex;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .robot-name input {
font-family: var(--font-title);
font-size: calc(var(--font-size-standard) * 1.4);
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 {
min-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 .capacity label {
min-width: 4rem;
max-width: 4rem;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .cargo input,
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .capacity input {
max-width: 6rem;
margin-right: 0.5rem;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .cargo .cargo-content,
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .capacity .cargo-content {
display: flex;
align-items: center;
gap: 4px;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .robot-infos {
display: flex;
flex-direction: column;
gap: 4px;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .robot-infos label {
min-width: 120px;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .robot-infos .robot-hp {
display: flex;
gap: 2px;
align-items: center;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .robot-infos .robot-hp .robot-hp-value .form-fields input {
flex: none;
width: 50px;
margin-left: 4px;
font-size: calc(var(--font-size-standard) * 1.4);
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .robot-infos .robot-hp .robot-hp-max {
clear: both;
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 3px 0;
align-items: center;
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .robot-infos .robot-hp .robot-hp-max input {
width: 50px;
text-align: center;
font-size: calc(var(--font-size-standard) * 1.4);
}
.fvtt-ftl-nomad .robot-main .robot-pc .robot-right .robot-infos .robot-hp .hp-separator {
font-size: calc(var(--font-size-standard) * 1.2);
display: flex;
align-items: center;
justify-content: center;
}
.fvtt-ftl-nomad .robot-main .robot-skills {
background-color: var(--color-light-1);
display: flex;
flex-direction: column;
justify-content: space-evenly;
flex: 1;
}
.fvtt-ftl-nomad .robot-main .robot-skills .robot-skill {
display: flex;
align-items: center;
}
.fvtt-ftl-nomad .robot-main .robot-skills .robot-skill .icon-skill {
width: 24px;
height: 24px;
margin-right: 4px;
}
.fvtt-ftl-nomad .robot-main .robot-skills .robot-skill .rollable:hover,
.fvtt-ftl-nomad .robot-main .robot-skills .robot-skill .rollable:focus {
text-shadow: 0 0 8px var(--color-shadow-primary);
cursor: pointer;
}
.fvtt-ftl-nomad .robot-main .robot-skills .robot-skill .rollable {
min-width: 4.5rem;
max-width: 4.5rem;
}
.fvtt-ftl-nomad .robot-main .robot-skills .robot-skill .char-text {
margin-left: 0.5rem;
}
.fvtt-ftl-nomad .robot-main .robot-skills .robot-skill .d100 {
flex: 0;
max-width: 0.6rem;
}
.fvtt-ftl-nomad .robot-main .robot-skills .robot-skill .form-group {
flex: 0;
padding-left: 5px;
}
.fvtt-ftl-nomad .robot-main .robot-skills .robot-skill .form-group .form-fields {
font-size: 1.1rem;
flex: none;
width: 40px;
}
.fvtt-ftl-nomad .robot-main .robot-skill-play {
min-width: 225px;
}
.fvtt-ftl-nomad .robot-main .robot-skill-edit {
min-width: 225px;
}
.fvtt-ftl-nomad .robot-main .robot-pc-play {
min-width: 500px;
}
.fvtt-ftl-nomad .robot-main .robot-pc-edit {
min-width: 500px;
}
.fvtt-ftl-nomad .robot-description {
background-color: var(--color-light-1);
}
.fvtt-ftl-nomad .robot-description .text-center {
text-align: left;
align-content: center;
}
.fvtt-ftl-nomad .robot-description prose-mirror.inactive {
min-height: 40px;
}
.fvtt-ftl-nomad .robot-description prose-mirror.active {
min-height: 150px;
}
.fvtt-ftl-nomad .robot-description .field-label {
margin-left: 8px;
}
.fvtt-ftl-nomad .robot-description .robot-brain input {
min-width: 32rem;
max-width: 32rem;
}
.fvtt-ftl-nomad .robot-description .section-editor {
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 {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
}
.fvtt-ftl-nomad .robot-description .biodata label {
min-width: 3rem;
}
.fvtt-ftl-nomad .robot-description .biodata .feature {
display: flex;
align-items: center;
gap: 4px;
min-width: 18rem;
max-width: 18rem;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div {
background-color: var(--color-light-1);
display: grid;
grid-template-columns: 1fr;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div legend a {
font-size: calc(var(--font-size-standard) * 1.4);
padding-left: 5px;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div .weapons {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 4px;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div .weapons .weapon {
display: flex;
align-items: center;
gap: 4px;
min-width: 13rem;
max-width: 13srem;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div .weapons .weapon .rollable:hover,
.fvtt-ftl-nomad .tab.robot-equipment .main-div .weapons .weapon .rollable:focus {
text-shadow: 0 0 8px var(--color-shadow-primary);
cursor: pointer;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div .weapons .weapon .controls {
min-width: 2rem;
max-width: 2rem;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div .weapons .weapon .damage {
min-width: 5rem;
max-width: 5rem;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div .weapons .weapon .name {
min-width: 8rem;
max-width: 8rem;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div .weapons .weapon .item-img {
width: 32px;
height: 32px;
margin: 4px 0 0 0;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div .equipments {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 4px;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div .equipments .equipment {
display: flex;
align-items: center;
gap: 4px;
min-width: 13rem;
max-width: 13srem;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div .equipments .equipment .rollable:hover,
.fvtt-ftl-nomad .tab.robot-equipment .main-div .equipments .equipment .rollable:focus {
text-shadow: 0 0 8px var(--color-shadow-primary);
cursor: pointer;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div .equipments .equipment .controls {
min-width: 2rem;
max-width: 2rem;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div .equipments .equipment .damage {
min-width: 5rem;
max-width: 5rem;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div .equipments .equipment .name {
min-width: 8rem;
max-width: 8rem;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div .equipments .equipment .item-img {
width: 32px;
height: 32px;
margin: 4px 0 0 0;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div prose-mirror.inactive {
min-height: 40px;
}
.fvtt-ftl-nomad .tab.robot-equipment .main-div prose-mirror.active {
min-height: 150px;
}
.fvtt-ftl-nomad .starship-content {
font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1);
@@ -1268,9 +1754,6 @@ i.fvtt-ftl-nomad {
min-width: 5rem;
max-width: 5rem;
}
.fvtt-ftl-nomad .sheet-tabs {
background-color: var(--color-light-1);
}
.fvtt-ftl-nomad .starship-main {
background-color: var(--color-light-1);
display: flex;
@@ -1324,6 +1807,10 @@ i.fvtt-ftl-nomad {
text-shadow: 0 0 8px var(--color-shadow-primary);
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 {
margin-left: 0.2rem;
max-width: 7rem;
@@ -1335,6 +1822,11 @@ i.fvtt-ftl-nomad {
align-self: center;
gap: 4px;
}
.fvtt-ftl-nomad .starship-main .starship-pc .starship-right .capacity .flexrow-guns .starship-guns-label {
min-width: 7.4rem;
max-width: 7.4rem;
font-weight: bold;
}
.fvtt-ftl-nomad .starship-main .starship-pc .starship-right .capacity input {
max-width: 5rem;
}
@@ -1352,6 +1844,18 @@ i.fvtt-ftl-nomad {
.fvtt-ftl-nomad .starship-main .starship-pc .starship-right .cargo select {
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 {
display: flex;
flex-direction: column;
@@ -1408,6 +1912,15 @@ 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 .section-editor .editor {
min-height: 10rem;
}
.fvtt-ftl-nomad .starship-description .section-editor .editor-content {
min-height: 10rem;
}
.fvtt-ftl-nomad .starship-description .biodata {
display: grid;
grid-template-columns: repeat(2, 1fr);
@@ -1432,6 +1945,65 @@ i.fvtt-ftl-nomad {
font-size: calc(var(--font-size-standard) * 1.4);
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 {
display: grid;
grid-template-columns: repeat(2, 1fr);
@@ -1678,7 +2250,7 @@ i.fvtt-ftl-nomad {
background-color: var(--color-light-1);
display: flex;
flex-direction: column;
gap: 5px;
justify-content: space-evenly;
flex: 1;
}
.fvtt-ftl-nomad .creature-main .creature-skills .creature-skill {
@@ -1744,6 +2316,15 @@ i.fvtt-ftl-nomad {
.fvtt-ftl-nomad .creature-biography .rank input {
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 {
display: grid;
grid-template-columns: repeat(2, 1fr);

View File

@@ -31,12 +31,20 @@ 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,
vehicle: models.FTLNomadVehicle,
creature: models.FTLNomadCreature,
starship: models.FTLNomadStarship
starship: models.FTLNomadStarship,
robot: models.FTLNomadRobot
}
CONFIG.Item.documentClass = documents.FTLNomadItem
@@ -58,6 +66,7 @@ Hooks.once("init", function () {
foundry.documents.collections.Actors.registerSheet("fvtt-ftl-nomad", applications.FTLNomadVehicleSheet, { types: ["vehicle"], makeDefault: true })
foundry.documents.collections.Actors.registerSheet("fvtt-ftl-nomad", applications.FTLNomadCreatureSheet, { types: ["creature"], makeDefault: true })
foundry.documents.collections.Actors.registerSheet("fvtt-ftl-nomad", applications.FTLNomadStarshipSheet, { types: ["starship"], makeDefault: true })
foundry.documents.collections.Actors.registerSheet("fvtt-ftl-nomad", applications.FTLNomadRobotSheet, { types: ["robot"], makeDefault: true })
foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet)
foundry.documents.collections.Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadPsionicSheet, { types: ["psionic"], makeDefault: true })

View File

@@ -292,6 +292,90 @@
}
}
},
"Robot": {
"Size": {
"Tiny": "Tiny",
"Small": "Small",
"Medium": "Medium",
"Large": "Large",
"Huge": "Huge",
"Giant": "Giant",
"Titanic": "Titanic",
"Gargantuan": "Gargantuan"
},
"FIELDS": {
"enc": {
"label": "Enc",
"value": {
"label": "Enc Curr."
},
"max": {
"label": "Enc Max"
}
},
"brain": {
"label": "Brain"
},
"cost": {
"label": "Cost"
},
"techAge": {
"label": "Tech Age"
},
"damage": {
"label": "Damage"
},
"robotSize": {
"label": "Size"
},
"speed": {
"label": "Speed"
},
"durability": {
"label": "Durability"
},
"protection": {
"label": "Protection"
},
"characteristics:": {
"char": {
"label": "Charisma"
},
"con": {
"label": "Constitution"
},
"dex": {
"label": "Dexterity"
},
"int": {
"label": "Intelligence"
},
"pow": {
"label": "Power"
},
"str": {
"label": "Strength"
}
},
"damageBonus": {
"label": "Dmg.Bonus"
},
"resources": {
"hand": {
"label": "Hand"
},
"permanentRating": {
"label": "Permanent Rating"
},
"storage": {
"label": "Storage"
},
"stowed": {
"label": "Stowed"
}
}
}
},
"CreatureAbility": {
"FIELDS": {
"description": {
@@ -351,8 +435,11 @@
}
},
"Label": {
"robot": "Robot",
"techAge": "Tech Age",
"mainStats": "Main Stats",
"formula": "Formula",
"damages": "Damages",
"damages": "Damage",
"modifications": "Modifications",
"abilities": "Abilities",
"Details": "Details",
@@ -360,6 +447,7 @@
"capacity" : "Capacity",
"Agility" : "Agility",
"Armor": "Armor",
"ArmorCritical": "Armor Critical",
"cargo": "Cargo",
"vehicle": "Vehicle",
"starship": "Starship",
@@ -388,6 +476,7 @@
"Unarmed": "Unarmed",
"Vehicle": "Vehicle",
"armor": "Armor",
"armorCritical": "Armor (Crit.)",
"armors": "Armors",
"biodata": "Biodata",
"biography": "Biography",
@@ -408,6 +497,7 @@
"max": "Max",
"maximum": "Maximum",
"modifier": "Modifier",
"numericModifier": "Additionnal Modifier",
"multiplier": "Multiplier",
"newArmor": "New Armor",
"newWeapon": "New Weapon",
@@ -436,7 +526,12 @@
"titleWeapon": "Weapon Roll",
"total": "Total",
"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": {
"FIELDS": {
@@ -512,6 +607,9 @@
"Carrier": "Carrier"
},
"FIELDS": {
"techAge": {
"label": "Tech Age"
},
"monthlyCost": {
"label": "Monthly Cost"
},
@@ -519,7 +617,10 @@
"label": "Hull Type"
},
"armor": {
"label": "Armor"
"label": "Armor (Reg.)"
},
"armorCritical": {
"label": "Armor (Crit.)"
},
"guns" : {
"label": "Guns"
@@ -542,6 +643,12 @@
"crew": {
"label": "Crew"
},
"crewCapacity": {
"label": "Crew Capacity"
},
"npcCrew": {
"label": "NPC Skill"
},
"description": {
"label": "Description"
},
@@ -590,7 +697,7 @@
"addPsionic" : "Add Psionic",
"addCreatureAbility" : "Add Creature Ability",
"addCreatureTrait" : "Add Creature Trait",
"damages": "Enter current damages suffered"
"damages": "Enter current damage suffered"
},
"Vehicle": {
"FIELDS": {
@@ -616,20 +723,46 @@
"label": "Speed"
},
"armor": {
"label": "Armor"
"label": "Armor (Reg.)"
},
"armorCritical": {
"label": "Armor (Crit.)"
},
"crew": {
"label": "Crew"
},
"crewCapacity": {
"label": "Crew Capacity"
},
"npcCrew": {
"label": "NPC Skill"
},
"description": {
"label": "Description"
},
"notes": {
"label": "Notes"
},
"techAge": {
"label": "Tech Age"
}
}
},
"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": {
"FIELDS": {
"cost": {
@@ -687,7 +820,8 @@
"character": "Character",
"creature": "Creature",
"starship": "Starship",
"vehicle": "Vehicle"
"vehicle": "Vehicle",
"robot": "Robot"
},
"Item": {
"armor": "Armor",

View File

@@ -11,4 +11,4 @@ export { default as FTLNomadImplantSheet } from "./sheets/implant-sheet.mjs"
export { default as FTLNomadStarshipSheet } from "./sheets/starship-sheet.mjs"
export { default as FTLNomadCreatureTraitSheet } from "./sheets/creature-trait-sheet.mjs"
export { default as FTLNomadCreatureAbilitySheet } from "./sheets/creature-ability-sheet.mjs"
export { default as FTLNomadRobotSheet } from "./sheets/robot-sheet.mjs"

View File

@@ -0,0 +1,174 @@
import FTLNomadActorSheet from "./base-actor-sheet.mjs"
export default class FTLNomadRobotSheet extends FTLNomadActorSheet {
/** @override */
static DEFAULT_OPTIONS = {
classes: ["robot"],
position: {
width: 860,
height: 620,
},
window: {
contentClasses: ["robot-content"],
},
actions: {
createEquipment: FTLNomadRobotSheet.#onCreateEquipment,
createArmor: FTLNomadRobotSheet.#onCreateArmor,
createWeapon: FTLNomadRobotSheet.#onCreateWeapon,
createTalent: FTLNomadRobotSheet.#onCreateTalent,
createImplant: FTLNomadRobotSheet.#onCreateImplant,
createPsionic: FTLNomadRobotSheet.#onCreatePsionic,
createLanguage: FTLNomadRobotSheet.#onCreateLanguage
},
}
/** @override */
static PARTS = {
main: {
template: "systems/fvtt-ftl-nomad/templates/robot-main.hbs",
},
tabs: {
template: "templates/generic/tab-navigation.hbs",
},
equipment: {
template: "systems/fvtt-ftl-nomad/templates/robot-equipment.hbs",
},
description: {
template: "systems/fvtt-ftl-nomad/templates/robot-description.hbs",
},
}
/** @override */
tabGroups = {
sheet: "equipment",
}
/**
* Prepare an array of form header tabs.
* @returns {Record<string, Partial<ApplicationTab>>}
*/
#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)) {
v.active = this.tabGroups[v.group] === v.id
v.cssClass = v.active ? "active" : ""
}
return tabs
}
/** @override */
async _prepareContext() {
const context = await super._prepareContext()
context.tabs = this.#getTabs()
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 })
return context
}
/** @override */
async _preparePartContext(partId, context) {
const doc = this.document
switch (partId) {
case "equipment":
context.tab = context.tabs.equipment
context.weapons = doc.itemTypes.weapon
context.weapons.sort((a, b) => a.name.localeCompare(b.name))
context.armors = doc.itemTypes.armor
context.armors.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 })
context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(doc.system.notes, { async: true })
break
}
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" }])
}
static #onCreateArmor(event, target) {
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("FTLNOMAD.Label.newArmor"), type: "armor" }])
}
static #onCreateTalent(event, target) {
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("FTLNOMAD.Label.newTalent"), type: "talent" }])
}
static #onCreateImplant(event, target) {
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("FTLNOMAD.Label.newImplant"), type: "implant" }])
}
static #onCreatePsionic(event, target) {
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("FTLNOMAD.Label.newPsionic"), type: "psionic" }])
}
static #onCreateLanguage(event, target) {
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("FTLNOMAD.Label.newLanguage"), type: "language" }])
}
/**
* Handles the roll action triggered by user interaction.
*
* @param {PointerEvent} event The event object representing the user interaction.
* @param {HTMLElement} target The target element that triggered the roll.
*
* @returns {Promise<void>} A promise that resolves when the roll action is complete.
*
* @throws {Error} Throws an error if the roll type is not recognized.
*
* @description This method checks the current mode (edit or not) and determines the type of roll
* (save, resource, or damage) based on the target element's data attributes. It retrieves the
* corresponding value from the document's system and performs the roll.
*/
async _onRoll(event, target) {
const rollType = $(event.currentTarget).data("roll-type")
let item
let li
switch (rollType) {
case "skill":
let skillId = $(event.currentTarget).data("skill-id");
item = this.actor.system.skills[skillId];
break
case "weapon":
case "damage":
li = $(event.currentTarget).parents(".item");
item = this.actor.items.get(li.data("item-id"));
break
default:
throw new Error(`Unknown roll type ${rollType}`)
}
await this.document.system.roll(rollType, item)
}
async _onDrop(event) {
if (!this.isEditable || !this.isEditMode) return
const data = TextEditor.getDragEventData(event)
// Handle different data types
switch (data.type) {
case "Item":
const item = await fromUuid(data.uuid)
return super._onDropItem(item)
}
}
}

View File

@@ -14,9 +14,148 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
actions: {
createEquipment: FTLNomadStarshipSheet.#onCreateEquipment,
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 */
static PARTS = {
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.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
}
/**
* 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) {
}
@@ -128,7 +293,41 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
case "Item":
const item = await fromUuid(data.uuid)
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 = {
classes: ["vehicle"],
position: {
width: 680,
height: 540,
width: 720,
height: 640,
},
window: {
contentClasses: ["vehicle-content"],
@@ -14,9 +14,148 @@ export default class FTLNomadVehicleSheet extends FTLNomadActorSheet {
actions: {
createEquipment: FTLNomadVehicleSheet.#onCreateEquipment,
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 */
static PARTS = {
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.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
}
/**
* 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) {
}
@@ -128,7 +293,36 @@ export default class FTLNomadVehicleSheet extends FTLNomadActorSheet {
case "Item":
const item = await fromUuid(data.uuid)
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

@@ -41,6 +41,13 @@ export const TECH_AGES = {
"cosmic": { id: "cosmic", label: "FTLNOMAD.TechAge.Cosmic", level: 13 }
}
export const ROBOT_SIZES = {
"tiny": { id: "tiny", label: "FTLNOMAD.Robot.Size.Tiny" },
"small": { id: "small", label: "FTLNOMAD.Robot.Size.Small" },
"medium": { id: "medium", label: "FTLNOMAD.Robot.Size.Medium" },
"large": { id: "large", label: "FTLNOMAD.Robot.Size.Large" },
"giant": { id: "giant", label: "FTLNOMAD.Robot.Size.Giant" }
}
export const WEAPON_TYPES = {
"melee": { id: "melee", label: "FTLNOMAD.Weapon.Types.Melee" },
@@ -72,6 +79,16 @@ export const ATTACK_MODIFIERS = {
"aware": -1
}
export const DAMAGE_MODIFIER_CHOICES = [
{ id: "-3", label: "-3", value: "-3" },
{ id: "-2", label: "-2", value: "-2" },
{ id: "-1", label: "-1", value: "-1" },
{ id: "0", label: "0", value: "0" },
{ id: "1", label: "+1", value: "1" },
{ id: "2", label: "+2", value: "2" },
{ id: "3", label: "+3", value: "3" }
]
export const TRIAGE_RESULTS = {
"none": { id: "none", dice: 0, label: "FTLNOMAD.TriageResults.None" },
"death": { id: "death", dice: 3, label: "FTLNOMAD.TriageResults.Death" },
@@ -127,6 +144,20 @@ export const MODIFIER_CHOICES = {
"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 = {
"pod": { id: "pod", label: "FTLNOMAD.Starship.Hull.Pod" },
"micro": { id: "micro", label: "FTLNOMAD.Starship.Hull.Micro" },
@@ -146,6 +177,7 @@ export const STARSHIP_HULL = {
export const SYSTEM = {
id: SYSTEM_ID,
MODIFIER_CHOICES,
NUMERIC_MODIFIER_CHOICES,
ATTACK_MODIFIERS,
TECH_AGES,
WEAPON_TYPES,
@@ -156,5 +188,7 @@ export const SYSTEM = {
CREATURE_NICHES,
STARSHIP_HULL,
SKILLS,
ROBOT_SIZES,
DAMAGE_MODIFIER_CHOICES,
ASCII
}

View File

@@ -62,8 +62,15 @@ export default class FTLNomadRoll extends Roll {
static updateFullFormula(options) {
let fullFormula
if (options.rollType === "damage") {
fullFormula = `${options.formula} + ${options.damageModifier}D6 `
} else {
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 "-"
fullFormula = fullFormula.replace(/\+\s*-/g, "- ")
$('#roll-dialog-full-formula').text(fullFormula)
@@ -112,6 +119,7 @@ export default class FTLNomadRoll extends Roll {
})
const choiceModifier = SYSTEM.MODIFIER_CHOICES
const choiceNumericModifier = SYSTEM.NUMERIC_MODIFIER_CHOICES
let choiceRangeModifier = {}
let rangeModifier = 0
if (options.weapon) {
@@ -119,23 +127,41 @@ export default class FTLNomadRoll extends Roll {
let range = SYSTEM.WEAPON_RANGE[options.weapon.system.rangeType]
for (let [key, value] of Object.entries(range.range)) {
choiceRangeModifier[key] = { label: `${key} (${value}D)`, value: value }
if (!rangeModifier && value) {
rangeModifier = value
}
}
}
const choiceDamageModifier = SYSTEM.DAMAGE_MODIFIER_CHOICES
let damageModifier = "0"
let modifier = "0"
let numericModifierSelect = 0
options.skillModifier = 0
options.numericModifier = 0
options.numericModifierSelect = 0
options.rangeModifier = rangeModifier
options.damageModifier = damageModifier
options.vehicleBonus = options.vehicleBonus || 0
options.useVehicleBonus = true // Par défaut, le bonus est activé
let fullFormula = `${formula} + ${options.rollItem.value}`
if (options.isEncumbered) {
fullFormula += ` - 1D`
}
if (options.vehicleBonus && options.useVehicleBonus) {
fullFormula += ` + ${options.vehicleBonus}`
}
options.fullFormula = fullFormula
options.formula = formula
// Prepare available skills if provided (for vehicle/starship piloting)
let availableSkills = null
if (options.availableSkills) {
availableSkills = Object.entries(options.availableSkills).map(([id, skill]) => ({
id: id,
label: skill.label,
value: skill.value,
selected: id === options.selectedSkillId
}))
}
let dialogContext = {
actorId: options.actorId,
actorName: options.actorName,
@@ -148,11 +174,17 @@ export default class FTLNomadRoll extends Roll {
rollModes,
fieldRollMode,
choiceModifier,
choiceNumericModifier,
choiceRangeModifier,
choiceDamageModifier,
rangeModifier,
damageModifier,
formula,
hasTarget: options.hasTarget,
modifier,
numericModifierSelect,
vehicleBonus: options.vehicleBonus,
availableSkills: availableSkills,
}
const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-ftl-nomad/templates/roll-dialog.hbs", dialogContext)
@@ -167,7 +199,10 @@ export default class FTLNomadRoll extends Roll {
label: label,
callback: (event, button, dialog) => {
const output = Array.from(button.form.elements).reduce((obj, input) => {
if (input.name) obj[input.name] = input.value
if (input.name) {
// For checkboxes, use checked property instead of value
obj[input.name] = input.type === 'checkbox' ? input.checked : input.value
}
return obj
}, {})
return output
@@ -179,10 +214,26 @@ export default class FTLNomadRoll extends Roll {
rejectClose: false, // Click on Close button will not launch an error
render: (event, dialog) => {
FTLNomadRoll.updateFullFormula(options)
$(".roll-skill-selector").change(event => {
const skillId = event.target.value
if (options.availableSkills && options.availableSkills[skillId]) {
options.rollItem = foundry.utils.duplicate(options.availableSkills[skillId])
options.selectedSkillId = skillId
FTLNomadRoll.updateFullFormula(options)
}
})
$(".roll-skill-modifier").change(event => {
options.skillModifier = Number(event.target.value)
FTLNomadRoll.updateFullFormula(options)
})
$(".roll-numeric-modifier").change(event => {
options.numericModifierSelect = Number(event.target.value)
FTLNomadRoll.updateFullFormula(options)
})
$(".roll-damage-modifier").change(event => {
options.damageModifier = Number(event.target.value)
FTLNomadRoll.updateFullFormula(options)
})
$(".roll-skill-range-modifier").change(event => {
options.rangeModifier = Number(event.target.value)
FTLNomadRoll.updateFullFormula(options)
@@ -197,6 +248,10 @@ export default class FTLNomadRoll extends Roll {
}
FTLNomadRoll.updateFullFormula(options)
})
$(".use-vehicle-bonus").change(event => {
options.useVehicleBonus = event.target.checked
FTLNomadRoll.updateFullFormula(options)
})
}
})
@@ -210,11 +265,22 @@ export default class FTLNomadRoll extends Roll {
if (Hooks.call("fvtt-ftl-nomad.preRoll", options, rollData) === false) return
// Update rollItem if a skill was selected from the dropdown
if (rollData.selectedSkill && options.availableSkills) {
options.rollItem = foundry.utils.duplicate(options.availableSkills[rollData.selectedSkill])
}
options.numericModifier = Number(rollData.numericModifier) || 0
options.skillModifier = Number(rollData.skillModifier) || 0
options.rangeModifier = Number(rollData.rangeModifier) || 0
options.numericModifierSelect = Number(rollData.numericModifierSelect) || 0
options.useVehicleBonus = rollData.useVehicleBonus === true
options.finalModifier = options.numericModifier + options.skillModifier + options.rangeModifier
let mod = options.rollItem?.value || 0
mod += options.numericModifierSelect
if (options.useVehicleBonus) {
mod += options.vehicleBonus || 0
}
// Build the dice formula
let diceFormula = "2d6"
@@ -229,18 +295,23 @@ export default class FTLNomadRoll extends Roll {
// Replace the D6 by the correct number of D6
damageFormula = damageFormula.replace(/(\d*)d6/gi, (match, p1) => {
let numDice = Number(p1) || 1
numDice += Math.abs(options.skillModifier)
return `${numDice}d6`
let damageModifier = Number(options.damageModifier)
let postArg = ""
if (damageModifier && damageModifier !== 0) {
postArg = (damageModifier > 0) ? `kh${numDice}` : `kl${numDice}`
numDice += Math.abs(damageModifier)
}
return `${numDice}d6${postArg} + ${mod}`
})
diceFormula = damageFormula
} else {
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)

View File

@@ -11,4 +11,4 @@ export { default as FTLNomadImplant } from "./implant.mjs"
export { default as FTLNomadStarship } from "./starship.mjs"
export { default as FTLNomadCreatureTrait } from "./creature-trait.mjs"
export { default as FTLNomadCreatureAbility } from "./creature-ability.mjs"
export { default as FTLNomadRobot } from "./robot.mjs"

View File

@@ -77,10 +77,7 @@ export default class FTLNomadProtagonist extends foundry.abstract.TypeDataModel
prepareDerivedData() {
super.prepareDerivedData();
let encMax = 10 + (2*this.skills.physical.value)
if (encMax !== this.enc.max) {
this.enc.max = encMax
}
let encMax = this.enc.max // 10 + (2 * this.skills.physical.value)
let enc = 0
let armor = 0
for (let i of this.parent.items) {

94
module/models/robot.mjs Normal file
View File

@@ -0,0 +1,94 @@
import { SYSTEM } from "../config/system.mjs"
import FTLNomadRoll from "../documents/roll.mjs"
export default class FTLNomadRobot extends foundry.abstract.TypeDataModel {
static defineSchema() {
const fields = foundry.data.fields
const requiredInteger = { required: true, nullable: false, integer: true }
const schema = {}
schema.description = new fields.HTMLField({ required: true, textSearch: true })
schema.notes = new fields.HTMLField({ required: true, textSearch: true })
schema.name = new fields.StringField({ required: true, nullable: false, initial: "" })
schema.techAge = new fields.StringField({ required: true, choices: SYSTEM.TECH_AGES, initial: "lateatomic" })
schema.robotSize = new fields.StringField({ required: true, choices: SYSTEM.ROBOT_SIZES, initial: "medium" })
schema.durability = new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 })
schema.protection = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
schema.brain = new fields.StringField({ required: true, nullable: false, initial: "" })
schema.speed = new fields.StringField({ required: true, nullable: false, initial: "" })
// Carac
const skillField = (label) => {
const schema = {
value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 5 }),
label: new fields.StringField({ required: true, nullable: false, initial: label })
}
return new fields.SchemaField(schema, { label })
}
schema.skills = new fields.SchemaField(
Object.values(SYSTEM.SKILLS).reduce((obj, characteristic) => {
obj[characteristic.id] = skillField(characteristic.label)
return obj
}, {}),
)
schema.enc = new fields.SchemaField({
value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
max: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
})
schema.cost = new fields.StringField({ required: true, initial: "0" })
return schema
}
/** @override */
static LOCALIZATION_PREFIXES = ["FTLNOMAD.Robot"]
prepareDerivedData() {
super.prepareDerivedData();
let encMax = this.enc.max // this.durability + (2 * this.skills.physical.value)
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() {
return this.enc.value > this.enc.max
}
/** */
/**
* Rolls a dice for a character.
* @param {("save"|"resource|damage")} rollType The type of the roll.
* @param {number} rollItem The target value for the roll. Which caracteristic or resource. If the roll is a damage roll, this is the id of the item.
* @returns {Promise<null>} - A promise that resolves to null if the roll is cancelled.
*/
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
await roll.toMessage({}, { rollMode: roll.options.rollMode })
}
}

View File

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

View File

@@ -9,16 +9,19 @@ export default class FTLNomadVehicle extends foundry.abstract.TypeDataModel {
schema.agility = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
schema.armor = new fields.StringField({ required: true, initial: "" })
schema.armorCritical = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
schema.cargo = new fields.StringField({ required: true, initial: "" })
schema.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.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 })

Binary file not shown.

Binary file not shown.

View File

@@ -1 +1 @@
MANIFEST-000051
MANIFEST-000140

View File

@@ -1,7 +1,7 @@
2025/08/26-08:04:22.211637 7f99c9ffb6c0 Recovering log #48
2025/08/26-08:04:22.223370 7f99c9ffb6c0 Delete type=3 #46
2025/08/26-08:04:22.223498 7f99c9ffb6c0 Delete type=0 #48
2025/08/26-08:13:33.915174 7f99c8ff96c0 Level-0 table #54: started
2025/08/26-08:13:33.915296 7f99c8ff96c0 Level-0 table #54: 0 bytes OK
2025/08/26-08:13:33.948896 7f99c8ff96c0 Delete type=0 #52
2025/08/26-08:13:33.949217 7f99c8ff96c0 Manual compaction at level-0 from '!folders!AuBtSOj1mJmh88qx' @ 72057594037927935 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at (end)
2025/11/16-13:42:15.516505 7f47817fa6c0 Recovering log #138
2025/11/16-13:42:15.531915 7f47817fa6c0 Delete type=3 #136
2025/11/16-13:42:15.531986 7f47817fa6c0 Delete type=0 #138
2025/11/16-13:48:27.487704 7f4780bff6c0 Level-0 table #143: started
2025/11/16-13:48:27.487749 7f4780bff6c0 Level-0 table #143: 0 bytes OK
2025/11/16-13:48:27.494893 7f4780bff6c0 Delete type=0 #141
2025/11/16-13:48:27.501327 7f4780bff6c0 Manual compaction at level-0 from '!folders!AuBtSOj1mJmh88qx' @ 72057594037927935 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at (end)

View File

@@ -1,11 +1,7 @@
2025/08/25-21:48:36.909732 7f99c9ffb6c0 Delete type=3 #1
2025/08/25-21:56:45.440471 7f99c8ff96c0 Level-0 table #49: started
2025/08/25-21:56:45.440527 7f99c8ff96c0 Level-0 table #49: 0 bytes OK
2025/08/25-21:56:45.504826 7f99c8ff96c0 Delete type=0 #47
2025/08/25-21:56:45.558056 7f99c8ff96c0 Manual compaction at level-0 from '!folders!AuBtSOj1mJmh88qx' @ 72057594037927935 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at '!items!zv9dwgL3p7ThQn7j' @ 385 : 1
2025/08/25-21:56:45.558080 7f99c8ff96c0 Compacting 1@0 + 0@1 files
2025/08/25-21:56:45.590210 7f99c8ff96c0 Generated table #50@0: 285 keys, 111653 bytes
2025/08/25-21:56:45.590298 7f99c8ff96c0 Compacted 1@0 + 0@1 files => 111653 bytes
2025/08/25-21:56:45.648076 7f99c8ff96c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2025/08/25-21:56:45.648259 7f99c8ff96c0 Delete type=2 #44
2025/08/25-21:56:45.801444 7f99c8ff96c0 Manual compaction at level-0 from '!items!zv9dwgL3p7ThQn7j' @ 385 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at (end)
2025/11/15-21:57:15.481581 7f4781ffb6c0 Recovering log #134
2025/11/15-21:57:15.491519 7f4781ffb6c0 Delete type=3 #132
2025/11/15-21:57:15.491588 7f4781ffb6c0 Delete type=0 #134
2025/11/15-21:59:21.237179 7f4780bff6c0 Level-0 table #139: started
2025/11/15-21:59:21.237222 7f4780bff6c0 Level-0 table #139: 0 bytes OK
2025/11/15-21:59:21.302054 7f4780bff6c0 Delete type=0 #137
2025/11/15-21:59:21.450579 7f4780bff6c0 Manual compaction at level-0 from '!folders!AuBtSOj1mJmh88qx' @ 72057594037927935 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

Binary file not shown.

Binary file not shown.

View File

View File

@@ -1 +1 @@
MANIFEST-000029
MANIFEST-000118

View File

@@ -1,7 +1,7 @@
2025/08/26-08:04:22.229470 7f99caffd6c0 Recovering log #26
2025/08/26-08:04:22.240597 7f99caffd6c0 Delete type=3 #24
2025/08/26-08:04:22.240743 7f99caffd6c0 Delete type=0 #26
2025/08/26-08:13:33.840012 7f99c8ff96c0 Level-0 table #32: started
2025/08/26-08:13:33.840112 7f99c8ff96c0 Level-0 table #32: 0 bytes OK
2025/08/26-08:13:33.862575 7f99c8ff96c0 Delete type=0 #30
2025/08/26-08:13:33.949166 7f99c8ff96c0 Manual compaction at level-0 from '!actors!3pydTJsM73Z4o0V6' @ 72057594037927935 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at (end)
2025/11/16-13:42:15.536081 7f4781ffb6c0 Recovering log #116
2025/11/16-13:42:15.550548 7f4781ffb6c0 Delete type=3 #114
2025/11/16-13:42:15.550621 7f4781ffb6c0 Delete type=0 #116
2025/11/16-13:48:27.494999 7f4780bff6c0 Level-0 table #121: started
2025/11/16-13:48:27.495027 7f4780bff6c0 Level-0 table #121: 0 bytes OK
2025/11/16-13:48:27.501164 7f4780bff6c0 Delete type=0 #119
2025/11/16-13:48:27.501339 7f4780bff6c0 Manual compaction at level-0 from '!actors!0FQ6XaRi24OorI21' @ 72057594037927935 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at (end)

View File

@@ -1,11 +1,7 @@
2025/08/25-21:48:36.994202 7f99ca7fc6c0 Delete type=3 #1
2025/08/25-21:56:45.505125 7f99c8ff96c0 Level-0 table #27: started
2025/08/25-21:56:45.505238 7f99c8ff96c0 Level-0 table #27: 0 bytes OK
2025/08/25-21:56:45.557727 7f99c8ff96c0 Delete type=0 #25
2025/08/25-21:56:45.648499 7f99c8ff96c0 Manual compaction at level-0 from '!actors!3pydTJsM73Z4o0V6' @ 72057594037927935 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at '!folders!vRnrOJqSMlxbSgyX' @ 92 : 1
2025/08/25-21:56:45.648514 7f99c8ff96c0 Compacting 1@0 + 0@1 files
2025/08/25-21:56:45.676577 7f99c8ff96c0 Generated table #28@0: 51 keys, 49087 bytes
2025/08/25-21:56:45.676616 7f99c8ff96c0 Compacted 1@0 + 0@1 files => 49087 bytes
2025/08/25-21:56:45.736809 7f99c8ff96c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2025/08/25-21:56:45.736931 7f99c8ff96c0 Delete type=2 #22
2025/08/25-21:56:45.801488 7f99c8ff96c0 Manual compaction at level-0 from '!folders!vRnrOJqSMlxbSgyX' @ 92 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at (end)
2025/11/15-21:57:15.495359 7f47817fa6c0 Recovering log #112
2025/11/15-21:57:15.505936 7f47817fa6c0 Delete type=3 #110
2025/11/15-21:57:15.505987 7f47817fa6c0 Delete type=0 #112
2025/11/15-21:59:21.388865 7f4780bff6c0 Level-0 table #117: started
2025/11/15-21:59:21.388934 7f4780bff6c0 Level-0 table #117: 0 bytes OK
2025/11/15-21:59:21.450426 7f4780bff6c0 Delete type=0 #115
2025/11/15-21:59:21.450606 7f4780bff6c0 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

View File

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

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

View File

@@ -5,6 +5,7 @@
@import "mixins.less";
@import "character.less";
@import "vehicle.less";
@import "robot.less";
@import "starship.less";
@import "creature.less";
@import "weapon.less";

View File

@@ -1,7 +1,10 @@
:root {
--font-size-standard: 0.9rem;
--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");
--font-primary: "Atkinson";
--font-secondary: "Atkinson";
@@ -12,12 +15,14 @@
--color-warning: darkorange;
--color-critical-success: rgb(21, 39, 204);
--color-critical-failure: rgb(141, 32, 231);
/*--img-icon-color-filter: invert(60%) sepia(12%) saturate(6853%) hue-rotate(81deg) brightness(113%) contrast(104%);*/
}
body {
--color-text-secondary: rgb(22, 3, 3);
--color-text-emphatic: rgb(9, 97, 14);
--input-height: 1.6rem;
}
.d100 {
@@ -65,7 +70,7 @@ i.fvtt-ftl-nomad {
.application.dialog.fvtt-ftl-nomad {
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);
button:hover {
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.whisper {
font-family: var(--font-primary);

View File

@@ -61,7 +61,6 @@
font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1);
}
}
.vehicle-sheet-common {
@@ -78,8 +77,8 @@
label {
font-weight: bold;
margin-right: 8px;
min-width: 4rem;
max-width: 4rem;
min-width: 5rem;
max-width: 5rem;
}
}
}
@@ -103,6 +102,27 @@
}
}
}
.robot-sheet-common {
label {
font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1);
}
.form-group {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 4px;
label {
font-weight: bold;
margin-right: 8px;
min-width: 5rem;
max-width: 5rem;
}
}
}
.creature-sheet-common {
label {
font-family: var(--font-secondary);

339
styles/robot.less Normal file
View File

@@ -0,0 +1,339 @@
.robot-content {
.sheet-common();
.robot-sheet-common();
overflow: scroll;
}
.sheet-tabs {
background-color: var(--color-light-1);
}
.robot-main {
background-color: var(--color-light-1);
display: flex;
.robot-pc {
display: flex;
gap: 4px;
flex: 1;
.robot-left {
min-width: 180px;
max-width: 180px;
display: flex;
flex-direction: column;
.robot-left-image {
display: flex;
justify-content: center;
align-items: center;
padding-bottom: 8px;
.robot-img {
height: 140px;
width: auto;
border: none;
}
}
.robot-cost {
label {
min-width: 3rem;
max-width: 3rem;
}
input {
min-width: 6rem;
max-width: 6rem;
}
}
}
.robot-right {
display: flex;
flex-direction: column;
gap: 5px;
.robot-name {
display: flex;
input {
font-family: var(--font-title);
font-size: calc(var(--font-size-standard) * 1.4);
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 {
min-width: 25rem;
max-width: 25rem;
.encumbered {
color: red;
font-weight: bold;
}
}
.cargo,
.capacity {
label {
min-width: 4rem;
max-width: 4rem;
}
input {
max-width: 6rem;
margin-right: 0.5rem;
}
.cargo-content {
display: flex;
align-items: center;
gap: 4px;
}
}
.robot-infos {
display: flex;
flex-direction: column;
gap: 4px;
label {
min-width: 120px;
}
.robot-hp {
display: flex;
gap: 2px;
align-items: center;
.robot-hp-value {
.form-fields input {
flex: none;
width: 50px;
margin-left: 4px;
font-size: calc(var(--font-size-standard) * 1.4);
}
}
.robot-hp-max {
clear: both;
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 3px 0;
align-items: center;
input {
width: 50px;
text-align: center;
font-size: calc(var(--font-size-standard) * 1.4);
}
}
.hp-separator {
font-size: calc(var(--font-size-standard) * 1.2);
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
}
.robot-skills {
background-color: var(--color-light-1);
display: flex;
flex-direction: column;
justify-content: space-evenly;
flex: 1;
.robot-skill {
display: flex;
align-items: center;
.icon-skill {
width: 24px;
height: 24px;
margin-right: 4px;
}
.rollable:hover,
.rollable:focus {
text-shadow: 0 0 8px var(--color-shadow-primary);
cursor: pointer;
}
.rollable {
min-width: 4.5rem;
max-width: 4.5rem;
}
.char-text {
margin-left: 0.5rem;
}
.d100 {
flex: 0;
max-width: 0.6rem;
}
.form-group {
flex: 0;
padding-left: 5px;
.form-fields {
font-size: 1.1rem;
flex: none;
width: 40px;
}
}
}
}
.robot-skill-play {
min-width: 225px;
}
.robot-skill-edit {
min-width: 225px;
}
.robot-pc-play {
min-width: 500px;
}
.robot-pc-edit {
min-width: 500px;
}
}
.robot-description {
.text-center {
text-align: left;
align-content: center;
}
background-color: var(--color-light-1);
prose-mirror.inactive {
min-height: 40px;
}
prose-mirror.active {
min-height: 150px;
}
.field-label {
margin-left: 8px;
}
.robot-brain {
input {
min-width: 32rem;
max-width: 32rem;
}
}
.section-editor {
min-height: 10rem;
.editor {
min-height: 10rem;
}
.editor-content {
min-height: 10rem;
}
}
.biodata {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
label {
min-width: 3rem;
}
.feature {
display: flex;
align-items: center;
gap: 4px;
min-width: 18rem;
max-width: 18rem;
}
}
}
.tab.robot-equipment .main-div {
background-color: var(--color-light-1);
display: grid;
grid-template-columns: 1fr;
legend {
a {
font-size: calc(var(--font-size-standard) * 1.4);
padding-left: 5px;
}
}
.weapons {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 4px;
.weapon {
display: flex;
align-items: center;
gap: 4px;
min-width: 13rem;
max-width: 13srem;
.rollable:hover,
.rollable:focus {
text-shadow: 0 0 8px var(--color-shadow-primary);
cursor: pointer;
}
.controls {
min-width: 2rem;
max-width: 2rem;
}
.damage {
min-width: 5rem;
max-width: 5rem;
}
.name {
min-width: 8rem;
max-width: 8rem;
}
.item-img {
width: 32px;
height: 32px;
margin: 4px 0 0 0;
}
}
}
.equipments {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 4px;
.equipment {
display: flex;
align-items: center;
gap: 4px;
min-width: 13rem;
max-width: 13srem;
.rollable:hover,
.rollable:focus {
text-shadow: 0 0 8px var(--color-shadow-primary);
cursor: pointer;
}
.controls {
min-width: 2rem;
max-width: 2rem;
}
.damage {
min-width: 5rem;
max-width: 5rem;
}
.name {
min-width: 8rem;
max-width: 8rem;
}
.item-img {
width: 32px;
height: 32px;
margin: 4px 0 0 0;
}
}
}
prose-mirror.inactive {
min-height: 40px;
}
prose-mirror.active {
min-height: 150px;
}
}

View File

@@ -4,10 +4,6 @@
overflow: scroll;
}
.sheet-tabs {
background-color: var(--color-light-1);
}
.starship-main {
background-color: var(--color-light-1);
display: flex;
@@ -42,7 +38,6 @@
max-width: 4rem;
}
}
}
.starship-right {
@@ -69,6 +64,12 @@
text-shadow: 0 0 8px var(--color-shadow-primary);
cursor: pointer;
}
.hull-field {
select {
min-width: 10rem;
max-width: 10rem;
}
}
label {
margin-left: 0.2rem;
max-width: 7rem;
@@ -79,6 +80,11 @@
align-items: center;
align-self: center;
gap: 4px;
.starship-guns-label {
min-width: 7.4rem;
max-width: 7.4rem;
font-weight: bold;
}
}
input {
max-width: 5rem;
@@ -99,9 +105,19 @@
select {
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 {
display: flex;
@@ -169,13 +185,22 @@
margin-left: 8px;
}
.section-editor {
min-height: 10rem;
.editor {
min-height: 10rem;
}
.editor-content {
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;
@@ -185,7 +210,6 @@
max-width: 18rem;
}
}
}
.tab.starship-equipment {
@@ -198,6 +222,68 @@
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 {
display: grid;
grid-template-columns: repeat(2, 1fr);

View File

@@ -34,6 +34,14 @@
}
}
.spec {
label {
max-width: 4rem;
}
input {
max-width: 4rem;
}
}
}
.vehicle-right {
@@ -53,19 +61,35 @@
.cargo,
.capacity {
label {
min-width: 4rem;
max-width: 4rem;
max-width: 7rem;
}
input {
max-width: 6rem;
margin-right: 0.5rem;
}
.cargo-content {
display: flex;
flex-direction: column;
gap: 4px;
.cargo-line {
display: flex;
align-items: center;
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 {
display: flex;
@@ -137,13 +161,22 @@
margin-left: 8px;
}
.section-editor {
min-height: 10rem;
.editor {
min-height: 10rem;
}
.editor-content {
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;
@@ -153,7 +186,6 @@
max-width: 18rem;
}
}
}
.tab.vehicle-equipment .main-div {
@@ -166,6 +198,68 @@
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 {
display: grid;
grid-template-columns: repeat(2, 1fr);

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",
@@ -37,7 +37,8 @@
"character": { "htmlFields": ["description", "notes"] },
"creature": { "htmlFields": ["description", "notes"] },
"vehicle": { "htmlFields": ["description", "notes"] },
"starship": { "htmlFields": ["description", "notes"] }
"starship": { "htmlFields": ["description", "notes"] },
"robot": { "htmlFields": ["description", "notes"] }
},
"Item": {
"talent": { "htmlFields": ["description"] },

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

@@ -1,109 +1,265 @@
<section class="character-main character-main-{{ifThen isPlayMode 'play' 'edit'}}">
<section
class="character-main character-main-{{ifThen isPlayMode 'play' 'edit'}}"
>
{{!log "character-main" this}}
<fieldset>
<legend>{{localize "FTLNOMAD.Label.character"}}</legend>
<div class="character-pc character-pc-{{ifThen isPlayMode 'play' 'edit'}}">
<div class="character-left">
<div class="character-left-image">
<img class="character-img" src="{{actor.img}}" data-edit="img" data-action="editImage"
data-tooltip="{{actor.name}}" />
<img
class="character-img"
src="{{actor.img}}"
data-edit="img"
data-action="editImage"
data-tooltip="{{actor.name}}"
/>
</div>
<fieldset class="character-hp">
<legend>{{localize "FTLNOMAD.Label.Stamina"}}</legend>
<div class="flexrow">
{{formField systemFields.health.fields.staminaValue value=system.health.staminaValue}}
{{formField systemFields.health.fields.staminaMax value=system.health.staminaMax rootId=partId disabled=true}}
{{formField
systemFields.health.fields.staminaValue
value=system.health.staminaValue
}}
{{formField
systemFields.health.fields.staminaMax
value=system.health.staminaMax
rootId=partId
disabled=true
}}
</div>
<div class="flexrow">
{{formField systemFields.health.fields.wounds value=system.health.wounds }}
{{formField
systemFields.health.fields.wounds
value=system.health.wounds
}}
</div>
</fieldset>
</div>
<div class="character-right">
<div class="character-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="character-spec">
{{formField systemFields.concept value=system.concept rootId=partId disabled=isPlayMode}}
{{formField systemFields.species value=system.species rootId=partId disabled=isPlayMode}}
{{formField systemFields.archetype value=system.archetype rootId=partId disabled=isPlayMode}}
{{formField
systemFields.concept
value=system.concept
rootId=partId
disabled=isPlayMode
}}
{{formField
systemFields.species
value=system.species
rootId=partId
disabled=isPlayMode
}}
{{formField
systemFields.archetype
value=system.archetype
rootId=partId
disabled=isPlayMode
}}
<div class="hero-armor">
{{formField systemFields.heroPoints value=system.heroPoints rootId=partId }}
{{formField systemFields.armor.fields.value value=system.armor.value rootId=partId disabled=isPlayMode}}
{{formField
systemFields.heroPoints
value=system.heroPoints
rootId=partId
}}
{{formField
systemFields.armor.fields.value
value=system.armor.value
rootId=partId
disabled=isPlayMode
}}
</div>
</fieldset>
<fieldset class="encumbrance">
{{#if isEncumbered}}
{{formField systemFields.enc.fields.value value=system.enc.value rootId=partId disabled=true classes="encumbered"}}
{{formField
systemFields.enc.fields.value
value=system.enc.value
rootId=partId
disabled=true
classes="encumbered"
}}
{{else}}
{{formField systemFields.enc.fields.value value=system.enc.value rootId=partId disabled=true}}
{{formField
systemFields.enc.fields.value
value=system.enc.value
rootId=partId
disabled=true
}}
{{/if}}
{{formField systemFields.enc.fields.max value=system.enc.max rootId=partId disabled=isPlayMode}}
{{formField systemFields.credits value=system.credits rootId=partId }}
{{formField
systemFields.enc.fields.max
value=system.enc.max
rootId=partId
disabled=isPlayMode
}}
<span class="character-credit">
{{formField
systemFields.credits
value=system.credits
rootId=partId
disabled=isPlayMode
}}
</span>
</fieldset>
</div>
</div>
</fieldset>
<fieldset class="character-skills character-skills-{{ifThen isPlayMode 'play' 'edit'}}">
<fieldset
class="character-skills character-skills-{{ifThen
isPlayMode
'play'
'edit'
}}"
>
<legend>{{localize "FTLNOMAD.Label.skills"}}</legend>
<div class="character-skill">
<img src="systems/fvtt-ftl-nomad/assets/icons/icon_combat.svg" class="icon-skill" />
<label class="rollable" data-roll-type="skill" data-skill-id="combat">{{localize
"FTLNOMAD.Label.combat"}}</label>
{{formInput systemFields.skills.fields.combat.fields.value value=system.skills.combat.value rootId=partId disabled=isPlayMode type="number" }}
<img
src="systems/fvtt-ftl-nomad/assets/icons/icon_combat.svg"
class="icon-skill"
/>
<label
class="rollable"
data-roll-type="skill"
data-skill-id="combat"
>{{localize "FTLNOMAD.Label.combat"}}</label>
{{formInput
systemFields.skills.fields.combat.fields.value
value=system.skills.combat.value
rootId=partId
disabled=isPlayMode
type="number"
}}
</div>
<div class="character-skill">
<img src="systems/fvtt-ftl-nomad/assets/icons/icon_knowledge.svg" class="icon-skill" />
<label class="rollable" data-roll-type="skill" data-skill-id="knowledge">{{localize
"FTLNOMAD.Label.knowledge"}}</label>
{{formInput systemFields.skills.fields.knowledge.fields.value value=system.skills.knowledge.value
rootId=partId disabled=isPlayMode type="number"}}
<img
src="systems/fvtt-ftl-nomad/assets/icons/icon_knowledge.svg"
class="icon-skill"
/>
<label
class="rollable"
data-roll-type="skill"
data-skill-id="knowledge"
>{{localize "FTLNOMAD.Label.knowledge"}}</label>
{{formInput
systemFields.skills.fields.knowledge.fields.value
value=system.skills.knowledge.value
rootId=partId
disabled=isPlayMode
type="number"
}}
</div>
<div class="character-skill">
<img src="systems/fvtt-ftl-nomad/assets/icons/icon_social.svg" class="icon-skill" />
<label class="rollable" data-roll-type="skill" data-skill-id="social">{{localize
"FTLNOMAD.Label.social"}}</label>
{{formInput systemFields.skills.fields.social.fields.value value=system.skills.social.value
rootId=partId disabled=isPlayMode type="number"}}
<img
src="systems/fvtt-ftl-nomad/assets/icons/icon_social.svg"
class="icon-skill"
/>
<label
class="rollable"
data-roll-type="skill"
data-skill-id="social"
>{{localize "FTLNOMAD.Label.social"}}</label>
{{formInput
systemFields.skills.fields.social.fields.value
value=system.skills.social.value
rootId=partId
disabled=isPlayMode
type="number"
}}
</div>
<div class="character-skill">
<img src="systems/fvtt-ftl-nomad/assets/icons/icon_physical.svg" class="icon-skill" />
<label class="rollable" data-roll-type="skill" data-skill-id="physical">{{localize
"FTLNOMAD.Label.physical"}}</label>
{{formInput systemFields.skills.fields.physical.fields.value value=system.skills.physical.value
rootId=partId disabled=isPlayMode type="number"}}
<img
src="systems/fvtt-ftl-nomad/assets/icons/icon_physical.svg"
class="icon-skill"
/>
<label
class="rollable"
data-roll-type="skill"
data-skill-id="physical"
>{{localize "FTLNOMAD.Label.physical"}}</label>
{{formInput
systemFields.skills.fields.physical.fields.value
value=system.skills.physical.value
rootId=partId
disabled=isPlayMode
type="number"
}}
</div>
<div class="character-skill">
<img src="systems/fvtt-ftl-nomad/assets/icons/icon_stealth.svg" class="icon-skill" />
<label class="rollable" data-roll-type="skill" data-skill-id="stealth">{{localize
"FTLNOMAD.Label.stealth"}}</label>
{{formInput systemFields.skills.fields.stealth.fields.value value=system.skills.stealth.value
rootId=partId disabled=isPlayMode type="number"}}
<img
src="systems/fvtt-ftl-nomad/assets/icons/icon_stealth.svg"
class="icon-skill"
/>
<label
class="rollable"
data-roll-type="skill"
data-skill-id="stealth"
>{{localize "FTLNOMAD.Label.stealth"}}</label>
{{formInput
systemFields.skills.fields.stealth.fields.value
value=system.skills.stealth.value
rootId=partId
disabled=isPlayMode
type="number"
}}
</div>
<div class="character-skill">
<img src="systems/fvtt-ftl-nomad/assets/icons/icon_vehicles.svg" class="icon-skill" />
<label class="rollable" data-roll-type="skill" data-skill-id="vehicles">{{localize
"FTLNOMAD.Label.vehicles"}}</label>
{{formInput systemFields.skills.fields.vehicles.fields.value value=system.skills.vehicles.value
rootId=partId disabled=isPlayMode type="number"}}
<img
src="systems/fvtt-ftl-nomad/assets/icons/icon_vehicles.svg"
class="icon-skill"
/>
<label
class="rollable"
data-roll-type="skill"
data-skill-id="vehicles"
>{{localize "FTLNOMAD.Label.vehicles"}}</label>
{{formInput
systemFields.skills.fields.vehicles.fields.value
value=system.skills.vehicles.value
rootId=partId
disabled=isPlayMode
type="number"
}}
</div>
<div class="character-skill">
<img src="systems/fvtt-ftl-nomad/assets/icons/icon_technology.svg" class="icon-skill" />
<label class="rollable" data-roll-type="skill" data-skill-id="technology">{{localize
"FTLNOMAD.Label.technology"}}</label>
{{formInput systemFields.skills.fields.technology.fields.value value=system.skills.technology.value
rootId=partId disabled=isPlayMode type="number"}}
<img
src="systems/fvtt-ftl-nomad/assets/icons/icon_technology.svg"
class="icon-skill"
/>
<label
class="rollable"
data-roll-type="skill"
data-skill-id="technology"
>{{localize "FTLNOMAD.Label.technology"}}</label>
{{formInput
systemFields.skills.fields.technology.fields.value
value=system.skills.technology.value
rootId=partId
disabled=isPlayMode
type="number"
}}
</div>
</fieldset>
</section>

View File

@@ -11,29 +11,30 @@
<li><strong>{{localize "FTLNOMAD.Label.skillRoll"}}</strong></li>
{{/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>
<li><strong>Aspects : {{weapon.system.aspect}}</strong></li>
{{/if}}
{{/if}}
<li><strong>{{localize rollItem.label}} : {{fullFormula}}</strong></li>
{{#if (eq rollType "damage")}}
{{else}}
{{#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>
<li>{{localize "FTLNOMAD.Label.modifier"}}
:
{{skillModifier}}D
{{rangeModifier}}D
{{numericModifier}}D</li>
{{/if}}
{{#if (eq rollType "damage")}}
{{else}}
{{#if (eq rollType "damage")}}{{else}}
{{#if isSuccess}}
<li class="result-success">
{{localize "FTLNOMAD.Label.success"}}
@@ -54,8 +55,12 @@
{{#if isDamage}}
<div>
{{#if (and isGM hasTarget)}}
{{{localize "FTLNOMAD.Roll.displayArmor" targetName=targetName targetArmor=targetArmor
realDamage=realDamage}}}
{{{localize
"FTLNOMAD.Roll.displayArmor"
targetName=targetName
targetArmor=targetArmor
realDamage=realDamage
}}}
{{/if}}
</div>
{{/if}}

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">
<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>
</div>

View File

@@ -0,0 +1,53 @@
<section
class="tab robot-{{tab.id}} {{tab.cssClass}}"
data-tab="{{tab.id}}"
data-group="{{tab.group}}"
>
<fieldset>
<legend>Tech Age</legend>
<div class="flexrow">
{{formField
systemFields.techAge
value=system.techAge
localize=true
disabled=isPlayMode
}}
</div>
</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>
</div>
</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 class="section-editor">
<legend>{{localize "FTLNOMAD.Label.notes"}}</legend>
{{formInput
systemFields.notes
enriched=enrichedNotes
value=system.notes
name="system.notes"
toggled=true
}}
</fieldset>
</section>

View File

@@ -0,0 +1,108 @@
<section
class="tab robot-{{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}}"
/>
<i class="fa-regular fa-dice"></i>
<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>

258
templates/robot-main.hbs Normal file
View File

@@ -0,0 +1,258 @@
<section class="robot-main robot-main-{{ifThen isPlayMode 'play' 'edit'}}">
<fieldset>
<legend>{{localize "FTLNOMAD.Label.robot"}}</legend>
<div class="robot-pc robot-pc-{{ifThen isPlayMode 'play' 'edit'}}">
<div class="robot-left">
<div class="robot-left-image">
<img
class="robot-img"
src="{{actor.img}}"
data-edit="img"
data-action="editImage"
data-tooltip="{{actor.name}}"
/>
</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 class="robot-right">
<div class="robot-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"
>
<i class="fa-solid fa-user-{{ifThen isPlayMode 'lock' 'pen'}}"></i>
</a>
</div>
<fieldset class="main-stats">
<legend>{{localize "FTLNOMAD.Label.mainStats"}}</legend>
<div class="flexrow">
{{formField
systemFields.robotSize
value=system.robotSize
localize=true
disabled=isPlayMode
}}
&nbsp;
{{formField
systemFields.protection
value=system.protection
localize=true
disabled=isPlayMode
}}
</div>
<div class="flexrow">
{{formField
systemFields.speed
value=system.speed
localize=true
disabled=isPlayMode
}}
&nbsp;
{{formField
systemFields.durability
value=system.durability
localize=true
disabled=isPlayMode
}}
</div>
<div class="flexrow">
{{#if isEncumbered}}
{{formField
systemFields.enc.fields.value
value=system.enc.value
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
}}
</div>
</fieldset>
<fieldset class="robot-brain">
<legend>Brain</legend>
<div class="flexrow">
<textarea
cols="64"
rows="2"
name="system.brain"
data-tooltip="{{localize 'FTLNOMAD.Tooltip.brain'}}"
{{#if isPlayMode}}disabled{{/if}}>{{system.brain}}</textarea>
</div>
</fieldset>
</div>
<fieldset
class="robot-skills robot-skills-{{ifThen isPlayMode 'play' 'edit'}}"
>
<legend>{{localize "FTLNOMAD.Label.skills"}}</legend>
<div class="robot-skill">
<img
src="systems/fvtt-ftl-nomad/assets/icons/icon_combat.svg"
class="icon-skill"
/>
<label
class="rollable"
data-roll-type="skill"
data-skill-id="combat"
>{{localize "FTLNOMAD.Label.combat"}}</label>
{{formInput
systemFields.skills.fields.combat.fields.value
value=system.skills.combat.value
rootId=partId
disabled=isPlayMode
type="number"
}}
</div>
<div class="robot-skill">
<img
src="systems/fvtt-ftl-nomad/assets/icons/icon_knowledge.svg"
class="icon-skill"
/>
<label
class="rollable"
data-roll-type="skill"
data-skill-id="knowledge"
>{{localize "FTLNOMAD.Label.knowledge"}}</label>
{{formInput
systemFields.skills.fields.knowledge.fields.value
value=system.skills.knowledge.value
rootId=partId
disabled=isPlayMode
type="number"
}}
</div>
<div class="robot-skill">
<img
src="systems/fvtt-ftl-nomad/assets/icons/icon_social.svg"
class="icon-skill"
/>
<label
class="rollable"
data-roll-type="skill"
data-skill-id="social"
>{{localize "FTLNOMAD.Label.social"}}</label>
{{formInput
systemFields.skills.fields.social.fields.value
value=system.skills.social.value
rootId=partId
disabled=isPlayMode
type="number"
}}
</div>
<div class="robot-skill">
<img
src="systems/fvtt-ftl-nomad/assets/icons/icon_physical.svg"
class="icon-skill"
/>
<label
class="rollable"
data-roll-type="skill"
data-skill-id="physical"
>{{localize "FTLNOMAD.Label.physical"}}</label>
{{formInput
systemFields.skills.fields.physical.fields.value
value=system.skills.physical.value
rootId=partId
disabled=isPlayMode
type="number"
}}
</div>
<div class="robot-skill">
<img
src="systems/fvtt-ftl-nomad/assets/icons/icon_stealth.svg"
class="icon-skill"
/>
<label
class="rollable"
data-roll-type="skill"
data-skill-id="stealth"
>{{localize "FTLNOMAD.Label.stealth"}}</label>
{{formInput
systemFields.skills.fields.stealth.fields.value
value=system.skills.stealth.value
rootId=partId
disabled=isPlayMode
type="number"
}}
</div>
<div class="robot-skill">
<img
src="systems/fvtt-ftl-nomad/assets/icons/icon_vehicles.svg"
class="icon-skill"
/>
<label
class="rollable"
data-roll-type="skill"
data-skill-id="vehicles"
>{{localize "FTLNOMAD.Label.vehicles"}}</label>
{{formInput
systemFields.skills.fields.vehicles.fields.value
value=system.skills.vehicles.value
rootId=partId
disabled=isPlayMode
type="number"
}}
</div>
<div class="robot-skill">
<img
src="systems/fvtt-ftl-nomad/assets/icons/icon_technology.svg"
class="icon-skill"
/>
<label
class="rollable"
data-roll-type="skill"
data-skill-id="technology"
>{{localize "FTLNOMAD.Label.technology"}}</label>
{{formInput
systemFields.skills.fields.technology.fields.value
value=system.skills.technology.value
rootId=partId
disabled=isPlayMode
type="number"
}}
</div>
</fieldset>
</div>
</fieldset>
</section>

View File

@@ -10,7 +10,20 @@
<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 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}}
<div class="dialog-skill">{{localize rollItem.label}}
: 2d6+{{rollItem.value}}</div>
{{/if}}
{{/if}}
{{#if (eq rollType "weapon")}}
@@ -18,33 +31,108 @@
{{/if}}
{{#if isEncumbered}}
<div class="dialog-skill red-warning">Encumbered : -1D</div>
<div class="dialog-skill red-warning">Encumbered : -1D for Physical Attacks</div>
{{/if}}
</fieldSet>
<fieldSet class="dialog-modifier">
<legend>{{localize "FTLNOMAD.Label.modifier"}}</legend>
{{#if (eq rollType "damage")}}
<legend>Damage advantages/disadvantages</legend>
<select name="damageModifier" class="roll-damage-modifier">
{{selectOptions
choiceDamageModifier
selected=damageModifier
localize=true
}}
</select>
{{else}}
<legend>{{localize "FTLNOMAD.Label.modifier"}}</legend>
<select name="modifier" class="roll-skill-modifier">
{{selectOptions choiceModifier selected=modifier localize=true}}
</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 (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>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>
<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}}
@@ -52,7 +140,10 @@
<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,24 +1,78 @@
<section class="tab starship-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}">
<section
class="tab starship-{{tab.id}} {{tab.cssClass}}"
data-tab="{{tab.id}}"
data-group="{{tab.group}}"
>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.techAge"}}</legend>
<div class="flexrow">
{{formField
systemFields.techAge
value=system.techAge
localize=true
disabled=isPlayMode
}}
&nbsp;
{{formField
systemFields.cost
value=system.cost
localize=true
disabled=isPlayMode
}}
&nbsp;
{{formField
systemFields.monthlyCost
value=system.monthlyCost
localize=true
disabled=isPlayMode
}}
</div>
</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>
<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}}
{{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}}
{{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}}
{{formInput
systemFields.notes
enriched=enrichedNotes
value=system.notes
name="system.notes"
toggled=true
}}
</fieldset>
</section>

View File

@@ -1,50 +1,84 @@
<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}}"
>
<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>
<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 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>
<a
class="pilot-button"
data-tooltip="{{localize 'FTLNOMAD.PilotStarship'}}"
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>
<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}}
<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="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>
<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}}

View File

@@ -1,45 +1,102 @@
<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.agility
value=system.agility
localize=true
disabled=isPlayMode
}}
{{formField
systemFields.armor
value=system.armor
localize=true
disabled=isPlayMode
}}
{{formField
systemFields.armorCritical
value=system.armorCritical
localize=true
disabled=isPlayMode
}}
{{formField
systemFields.endurance
value=system.endurance
localize=true
disabled=isPlayMode
}}
</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">
<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}}
</div>
<div class="flexrow">
{{formField systemFields.travelMultiplier value=system.travelMultiplier localize=true}}
{{formField systemFields.monthlyCost value=system.monthlyCost localize=true}}
<div class="flexrow hull-field">
{{formField
systemFields.hullType
value=system.hullType
localize=true
disabled=isPlayMode
}}
</div>
<div class="flexrow-guns rollable" data-roll-type="starship-guns">
<i class="fa-regular fa-dice dice-2d6"></i>
{{formField systemFields.guns value=system.guns localize=true}}
<div class="flexrow-guns">
<a
class="rollable starship-guns-label"
data-roll-type="starship-guns"
>
<i class="fa-regular fa-dice dice-2d6"></i>Guns
</a>
{{formInput
systemFields.guns
value=system.guns
localize=true
disabled=isPlayMode
}}
{{formField
systemFields.travelMultiplier
value=system.travelMultiplier
localize=true
disabled=isPlayMode
}}
</div>
</fieldset>
@@ -47,8 +104,33 @@
<fieldset class="cargo">
<legend>{{localize "FTLNOMAD.Label.cargo"}}</legend>
<div class="flexrow">
{{formField systemFields.crew value=system.crew localize=true}}
{{formField systemFields.cargo value=system.cargo localize=true}}
{{formField
systemFields.crewCapacity
value=system.crewCapacity
localize=true
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
systemFields.cargo
value=system.cargo
localize=true
disabled=isPlayMode
}}
</div>
</fieldset>

View File

@@ -1,21 +1,67 @@
<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.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>
<legend>{{localize "FTLNOMAD.Label.techAge"}}</legend>
<div class="flexrow">
{{formField
systemFields.techAge
value=system.techAge
localize=true
disabled=isPlayMode
}}
&nbsp;
{{formField
systemFields.cost
value=system.cost
localize=true
disabled=isPlayMode
}}
&nbsp;
{{formField
systemFields.monthlyCost
value=system.monthlyCost
localize=true
disabled=isPlayMode
}}
</div>
</fieldset>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.description"}}</legend>
{{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}}
<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>
</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
}}
</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

@@ -1,26 +1,99 @@
<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}}"
>
<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>
<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}}
<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}}}">
<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"
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"}} :
<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>
<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}}
@@ -29,22 +102,41 @@
<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}}
<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="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>
<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}}

View File

@@ -5,23 +5,51 @@
<div class="vehicle-pc vehicle-pc-{{ifThen isPlayMode 'play' 'edit'}}">
<div class="vehicle-left">
<div class="vehicle-left-image">
<img class="vehicle-img" src="{{actor.img}}" data-edit="img" data-action="editImage"
data-tooltip="{{actor.name}}" />
</div>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.Agility"}}</legend>
<div class="flexrow">
{{formField systemFields.agility value=system.agility localize=true}}
<img
class="vehicle-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
disabled=isPlayMode
}}
{{formField
systemFields.armor
value=system.armor
localize=true
disabled=isPlayMode
}}
{{formField
systemFields.armorCritical
value=system.armorCritical
localize=true
disabled=isPlayMode
}}
</fieldset>
</div>
<div class="vehicle-right">
<div class="vehicle-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>
@@ -29,24 +57,69 @@
<fieldset class="capacity">
<legend>{{localize "FTLNOMAD.Label.capacity"}}</legend>
<div class="flexrow">
{{formField systemFields.armor value=system.armor localize=true}}
{{formField systemFields.force value=system.force localize=true}}
{{formField
systemFields.force
value=system.force
localize=true
disabled=isPlayMode
}}
</div>
<div class="flexrow">
{{formField systemFields.range value=system.range localize=true}}
{{formField systemFields.speed value=system.speed localize=true}}
{{formField
systemFields.range
value=system.range
localize=true
disabled=isPlayMode
}}
{{formField
systemFields.speed
value=system.speed
localize=true
disabled=isPlayMode
}}
</div>
</fieldset>
<fieldset class="cargo">
<legend>{{localize "FTLNOMAD.Label.cargo"}}</legend>
<div class="cargo-content">
{{formField systemFields.crew value=system.crew localize=true}}
{{formField systemFields.cargo value=system.cargo localize=true}}
{{formField systemFields.tonnage value=system.tonnage localize=true}}
<div class="cargo-line">
{{formField
systemFields.crewCapacity
value=system.crewCapacity
localize=true
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
systemFields.cargo
value=system.cargo
localize=true
disabled=isPlayMode
}}
{{formField
systemFields.tonnage
value=system.tonnage
localize=true
disabled=isPlayMode
}}
</div>
</div>
</fieldset>
</div>
</div>
</fieldset>