22 Commits
12.0.5 ... main

Author SHA1 Message Date
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
d80e3e4658 Fix roll options
All checks were successful
Release Creation / build (release) Successful in 1m8s
2025-08-26 22:14:45 +02:00
188501423a Add new roll options
All checks were successful
Release Creation / build (release) Successful in 1m24s
2025-08-25 22:41:42 +02:00
668da28d2c Fix various issues with rolls and compendiums
All checks were successful
Release Creation / build (release) Successful in 57s
2025-08-24 16:19:35 +02:00
8a5b402388 Fix v13 issue
All checks were successful
Release Creation / build (release) Successful in 2m15s
2025-08-20 18:43:53 +02:00
ebb3bd9fb3 Fix enc for equipments/weapons 2025-07-13 21:02:49 +02:00
d2cbe71731 Fix enc for equipments/weapons
All checks were successful
Release Creation / build (release) Successful in 1m34s
2025-07-13 19:30:28 +02:00
8197e3c369 Add vehicle compendium
All checks were successful
Release Creation / build (release) Successful in 48s
2025-07-01 16:02:34 +02:00
4b38dc0a1d Importers ready 2025-06-27 22:38:06 +02:00
0ce629ea49 Attempt to fix wrong tokens list
All checks were successful
Release Creation / build (release) Successful in 50s
2025-06-27 14:31:14 +02:00
a77d19fb04 Attempt to fix wrong tokens list 2025-06-27 14:31:07 +02:00
d9604d606a Add compendiums
All checks were successful
Release Creation / build (release) Successful in 55s
2025-06-26 22:29:38 +02:00
57eb9e76a4 Add compendiums
All checks were successful
Release Creation / build (release) Successful in 1m40s
2025-06-26 22:20:24 +02:00
b7dfc71335 Fix creature-trait + edit hero points
All checks were successful
Release Creation / build (release) Successful in 50s
2025-03-31 15:57:05 +02:00
38e01dad24 Minor fixes
All checks were successful
Release Creation / build (release) Successful in 1m27s
2025-03-30 16:23:16 +02:00
100 changed files with 6807 additions and 871 deletions

View File

@@ -1,6 +1,6 @@
name: Release Creation
on:
on:
release:
types: [published]
@@ -8,45 +8,45 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "💡 The ${{ gitea.repository }} repository will cloned to the runner."
#- uses: actions/checkout@v3
- uses: RouxAntoine/checkout@v3.5.4
- run: echo "💡 The ${{ gitea.repository }} repository will cloned to the runner."
# get part of the tag after the `v`
- name: Extract tag version number
id: get_version
uses: battila7/get-version-action@v2
#- uses: actions/checkout@v3
- uses: RouxAntoine/checkout@v3.5.4
# Substitute the Manifest and Download URLs in the module.json
- name: Substitute Manifest and Download Links For Versioned Ones
id: sub_manifest_link_version
uses: microsoft/variable-substitution@v1
with:
files: 'system.json'
env:
version: ${{steps.get_version.outputs.version-without-v}}
url: https://www.uberwald.me/gitea/${{gitea.repository}}
manifest: https://www.uberwald.me/gitea/uberwald/${{gitea.repository}}/releases/download/latest/system.json
download: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/fvtt-ftl-nomad-${{github.event.release.tag_name}}.zip
# Create a zip file with all files required by the module to add to the release
- run: |
apt update -y
apt install -y zip
# get part of the tag after the `v`
- name: Extract tag version number
id: get_version
uses: battila7/get-version-action@v2
- run: zip -r ./fvtt-ftl-nomad-${{github.event.release.tag_name}}.zip system.json README.md LICENSE assets/ css/ lang/ module/ packs-system/ templates/ fvtt-ftl-nomad.mjs
- name: setup go
uses: https://github.com/actions/setup-go@v4
with:
go-version: '>=1.20.1'
- name: Use Go Action
id: use-go-action
uses: https://gitea.com/actions/release-action@main
with:
files: |-
./fvtt-ftl-nomad-${{github.event.release.tag_name}}.zip
system.json
api_key: '${{secrets.ALLOW_PUSH_RELEASE}}'
# Substitute the Manifest and Download URLs in the module.json
- name: Substitute Manifest and Download Links For Versioned Ones
id: sub_manifest_link_version
uses: microsoft/variable-substitution@v1
with:
files: "system.json"
env:
version: ${{steps.get_version.outputs.version-without-v}}
url: https://www.uberwald.me/gitea/${{gitea.repository}}
manifest: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/latest/system.json
download: https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/fvtt-ftl-nomad-${{github.event.release.tag_name}}.zip
# Create a zip file with all files required by the module to add to the release
- run: |
apt update -y
apt install -y zip
- run: zip -r ./fvtt-ftl-nomad-${{github.event.release.tag_name}}.zip system.json README.md LICENSE assets/ css/ lang/ module/ packs/ packs-system/ templates/ fvtt-ftl-nomad.mjs
- name: setup go
uses: https://github.com/actions/setup-go@v4
with:
go-version: ">=1.20.1"
- name: Use Go Action
id: use-go-action
uses: https://gitea.com/actions/release-action@main
with:
files: |-
./fvtt-ftl-nomad-${{github.event.release.tag_name}}.zip
system.json
api_key: "${{secrets.ALLOW_PUSH_RELEASE}}"

View File

@@ -1,3 +1,14 @@
# fvtt-ftl-nomad
Faster Than Light: Nomad (FTL: Nomad) for Foundry Virtual TableTop
Faster Than Light : Nomad system for FoundryVTT
The official game system for playing Faster Than Light: Nomad on FoundryVTT. This framework covers all the fundemental aspects of Faster Than Light: Nomad and permits full FTL:N online gameplay.
This product's format, computer code, graphics, and presentation are copyrighted by Stellagama Publishing.
This system is used with permission granted as part of the partnership agreement between Foundry Gaming LLC and Stellagama Publishing. It uses the following copyright:
Faster Than Light: Nomad, © 2025 Stellagama Publishing. All rights reserved.
Stellagama Publishing's web page is available at https://stellagamapublishing.co/ and the company's owner, Omer Golan-Joel, may be contacted at golan2072@gmail.com.
Community
You are invited to join Stellagama Publishing's Discord server: https://discord.gg/MHpMDBpcZ6

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

@@ -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(11, 1, 1, 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 34 47.898 35.924 61.563 123.123-8.057 32.23-24.943-4.158 3.16-10.533 2.842-9.473L256 182.823l-91.463 18.29 6.002 20.006-24.943 4.156-8.057-32.228L199.1 69.926 247 34v56h-39l-16 32 64 38 64-38-16-32h-39zm188.313 169.258 30.3 10.101-13.478 29.205-30.016-5.001zm-394.626 0 13.194 34.304-30.016 5.002-13.478-29.205zM256 205.32l53.8 58.692L281.306 359h-50.61L202.2 264.012zm25.254.909 43.283 8.658-8.715 29.052zm-50.508.002-34.568 37.709-8.715-29.053zm105.5 32.267L482.5 262.873 429.799 368.28 329.98 259.385zm-160.492 0 6.266 20.887L82.2 368.279 29.5 262.873zm148.205 40.96 72.201 78.765-84.556-37.582zm-135.918 0 12.355 41.183-84.556 37.582zm118.348 58.564 28.646 12.732L312.973 439H265v-62h29.695zm-100.778 0L217.305 377H247v62h-47.973l-22.062-88.246zM387.6 374.115l18.105 8.047-9.984 21.635-16.387-8.193zm-263.2 0 8.266 21.489-16.387 8.193-9.984-21.635zM311 457v30h-30v-30zm-80 0v30h-30v-30z" fill="#7ed321" fill-opacity="1" filter="url(#shadow-1)" stroke="#ccc" stroke-opacity="1" stroke-width="8"></path></g></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

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(11, 1, 1, 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="M304 25c-9.496 0-17.002 7.504-17.002 17S294.504 59.002 304 59.002c9.496 0 17.002-7.506 17.002-17.002 0-9.496-7.506-17-17.002-17zm-9 50.809V201h-95.377l-13.314 79.885L256 294.822l69.691-13.937L313 204.738V75.808A34.63 34.63 0 0 1 304 77a34.63 34.63 0 0 1-9-1.191zM228.2 137l-38.557 46H277v-46zM55 179.402v139.405l-14.621 13.209 22.738 23.492 164.969-5.906-3.014-29.946-15.199-15.705-35.639-7.127-8.543-1.709 4.266-25.597-42.064-16.569L73 302.543v-123.14zm128.07 11.438-23.379 27.892 17.844 5.323zM329.123 192l5.342 32.055 17.844-5.323c-5.456-6.278-8.806-10.732-23.186-26.732zm54.984 60.95-42.064 16.568 4.266 25.597-44.182 8.836-15.2 15.705-3.013 29.946 164.969 5.906 22.738-23.492zm-265.744 28.687 48 48-12.726 12.726-48-48zm275.274 0 12.726 12.726-48 48-12.726-12.726zm-240.453 88.119-20.323.396-24.914 49.83L96 416l-32 32 48 16 32-32-18.805-6.268zm205.906.547 27.715 55.43L368 432l32 32 48-16-32-32-11.947 3.982-24.473-48.945z" fill="#7ed321" fill-opacity="1" stroke="#ccc" stroke-opacity="1" stroke-width="8" filter="url(#shadow-1)"></path></g></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,114 @@
[
{
"name": "Leather",
"protection": 2,
"cost": 50,
"enc": 1,
"techAge": "Early Primitive",
"description": "Made from Boiled animal hide or other non-metallic material, this armor can be worn as regular clothing. When facing firearms or other weapons from the Early Mechanical Eras or later, this armor provides 1 point of Protection [1]."
},
{
"name": "Chainmail",
"protection": 4,
"cost": 300,
"enc": 2,
"techAge": "Late Primitive",
"description": "Manufactured from rings of iron or primitive steel woven together. Typically, chainmail covers the upper body and hangs to the knees. When facing firearms or other weapons from the Early Mechanical Age or later, this armor provides 2 points of Protection [2]."
},
{
"name": "Plate Mail",
"protection": 6,
"cost": 1000,
"enc": 3,
"techAge": "Late Primitive",
"description": "A full suit of metal plated armor with a thick woven undergarment to reduce irritation. Plate mail is normally only worn by the wealthy nobles. When facing firearms or other weapons from the Early Mechanical Eras or later, this armor provides 2 points of Protection [3]."
},
{
"name": "Bulletproof Vest",
"protection": 4,
"cost": 150,
"enc": 1,
"techAge": "Early Atomic",
"description": "A lightweight ballistic armor for torso protection. Bulletproof vests are easy to wear under clothes and are quite concealable [3]."
},
{
"name": "Ceramic Plates",
"protection": 8,
"cost": 300,
"enc": 2,
"techAge": "Early Atomic",
"description": "Modern heavy-duty ballistic-cloth armor. Commonly worn by soldiers, well-equipped security, and Atomic Age mercenaries. Ceramic Plate counts as two Items for encumbrance purposes and is not concealable [4]."
},
{
"name": "Synthsilk Armor",
"protection": 7,
"cost": 6000,
"enc": 0,
"techAge": "Early Interstellar",
"description": "This advanced personal armor is bio-engineered from spider silk. Synthsilk is easily concealable and does not count as an item for Encumbrance [5]."
},
{
"name": "Energy Shield",
"protection": 0,
"cost": 20000,
"enc": 1,
"techAge": "Late Galactic",
"description": "This high-energy emitter is worn on a belt clip. The energy shield is capable of stopping massive amounts of damage and may be worn with other armor. An energy shield completely negates the first hit it receives in combat but is then depleted. Roll 1d6 every following combat round; on a result of 4-6, the shield regenerates on the wearers turn, and may negate another hit afterwards [6]."
},
{
"name": "Envirosuit",
"protection": 4,
"cost": 700,
"enc": 2,
"techAge": "Early Atomic",
"description": "A full body sealed suit with attached filters and ports to attach oxygen tanks as well. The Envirosuit fully protects against airborne toxins and pathogens. An Envirosuit will absorb the first 20 rads of radiation exposure [6]."
},
{
"name": "Spacesuit",
"protection": 6,
"cost": 2000,
"enc": 2,
"techAge": "Early Space",
"description": "This is a standard space suit, much lighter and cheaper than a 20th Century Terran space suit. A space suit carries life support supplies for up to 6 hours. It protects against Vacuum, Tainted, and Exotic atmospheres, as well as airborne pathogens. Absorbs 60 rads [7]."
},
{
"name": "Spacesuit, Advanced",
"protection": 6,
"cost": 4000,
"enc": 0,
"techAge": "Early Interstellar",
"description": "This represents the final evolution of the space suit. An advanced space suit does not count as an item for encumbrance and provides life support for 12 hours. It offers the same protection as a regular space suit [7]."
},
{
"name": "Spacesuit, Hostile Environment",
"protection": 10,
"cost": 10000,
"enc": 3,
"techAge": "Late Space",
"description": "A heavy-duty and reinforced space suit designed for extreme conditions. It protects against vacuum and corrosive atmospheres, as well as airborne pathogens and toxins, and provides 2d6 hours of protection from highly corrosive atmospheres. The Hostile Environment space suit carries life support supplies for 6 hours and absorbs 150 rads worth of radiation [5]."
},
{
"name": "Envirosuit, Advanced",
"protection": 6,
"cost": 5000,
"enc": 0,
"techAge": "Early Interstellar",
"description": "This is a much higher-tech version of the Enrivosuit, and works the same way, but is ultra-light. It can absorb 40 rads worth of radiation [8]."
},
{
"name": "Encased Armor",
"protection": 10,
"cost": 10000,
"enc": 2,
"techAge": "Late Space",
"description": "A suit of heavy, full body rigid armor, often used by corporate SWAT and high-end mercenaries. The suit offers environmental protection as an Envirosuit (see below) and includes integrated comms and a Heads-Up Display [4]."
},
{
"name": "Powered Armor",
"protection": 14,
"cost": 200000,
"enc": 0,
"techAge": "Late Interstellar",
"description": "This is servo-assisted, fully enclosed, combat armor. This powerful armor grants +3D to all Physical checks related to brute strength and doubles the wearers normal Encumbrance limits. Powered armor grants +1D to all melee damage done by its wearer. It also removes the Bulky aspect from any weapons the wearer is using. Powered Armor protects against vacuum and hostile environments, as a space suit, with 6 hours of life support, and absorbs 50 rads of radiation. Powered armor does not count as an item for encumbrance when worn. It counts as 3 encumbrance items when carried [8]."
}
]

View File

@@ -0,0 +1,38 @@
[
{
"name": "Antirad",
"tech_age": "Early Space",
"cost": 1000,
"description": "Administering this drug before exposure to radiation will prevent the accumulation of rads for 1d6 hours. After being exposed to radiation, it removes 2d6 rads [1]."
},
{
"name": "Fast Forward",
"tech_age": "Early Space",
"cost": 200,
"description": "This emergency life support drug dramatically slows the subjects metabolism; this drastically reduces life support costs and can keep a subject alive for 1d6 days without the use of any cryogenic medical technology [2]."
},
{
"name": "Hyper",
"tech_age": "Early Space",
"cost": 50,
"description": "A dangerous drug that allows a person to go 72 hours without sleep at full alertness and functionality. The subject ignores Fatigue for the full duration. Afterwards, the subject must sleep for 24 hours. Another dose of Hyperspace before the 24 hours is up forces a roll on the Wound Triage Table [2]."
},
{
"name": "Ice",
"tech_age": "Early Space",
"cost": 20,
"description": "A combat drug used by many professional mercenaries; Ice gives a +2D bonus to all morale checks. It is rumored that prolonged use of Ice will result in lack of empathy and sociopathic behavior. Ice manufacturers vehemently deny such calumnies [3]."
},
{
"name": "Panacea",
"tech_age": "Late Space",
"cost": 50,
"description": "When using this drug, roll Knowledge 8+ to cure most diseases or poisons. This drug does not work on tailored viruses or biological weapons [3]."
},
{
"name": "SlowMo",
"tech_age": "Late Space",
"cost": 300,
"description": "This drug will heal one Wound in 10 minutes. This metabolic accelerator can only be used safely once per week. It gets its name because those who take it spend ten minutes watching the world go by very, very slowly. If it is used more than once per week, roll on the Wound Triage Table with a -2D penalty [3]."
}
]

View File

@@ -0,0 +1,320 @@
[
{
"name": "Artificial Gill",
"tech_age": "Early Space",
"cost": 4000,
"description": "This device allows unlimited underwater activity on worlds with otherwise breathable atmospheres."
},
{
"name": "Auto Doc",
"tech_age": "Early Interstellar",
"cost": 10000,
"description": "A large device normally carried in a vehicle or space craft, the Auto Doc uses advanced AI and sensors to heal almost any disease, poison, or injury. The Auto Doc provides a +1D advantage on any Triage rolls or any roll to resist poisons or diseases. It can serve as a qualified nurse or doctor for the purposes of supervising healing from Wounds."
},
{
"name": "Autokitchen",
"tech_age": "Early Interstellar",
"cost": 10000,
"description": "An automated kitchen which can store and prepare meals. The standard kitchen can prepare 25 meals from internal supplies. The mass of the kitchen is 100 kg. Resupply costs depend on the quality of ingredients desired and can be determined using the Cost-of-Living table above."
},
{
"name": "Autokitchen, Emergency",
"tech_age": "Early Interstellar",
"cost": 5000,
"description": "A smaller and much more restrictive version of an autokitchen, this emergency kitchen provides no-frills survival food for 10 meals. This unit weighs 5kg, or two items of Encumbrance."
},
{
"name": "Backpack",
"tech_age": "Early Primitive",
"cost": 10,
"description": "A backpack does not count as an item for encumbrance when worn. The items in the backpack still count towards encumbrance. It takes one Action to remove an item from a backpack while in combat."
},
{
"name": "Binoculars",
"tech_age": "Early Mechanical",
"cost": 50,
"description": "A standard piece of survival and exploration equipment. At the Early Mechanical Age, they are ruggedized for extended wilderness use, and come equipped with a compass and scaled optics. Beyond the Late Atomic Age, hand-held binoculars become integrated into high-tech optical sensors like the Night Visor."
},
{
"name": "Bioscanner",
"tech_age": "Early Interstellar",
"cost": 5000,
"description": "This handheld device provides data on an organic bodys composition, chemistry, physiology, and life signs. A Knowledge roll is required to properly interpret the data."
},
{
"name": "Breather Mask",
"tech_age": "Late Mechanical",
"cost": 100,
"description": "A dual-purpose gas/filter mask apparatus that condenses thin atmospheres for comfortable breathing. It also filters out tainted atmospheres and provides protection against airborne toxins. Attachments for oxygen bottles make the Breather useful for operating in oxygen-poor or poisonous atmospheres."
},
{
"name": "Chameleon Suit",
"tech_age": "Late Interstellar",
"cost": 2500,
"description": "This full body suit can shift its color patterns to blend in with the surroundings. It does not make a wearer invisible, but at medium and long ranges the wearer will be almost impossible to see and gains +2D to Stealth tests. It includes infra-red cloaking. The same technology can be applied to an Encased Armor Suit for an additional cost of 10000 Credits."
},
{
"name": "Cold Weather Clothing",
"tech_age": "Early Primitive",
"cost": 50,
"description": "These protect against inclement weather. When wearing Cold Weather Clothing, characters can survive in Arctic environments without taking any damage. The Early Interstellar Age version costs 800 Credits and does not count as an item for encumbrance. Note that surviving in a harsher environment, like one that is far colder than a typical arctic climate, may require additional protection, like a space suit."
},
{
"name": "Compass",
"tech_age": "Early Mechanical",
"cost": 10,
"description": "This is a standard piece of equipment in all wilderness survival kits. By the Early Space Age, they incorporate gyroscopic and electronic features that make them usable on any world, given a few minutes of calibration."
},
{
"name": "Desert Suit",
"tech_age": "Later Space",
"cost": 1000,
"description": "An all-in-one suit that traps the bodies moisture and recycles it as drinking water. It includes a hood, breather mask, and goggles."
},
{
"name": "Disguise Kit",
"tech_age": "Early Mechanical",
"cost": 500,
"description": "This kit consists of highly personalized collections of makeup, clothing, wigs, and other accouterments that allow a skilled user to not be recognized, or even pass as someone else. At more advanced Tech Ages, Disguise Kits may include 3-D printed latex masks (Late Atomic Age), retina scanner spoofers (Early Space Age), or even holographic enhancements designed to spoof facial recognition algorithms (Early Interstellar Age). Increase the kits price by 100% for each of these listed features."
},
{
"name": "Emergency Beacon",
"tech_age": "Early Space",
"cost": 1000,
"description": "A portable device that can be activated and will transmit an emergency signal up to a 1000 km. The device has an internal battery that will last for 48 hours. Most vehicles at Late Space Age and above include one automatically, but this portable version can be easily carried along with other survival supplies."
},
{
"name": "Exoskeleton",
"tech_age": "Early Space",
"cost": 20000,
"description": "This marvel of robotics grants wearers +2D to athletics-related Physical checks. It also allows the wearer to jump up to 2m vertically or 5m horizontally. Soldiers wearing exoskeletons may march their normal cross-country speed while tiring at half the rate. The exoskeletons batteries are good for 48 hours of activity before requiring replacement. At higher tech levels, exoskeletons are often replaced by cybernetics."
},
{
"name": "Field Radio",
"tech_age": "Late Mechanical",
"cost": 100,
"description": "A radio transmitter and receiver with a 100 km range. At the Late Mechanical Age is counts as 2 items of Encumbrance, reduced to 1 item at Early Atomic, and 0 encumbrance at the Late Atomic Age."
},
{
"name": "Field Rations",
"tech_age": "Late Primitive",
"cost": 5,
"description": "These are foodstuffs specially prepared to stay edible for 6 months. Each ration counts as a single item for encumbrance. Early Space Age field rations are much lighter: 25 field rations count as one item, and they last for 6 decades."
},
{
"name": "Glidesuit",
"tech_age": "Early Space",
"cost": 500,
"description": "A form-fitting suit that includes adjustable wings that allow the wearer to glide. Flapping provides limited flight. The Glidesuit reduces a persons falling rate in half. Roll Physical to avoid injury when landing. Wearers use their Physical skill to make complex maneuvers."
},
{
"name": "Handcuffs",
"tech_age": "Early Mechanical",
"cost": 50,
"description": "An item commonly used by bounty hunters and law enforcement officers. Escaping properly applied handcuffs requires a Physical roll at -3D. Palming the key and keeping it hidden until the right time is a standard Stealth roll."
},
{
"name": "Hotsuit",
"tech_age": "Early Space",
"cost": 200,
"description": "A reflective suit designed to protect the wearer from temperatures up to 100 degrees centigrade. The suit is clumsy and imposes a -1D disadvantage on all physical activity while wearing it. At Early Interstellar Age, the suit is form-fitting and is not clumsy to wear and does not count as an item of encumbrance."
},
{
"name": "Intelligent Rooms",
"tech_age": "Late Space",
"cost": "Double Cost",
"description": "Fully integrated rooms, houses, or apartments with voice activated commands controlling lighting, heating, and general appearance controlled by an Independent robotic brain. Smartwalls provide 3-D entertainment. At Early Interstellar Age, Low Simulated AI rooms are expected even at the subsistence quality of living and are included in the listed prices."
},
{
"name": "LED Flashlight",
"tech_age": "Late Atomic",
"cost": 5,
"description": "A hand-held, rubberized, sturdy light source with a variable light aperture. The 2m cone of light has a range of 50m, but it can be adjusted to illuminate a 5m radius. Smaller, more expensive (20 Credits) versions can be mounted on weapons or clipped to armor. A Late Atomic Age LED Flashlights battery will last for 24 hours. By Early Interstellar Age, the battery will last for a decade of continual use."
},
{
"name": "Lockpicks",
"tech_age": "Late Primitive",
"cost": 50,
"description": "A collection of specialized tools for opening locks, in a handy carrying pouch. Attempting to pick a lock without lockpicks penalizes the attempt by -2D."
},
{
"name": "Map Box",
"tech_age": "Late Space",
"cost": 3000,
"description": "Designed for wilderness exploration, this self-contained nav-computer system provides scalable maps of a worlds surface based on known data and any additional data obtained by the exploration team. Most inhabited worlds have detailed map drives which can be inserted and provide up to street-level details of any explored area and high-level maps of the entire surface. Map boxes count as 2 items of Encumbrance. At Early Interstellar, it is 1 item."
},
{
"name": "Medkit",
"tech_age": "Early Mechanical",
"cost": 100,
"description": "This is standard issue in all survival kits and can be found in ships lockers across known space. Medkits contain all the necessary equipment and compounds to deal with minor trauma and easily treatable emergencies."
},
{
"name": "Medkit, Advanced",
"tech_age": "Early Space",
"cost": 1000,
"description": "Containing advanced scanners and additional medications, the advanced version of the medical kit provides a +1D advantage when rolling on the Triage table."
},
{
"name": "Multiscanner",
"tech_age": "Late Space",
"cost": 2500,
"description": "This hand-held sensor suite is a combination of several functions: it can detect radiation, electromagnetic emissions, metals, and a limited set of chemicals and biological compounds. It can also perform standard blood tests. A Knowledge roll is required to make real use of the data, but basic analysis is possible with the use of on-board software."
},
{
"name": "Night Visor",
"tech_age": "Late Atomic",
"cost": 300,
"description": "This stylish set of eye wear combines low-light and infra-red vision goggles into one handy device. Safety features prevent blindness if the light level suddenly changes. Wearing a Night Visor eliminates the disadvantages of working in dim light and reduces the penalty for total darkness to -1D."
},
{
"name": "OmniComm",
"tech_age": "Early Space",
"cost": 50,
"description": "Todays smartphones will eventually evolve into the OmniComm, which handles all your telecom needs in one device, with holographic augmented reality capability. The OmniComm can automatically integrate with whatever telecommunication networks are present on a given world. Batteries last for a few days in the Early Space Age. By Early Interstellar, batteries will last for months, if not years."
},
{
"name": "OmniComp",
"tech_age": "Early Space",
"cost": 250,
"description": "A hand-held, light-weight computer which evolved from both the laptop and the tablet computer. It functions much like an OmniComm but is intended for more advanced content production and computing tasks. Early Space Age batteries for these devices last for a few days; Early Interstellar Age batteries last for months between recharging."
},
{
"name": "Omnitool",
"tech_age": "Late Space",
"cost": 500,
"description": "An auto-adjusting, auto-fitting repair tool. The Omnitool will fit exactly to any kind of bolt, screw or fastening device, it doubles as wire-cutters, small hacksaw, flashlight, and a myriad of other tools. All this is packed into one items worth of encumbrance!"
},
{
"name": "Oxygen Tank",
"tech_age": "Late Mechanical",
"cost": 100,
"description": "An oxygen tank that can be attached to a space suit or breather mask to provide 90 minutes of breathable air. Each tank is 2 items of encumbrance. At the Late Space Age, the tanks are only 1 item of encumbrance."
},
{
"name": "Personal Reentry Capsule",
"tech_age": "Late Space",
"cost": 15000,
"description": "Used as a last-ditch survival tool, the personal capsule allows for reentry into an atmosphere and a relatively safe landing on a worlds surface. The capsule includes a primitive autopilot and a small reentry thruster to make a soft landing. The occupant has no control over the capsule. The autopilot will attempt to land on flat, dry land if possible. All uses must make a Physical check at +1D to avoid 2d6 damage upon landing."
},
{
"name": "Personal HUD",
"tech_age": "Early Interstellar",
"cost": 1500,
"description": "A personal Heads-Up-Display (HUD) can be fitted to any pair of goggles or a helmet visor. At the Late Interstellar Age, it can be fitted as a contact lens. The HUD interfaces with an OmniComp displaying information and messages. The HUD can also be synched to any Smart Gun system (see the Weapons Accessories section)."
},
{
"name": "Portable Fusion Generator",
"tech_age": "Early Interstellar",
"cost": 20000,
"description": "A marvel of interstellar technology, and a crucial piece of equipment for colonies across the galaxy. Fusion generators are also very useful for mercenary outfits that rely on energy weapons. These generators are small (20kg, roughly 2 Encumbrance), rugged, and designed to last for decades."
},
{
"name": "Portable Generators",
"tech_age": "Late Mechanical",
"cost": 1000,
"description": "A ubiquitous device still used across the galaxy to generate electricity far away from central power grids. Most runoff refined hydrocarbons that can be sourced locally. This one is 15kg and consumes 4 liters of fuel per hour. Higher tech level versions are smaller and more fuel efficient."
},
{
"name": "Prefab Space Base",
"tech_age": "Early Space",
"cost": 50000,
"description": "This is a pressurized, modular, temporary structure that is capable of housing 6 persons. It has a single airlock and requires 12 person-hours to assemble. Life support lasts for 24 hours without a portable generator to power atmoscrubbers."
},
{
"name": "Pressure Tent",
"tech_age": "Early Space",
"cost": 5000,
"description": "This basic survival shelter lacks an airlock and must be depressurized to enter or leave; it can house up to 2 people and requires an external oxygen tank."
},
{
"name": "Radiation Detector",
"tech_age": "Early Atomic",
"cost": 150,
"description": "A matchbox sized device that displays radiation levels in a 10m radius. It also indicates the type of radiation if that is important. The detector can also serve as an alarm, chiming loudly when radiation levels are dangerous to humans. This feature can be shut off."
},
{
"name": "Responsive Clothes",
"tech_age": "Late Space",
"cost": 200,
"description": "Clothing that can adapt to a wearer, fitting them perfectly. The clothing is self-cleaning and can change color and pattern within limits. Not quite one-size-fits-all, but almost."
},
{
"name": "Rope",
"tech_age": "Early Primitive",
"cost": 5,
"description": "At the Early Primitive Age, rope can hold 50kg. By the Late Atomic Age, the rope is fully synthetic, and can support 500kg of mass before breaking. Roughly 100m of rope is the equivalent of one encumbrance item."
},
{
"name": "Rope, Advanced",
"tech_age": "Early Interstellar",
"cost": 10,
"description": "This synthetic rope is incredibly light and strong. 10m of this rope can support 1000 kg before breaking."
},
{
"name": "Sensor Gloves",
"tech_age": "Late Interstellar",
"cost": 4000,
"description": "Thin gloves that incorporate sensitive tactile, pressure, chemical, and bioscanner sensors. They can interface with an OmniComp and provide detailed information about weight, mass, composition, even recent users. They can sense residual heat and chemical signatures for up to an hour after the object was used. The gloves provide a +1D advantage on checks for information where they would apply."
},
{
"name": "Sentry Gun",
"tech_age": "Late Space",
"cost": 750,
"description": "This security system consists of a weapons tripod mounted with a processor and sensor array. It can be fitted with a support weapon. The operator sets the sentrys guns parameters for when and who it opens fire on. It has a Combat skill of 1."
},
{
"name": "Sleeping Bag",
"tech_age": "Late Primitive",
"cost": 30,
"description": "A cloth or synthetic padded bag for one person. It provides insulation while sleeping. In the Early Atomic Age, cold weather bags are available. Regular sleeping bags are effective to zero degrees centigrade, while cold weather bags, costing 50 Credits, are insulated to negative 30 degrees centigrade."
},
{
"name": "Smart Clothes",
"tech_age": "Early Interstellar",
"cost": 500,
"description": "Responsive clothes that incorporate microelectronics providing the equivalent of an Omnicomp and allowing images and messages to be displayed on the clothing if desired."
},
{
"name": "Super Adhesive",
"tech_age": "Late Atomic",
"cost": 20,
"description": "A powerful adhesive that bonds two materials together and dries in one combat round (6 seconds). The adhesive bond is limited by the strength of the weaker of the two objects. 20 Credits buys a small tube that can cover 1 square meter of surface."
},
{
"name": "Survival Kit",
"tech_age": "Early Atomic",
"cost": 50,
"description": "A standard-issue item in most aircraft, explorer vehicles, and spacecraft across known space. The survival kits contents vary over Tech Age but consist mainly of the basic supplies to keep a small group of humans alive, fed, and healthy for a few weeks. A kit usually contains thermal tarps, LED flashlights, fire starters, water filter and decontamination pills, magnesium flares, and a radio/flash rescue beacon. They count as one item for Encumbrance."
},
{
"name": "Technical Toolkit",
"tech_age": "Early Atomic",
"cost": 300,
"description": "This toolkit is fully equipped to handle almost any technical job that doesnt require a full workshop. As the Tech Ages increase, many of the tools become self-modifying smart omnitools that can reconfigure depending on what the tech needs. This greatly reduces the bulk of the toolkit: Space Age Tool Kits are 2 Encumbrance points, while all but the largest Interstellar kits are 1 Encumbrance point."
},
{
"name": "Thruster Pack",
"tech_age": "Early Space",
"cost": 5000,
"description": "This wearable harness allows maneuvering in zero-G conditions at normal movement rates. Characters and objects moving by thruster pack are still subject to the laws of motion."
},
{
"name": "Trauma Tab",
"tech_age": "Late Space",
"cost": 500,
"description": "A single-use medical application that automatically allows a character who has suffered a Wound to continue to fight. However, the strain adds a -1D penalty to the Wound Triage table roll after the fight. At Late Interstellar age, this penalty is dropped."
},
{
"name": "Water Purification Tablets",
"tech_age": "Late Atomic",
"cost": 10,
"description": "A pack of 50 tablets that are standard issue in survival kits. Each tablet can sterilize up to 1L of water and make it fit for drinking."
},
{
"name": "Welder, Laser",
"tech_age": "Early Space",
"cost": 3000,
"description": "This portable workshop tool uses a focused laser beam to perform cutting and welding operations. It can cut through a reinforced bulkhead in 1d6 starship combat rounds (6-36 minutes). Roll Technology to reduce the time to one starship combat round (6 minutes). As a weapon, the laser welder is inaccurate and clumsy, but extremely dangerous: it does 4D (or AV 3D) damage with a range of Close and has energy for 5 attacks. When used as a weapon, the laser welder gains the Fire Weapon Aspect."
}
]

View File

@@ -0,0 +1,82 @@
[
{
"name": "Anti-Armor Grenade",
"tech_age": "Late Mechanical",
"cost": 50,
"damage": "2d6+1",
"aspects": ["Blast", "AV 3d6"],
"description": "Anti-tank grenades use a focused blast to penetrate armor. This grenade can only be fired from a grenade launcher [1]."
},
{
"name": "Dynamite",
"tech_age": "Early Mechanical",
"cost": 75,
"damage": "2d6",
"aspects": ["Blast"],
"description": "A low-tech explosive made of nitroglycerin, sorbents (such as powdered shells or clay) and stabilizers. Dynamite is typically used for demolition but can also be thrown with a lit fuse as a \"grenade\" [2]."
},
{
"name": "EMP Grenade",
"tech_age": "Early Space",
"cost": 50,
"damage": "4d6",
"aspects": ["Blast", "Stun (Machines)", "AV 3d6"],
"description": "This Electro-Magnetic Pulse grenade emits a powerful magnetic pulse capable of disrupting electronics. It causes full damage to robots but is otherwise harmless to humans. Characters with implanted cybernetics are vulnerable to EMP but reduce the damage from an EMP grenade by -2d6. Non-cybered organic beings are immune to this stun damage. This grenades AV dice are effective against Late Atomic Age or later vehicles [3]."
},
{
"name": "Flashbang Grenade",
"tech_age": "Late Mechanical",
"cost": 30,
"damage": "3d6+1",
"aspects": ["Blast", "Stun"],
"description": "A non-lethal stun grenade emitting a powerful flash and deafening noise upon detonation [3]."
},
{
"name": "Fragmentation Grenade",
"tech_age": "Early Mechanical",
"cost": 30,
"damage": "3d6+3",
"aspects": ["Blast"],
"description": "The basic anti-personnel hand grenade that explodes into a hail of shrapnel [4]."
},
{
"name": "Incendiary Grenade",
"tech_age": "Late Mechanical",
"cost": 30,
"damage": "3d6",
"aspects": ["Blast", "Fire"],
"description": "A military-grade fire-bomb grenade [4]."
},
{
"name": "Molotov Cocktail",
"tech_age": "Early Mechanical",
"cost": 5,
"damage": "2d6+1",
"aspects": ["Blast", "Fire"],
"description": "These are home-made incendiary bombs, commonly made with a glass container filled with highly flammable liquid and lit with a rag [4]."
},
{
"name": "Plasma Grenade",
"tech_age": "Late Interstellar",
"cost": 250,
"damage": "4d6",
"aspects": ["Blast", "Fire", "AV 4d6"],
"description": "A plasma explosive device in a grenade-sized package [4]."
},
{
"name": "Plastique",
"tech_age": "Late Mechanical",
"cost": 200,
"damage": "2d6+2",
"aspects": ["Greater Blast"],
"description": "This generic, multi-purpose plastic explosive is a favorite of military units, terrorists, demolition teams, and adventurers across known space [4]."
},
{
"name": "Smoke Grenade",
"tech_age": "Early Mechanical",
"cost": 15,
"damage": null,
"aspects": ["Greater Blast (Smoke)"],
"description": "This grenade dispenses a cloud of thick smoke upon impact. Apply -1D to all attacks passing within Near range of its detonation point. Smoke also penalizes attacks by laser weapons by an additional -1D. The smoke stays in the air for 1d6+1 combat rounds [5]."
}
]

View File

@@ -0,0 +1,219 @@
[
{
"name": "Advanced Cyberarms",
"cost": 20000,
"loss": 2,
"tech_age": "Late Space",
"description": "The arms are replaced by obvious cybernetic appendages. This implant grants +2D for brute strength tasks involving the arms. Unarmed attacks do 3d6 damage. Both real arms have to be replaced to provide proper structural support."
},
{
"name": "Advanced Cyberlegs",
"cost": 50000,
"loss": 2,
"tech_age": "Late Space",
"description": "The subjects legs are replaced by obvious cybernetic versions. The hips and spine are reinforced to deal with the additional strain. The subject gains the Runner Talent, with a 15+2d6m base rate. As an action, the character may throw Physical to jump 10m horizontally in any direction or 3m upwards. The subject also ignores fall damage for any falls less than 10m."
},
{
"name": "Artificial Gill",
"cost": 2500,
"loss": 1,
"tech_age": "Early Space",
"description": "This implant permits the subject to breathe underwater with no difficulty. Diving too deep will still be lethal. The artificial gill runs off the characters own energy and does not need recharging."
},
{
"name": "Bastet Frame Upgrade",
"cost": 1000000,
"loss": 3,
"tech_age": "Late Space",
"description": "This series of implants represents a radical reconstruction of the entire organic body to grant superhuman agility and speed. The Bastet upgrade grants +1D to all Physical and Stealth skill rolls related to speed and agility. The Bastet Frame Upgrade is incompatible with the Hercules Frame Upgrade."
},
{
"name": "Chem Injector",
"cost": 10000,
"loss": 1,
"tech_age": "Early Space",
"description": "An assassins implant par excellence, this cybernetic is mounted in the users fingertips or canines. Different chemicals are available, but typically they amount to lethal or non-lethal poisons. Attacks against unsuspecting targets are automatically successful. In combat, or against a wary target, roll Combat normally to hit. Targets must roll Physical to avoid the effects of the poison."
},
{
"name": "Control Rig Implant",
"cost": 1000000,
"loss": 1,
"tech_age": "Late Space",
"description": "This is a highly specialized implant designed to give elite vehicle pilots even more of an edge. The control rig allows the operator to fully interface their minds with vehicles. The control rig gives the character +1D on Vehicles skill throws with suitably modified vehicles. Position rolls remain unaffected. The Control Rig requires that the operator to be in the vehicle, and “plugged in.” Modifying a vehicle to work with a control rig increases its cost by 10%. When the vehicle takes any damage, the plugged in pilot must roll Physical to avoid taking 1D damage from electrical feedback—this damage ignores any armor the pilot may be wearing."
},
{
"name": "Cosmetic Modification",
"cost": "varies",
"loss": 0.25,
"tech_age": "Early Space",
"description": "It is a simple matter to effect changes to a persons appearance with cybernetics. Small modifications cost 500 Credits; a general makeover costs 1000 Credits; and exotic options—for example, changing your body to resemble that of your favorite animal—cost 5000 Credits and upwards."
},
{
"name": "Cybernetic Eyes",
"cost": 7500,
"loss": 0.5,
"tech_age": "Early Space",
"description": "Both eyes are replaced with artificial versions. Cybereyes are considered to have internal Night Visor upgrades (low light and infrared optics). They also come with x4 image intensification, and anti-flare protection which provides a +1D bonus against flash-bang grenades and other similar effects."
},
{
"name": "Cyber-Blades",
"cost": 5000,
"loss": 0.5,
"tech_age": "Early Space",
"description": "The characters arm carries a blade that can be extended or retracted at will. The blade does 2d6+1 damage. Internal blades are made with ceramic composites to avoid detection and cannot be detected by any means short of exploratory surgery."
},
{
"name": "Data safe",
"cost": 5000,
"loss": 0.5,
"tech_age": "Early Space",
"description": "This secured electronic storage device secures encrypted files in a small data chip implanted in the characters skull. The data safe cannot be detected by a cursory sensor scan, but a medical scan will reveal its presence. The safes capacity is very large and can store (not run!) even advanced AI software. Data must be uploaded and downloaded from the data safe by means of a Neural Interface. The safe can be set so that failed attempts to break the encryption cause it to shut down and be safely dissolved by the subjects body."
},
{
"name": "Filtration System",
"cost": 3000,
"loss": 0.5,
"tech_age": "Early Space",
"description": "This lung filtration implant protects from airborne and pathogens. It requires a few minutes of maintenance after every month of use, but otherwise draws its power from the subjects own electrical impulses. Certain extremely high-tech artificially designed chemical agents might degrade the filtration system very quickly."
},
{
"name": "Gekko Implants",
"cost": 25000,
"loss": 0.5,
"tech_age": "Late Interstellar",
"description": "Miniature gravitic generators are implanted in the characters hands and feet. This allows them to climb sheer surfaces and run along walls or ceilings. Earlier versions (same price, Late Space Age) deploy biomimickry micro-hairs that provide the same performance but require bare hands and feet to use."
},
{
"name": "Glow Tattoos",
"cost": 100,
"loss": 0,
"tech_age": "Early Space",
"description": "These advanced tattoos consist of smart bioluminescent skin grafts implanted in complex patterns across the subjects skin. Patterns and designs are up to the subject. The subject may activate or deactivate the tattoos at will."
},
{
"name": "Head bomb",
"cost": 3000,
"loss": 0.25,
"tech_age": "Early Space",
"description": "A tiny remote-controlled explosive device implanted in the brain. They are designed so that the bombs detonation will kill the subject without breaking the skull: no collateral damage! These devices are rarely implanted voluntarily."
},
{
"name": "Hercules Frame Replacement",
"cost": 1000000,
"loss": 3,
"tech_age": "Late Space",
"description": "A radical reconstruction and replacement of the entire organic body grants superhuman endurance and might. The Hercules Frame grants the character +1D to all Physical rolls related to brute strength and doubles their Encumbrance capacity. All melee damage rolls gain +1d6 as well. The Hercules Frame also provides +10 Stamina. The Hercules frame upgrade is incompatible with the Bastet Frame Upgrade."
},
{
"name": "Hibernation Suite",
"cost": 100000,
"loss": 1,
"tech_age": "Early Interstellar",
"description": "This emergency cybernetic implant puts the character into a medical coma upon command. The user appears dead and has no need of any air, food, or water while in suspended animation. The Hybernation Suite also pauses any healing and prevents the spread of poisons or disease. The length of hybernation is determined by the user before it begins, and the maximum duration is four weeks. The Hybernation Suite cannot be used for a week after the user is woken from their coma."
},
{
"name": "Hypercosmetic Surgery",
"cost": 1000000,
"loss": 2,
"tech_age": "Late Space",
"description": "Perfect body sculpting and implanted synthetic pheromone glands radically reconstructs the subjects body to be perfectly attractive to other members of their species. Grants +1D to all Social skill rolls in situations where physical attractiveness matters."
},
{
"name": "Neural Booster",
"cost": 1000000,
"loss": 3,
"tech_age": "Late Space",
"description": "This invasive augmentation to the characters nervous system and adrenal glands grants the character super speed and reaction times for very short periods of time. Once per combat, the character may go twice, for a total of four actions per combat round rather than the usual two. As well, they may use this ability as an interrupt action, going before anyone else in the round."
},
{
"name": "Neural Interface, Military Grade",
"cost": 10000,
"loss": 0.5,
"tech_age": "Late Space",
"description": "A basic way to jack into a computer, allowing rapid upload of code directly from a hackers mind and both combat actions per round to be used as hacking actions."
},
{
"name": "Neural Interface, Military Grade (Ultimate Jack)",
"cost": 1000000,
"loss": 0.5,
"tech_age": "Late Space",
"description": "The ultimate interface between the human brain and a machine. In addition to all the benefits of the regular Neural Interface, this implant grants +1D to all throws made to hack computers and tamper with electronics."
},
{
"name": "Omnicomm Implant",
"cost": 5000,
"loss": 0.25,
"tech_age": "Early Space",
"description": "This implant functions as an Omnicomm but with a neural interface, allowing communication without audible speech. This implant allows the subject to send and receive images and videos as well. Nearly every operator in the starfaring future has such an implant."
},
{
"name": "Omnicomp Implant",
"cost": 10000,
"loss": 0.25,
"tech_age": "Early Space",
"description": "This implant provides full Omnicomp capabilities to any operator, but with a neural interface. Dedicated hackers tend to eschew this implant, as it is difficult to constantly upgrade with custom modifications."
},
{
"name": "Oxygen Supply",
"cost": 4000,
"loss": 0.25,
"tech_age": "Early Space",
"description": "This implant provides 3 hours of oxygen. This means that the subject can avoid breathing tainted air without any other implants. It is also an excellent emergency oxygen backup supply for spacers operating in dire circumstances."
},
{
"name": "Prehensile Tail",
"cost": 15000,
"loss": 1,
"tech_age": "Early Space",
"description": "This implant provides the subject with an additional grasping and manipulating appendage. The tail is not easily concealed but can be made to look like anything the character desires. The character still only has two actions per combat round. The tail is strong enough to support the weight of the owner."
},
{
"name": "Prosthetic Limb/Organ",
"cost": 5000,
"loss": 0.25,
"tech_age": "Early Space",
"description": "This entry covers a variety of medical cybernetics intended to replace missing or damaged hands, eyes, fingers, arms, legs, feet, or internal organs. These prosthetics are cosmetically indistinguishable from the real thing, but close inspection will reveal the truth."
},
{
"name": "Smart Gun, Internal",
"cost": 15000,
"loss": 1,
"tech_age": "Late Space",
"description": "Some gun-bunnies need to project their aiming reticule all the time. This cybernetic implant grants the standard Smart Gun advantages to all weapons the user fires, as long as the weapon itself has the Smart Gun sensors. The character must have Cybernetic Eyes or an Omnicomp implanted to benefit from the Internal Smart Gun. Modifying a weapon to work with an Internal Smart Gun costs 100 Credits."
},
{
"name": "Storage Pouch",
"cost": 2000,
"loss": 0.5,
"tech_age": "Early Space",
"description": "This is a discreet abdominal pouch accessible via a well-concealed sphincter. Stows items up to 0.5 kg in weight and 0.5 liters in volume: one Encumbrance points worth of items."
},
{
"name": "Subdermal armor",
"cost": 30000,
"loss": 0.5,
"tech_age": "Early Space",
"description": "This implant consists of subtle bone reinforcement and flexible mesh implants that provide 4 points of Protection. Subdermal armor is detectable upon visual inspection, but only if the subject removes their clothing. Subdermal armor is added to the Protection of any worn armor."
},
{
"name": "Vacuum Adaptation",
"cost": 1000000,
"loss": 2,
"tech_age": "Late Interstellar",
"description": "This implant turns the user into a natural spacer. Internal oxygen reserves, micro-seals, and metal weave skin permit the character an hour of operation in vacuum without a spacesuit. An integral grav unit allows short-range maneuvering in low and microgravity. The grav unit is too weak to maneuver in any gravity beyond 0.05g. This augment also provides 4 points of integral armor Protection and reduces radiation by 10 rads. The Vacuum Adaptation implant is visible upon medical inspection or sensor scan but is otherwise quite discreet. The Vacuum Adaptation requires 1d6+1 hours to recharge after use."
},
{
"name": "Weapon, Internal",
"cost": 5000,
"loss": 1,
"tech_age": "Early Space",
"description": "The character carries a concealed weapon in an internal arm mounting. This can be any pistol-sized weapon, according to the tech age of the society installing the cybernetic: stealth pistol, gyrojet pistol, gauss pistol, laser pistol, blaster pistol, or stunner. The weapons magazine is half normal capacity, but it can be reloaded normally via a retractable magazine holder. The cybernetics price is 5000 Credits, plus twice the weapons cost. Internal weapons can be detected with medical scans or detailed physical inspections. Internal weapons are made to be automatically compatible with a Smart Gun system (internal or external)."
},
{
"name": "Wound Triage Booster",
"cost": 15000,
"loss": 1,
"tech_age": "Early Space",
"description": "An implanted autodispenser of emergency combat drugs that stabilize wounds and minimize pain. Characters with this implant gain a +1D to Wound Triage rolls after combat. As well, they do not die until they suffer 4 Wounds in combat."
}
]

View File

@@ -0,0 +1,142 @@
[
{
"name": "Augmented Speed",
"description": "The character may move to Far distance in half the number of Move Actions normally required. This power lasts for 3 combat rounds [1]."
},
{
"name": "Augmented Strength",
"description": "Gain +1D to Physical throws, as well as all melee and unarmed damage rolls for the rest of the battle [1]."
},
{
"name": "Blink",
"description": "The character may teleport once to any point within Far distance, as long as they have line of sight to it, or they have been there previously [2]."
},
{
"name": "Choke",
"description": "Telekinetically grab one humanoid creature by its throat (or analogous body part) and strangle them for 1D Damage every round, for a maximum of 5 rounds. The victim may throw Physical each round to break out of the chokehold [2]."
},
{
"name": "Clairvoyance",
"description": "This power allows characters to psionically watch and listen at a spot they choose within Far distance. This power ignores solid objects, and the character does not have to be familiar with the location in question. Whether or not a psion can use Clairvoyance to familiarize themselves sufficiently for the Blink power (above) is up to the Referee [2]."
},
{
"name": "Cryokinesis",
"description": "Characters with this power may freeze up to 5 cubic meters of material for 10 minutes. Cryokinesis can also be used offensively. Throw Combat to attack a target within Near range, causing 2D+2 damage, with AV 2D. This affects targets internally; survival clothes do not protect from this power [3]."
},
{
"name": "Electrokinesis",
"description": "This character is able to manipulate electrical energy in their vicinity. They may use this power to recharge batteries, short-circuit electrical devices, or generate spectacular lightshows. They may also attack a target within Near range with lightning! This causes 3D damage, with AV 2D. The target may throw Physical to take half damage. Robots suffer -2D on that roll [3]."
},
{
"name": "Emotion",
"description": "This power allows the psion to evoke a powerful emotion in a target at Near range; fear, joy, or friendliness are typical emotions. It is obvious to everyone, affected or not, that something has happened. This power can be used to force a Morale check among enemy (or friendly) forces. This effect lasts until the end of the battle, or for 1d6x10 minutes [4]."
},
{
"name": "Empathy",
"description": "Psions may read a targets emotions and subtly affect them. This includes changing a Near targets NPC Reaction Roll result by one category up or down, players choice [4]."
},
{
"name": "False Perception",
"description": "The psion causes a single target within Near range to hallucinate. This effect lasts as long as the psion concentrates to maintain it. The details of the False Perception are left to the psion but can range from a normal illusion or distraction to something that closely resembles a drug-fueled fugue state. The target is permitted a Knowledge throw to shake off the effect after one round [5]."
},
{
"name": "Hibernation",
"description": "The character may enter into a trance-like state and meditate for up to 7 days. While meditating, the psychic does not require food, water, or air. They remain aware of their surroundings and may end the hibernation at will [5]."
},
{
"name": "Inspiration",
"description": "When the psion uses this power, they gain +1D to their next roll, regardless of what the roll is for. This power may only be used once per day [6]."
},
{
"name": "Invisibility",
"description": "The psion is able to conceal themselves from nearby onlookers. While invisible, organic targets within Near range will not see the psion. This power works on electronic sensors and video cameras within Near range. The psion must concentrate for this power to be effective. Attacking any target immediately terminates this effect [6]."
},
{
"name": "Kinetic Blast",
"description": "The psion generates a powerful if clumsy blast of telekinetic force! This invisible telekinetic bolt of force does 4D damage with AV 3D. The target may throw Physical (or Vehicles if in a vehicle) to completely avoid the attack [7]."
},
{
"name": "Kinetic Shield",
"description": "This power grants the psion 8 points of armor Protection for the duration of the battle. The kinetic shield is not cumulative with worn armor [7]."
},
{
"name": "Levitation",
"description": "The Psion may fly at a speed of one Move Action per round, for 5 rounds, in any direction desired [7]."
},
{
"name": "Life Detection",
"description": "This power allows the psion to instinctively detect all living beings within a Far radius. This power cannot be used to pinpoint the exact whereabouts of a target but will give a general sense of the location of a hidden interlocutor or sniper [8]."
},
{
"name": "Memory Block",
"description": "To use this power, the psion must be within Near range of a target. The target is allowed a Knowledge throw to avoid the effect. If the target fails the throw, the psion may block out up to 15 minutes of the targets memories. The targeted memories must be targeted as a block for each use of this power. The memories can only be unblocked by another psion using Memory Block on the target [8, 9]."
},
{
"name": "Microkinesis",
"description": "The psion gains telekinetic control of small or microscopic objects. Gain +2D on any one Technology throw involving components or systems containing small or microscopic objects [9]."
},
{
"name": "Mind Blast",
"description": "This powerful telepathic blast renders a Near target unconscious for 10 minutes. The target is allowed a Knowledge throw to reduce this to being stunned (no actions) for one combat round [9]."
},
{
"name": "Mind Control",
"description": "The psion gains control of a Near target, who becomes the psions ally for 15 minutes. The target may make a successful Knowledge throw to reduce the duration to 1D rounds. The target of Mind Control will only perform tasks a typical ally would do and will not perform any action that would harm themselves [10]."
},
{
"name": "Mind Lock",
"description": "A Near target is paralyzed for 2d6 combat rounds and may not move. They may still speak. The target is allowed a Physical throw to resist this power [10]."
},
{
"name": "Mind Shield",
"description": "The psion may erect an invisible mental shield that protects themselves and all allies within Near range any mind-affecting power or psionic ability. The Mind Shield will last for ten minutes [10]."
},
{
"name": "Precognition",
"description": "This power allows the player to ask the Referee one question about what may happen to their character in the next 24 hours. The Referee must respond truthfully with either “yes” or “no.” Precognition may only be used once per day [11]."
},
{
"name": "Psychic Healing",
"description": "This handy power allows the psion to heal 1 Wound on an injured target [11]."
},
{
"name": "Pyrokinesis",
"description": "The psion may ignite a flammable object within a Near range. When used to directly attack a target, throw Combat to hit the target. A successful attack does 3D damage and has the Fire weapon Aspect. See the Environmental Hazard chapter for details on fire damage [11]."
},
{
"name": "Regeneration",
"description": "This power allows a psychic to automatically treat a single Wound Triage Table result as though it were a result of 11: the wound will heal after 10 minutes of rest. Regeneration cannot be used on other targets but may be used after the results of the Triage Table roll are known. The psychic must be able to rest for ten minutes, and Regeneration only works on one wound at a time [12]."
},
{
"name": "Second Wind",
"description": "This power allows the psion to ignore the effects of Fatigue for 1 hour [12]."
},
{
"name": "Suggestion",
"description": "Psions may use this power to plant a simple hypnotic suggestion in one target. This effect will last until the target has performed their suggested task, or ten minutes have passed. Victims will not obey suggestions to harm themselves directly or indirectly [12, 13]."
},
{
"name": "Telekinesis",
"description": "The psion may move objects up to 100kg by the power of their brain. Telekinetics may throw a heavy object at a target at Near range; such an attack requires a Combat roll and causes 4D damage, with AV 3D [13]."
},
{
"name": "Telepathy",
"description": "This power allows the psion to read a Near targets surface thoughts for one minute [13]."
},
{
"name": "Thousand Faces",
"description": "The psion may change their appearance and biometric data to those of any target of the same or similar species for 10 minutes. To mimic the specific biometric data of another person, the psion must have a sample of the targets DNA [13]."
},
{
"name": "Truth",
"description": "This telepathic ability forces one Near target to answer questions truthfully. They must be able to speak or communicate to the psion, and the questions can be about anything: the target will fully answer to the best of their ability [14]."
},
{
"name": "Vampire",
"description": "The psion must make a normal unarmed attack at Close range. The Vampire power inflicts a Wound on the target, and instantly heals a Wound the psion has suffered [14]."
},
{
"name": "Zombie",
"description": "This gruesome power allows the psion to control one body of a creature killed in the past 24 hours. The target creature must be within Near range, and the power lasts for 5 combat rounds. The corpse may act, speak, and attack as the psion desires. The creatures abilities might be limited depending on the amount and kinds of damage it suffered when it died [14]."
}
]

View File

@@ -0,0 +1,268 @@
[
{
"name": "Orbital Transit Vehicle",
"agility": "+1",
"hullType": "Pod",
"endurance": "1 week Travel x2",
"armor": "2/4",
"crew": "1 (3)",
"cargo": "8",
"guns": "0",
"travelMultiplier": "x2",
"cost": 66000,
"monthlyCost": 4970,
"description": "The OTV (Orbital Transfer Vehicle) is a larger and slower version of a standard pod. It trades acceleration and travel velocity for a larger life module that holds a pilot and three passengers. It also has more Endurance, and more Cargo. OTV Pods are often used for moving cargo and passengers from planets to vessels in orbit. They are often carried by colony ships. Often, OTVs double as landers, and are able to convert into a shelter for its four occupants who rely on the OTVs extended Endurance while waiting for resupply."
},
{
"name": "Defense Fighter",
"agility": "+4",
"hullType": "Micro",
"endurance": "1 Day Travel x2",
"armor": "14/17",
"crew": "1",
"cargo": "0.5",
"guns": "5d6",
"travelMultiplier": "x2",
"cost": 1120000,
"monthlyCost": 5300,
"description": "The Defense Fighter is a common sight on frontier worlds. Tough little vessels, these fighters have excellent acceleration, and the cutting edge FTL drive provides additional inertial dampening for truly breakneck maneuvers. The ship is otherwise incapable of FTL travel. The ship has minimal cargo space but carries decent guns making it a serious threat to small and medium-sized craft. Any colony world and many settled planets will have these ships on hand to deter pirate, and force down questionable ships for inspection."
},
{
"name": "Shuttle",
"agility": "+3",
"hullType": "Small",
"endurance": "1 Week",
"armor": "7/9",
"crew": "3 (7)",
"cargo": "8",
"guns": "2d6",
"travelMultiplier": "x1",
"cost": 2500000,
"monthlyCost": 22500,
"description": "A lightly armored and armed transfer vehicle. This shuttle is designed to move people and cargo to and from space. Shuttles take up a bit of cargo space, they are typically only found on larger vessels or based at a space station or spaceport. It lacks the armor or weapons for rougher frontier areas."
},
{
"name": "Tramp Freighter",
"agility": "0",
"hullType": "Scout",
"endurance": "1 Month",
"armor": "14/17",
"crew": "4 (6)",
"cargo": "64",
"guns": "4d6",
"travelMultiplier": "x1",
"cost": 6800000,
"monthlyCost": 39000,
"description": "The tramp freighter sacrifices Agility, Armor, and Guns for Cargo. Typically, a vessel like this can make a tidy profit of 6000-7000 credits a month, more if the crew/owners forego part of their salary to buy off the ships debt. This version retains some weapons and armor to deal with unsavory types and is suited to Frontier regions. Running cargo in risky systems can pay off: freight and passenger rates are liable to be two or three time the normal rate for emergency shipments via these dangerous systems."
},
{
"name": "Merchant",
"agility": "0",
"hullType": "Picket",
"endurance": "3 Months",
"armor": "18/21",
"crew": "10 (15)",
"cargo": "125",
"guns": "4d6",
"travelMultiplier": "x1",
"cost": 23800000,
"monthlyCost": 98000,
"description": "Merchant pickets are bought outright by mid-sized independent companies. They carry vital supplies to new colonies and outposts, something no large corporation wants to deal with. They are often stripped down former military ships. The largest hull capable of landing, they are very handy for frontier worlds. Many captains crew these ships at half strength to carry five more passengers and make an extra 40000 credits a month. This amounts to working the crew to the point of burn-out. Crew turnover on these vessels is exceedingly high."
},
{
"name": "Explorer",
"agility": "0",
"hullType": "Picket",
"endurance": "6 Months",
"armor": "18/21",
"crew": "10 (15)",
"cargo": "64",
"guns": "4d6",
"travelMultiplier": "x1",
"cost": 27700000,
"monthlyCost": 138500,
"description": "The Explorer is an under-gunned picket hull that possesses increased Endurance but reduces the armament even more. Propellant is sacrificed as well to allow a suite of advanced sensors. The 15 passengers are explorers and scientists. The shuttle can ferry field teams around a planet being investigated. Some missions forgo this for more cargo and simply land the ship."
},
{
"name": "Gunship",
"agility": "+1",
"hullType": "Picket",
"endurance": "3 Months",
"armor": "18/21",
"crew": "10 (15)",
"cargo": "32",
"guns": "6d6",
"travelMultiplier": "x1",
"cost": 28000000,
"monthlyCost": 98000,
"description": "The gunship is a vessel much-loved by pirates. Small enough to land on a planet for a raid of opportunity, yet with large enough guns to terrorize a small convoy or space station. Its light armor does mean that it must flee when larger escorts arrive. The 15 passengers comprise the boarding/looting party. The gunship is an all-too-common sight on the wild frontier."
},
{
"name": "Force Transport",
"agility": "0",
"hullType": "Destroyer",
"endurance": "6 Months",
"armor": "21/24",
"crew": "25 (75)",
"cargo": "177",
"guns": "6d6",
"travelMultiplier": "x1",
"cost": 102570000,
"monthlyCost": 331500,
"description": "The Force Transport is designed to deliver ground troops to serve as garrisons and pacify low-intensity conflicts: civil disorder, unrest, and similar situations. Its guns are supplemented by seven torpedoes to deal with space-borne threats. Torpedo reloads are stored as cargo. Since this hull is too large to land on a planet, three shuttles serve to deliver troops to all but the hottest landing zones."
},
{
"name": "Assault",
"agility": "0",
"hullType": "Destroyer",
"endurance": "3 Months",
"armor": "25/28",
"crew": "25",
"cargo": "7",
"guns": "8d6",
"travelMultiplier": "x1",
"cost": 145700000,
"monthlyCost": 264000,
"description": "The Assault ship is a powerful ship that is designed to do one thing: go into hot spots, fight the enemy, and win! Its powerful guns make it dangerous to smaller craft, and its compliment of torpedoes make it a threat to larger ships. This ship is common in all space forces anticipating sharp engagements. Force Transports are often paired with Assault ships: the Assault ships clear a path to a planet, and the Transports offload their troops to establish a beachhead."
},
{
"name": "Colonizer",
"agility": "-2",
"hullType": "Cruiser",
"endurance": "2 Years Travel x2",
"armor": "25/28",
"crew": "100 (1100)",
"cargo": "528",
"guns": "6d6",
"travelMultiplier": "x2",
"cost": 381400000,
"monthlyCost": 1532000,
"description": "Colonizer cruisers are the vanguard of colonization and immigration efforts. They carry the OTV pods and colonists to a hopefully promising planet and carries all the necessary supplies for the initial colony to be established. The colonists are transported in tight confines and spend their days training and preparing for their new lives. Some Colonizers carry cryo-tubes to transport even more colonists at a fraction of the life support cost. By the time the Colonizer arrives over the new planet, the crew will have programmed the on-board OTV pods with descent parameters. Occasionally a colonist will receive a week of training to fly the OTV pod. The pods descend, each with four passengers, and eight tons of supplies. The pods are designed to be dismantled and used to create permanent shelters. The colonizer remains in orbit for four to five months to assist the fledgling colony by using its shuttles to move additional colonists, supplies, and heavier equipment down to the planet. The ship has enough firepower to dissuade all but the most aggressive raiders. This is an older and slower colonizer. One thousand colonist are transported awake, while 800 more are in cryo-tubes!"
},
{
"name": "Miner",
"agility": "-1",
"hullType": "Scout",
"endurance": "1 Month Travel x1.5",
"armor": "18/21",
"crew": "4",
"cargo": "32",
"guns": "2d6",
"travelMultiplier": "x1.5",
"cost": 7600000,
"monthlyCost": 32000,
"description": "The Mining Scout sacrifices Guns, travel speed and acceleration to mount mining gear and an enlarged cargo hold. It retains the Scouts armor for protection against mining debris. The Scout is seldom troubled by pirates, who prefer looting a hold of luxury items to raw minerals. In areas where mining operations are harassed, these ships are guarded by interceptors. These ships regularly operate with military operations to provide fuel."
},
{
"name": "Escort Tender",
"agility": "0",
"hullType": "Picket",
"endurance": "1 Month Travel x0.75",
"armor": "18/21",
"crew": "19 (6)",
"cargo": "16",
"guns": "4d6",
"travelMultiplier": "x0.75",
"cost": 30520000,
"monthlyCost": 218800,
"description": "Escort tenders are the unglamorous workhorses of many navies, as they transport Defense Fighters, the agile combat craft with low Travel Multipliers, to a fight. Tenders are built around large propellant tanks, and very little else. The tenders will deploy their fighters and hang back while the fighters deploy to deal with threats. The six fighters pilots are considered passengers in this entry. Attacks that incapacitate crew if a tender while it is operating fighters will soon leave it under-crewed."
},
{
"name": "Express Picket",
"agility": "+2",
"hullType": "Picket",
"endurance": "1 Month Travel x1",
"armor": "21/24",
"crew": "4 Auto.",
"cargo": "32 (10 Cryo)",
"guns": "6d6",
"travelMultiplier": "x1",
"cost": 30800000,
"monthlyCost": 69000,
"description": "Express pickets are high speed craft that are designed to move vital information, supplies, and individuals over vast distances with very little external support. To reduce the logistical burden and simplify matters, many VIPs are placed in cryo-tubes for the entirety of the voyage. Express Pickets often possess redundant FTL Drives that permit two FTL voyages in rapid succession before requiring recharge. Another unique feature of this vessel is the use of an advanced Artificial Intelligence to reduce crew size to the bare minimum. Meanwhile, with such valuable components and the presence of sensitive information and persons, Express Pickets are armored and armed well enough to deter pirates."
},
{
"name": "Racer Rocket",
"agility": "+1",
"hullType": "Destroyer",
"endurance": "6 months Travel x0.5",
"armor": "7/9",
"crew": "25",
"cargo": "16",
"guns": "1d6",
"travelMultiplier": "x0.5",
"cost": 50000000,
"monthlyCost": 450000,
"description": "Competitive rocket racing is a popular and profitable sport, with many clubs and racing circuits across many sectors. The Racing Rocket is a standard high-speed, long-distance racer, though other types of rockets also exist for shorter races. This particular rocket is outfitted for dangerous and cutting-edge antimatter fuel. The Agility increases to +3 and the Travel Multiplier increases to x0.33 (faster!) when antimatter fuel is available. Racing rockets are also used as an emergency express courier to quickly send help or supplies to remote outposts in a given system."
},
{
"name": "Pleasure Craft",
"agility": "+1",
"hullType": "Picket",
"endurance": "3 months",
"armor": "18/21",
"crew": "10(20/70)",
"cargo": "16",
"guns": "4d6",
"travelMultiplier": "x1",
"cost": 33732000,
"monthlyCost": 167940,
"description": "Pleasure craft are popular among the elite and leaders of worlds. The ship is designed to carry many passengers. The ten crew are supported by another twenty stewards who tend to the seventy or so passengers. Of course, many of the passengers are themselves guards, agents, and other members of a wealthy VIPs household or entourage. It is rare for these vessels to be attacked, but if an attack does occur, the ship uses its Agility to stay out of the field of fire, and launches its torpedoes before fleeing."
},
{
"name": "Refinery",
"agility": "-1",
"hullType": "Battleship",
"endurance": "6 Months Travel x2",
"armor": "32/35",
"crew": "300",
"cargo": "4000",
"guns": "6d6",
"travelMultiplier": "x2",
"cost": 4400000000,
"monthlyCost": 2364000,
"description": "A Refinery Ship costs is a large and costly vessel. Those that arent constructed outright by corporations or governments to serve as the lynchpins of resource exploitation projects are usually hobbled together by several clans of belters pooling together their hard-won resources. A Refinery ship will have huge cargo holds and often have an entire fleet of smaller mining ships operating out of its hangars. Refinery ships are heavily reinforced designs and are constructed to withstand the nearby explosion of an asteroid. They have enough defensive systems to carefully guard their resources. Many belter communities also hire mercenary ships to further bolster their refinerys defenses. A refinery ship has never been successfully boarded or looted."
},
{
"name": "Prison Ship",
"agility": "+1",
"hullType": "Picket",
"endurance": "6 Months",
"armor": "18/21",
"crew": "10(15)",
"cargo": "22",
"guns": "5d6",
"travelMultiplier": "x1",
"cost": 28020000,
"monthlyCost": 116000,
"description": "This prison ship serves as a mobile base and prison for affiliated bounty hunters. Five of the passengers are guards, the rest prisoners. Many crews will store extra prisoners on ice in cryo-tubes in the hold. The ship sacrifices some armor and firepower for the larger life support system, and it cannot stand up to similar military ships. However, it remains a credible threat to most pirates who may want to mount a rescue. The guards on such a vessel are often replaced by robots, the likes of which are not likely to be bribed or coerced."
},
{
"name": "Torpedo Boat",
"agility": "+2",
"hullType": "Scout",
"endurance": "1 Week",
"armor": "18/21",
"crew": "4",
"cargo": "0",
"guns": "6d6",
"travelMultiplier": "x1",
"cost": 8000000,
"monthlyCost": 39000,
"description": "Torpedo Boats serve as a defensive vessel for mid-sized colonies that are occasionally the targets of larger pirate raids. The Torpedo Boat uses its high Agility to maintain an advantageous position, while launching torpedo after torpedo at pirate pickets. Torpedo Boats are often used with Defense Fighters or Gunships. They are also carried by larger ships like Cruisers."
},
{
"name": "Drop Ship",
"agility": "+3",
"hullType": "Scout",
"endurance": "1 Day",
"armor": "18/21",
"crew": "4(21)",
"cargo": "2",
"guns": "6d6",
"travelMultiplier": "x1",
"cost": 9600000,
"monthlyCost": 37175,
"description": "The Drop Ship is a large, militarized shuttle bristling with weapons. Its primary task is to deliver a platoon of 20 soldiers to a hostile planetary surface in very little time. Its engines give it excellent acceleration, hopefully enough to evade fire—any trooper will tell you that a Drop Ship ride is never a restful experience."
}
]

View File

@@ -0,0 +1,270 @@
[
{
"name": "Armor Training",
"description": "This talent allows the character to use armor more effectively. The encumbrance values of all armors are reduced by 1 to a minimum of 0."
},
{
"name": "Artillery",
"description": "This character received advanced training in using heavy artillery. Usually, this means acting as a forward observer, but the character is also an expert in artillery gunnery, fuse setting, and demolishing fortifications with artillery. Gain +1D when firing artillery, or acting as a forward observer, or when conducting counter-battery fire."
},
{
"name": "Assault",
"description": "Assault specialists receive training in the use of heavy weapons. Gain +1D when using assault weapons, hunting tanks or other large vehicles, or when attacking prepared enemy fortifications."
},
{
"name": "Berserker",
"description": "When injured in combat but still conscious, the character may enter a Rage. This grants them +1D to hit and +1D to damage in melee combat, but also grants the character's enemies +1D to hit them. This lasts until the end of that combat encounter."
},
{
"name": "Blind Fighter",
"description": "The character can ignore the Penalty Die for fighting in darkness."
},
{
"name": "Bodyguard",
"description": "This talent allows the character to quickly move into harms way and take a hit meant for a comrade. This works as an interrupting action, and uses the bodyguards next Action in combat, if they survive."
},
{
"name": "Evasive Action",
"description": "This talent reflects innate luck, unconscious skill, or lightning fast reflexes. Once per battle, the character may avoid an otherwise successful attack and take no damage. They may elect to use this ability after damage is rolled. This talent can apply in vehicle combat as well as in personal combat."
},
{
"name": "Hardy",
"description": "The damage roll of the first (and only the first) successful attack on the character in a given battle incurs a -2D penalty."
},
{
"name": "Heavy Hitter",
"description": "Once per battle, you may opt to inflict maximum damage with an attack. You may use this ability after you have rolled damage."
},
{
"name": "Hunter",
"description": "The character is practiced at setting ambushes. Gain +1D on Surprise throws when attacking from ambush."
},
{
"name": "Leader",
"description": "Whether a natural, or an experienced, trained leader, this character knows how to motivate people into doing things they might not normally do. They gain +1D when attempting to rally troops and convince others to carry out their orders. As an action in Combat, they may roll Social 8+. If the roll is successful, the Leader generates Hero Points equal to the result of the roll, minus 7 (a result of 8 provides 1 Hero Point). These Hero Points can be distributed as a free action to comrades during the battle, but disappear when the fight is over."
},
{
"name": "Marksman",
"description": "The character is particularly adept at hitting where it counts most with ranged weapons. After spending one Hero Point, add +2D to damage rolls with ranged weapons."
},
{
"name": "Martial Artist",
"description": "Your character is a highly trained martial artist. Their feet and fists are lethal weapons. Add +1d6 to the damage rolls of all unarmed attacks."
},
{
"name": "Maverick",
"description": "A brash, risk-taking combatant, the Maverick has raw talent and little time for rules and personal safety. They may spend a Hero Point to perform an additional action in a combat round. They may use this ability as an interrupting action, and act out of initiative sequence. But beware: whenever they use this ability, enemies may target the character with +1D to hit in the next round."
},
{
"name": "Quick Draw",
"description": "If the character has a weapon at the ready—in a quick-draw holster or sheath, or just at hand—then they may make a rapid attack at the start of the first round of combat, before the initiative order. They incur one Penalty Die on the attack."
},
{
"name": "Relentless",
"description": "This talent allows the character to temporarily ignore the effects of one hit in combat. They may use this talent after they have learned what the damage might be. After the combat, roll on the Triage table."
},
{
"name": "Sneak Attack",
"description": "This character is well practiced at sneak attacks. When attacking a completely unaware target in melee, gain +1D to hit, and +1D to the attack's damage."
},
{
"name": "Tactics",
"description": "At the start of a fight, roll Knowledge 8+. The characters training and drills provide a number of Advantage Dice equal to the result of the roll, minus 7 (with 8 providing +1D). These Advantage Dice can be spent by the character and their comrades at any time during the combat."
},
{
"name": "Two-Fisted",
"description": "The character may wield a one-handed weapon in each hand. They may attack with each of the two weapon once per round. Their second action in the round cannot be used to make another two attacks. The attack from the off-hand weapon is made with a -1D penalty. If the character is also Ambidextrous (see below), then the Penalty Die is removed."
},
{
"name": "Weak Point",
"description": "With training and experience, this character can spot an opening in an opponents armor or defensive posture. Throw Knowledge 12+ to grant you and your allies +1D to hit against a single enemy during the next round."
},
{
"name": "Whirlwind",
"description": "On the characters turn, they may spend a Hero Point to make another melee attack that round."
},
{
"name": "Ambidextrous",
"description": "This character has an innate or learned ability to use their off-hand equally as well as their dominant hand. This is useful in case of injury, among other things. However, without the Two-Fisted Talent they cant use a second weapon to attack with their off-hand."
},
{
"name": "Awareness",
"description": "Gain +1D on throws to avoid Surprise in combat. This does not refer to setting up ambushes, where the Hunter Talent applies."
},
{
"name": "Beast Friendship",
"description": "Gain +1D when identifying flora or fauna, as well as in Reaction throws with (non-magical) animals."
},
{
"name": "Big Mouth",
"description": "This character has a witty retort, insult, or inspiring word at the ready for all occasions. The character gains +1D whenever they are involved in an argument, debate, or they just want to aggravate or antagonize someone."
},
{
"name": "Charming",
"description": "This characters natural habitat is a room full of people. Gain +1D when carousing, networking, or making a good impression in social settings."
},
{
"name": "Deduction",
"description": "Spend a Hero Point to ask the GM three yes-or-no questions about any person, place, or object you are investigating or observing."
},
{
"name": "Determined",
"description": "Gain one extra Hero Point at the start of each game session."
},
{
"name": "Eidetic Memory",
"description": "This character remembers everything their senses receive in raw excruciating detail. They gain +1D whenever they try to remember details of past events."
},
{
"name": "Empath",
"description": "This talent represents an innate ability to relate to other sentient beings. The character gains +1D on Reaction throws when interacting with humans and sentient aliens."
},
{
"name": "Endurance",
"description": "Your character is used to physical hardship. Ignore the first Penalty Die from fatigue, pain, Wounds (including the Physical roll to keep fighting), or other physical difficulties."
},
{
"name": "Pet",
"description": "The character has a special animal companion that is extremely loyal, surprisingly intelligent, but not particularly obedient. Distribute 4 points among Combat, Physical, Social, and Stealth skills, determine Stamina and Lifeblood normally, and select two innate Talents for it. The Referee has final say on what Talents are appropriate."
},
{
"name": "Immunity",
"description": "The character has a very strong immune system. They gain +1D on throws to resist the effects of poisons and disease."
},
{
"name": "Infuriating",
"description": "The character is a notorious troll. The character may taunt a target as an action: roll Social 8+. If successful, one target creature gains a Penalty Die on their actions for the next round."
},
{
"name": "Ingenious",
"description": "The character is talented at improvising with technology and their environmental surroundings in delightfully different ways. Gain +1D when the character uses tools or found objects in an interesting or creative manner."
},
{
"name": "Insightful",
"description": "Due to training or intuition, the character gains +1D when attempting to determine if someone is lying to them."
},
{
"name": "Inspiring",
"description": "As an Action in combat, they may offer a word of inspiration to a comrade, and grant +1D to whatever action the comrade is attempting."
},
{
"name": "Intimidating",
"description": "Gain +1D to rolls made to intimidate and terrify opponents."
},
{
"name": "Mighty",
"description": "The character is a physically powerful specimen. Gain +1D to all Physical skill rolls when attempting feats of strength and athleticism."
},
{
"name": "Runner",
"description": "The character gains +1D when engaging in foot races, sprints over obstacles, or other feats of athletic speed. This Talent does not apply to changing range bands in combat, unless the Referee allows it in specific situations. In cases where exact distances are required, the Runner talent adds 1d6 to the 10m of distance covered with each Move action. The d6 roll is an abstraction to take into account rougher terrain and unforeseen obstacles. If both Move actions are used to run, then the total distance is 20 + 2d6m that round."
},
{
"name": "Status",
"description": "This character has some sort of innate social status or rank that provides privileges. This may include special treatment, or higher level security access. The player and Referee should determine what the source of this status is."
},
{
"name": "Ace Pilot",
"description": "When piloting ships or other vehicles, this character gains +1D to Position rolls."
},
{
"name": "Acrobat",
"description": "The character is a highly trained gymnast and acrobat, and is comfortable operating at great heights. Gain +1D on Physical throws for tumbling, athletics, jumps, and landings."
},
{
"name": "Animal Handling",
"description": "Through training or natural affinity, the character is good with animals, and knows how to care for them. This also extends to riding animals. Gain +1D when dealing with animals, or when making throws to ride animals. This is cumulative with Beast Friendship."
},
{
"name": "Broker",
"description": "You have an expert eye for merchandise and deal making. Gain +1D when rolling to negotiate trade deals and haggle on prices."
},
{
"name": "Commando",
"description": "Commando training covers stealth and sabotage. The character gains +1D when infiltrating enemy positions and when setting explosives to destroy military targets like radar dishes and ammunition depots."
},
{
"name": "Con Artist",
"description": "The character is an accomplished liar, and has developed false identities. Gain +1D when acting as an imposter, or when running a confidence scheme."
},
{
"name": "Contortionism",
"description": "This character is trained in moving their body in very tight confines. The character may throw Physical 10+ to escape from bonds or manacles, or to slip through bars."
},
{
"name": "Demolitions Expert",
"description": "This talent grants the character +1D when setting explosives, carrying out controlled demolition operations of buildings, bridges, and other large structures, and disarming explosives."
},
{
"name": "Detective",
"description": "The character has a trained eye for details and is very familiar with investigative and forensic protocols. Gain +1D when looking for clues or conducting interrogations."
},
{
"name": "Drone Operator",
"description": "Whether a hard-working asteroid miner, a canny salvager, or a combat photographer, this character is a gifted drone operator. They gain +1D whenever they need to perform difficult tasks remotely with drones or other remotely controlled robots."
},
{
"name": "Gambler",
"description": "You know how to play games of chance very well. You also know how to cheat, and how to spot a cheater. Gain +1D for Knowledge throws to win a game. Gain +1D when using the Social skill to cheat, or to spot a cheater."
},
{
"name": "Ghost",
"description": "Whenever the character is attempting to sneak under cover of darkness, smoke, or other obscuring cover, they gain +1D."
},
{
"name": "Hacker",
"description": "Hackers are not just expert programmers. They are gifted improvisers who understand how to build workarounds on the fly, and make computers do their bidding. Gain +1D when attempting to hack a computer system, break encryption, jam sensors, or counter sensor jamming."
},
{
"name": "Intelligence Analyst",
"description": "This character has received specialized training in intelligence gathering and analysis. Whenever they are attempting to make sense of large amounts of data and determining what is actually going on, they gain +1D."
},
{
"name": "Logistics Expert",
"description": "This character has gained expertise in making plans and getting resources to where they have to be, on time. Gain +1D when drawing up plans, negotiating with suppliers, and ensuring that things run smoothly."
},
{
"name": "Medic",
"description": "This character has received enough life-saving medical training to act as a combat medic. They grant characters under their treatment with +1D on rolls on the Triage Table."
},
{
"name": "Professional",
"description": "This character had a well-developed career before becoming a Nomad. They have a non-combat professional background of some kind that might come in useful: administration, law, accounting, or the like. They gain +1D when practicing their profession."
},
{
"name": "Rigger",
"description": "You are an expert at quick battlefield repairs. Gain +1D when attempting to make a spot repair on a vehicle. The repair fail after the battle is over; more extensive repairs will have to be made later on."
},
{
"name": "Scholar",
"description": "Gain +1D when dealing in a specific field of knowledge, such as biology, physics, history, or mathematics. This includes research, experimentation, and drawing conclusions. This Talent can be taken multiple times, each applying to a different field of study."
},
{
"name": "Spacer",
"description": "Some individuals are born in outer space, while others become so acclimated that they could have been born there anyways. This character gains +1D when attempting physical skills in zero-gravity, or whenever they are operating in the vacuum of space."
},
{
"name": "Streetwise",
"description": "The character is wise to the criminal element wherever they find themselves. They gain +1D when attempting to fence stolen goods, find illegal work, or make connections with criminals."
},
{
"name": "Street Thief",
"description": "This character is a practiced petty criminal. Gain +1D whenever attempting to pick pockets, open locks, hotwire vehicles, or when fencing stolen goods."
},
{
"name": "Survivalist",
"description": "Gain +1D when making skill rolls involving wilderness survival, hunting, and overland navigation."
},
{
"name": "Tech Specialist",
"description": "Gain +1D when dealing with a specific technological field of knowledge: electronics, computers, vehicle mechanics, power systems, or weapons systems. This includes repairing devices and designing them."
},
{
"name": "Tinker",
"description": "This character spends all their free time tinkering with everyones gear. Once per game session, each player character gains +1D when using their personal equipment."
},
{
"name": "Untraceable",
"description": "You are especially well-practiced at passing through an area and covering your tracks. Anyone attempting to track you is penalized by -1D to the roll."
}
]

View File

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

View File

@@ -0,0 +1,254 @@
[
{
"name": "Ground Car",
"agility": 0,
"armor": "6/8",
"cargo": "250kg",
"crew": "1/4",
"force": 0,
"range": "400km",
"speed": "160km/h",
"techAge": "Early Mechanical",
"tonnage": "2 Tons",
"cost": 10000,
"description": "The ground car is popular with civilians on many worlds due to its rugged and simple construction. They are ubiquitous with models for sale or rental everywhere. Typically has no weapon."
},
{
"name": "Pickup Truck",
"agility": 0,
"armor": "6/8",
"cargo": "1 ton",
"crew": "1/6",
"force": 1,
"range": "400km",
"speed": "120km/h",
"techAge": "Early Mechanical",
"tonnage": "4 Tons",
"cost": 15000,
"description": "A bigger version of the ground car with a flat-bed cargo bay instead of passenger seating. Any passengers would sit in the open bay. This is a ubiquitous vehicle and has a notable reputation for being able to go anywhere, and in any condition. Many mercenary teams desperately get their hands on pickup trucks and fit any manner of weapons onto their flatbed. Some manufacturers are happy to see a new market for their vehicles. Others are less enthusiastic. Typically has no weapon."
},
{
"name": "Armored Personnel Carrier",
"agility": -1,
"armor": "12/16",
"cargo": "2 tons",
"crew": "2/8",
"force": 2,
"range": "400km",
"speed": "60km/h",
"techAge": "Late Mechanical",
"tonnage": "5 Tons",
"cost": 177250,
"description": "Introduced in the Mechanical Age, Armored Personnel Carriers are essential to modern warfare, allowing infantry to keep pace with armored units. Weapons include a Heavy Machinegun (Damage 5d6, Auto, AV 3d6). Some mount a Light Autocannon (Damage 5d6, Auto, AV 4d6)."
},
{
"name": "Light Tank",
"agility": -1,
"armor": "14/20",
"cargo": "1 ton",
"crew": "2/8",
"force": 2,
"range": "500km",
"speed": "60km/h",
"techAge": "Late Mechanical",
"tonnage": "10 Tons",
"cost": 177250,
"description": "The light tank is popular in various low-tech worlds for internal security and counter insurgency. In wartime they are used to reconnoiter for heavier armored vehicles. Later models include IR sensors and fire suppression systems for the crew. Weapons include a Heavy Machinegun (Dam 5d6, Auto, AV 3d6), Light Cannon (Dam 4d6, AV 4d6)."
},
{
"name": "Sports Car",
"agility": 0,
"armor": "5/7",
"cargo": "200kg",
"crew": "1/1",
"force": 1,
"range": "360km",
"speed": "240km/h",
"techAge": "Late Mechanical",
"tonnage": "2 Tons",
"cost": 14825,
"description": "The sports car is popular with the wealthy on many worlds due to its speed and comfort. Typically has no weapon."
},
{
"name": "Explorer",
"agility": -2,
"armor": "7/10",
"cargo": "1500kg",
"crew": "2/2",
"force": 2,
"range": "Unlimited",
"speed": "60km/h",
"techAge": "Early Interstellar",
"tonnage": "10 Tons",
"cost": 159300,
"description": "Explorers are popular ground vehicles in Early Interstellar Age cultures. It is powered by a Fusion pack which provides effectively unlimited range. The Explorer carries a driver, a sensor technician, and two passengers in cramped seats. The sensor operator has dual controls for driving. Two bunks allow sleeping in rotation to recover from fatigue. Life Support lasts indefinitely. The ample cargo bay, rest accommodations, and amenities make the Explorer very popular with survey crews. Sensors: IR, Radar, Ladar, Dynamometer. Has no weapon."
},
{
"name": "Hovercraft",
"agility": -1,
"armor": "6/8",
"cargo": "1750kg",
"crew": "1/5",
"force": 1,
"range": "400km",
"speed": "160km/h",
"techAge": "Early Atomic",
"tonnage": "10 Tons",
"cost": 40800,
"description": "Hovercraft can travel over virtually any terrain or water. This civilian hovercraft has an unarmored chassis, and transports five passengers in cramped seats alongside the driver. This vehicle also has a waterproof body, allowing it to float. Has no weapon."
},
{
"name": "Cabin Cruiser",
"agility": -2,
"armor": "6/8",
"cargo": "2000kg",
"crew": "2/3",
"force": 2,
"range": "1080km",
"speed": "15 km/h",
"techAge": "Late Mechanical",
"tonnage": "10 Tons",
"cost": 25100,
"description": "The Cabin Cruiser serves for fishing and other leisure activities. It also can be fitted with weapons and used for security duties (shown in the example). The below-deck area is popular with crew, though a galley is not provided. A skipper, gunner, and three passengers are carried above deck. There are two bunks below-decks. The civilian version removes the weapon station and adds 0.5 tons of cargo and costs 13,600 Credits. Weapon is GP Machinegun (Damage 3d6+3, Auto, AV 2d6)."
},
{
"name": "Speedboat",
"agility": 0,
"armor": "6/8",
"cargo": "750kg",
"crew": "1/4",
"force": 0,
"range": "600km",
"speed": "120km/h",
"techAge": "Late Mechanical",
"tonnage": "2 Tons",
"cost": 14750,
"description": "The Speed Boat was designed for harbor and coastal patrol, as well as for leisure activities during the Late Mechanical Age. There is no below deck area. A skipper and four passengers are carried above deck. Has no weapon."
},
{
"name": "Mini-Sub",
"agility": -3,
"armor": "9/12 (pressure hull)",
"cargo": "1150kg",
"crew": "1/4",
"force": 1,
"range": "1080km",
"speed": "40km/h surface, 20km/h submerged",
"techAge": "Late Mechanical",
"tonnage": "10 Tons",
"cost": 358000,
"description": "This mini-sub can carry a pilot and four passengers in cramped seats. It has no airlock. Underwater, the mini-sub travels at 20kph up to two hours before having to surface and recharge its batteries. It has a maximum diving depth of 100 meters. Has no weapon."
},
{
"name": "Biplane",
"agility": 1,
"armor": "6/9",
"cargo": "Negligible",
"crew": "1/1",
"force": 0,
"range": "1000km",
"speed": "250km/h",
"techAge": "Late Mechanical",
"tonnage": "2 Tons",
"cost": 61000,
"description": "Biplanes are simple aircraft, using twin wings to generate lift. They have a maximum speed of 250km/h, and a Stall Speed of 80km/h. Armed variants carry machineguns, while unarmed variants gain 100kg of cargo space. Weapon is GP Machinegun (Damage 3d6+3, Auto, AV2d6)."
},
{
"name": "Propeller Plane",
"agility": 1,
"armor": "7/10",
"cargo": "500kg",
"crew": "2/3",
"force": 0,
"range": "2000km",
"speed": "400km/h",
"techAge": "Late Mechanical",
"tonnage": "10 Tons",
"cost": 166000,
"description": "The propeller-driven monoplane soon supersedes the biplane in the Late Mechanical Age. This variant is used for urgent errands on frontier planets, and can carry a pilot, co-pilot, and four passengers (one being a gunner). This aircraft has a stall speed of 120km/h and requires a landing strip. Weapon is GP Machinegun (Damage 3d6+3, Auto, AV2d6)."
},
{
"name": "Cargo Plane",
"agility": 0,
"armor": "8/11",
"cargo": "4000kg",
"crew": "2/20",
"force": 1,
"range": "2000km",
"speed": "400km/h",
"techAge": "Late Mechanical",
"tonnage": "20 Tons",
"cost": 250000,
"description": "This is a medium sized cargo plane driven by two, three, or four propellers. It is very reliable and rugged and can be found on any world where aircraft are useful and cheap to operate. Has no weapon."
},
{
"name": "Helicopter",
"agility": 1,
"armor": "7/10",
"cargo": "500kg",
"crew": "1/1",
"force": 1,
"range": "2100km",
"speed": "250km/h",
"techAge": "Late Mechanical",
"tonnage": "10 Tons",
"cost": 193500,
"description": "Introduced in the Late Mechanical Age, the Helicopter is the first heavier-than-air aircraft capable of hovering and vertical flight. It is popular on Earth-like worlds for search and rescue, law enforcement, and supply runs to remote settlements since it doesnt need a landing strip. Has no weapon."
},
{
"name": "Jump Jet",
"agility": 1,
"armor": "7/10",
"cargo": "1250kg",
"crew": "2/3",
"force": 1,
"range": "2500km",
"speed": "800km/h",
"techAge": "Early Atomic",
"tonnage": "12 Tons",
"cost": 656000,
"description": "Jump Jets became feasible in the Early Atomic Age. They provide the high speed and high-altitude flight of normal jet aircraft, as well as the hovering, take-off, and landing capabilities of a helicopter. This version carries a pilot, flight engineer/electronics specialist, and three passengers. A commercial passenger version removes the advanced sensors and carries a pilot and 8 passengers with 1.5 tons of cargo. It costs 647000 Credits. Has no weapon."
},
{
"name": "Sky Car",
"agility": 2,
"armor": "7/9",
"cargo": "500kg",
"crew": "1/3",
"force": 1,
"range": "8000km",
"speed": "800km/h",
"techAge": "Early Space",
"tonnage": "5 Tons",
"cost": 170000,
"description": "This Space Age Skycar or “Buzzer” is a small, lightly armored vehicle. Skycars are often used by the authorities, emergency services, and the super-rich. This vehicle can hover in place. It holds a pilot and three passengers in cramped seats. Has no weapon (as per its listed stats, though an example later states it can be equipped with a Support Laser)."
},
{
"name": "Jet Fighter",
"agility": 1,
"armor": "7/10",
"cargo": "Nil",
"crew": "2/0",
"force": 1,
"range": "5000km",
"speed": "2000km/h",
"techAge": "Early Atomic",
"tonnage": "10 Tons",
"cost": 454000,
"description": "Jet fighters are a crucial defense against raiders and invasion. First introduced in the Early Atomic Age, they continue to improve until the Interstellar Age and are vital to planets with little or no space presence. This fighter has a crew of two: a pilot and electronics specialist, who both must wear oxygen masks. Jet fighters require extensive landing strips and maintenance to keep them flying. The aircrafts stall speed is 300km/h, and they cannot reach their top speed without being at very high altitudes. Sensors: IR, Radar. Weapons include Light Autocannon (5d6, Auto, AV 3d6+1), 2x Anti-Tank Missile (5d6, Blast, AV 5d6), 2x Anti-Aircraft Missile (4d6, Blast, AV 3d6)."
},
{
"name": "Grav Car",
"agility": 2,
"armor": "7/9",
"cargo": "1750kg",
"crew": "1/5",
"force": 1,
"range": "Unlimited",
"speed": "1000km/h",
"techAge": "Late Galactic",
"tonnage": "5 Tons",
"cost": 170000,
"description": "The Grav Car is civilian transportation in the Late Galactic Age. It is built on a small, unarmored chassis. Its gravity drive gives it an impressive top speed and allows hovering or vertical flight. The grav car can reach orbit in 1d6 hours. Its cabin is sealed. Has no weapon."
}
]

View File

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

View File

@@ -0,0 +1,255 @@
[
{
"name": "Anti-Materiel Rifle",
"tech_age": "Late Mechanical",
"range": "Rifle",
"cost": 1200,
"mag": 5,
"ammo_cost": 100,
"damage": "5d6",
"aspects": ["Scope", "AV 2d6"],
"description": "A rifle that fires re-purposed Heavy Machinegun or light cannon ammunition. Some are used as sniper rifles among elite soldiers."
},
{
"name": "Assault Rifle",
"tech_age": "Early Atomic",
"range": "Assault",
"cost": 300,
"mag": 30,
"ammo_cost": 15,
"damage": "3d6",
"aspects": ["Auto"],
"description": "The standard military weapon on mid-tech worlds. An automatic rifle that fires an intermediate caliber. At the Referee's discretion, its ammunition, or even magazines, may be interchangeable with those of a Carbine."
},
{
"name": "Bow",
"tech_age": "Early Primitive",
"range": "Rifle",
"cost": 60,
"mag": 1,
"ammo_cost": 10,
"damage": "2d6",
"aspects": [],
"description": "These are muscle-powered ranged weapons. Arrows for a bow or bolts for a crossbow are stored in a quiver of 20, which counts as one encumbrance item. A Bow may fire once per Action."
},
{
"name": "Crossbow",
"tech_age": "Late Primitive",
"range": "Rifle",
"cost": 75,
"mag": 1,
"ammo_cost": 10,
"damage": "3d6",
"aspects": [],
"description": "These are muscle-powered ranged weapons. Arrows for a bow or bolts for a crossbow are stored in a quiver of 20, which counts as one encumbrance item. A Crossbow requires 2 actions to reload."
},
{
"name": "Carbine",
"tech_age": "Early Atomic",
"range": "Assault",
"cost": 400,
"mag": 20,
"ammo_cost": 15,
"damage": "3d6",
"aspects": ["Auto"],
"description": "This weapon is popular among vehicle crews and light infantry due to its handiness and light weight. Carbines often fire regular assault rifle ammunition, but some fire pistol ammunition. Carbines count as one encumbrance item."
},
{
"name": "Gyrojet Rifle",
"tech_age": "Early Space",
"range": "Assault",
"cost": 900,
"mag": 20,
"ammo_cost": 15,
"damage": "3d6+2",
"aspects": ["Auto", "Zero-G"],
"description": "Designed for use in zero-G environment, gyrojet weapons fire small, self-propelled rocket rounds. They have minimal recoil and work in vacuum as well."
},
{
"name": "Gyrojet Pistol",
"tech_age": "Early Space",
"range": "Handgun",
"cost": 400,
"mag": 8,
"ammo_cost": 10,
"damage": "2d6+2",
"aspects": ["Zero-G"],
"description": "Designed for use in zero-G environment, gyrojet weapons fire small, self-propelled rocket rounds. They have minimal recoil and work in vacuum as well."
},
{
"name": "Light Machinegun",
"tech_age": "Late Mechanical",
"range": "Rifle",
"cost": 1200,
"mag": 100,
"ammo_cost": 125,
"damage": "3d6",
"aspects": ["Auto", "Bulky"],
"description": "This is the standard mid-tech squad-level support automatic weapon and is typically belt-fed. Light machine guns count as two items for encumbrance purposes."
},
{
"name": "Pulse Rifle",
"tech_age": "Late Space",
"range": "Assault",
"cost": 1000,
"mag": 40,
"ammo_cost": 30,
"damage": "3d6+3",
"aspects": ["Auto"],
"description": "An advanced automatic rifle that fires electrically ignited, caseless, high explosive, armor-piercing rounds. The ultimate in projectile weaponry. The pulse rifle provides a high rate of fire and a large magazine capacity."
},
{
"name": "Revolver",
"tech_age": "Early Mechanical",
"range": "Handgun",
"cost": 150,
"mag": 6,
"ammo_cost": 5,
"damage": "2d6+1",
"aspects": [],
"description": "A simple handgun that uses a manually loaded rotating drum to feed the action. Revolvers are reliable weapons."
},
{
"name": "Rifle",
"tech_age": "Early Mechanical",
"range": "Rifle",
"cost": 500,
"mag": 8,
"ammo_cost": 15,
"damage": "3d6+3",
"aspects": [],
"description": "The standard military firearm on low-tech worlds. Rifles use larger caliber projectiles and are common hunting weapons on the interstellar frontier."
},
{
"name": "Semi-Auto Pistol",
"tech_age": "Late Mechanical",
"range": "Handgun",
"cost": 150,
"mag": 16,
"ammo_cost": 7,
"damage": "2d6",
"aspects": [],
"description": "This is a handgun fed from a magazine. One pull of the trigger fires one bullet. At the Referee's discretion, its ammunition, or even magazines, may be interchangeable with those of a Submachine Gun."
},
{
"name": "Shotgun",
"tech_age": "Early Mechanical",
"range": "Assault",
"cost": 200,
"mag": 6,
"ammo_cost": 10,
"damage": "4d6",
"aspects": ["Scatter."],
"description": "A smoothbore weapon that fires shot pellets capable of hitting multiple targets at once. Shotguns are effective short-ranged weapons, but are not useful beyond Near Range, or against armored targets. These particulate stats represent a pump-action weapon with an internal magazine."
},
{
"name": "Sniper Rifle",
"tech_age": "Late Mechanical",
"range": "Rifle",
"cost": 800,
"mag": 5,
"ammo_cost": 30,
"damage": "3d6+3",
"aspects": ["Scope"],
"description": "This rifle is a higher quality version of the standard rifle, with better optics. It fires higher quality ammunition as well."
},
{
"name": "Stealth Pistol",
"tech_age": "Early Space",
"range": "Handgun",
"cost": 500,
"mag": 6,
"ammo_cost": 20,
"damage": "2d6",
"aspects": [],
"description": "This is an especially light, discreet, and concealable weapon made from advanced polymers. A stealth pistol can also be disguised as more innocuous items, like comms, digital recorders, and so on."
},
{
"name": "Submachine Gun",
"tech_age": "Late Mechanical",
"range": "Assault",
"cost": 500,
"mag": 30,
"ammo_cost": 20,
"damage": "2d6",
"aspects": ["Auto"],
"description": "This is a light automatic weapon that fires pistol rounds. It is intended for close quarters combat and counts as one item for encumbrance purposes."
},
{
"name": "Blaster Pistol",
"tech_age": "Late Interstellar",
"range": "Handgun",
"cost": 5000,
"mag": 20,
"ammo_cost": 100,
"damage": "3d6+2",
"aspects": ["Laser", "AV 1d6"],
"description": "Blasters are advanced laser weapons with greater power and penetration. Their power packs are rechargeable from any major power source, such as a ships power plant [1]."
},
{
"name": "Blaster Rifle",
"tech_age": "Late Interstellar",
"range": "Rifle",
"cost": 10000,
"mag": 50,
"ammo_cost": 500,
"damage": "4d6+3",
"aspects": ["Auto", "Laser", "AV 2d6"],
"description": "Blasters are advanced laser weapons with greater power and penetration. Their power packs are rechargeable from any major power source, such as a ships power plant [1]."
},
{
"name": "Laser Pistol",
"tech_age": "Late Space",
"range": "Handgun",
"cost": 1500,
"mag": 10,
"ammo_cost": 50,
"damage": "3d6",
"aspects": ["Laser"],
"description": "A handgun-sized directed energy weapon. Its power pack is rechargeable from any major power source, such as a ships power plant [1]."
},
{
"name": "Laser Rifle",
"tech_age": "Early Space",
"range": "Rifle",
"cost": 3500,
"mag": 20,
"ammo_cost": 100,
"damage": "4d6",
"aspects": ["Laser", "AV 1d6"],
"description": "A long-range version of the laser pistol, with better armor penetration, range, and even light anti-vehicular capabilities [1]."
},
{
"name": "Plasma Rifle",
"tech_age": "Early Galactic",
"range": "Rifle",
"cost": 15000,
"mag": 10,
"ammo_cost": 500,
"damage": "6d6",
"aspects": ["Fire", "AV 3d6"],
"description": "The ultimate small arms, using miniaturized plasma gun technology to propel magnetically shaped pockets of super-hot ionized plasma at its targets [1]."
},
{
"name": "Plasma Pistol",
"tech_age": "Late Galactic",
"range": "Handgun",
"cost": 10000,
"mag": 6,
"ammo_cost": 200,
"damage": "5d6",
"aspects": ["Fire", "AV 3d6"],
"description": "The ultimate small arms, using miniaturized plasma gun technology to propel magnetically shaped pockets of super-hot ionized plasma at its targets [1]."
},
{
"name": "Stunner",
"tech_age": "Early Interstellar",
"range": "Assault",
"cost": 600,
"mag": 10,
"ammo_cost": 10,
"damage": "3d6+1",
"aspects": ["Stun", "Zero-G"],
"description": "Firing a precise electromagnetic pulse, this non-lethal weapon disrupts the target's neural processes, leading to incapacitation and potentially unconsciousness. The stunner counts as one item for encumbrance purposes [2]."
}
]

View File

@@ -0,0 +1,123 @@
[
{
"name": "Anti-Aircraft Rocket Launcher",
"tech_age": "Early Atomic",
"range": "HeavyWeapon",
"cost": 10000,
"mag": 1,
"ammo_cost": 500,
"damage": "4d6",
"aspects": ["AV 3d6"],
"description": "This is a portable anti-air defense system designed to shoot down enemy aircraft with a self-guided rocket. It is not particularly effective against armored vehicles: reduce AV dice to 2d6."
},
{
"name": "Disposable Anti-Vehicle Rocket",
"tech_age": "Late Mechanical",
"range": "Assault",
"cost": 200,
"mag": 1,
"ammo_cost": null,
"damage": "4d6",
"aspects": ["Blast", "Bulky", "AV 4d6"],
"description": "A cheap, single-use, portable rocket launcher. These are often the only anti-tank weapons available to infantry. Note that this weapon cannot make attacks at Close range, despite using the Assault weapon range modifiers."
},
{
"name": "Flamer",
"tech_age": "Late Mech.",
"range": "Assault",
"cost": 1000,
"mag": 5,
"ammo_cost": 25,
"damage": "3d6",
"aspects": ["Bulky", "Fire"],
"description": "These terrifying weapons spew a stream of fire 3m wide at its far end. All targets within this cone suffer damage and catch fire (see the Environmental Hazards rules). The tank for the flamethrower itself holds enough fuel for five full attacks and counts as two items for encumbrance."
},
{
"name": "General Purpose Machinegun",
"tech_age": "Late Mechanical",
"range": "Rifle",
"cost": 1500,
"mag": 100,
"ammo_cost": 150,
"damage": "3d6+3",
"aspects": ["Auto", "Bulky", "AV 2d6"],
"description": "A belt-fed medium machine gun. These are often mounted on vehicles but are also portable, although they are 3 items of encumbrance. Usually they are crew-served."
},
{
"name": "Grav Launcher",
"tech_age": "Late Interstellar",
"range": "HeavyWeapon",
"cost": 20000,
"mag": 1,
"ammo_cost": 100,
"damage": "6d6",
"aspects": ["Greater Blast", "Bulky", "Fire", "AV 5d6"],
"description": "Advanced micro-gravitic technology allows this weapon to guide a floating plasma bomb to its target without having to account for ballistic trajectories or inertia. Once launched, the bomb travels 50m per combat round. Its operator can move it in any direction and can also stop it and have it hover in mid-air. Detonation is on command. The bomb's internal battery allows for 10 rounds of gravitic flight."
},
{
"name": "Guided Anti-Tank Missile",
"tech_age": "Early Atomic",
"range": "HeavyWeapon",
"cost": 4000,
"mag": 1,
"ammo_cost": 200,
"damage": "5d6",
"aspects": ["Blast", "AV 5d6"],
"description": "This is a portable guided missile system, like the older AT-3 Sagger, or present-day Javelin and Eryx systems. These weapons must be fired from a fixed stationary position. However, the gunner need not be adjacent to the missiles firing position."
},
{
"name": "Heavy Machinegun",
"tech_age": "Early Mechanical",
"range": "HeavyWeapon",
"cost": 2000,
"mag": 100,
"ammo_cost": 200,
"damage": "5d6",
"aspects": [],
"description": "This is the largest portable support weapon in the Mechanical and Atomic ages. These weapons are usually mounted on vehicles but can be mounted on fixed tripods. If they are carried, they count as four items of encumbrance and each ammo pack is two items of encumbrance."
},
{
"name": "Plasma Gun",
"tech_age": "Late Interstellar",
"range": "Rifle",
"cost": 20000,
"mag": 40,
"ammo_cost": 2500,
"damage": "6d6",
"aspects": ["Bulky", "Fire", "AV 5d6"],
"description": "A high-energy, anti-vehicular, portable weapon firing magnetically contained plasma bolts. It requires a backpack-mounted, rechargeable power pack that counts as two Items for encumbrance purposes."
},
{
"name": "Rocket Launcher",
"tech_age": "Early Atomic",
"range": "HeavyWeapon",
"cost": 2000,
"mag": 1,
"ammo_cost": 150,
"damage": "4d6",
"aspects": ["Greater Blast", "Bulky", "AV 3d6"],
"description": "A portable rocket launcher utilizing unguided munitions. Rocket launchers are unsafe to fire in enclosed spaces. Rocket payloads are considered high explosive and are not particularly effective against armored vehicles. Armor piercing rockets cost 500 Credits per rocket: trade the Greater Blast for AV 4d6, Blast. Rocket launchers can also be mounted on vehicles, where they usually have 12 or even 24 shots before requiring reloading."
},
{
"name": "Support Laser",
"tech_age": "Early Space",
"range": "HeavyWeapon",
"cost": 5000,
"mag": 20,
"ammo_cost": 200,
"damage": "5d6",
"aspects": ["Bulky", "AV 3d6+1"],
"description": "This is a heavy directed-energy portable weapon for fire support and light anti-vehicular duties. Its backpack mounted power pack counts as two Items for encumbrance purposes."
},
{
"name": "Under-barrel Grenade Launcher",
"tech_age": "Early Atomic",
"range": "Rifle",
"cost": 1000,
"mag": 1,
"ammo_cost": null,
"damage": "By gren.",
"aspects": [],
"description": "This weapon greatly increases the firepower of an infantry team. The under-barrel grenade launcher can be mounted under most two-handed firearms in the Early Atomic Age or later. It is not Bulky and can fire a single grenade before reloading. In the Late Space Age, the weapon has a 3-shot magazine."
}
]

View File

@@ -0,0 +1,105 @@
[
{
"cost": 25,
"damage": "2d6+1",
"description": "A one-handed ax made from metal or stone, anything from a stone-age tool through a medieval war ax to a modern fire ax [1].",
"name": "Axe",
"tech_age": "Early Primitive",
"aspects": [
"Throwable"
]
},
{
"cost": 300,
"damage": "3d6+1",
"description": "A large two-handed sword that counts as 2 items for encumbrance purposes. A two-handed Great-Axe uses the same stats [1].",
"name": "Greatsword or Great-Axe",
"tech_age": "Late Primitive",
"aspects": [
"Bulky",
"Two-Handed"
]
},
{
"cost": 10,
"damage": "2d6",
"description": "A straight, short knife [1].",
"name": "Dagger",
"tech_age": "Early Primitive",
"aspects": [
"Throwable"
]
},
{
"cost": 50,
"damage": "2d6+1",
"description": "A simple yet sturdy broad blade used for cutting foliage and foes alike [1].",
"name": "Machete",
"tech_age": "Late Primitive",
"aspects": []
},
{
"cost": 500,
"damage": "1d6",
"description": "This slavers weapon consists of a stocky handle connected to a flexible strap. Each attack causes stun damage. Additionally, any target hit must roll Physical or fall to the ground, incapacitated for 2d6 combat rounds due to nightmarish pain. It also causes 1d6 physical damage per hit. The neural whip is ineffective against anyone in armor [1, 2].",
"name": "Neural Whip",
"tech_age": "Late Interstellar",
"aspects": [
"Stun"
]
},
{
"cost": 20,
"damage": "1d6+1",
"description": "A personal shield, primarily used to protect its wielder by providing a -1D penalty against melee attacks. Anyone carrying a shield can penalize a number of enemy attacks per round equal to their Combat skill -1, with a minimum of 1 [2].",
"name": "Shield",
"tech_age": "Early Primitive",
"aspects": []
},
{
"cost": 15,
"damage": "3d6",
"description": "This weapon comes in all types of construction, from a sharpened shaft to a metal-tipped spear. Regardless of how it was made, a spear is a basic, effective, melee weapon [3].",
"name": "Spear",
"tech_age": "Early Primitive",
"aspects": [
"Throwable"
]
},
{
"cost": 10,
"damage": "1d6+2",
"description": "A long wooden shaft used as a bludgeon, sometimes with metal fittings. It must be used with two hands [3].",
"name": "Staff",
"tech_age": "Early Primitive",
"aspects": [
"Two-Handed"
]
},
{
"cost": 300,
"damage": "2d6",
"description": "A high-tech anti-riot weapon. The stun prod augments the basic batons blunt force with an electric charge capable of stunning opponents [3].",
"name": "Stun Prod",
"tech_age": "Early Space",
"aspects": [
"Stun"
]
},
{
"cost": 150,
"damage": "3d6",
"description": "One of any variety of medium-sized one-handed blades, including the gladius, cutlass, longsword, and katana [3].",
"name": "Sword",
"tech_age": "Late Primitive",
"aspects": []
},
{
"cost": 1000,
"damage": "3d6+2",
"description": "An intermediate-sized, one-handed, bladed weapon that uses hypersonic micro-vibrations in the blade to create a deadly cutting edge [4].",
"name": "Vibroblade",
"tech_age": "Early Interstellar",
"aspects": []
}
]

File diff suppressed because it is too large Load Diff

View File

@@ -28,21 +28,30 @@ Hooks.once("init", function () {
applications,
models,
documents,
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
CONFIG.Item.dataModels = {
psionic: models.FTLNomadPsionic,
weapon: models.FTLNomadWeapon,
armor: models.FTLNomadArmor,
armor: models.FTLNomadArmor,
talent: models.FTLNomadTalent,
language: models.FTLNomadLanguage,
equipment: models.FTLNomadEquipment,
@@ -52,22 +61,23 @@ Hooks.once("init", function () {
}
// Register sheet application classes
Actors.unregisterSheet("core", ActorSheet)
Actors.registerSheet("fvtt-ftl-nomad", applications.FTLNomadCharacterSheet , { types: ["character"], makeDefault: true })
Actors.registerSheet("fvtt-ftl-nomad", applications.FTLNomadVehicleSheet, { types: ["vehicle"], makeDefault: true })
Actors.registerSheet("fvtt-ftl-nomad", applications.FTLNomadCreatureSheet, { types: ["creature"], makeDefault: true })
Actors.registerSheet("fvtt-ftl-nomad", applications.FTLNomadStarshipSheet, { types: ["starship"], makeDefault: true })
foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet)
foundry.documents.collections.Actors.registerSheet("fvtt-ftl-nomad", applications.FTLNomadCharacterSheet, { types: ["character"], makeDefault: true })
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 })
Items.unregisterSheet("core", ItemSheet)
Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadPsionicSheet, { types: ["psionic"], makeDefault: true })
Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadTalentSheet, { types: ["talent"], makeDefault: true })
Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadLanguageSheet, { types: ["language"], makeDefault: true })
Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadWeaponSheet, { types: ["weapon"], makeDefault: true })
Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadArmorSheet, { types: ["armor"], makeDefault: true })
Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadEquipmentSheet, { types: ["equipment"], makeDefault: true })
Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadImplantSheet, { types: ["implant"], makeDefault: true })
Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadCreatureTraitSheet, { types: ["creature-trait"], makeDefault: true })
Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadCreatureAbilitySheet, { types: ["creature-ability"], 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 })
foundry.documents.collections.Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadTalentSheet, { types: ["talent"], makeDefault: true })
foundry.documents.collections.Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadLanguageSheet, { types: ["language"], makeDefault: true })
foundry.documents.collections.Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadWeaponSheet, { types: ["weapon"], makeDefault: true })
foundry.documents.collections.Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadArmorSheet, { types: ["armor"], makeDefault: true })
foundry.documents.collections.Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadEquipmentSheet, { types: ["equipment"], makeDefault: true })
foundry.documents.collections.Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadImplantSheet, { types: ["implant"], makeDefault: true })
foundry.documents.collections.Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadCreatureTraitSheet, { types: ["creature-trait"], makeDefault: true })
foundry.documents.collections.Items.registerSheet("fvtt-ftl-nomad", applications.FTLNomadCreatureAbilitySheet, { types: ["creature-ability"], makeDefault: true })
// Other Document Configuration
CONFIG.ChatMessage.documentClass = documents.FTLNomadChatMessage
@@ -88,7 +98,7 @@ Hooks.once("init", function () {
FTLNomadUtils.registerSettings()
FTLNomadUtils.registerHandlebarsHelpers()
console.info("FTL Nomad | System Initialized")
})
@@ -115,7 +125,7 @@ Hooks.once("ready", function () {
})
Hooks.on("renderChatMessage", (message, html, data) => {
Hooks.on("renderChatMessageHTML", (message, html, data) => {
})

View File

@@ -100,7 +100,7 @@
},
"rank": {
"label": "Rank",
"experienced": {
"experienced": {
"label": "Experienced"
},
"expert": {
@@ -190,6 +190,18 @@
"Shallows" : "Shallows"
},
"FIELDS": {
"health": {
"staminaValue": {
"label": "Cur."
},
"staminaMax": {
"label": "Max"
},
"wounds": {
"label": "Wounds"
},
"label": "Stamina"
},
"damage": {
"label": "Damage"
},
@@ -280,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": {
@@ -330,16 +426,23 @@
"enc": {
"label": "Enc"
},
"loss": {
"label": "Loss"
},
"techAge": {
"label": "Tech Age"
}
}
},
"Label": {
"damages": "Damages",
"robot": "Robot",
"techAge": "Tech Age",
"mainStats": "Main Stats",
"formula": "Formula",
"damages": "Damage",
"modifications": "Modifications",
"abilities": "Abilities",
"Details": "Details",
"Details": "Details",
"traits": "Traits",
"capacity" : "Capacity",
"Agility" : "Agility",
@@ -347,11 +450,17 @@
"cargo": "Cargo",
"vehicle": "Vehicle",
"starship": "Starship",
"Easy4": "Easy (+4D)",
"Easy3": "Easy (+3D)",
"Easy2": "Easy (+2D)",
"Easy": "Easy (+1D)",
"Moderate": "Moderate (+0D)",
"Difficult": "Difficult (-1D)",
"Formidable": "Formidable (-2D)",
"Formidable3": "Formidable (-3D)",
"Impossible": "Impossible (-4D)",
"Impossible5": "Impossible (-5D)",
"Impossible6": "Impossible (-6D)",
"combat": "Combat",
"physical": "Physical",
"social": "Social",
@@ -390,13 +499,15 @@
"newArmor": "New Armor",
"newWeapon": "New Weapon",
"newTalent": "New Talent",
"newTrait": "New Trait",
"newAbility": "New Ability",
"newSkill": "New Skill",
"newImplant": "New Implant",
"newEquipment": "New Equipment",
"newLanguage": "New Language",
"newPsionic": "New Psionic",
"newCreatureAbility": "New Creature Ability",
"newCreatureTrait": "New Creature Trait",
"newCreatureTrait": "New Creature Trait",
"notes": "Notes",
"psionics": "Psionics",
"rollView": "Roll View",
@@ -406,7 +517,7 @@
"status": "Status",
"success": "Success",
"talents": "Talents",
"implants": "Implants",
"implants": "Implants",
"targetScore": "Target Score",
"titleSkill": "Skill Roll",
"titleWeapon": "Weapon Roll",
@@ -483,11 +594,14 @@
"Scout": "Scout",
"Picket": "Picket",
"Destroyer": "Destroyer",
"Cruiser": "Cruiser",
"Cruiser": "Cruiser",
"Battleship": "Battleship",
"Carrier": "Carrier"
},
"FIELDS": {
"techAge": {
"label": "Tech Age"
},
"monthlyCost": {
"label": "Monthly Cost"
},
@@ -558,13 +672,15 @@
"addSkill" : "Add Skill",
"addWeapon" : "Add Weapon",
"addArmor" : "Add Armor",
"addAbility" : "Add Ability",
"addEquipment" : "Add Equipment",
"addTrait" : "Add Trait",
"addImplant" : "Add Implant",
"addLanguage" : "Add Language",
"addPsionic" : "Add Psionic",
"addCreatureAbility" : "Add Creature Ability",
"addCreatureTrait" : "Add Creature Trait",
"damages": "Enter current damages suffered"
"damages": "Enter current damage suffered"
},
"Vehicle": {
"FIELDS": {
@@ -600,6 +716,9 @@
},
"notes": {
"label": "Notes"
},
"techAge": {
"label": "Tech Age"
}
}
},
@@ -612,6 +731,9 @@
"damage": {
"label": "Damage"
},
"aspect": {
"label": "Aspect"
},
"description": {
"label": "Description"
},
@@ -626,6 +748,12 @@
},
"weaponType": {
"label": "Type"
},
"ammoCost": {
"label": "Ammo Cost"
},
"magazine": {
"label": "Mag"
}
},
"Range": {
@@ -652,7 +780,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

@@ -22,7 +22,7 @@ export default class FTLNomadArmorSheet extends FTLNomadItemSheet {
/** @override */
async _prepareContext() {
const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true })
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
return context
}

View File

@@ -66,8 +66,8 @@ export default class FTLNomadActorSheet extends HandlebarsApplicationMixin(found
actor: this.document,
system: this.document.system,
source: this.document.toObject(),
isEncumbered: this.document.system.isEncumbered(),
enrichedDescription: await TextEditor.enrichHTML(this.document.system.description, { async: true }),
isEncumbered: this.document.system.isEncumbered(),
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }),
isEditMode: this.isEditMode,
isPlayMode: this.isPlayMode,
isEditable: this.isEditable,
@@ -99,7 +99,7 @@ export default class FTLNomadActorSheet extends HandlebarsApplicationMixin(found
dragover: this._onDragOver.bind(this),
drop: this._onDrop.bind(this),
}
return new DragDrop(d)
return new foundry.applications.ux.DragDrop.implementation(d)
})
}
@@ -140,7 +140,7 @@ export default class FTLNomadActorSheet extends HandlebarsApplicationMixin(found
_onDragOver(event) {}
async _onDropItem(item) {
console.log("Dropped item", item)
console.log("Dropped item", item)
let itemData = item.toObject()
await this.document.createEmbeddedDocuments("Item", [itemData], { renderSheet: false })
}

View File

@@ -64,7 +64,7 @@ export default class FTLNomadItemSheet extends HandlebarsApplicationMixin(foundr
item: this.document,
system: this.document.system,
source: this.document.toObject(),
enrichedDescription: await TextEditor.enrichHTML(this.document.system.description, { async: true }),
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }),
isEditMode: this.isEditMode,
isPlayMode: this.isPlayMode,
isEditable: this.isEditable,
@@ -94,7 +94,7 @@ export default class FTLNomadItemSheet extends HandlebarsApplicationMixin(foundr
dragover: this._onDragOver.bind(this),
drop: this._onDrop.bind(this),
}
return new DragDrop(d)
return new foundry.applications.ux.DragDrop.implementation(d)
})
}

View File

@@ -69,8 +69,8 @@ export default class FTLNomadCharacterSheet extends FTLNomadActorSheet {
const context = await super._prepareContext()
context.tabs = this.#getTabs()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true })
context.enrichedNotes = await TextEditor.enrichHTML(this.document.system.notes, { async: true })
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes, { async: true })
return context
}
@@ -103,8 +103,8 @@ export default class FTLNomadCharacterSheet extends FTLNomadActorSheet {
break
case "biography":
context.tab = context.tabs.biography
context.enrichedDescription = await TextEditor.enrichHTML(doc.system.description, { async: true })
context.enrichedNotes = await TextEditor.enrichHTML(doc.system.notes, { async: true })
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
@@ -112,7 +112,7 @@ export default class FTLNomadCharacterSheet extends FTLNomadActorSheet {
static #onCreateEquipment(event, target) {
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("FTLNOMAD.Label.newGear"), type: "gear" }])
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("FTLNOMAD.Label.newEquipment"), type: "equipment" }])
}
static #onCreateWeapon(event, target) {
@@ -138,7 +138,7 @@ export default class FTLNomadCharacterSheet extends FTLNomadActorSheet {
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.

View File

@@ -22,7 +22,7 @@ export default class FTLNomadCreatureAbilitySheet extends FTLNomadItemSheet {
/** @override */
async _prepareContext() {
const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true })
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
return context
}
}

View File

@@ -26,7 +26,7 @@ export default class FTLNomadCreatureSheet extends FTLNomadActorSheet {
template: "templates/generic/tab-navigation.hbs",
},
traits: {
template: "systems/fvtt-ftl-nomad/templates/creature-trait.hbs",
template: "systems/fvtt-ftl-nomad/templates/creature-sheet-trait.hbs",
},
biography: {
template: "systems/fvtt-ftl-nomad/templates/creature-biography.hbs",
@@ -59,8 +59,8 @@ export default class FTLNomadCreatureSheet extends FTLNomadActorSheet {
const context = await super._prepareContext()
context.tabs = this.#getTabs()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true })
context.enrichedNotes = await TextEditor.enrichHTML(this.document.system.notes, { async: true })
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes, { async: true })
return context
}
@@ -80,8 +80,8 @@ export default class FTLNomadCreatureSheet extends FTLNomadActorSheet {
break
case "biography":
context.tab = context.tabs.biography
context.enrichedDescription = await TextEditor.enrichHTML(doc.system.description, { async: true })
context.enrichedNotes = await TextEditor.enrichHTML(doc.system.notes, { async: true })
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
@@ -93,11 +93,11 @@ export default class FTLNomadCreatureSheet extends FTLNomadActorSheet {
* @param {HTMLElement} target The current target of the event listener.
*/
static #onCreateTrait(event, target) {
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("FTLNOMAD.Label.newTrait"), type: "creaturetrait" }])
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("FTLNOMAD.Label.newTrait"), type: "creature-trait" }])
}
static #onCreateAbility(event, target) {
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("FTLNOMAD.Label.newAbility"), type: "creatureability" }])
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("FTLNOMAD.Label.newAbility"), type: "creature-ability" }])
}
/**

View File

@@ -22,7 +22,7 @@ export default class FTLNomadCreatureTraitSheet extends FTLNomadItemSheet {
/** @override */
async _prepareContext() {
const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true })
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
return context
}
}

View File

@@ -22,7 +22,7 @@ export default class FTLNomadEquipmentSheet extends FTLNomadItemSheet {
/** @override */
async _prepareContext() {
const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true })
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
return context
}
}

View File

@@ -22,7 +22,7 @@ export default class FTLNomadLanguageSheet extends FTLNomadItemSheet {
/** @override */
async _prepareContext() {
const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true })
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
return context
}
}

View File

@@ -22,7 +22,7 @@ export default class FTLNomadPsionicSheet extends FTLNomadItemSheet {
/** @override */
async _prepareContext() {
const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true })
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
return context
}
}

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

@@ -12,6 +12,8 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
contentClasses: ["starship-content"],
},
actions: {
createEquipment: FTLNomadStarshipSheet.#onCreateEquipment,
createWeapon: FTLNomadStarshipSheet.#onCreateWeapon,
},
}
@@ -23,22 +25,26 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
tabs: {
template: "templates/generic/tab-navigation.hbs",
},
equipment: {
template: "systems/fvtt-ftl-nomad/templates/starship-equipment.hbs",
},
description: {
template: "systems/fvtt-ftl-nomad/templates/starship-description.hbs",
},
}
/** @override */
tabGroups = {
sheet: "description",
/** @override */
tabGroups = {
sheet: "equipment",
}
/**
* 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)) {
@@ -53,10 +59,10 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
const context = await super._prepareContext()
context.tabs = this.#getTabs()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true })
context.enrichedNotes = await TextEditor.enrichHTML(this.document.system.notes, { async: true })
context.enrichedModifications = await TextEditor.enrichHTML(this.document.system.modifications, { async: true })
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes, { async: true })
context.enrichedModifications = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.modifications, { async: true })
return context
}
@@ -69,31 +75,47 @@ export default class FTLNomadStarshipSheet extends FTLNomadActorSheet {
switch (partId) {
case "main":
break
case "equipment":
context.tab = context.tabs.equipment
context.weapons = doc.itemTypes.weapon
context.weapons.sort((a, b) => a.name.localeCompare(b.name))
context.equipments = doc.itemTypes.equipment
context.equipments.sort((a, b) => a.name.localeCompare(b.name))
break
case "description":
context.tab = context.tabs.description
context.enrichedDescription = await TextEditor.enrichHTML(doc.system.description, { async: true })
context.enrichedNotes = await TextEditor.enrichHTML(doc.system.notes, { async: true })
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" }])
}
async _onRoll(event, target) {
const rollType = $(event.currentTarget).data("roll-type")
let rollType = $(event.currentTarget).data("roll-type")
let item
let formula
let roll
console.log("rollType", rollType)
switch (rollType) {
case "damage":
let li = $(event.currentTarget).parents(".item");
item = this.actor.items.get(li.data("item-id"));
break
case "starship-guns":
formula = this.actor.system.guns
// Rolll the damage
roll = new Roll(formula)
await roll.evaluate()
roll.toMessage( { flavor: `Starship ${this.actor.name} : Guns Damage` })
item = { name: "Starship Guns", type: "weapon", system: { damage: this.actor.system.guns, rangeType: "heavyweapon" } }
rollType = "damage"
break
default:
throw new Error(`Unknown roll type ${rollType}`)
}
await this.document.system.roll(rollType, item)
}

View File

@@ -22,7 +22,7 @@ export default class FTLNomadTalentSheet extends FTLNomadItemSheet {
/** @override */
async _prepareContext() {
const context = await super._prepareContext()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true })
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
return context
}
}

View File

@@ -33,11 +33,11 @@ export default class FTLNomadVehicleSheet extends FTLNomadActorSheet {
},
}
/** @override */
tabGroups = {
/** @override */
tabGroups = {
sheet: "equipment",
}
/**
* Prepare an array of form header tabs.
* @returns {Record<string, Partial<ApplicationTab>>}
@@ -59,9 +59,9 @@ export default class FTLNomadVehicleSheet extends FTLNomadActorSheet {
const context = await super._prepareContext()
context.tabs = this.#getTabs()
context.enrichedDescription = await TextEditor.enrichHTML(this.document.system.description, { async: true })
context.enrichedNotes = await TextEditor.enrichHTML(this.document.system.notes, { async: true })
context.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true })
context.enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes, { async: true })
return context
}
@@ -80,11 +80,11 @@ export default class FTLNomadVehicleSheet extends FTLNomadActorSheet {
context.weapons.sort((a, b) => a.name.localeCompare(b.name))
context.equipments = doc.itemTypes.equipment
context.equipments.sort((a, b) => a.name.localeCompare(b.name))
break
break
case "description":
context.tab = context.tabs.description
context.enrichedDescription = await TextEditor.enrichHTML(doc.system.description, { async: true })
context.enrichedNotes = await TextEditor.enrichHTML(doc.system.notes, { async: true })
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
@@ -103,6 +103,21 @@ export default class FTLNomadVehicleSheet extends FTLNomadActorSheet {
this.document.createEmbeddedDocuments("Item", [{ name: game.i18n.localize("FTLNOMAD.Label.newWeapon"), type: "weapon" }])
}
async _onRoll(event, target) {
const rollType = $(event.currentTarget).data("roll-type")
let item
let li
switch (rollType) {
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

View File

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

View File

@@ -62,11 +62,14 @@ export default class FTLNomadRoll extends Roll {
static updateFullFormula(options) {
let fullFormula
if ( options.numericModifier >= 0) {
fullFormula = `${options.formula} + ${options.rollItem.value} + ${options.numericModifier}D`
if (options.rollType === "damage") {
fullFormula = `${options.formula} + ${options.damageModifier}D6 `
} else {
fullFormula = `${options.formula} + ${options.rollItem.value} - ${Math.abs(options.numericModifier)}D`
let mod = options.rollItem?.value || 0
fullFormula = `${options.formula} + ${options.skillModifier}D + ${mod} + ${options.rangeModifier}D + ${options.numericModifier}D`
}
// Replace all the "+ -" with "-"
fullFormula = fullFormula.replace(/\+\s*\-/g, "- ")
$('#roll-dialog-full-formula').text(fullFormula)
options.fullFormula = fullFormula
}
@@ -87,20 +90,16 @@ export default class FTLNomadRoll extends Roll {
*/
static async prompt(options = {}) {
let formula = "2d6"
let actor = game.actors.get(options.actorId)
switch (options.rollType) {
case "skill":
break
case "damage":
let formula = options.rollItem.system.damage
let damageRoll = new Roll(formula)
await damageRoll.evaluate()
await damageRoll.toMessage({
flavor: `${options.rollItem.name} - Damage Roll`
});
return
options.weapon = foundry.utils.duplicate(options.rollItem)
formula = options.weapon.system.damage
break
case "weapon":
let actor = game.actors.get(options.actorId)
options.weapon = foundry.utils.duplicate(options.rollItem)
options.rollItem = actor.system.skills.combat
break
@@ -108,7 +107,8 @@ export default class FTLNomadRoll extends Roll {
break
}
const rollModes = Object.fromEntries(Object.entries(CONFIG.Dice.rollModes).map(([key, value]) => [key, game.i18n.localize(value)]))
options.actor = actor
const rollModes = foundry.utils.duplicate(CONFIG.Dice.rollModes)
const fieldRollMode = new foundry.data.fields.StringField({
choices: rollModes,
blank: false,
@@ -118,26 +118,24 @@ export default class FTLNomadRoll extends Roll {
const choiceModifier = SYSTEM.MODIFIER_CHOICES
let choiceRangeModifier = {}
let rangeModifier = 0
if ( options.weapon) {
if (options.weapon) {
// Build the range modifiers
let range = SYSTEM.WEAPON_RANGE[options.weapon.system.rangeType]
for (let [key, value] of Object.entries(range.range)) {
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"
options.numericModifier = rangeModifier
options.skillModifier = 0
options.numericModifier = 0
options.rangeModifier = rangeModifier
options.damageModifier = damageModifier
let fullFormula = `${formula} + ${options.rollItem.value}`
if (options.isEncumbered) {
options.numericModifier += -1
fullFormula += ` - ${options.numericModifier}D`
} else {
options.numericModifier += 0
fullFormula += ` + ${options.numericModifier}D`
fullFormula += ` - 1D`
}
options.fullFormula = fullFormula
options.formula = formula
@@ -155,12 +153,14 @@ export default class FTLNomadRoll extends Roll {
fieldRollMode,
choiceModifier,
choiceRangeModifier,
choiceDamageModifier,
rangeModifier,
damageModifier,
formula,
hasTarget: options.hasTarget,
modifier,
}
const content = await renderTemplate("systems/fvtt-ftl-nomad/templates/roll-dialog.hbs", dialogContext)
const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-ftl-nomad/templates/roll-dialog.hbs", dialogContext)
const title = FTLNomadRoll.createTitle(options.rollType, options.rollTarget)
const label = game.i18n.localize("FTLNOMAD.Roll.roll")
@@ -184,19 +184,23 @@ 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-modifier").change(event => {
options.numericModifier += Number(event.target.value)
options.skillModifier = 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.numericModifier += Number(event.target.value)
options.rangeModifier = Number(event.target.value)
FTLNomadRoll.updateFullFormula(options)
})
$(".select-combat-option").change(event => {
console.log(event)
let field = $(event.target).data("field")
let modifier = SYSTEM.ATTACK_MODIFIERS[field]
if ( event.target.checked) {
if (event.target.checked) {
options.numericModifier += modifier
} else {
options.numericModifier -= modifier
@@ -215,14 +219,45 @@ export default class FTLNomadRoll extends Roll {
rollData.targetScore = 8
if (Hooks.call("fvtt-ftl-nomad.preRoll", options, rollData) === false) return
let diceFormula = `${2+Math.abs(options.numericModifier)}D6`
if ( options.numericModifier > 0 ) {
diceFormula += `kh2 + ${options.rollItem.value}`
options.numericModifier = Number(rollData.numericModifier) || 0
options.skillModifier = Number(rollData.skillModifier) || 0
options.rangeModifier = Number(rollData.rangeModifier) || 0
options.finalModifier = options.numericModifier + options.skillModifier + options.rangeModifier
let mod = options.rollItem?.value || 0
// Build the dice formula
let diceFormula = "2d6"
if (options.rollType === "damage") {
let damageFormula = options.weapon.system.damage.toUpperCase().replace(/D/g, "d")
// Extract the mod (if present), like in 3d6+1
let match = damageFormula.match(/([+-]\d+)$/)
if (match) {
mod += Number(match[1])
damageFormula = damageFormula.replace(match[1], "")
}
// Replace the D6 by the correct number of D6
damageFormula = damageFormula.replace(/(\d*)d6/gi, (match, p1) => {
let numDice = Number(p1) || 1
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 += `kl2 + ${options.rollItem.value}`
diceFormula = `${2 + Math.abs(options.finalModifier)}D6`
if (options.finalModifier > 0) {
diceFormula += `kh2 + ${mod}`
} else {
diceFormula += `kl2 + ${mod}`
}
}
console.log("FTLNomadRoll | Rolling ", diceFormula, options, rollData)
const roll = new this(diceFormula, options.data, rollData)
await roll.evaluate()
@@ -239,12 +274,12 @@ export default class FTLNomadRoll extends Roll {
let resultType = "failure"
if (this.total >= 8) {
resultType = "success"
// Detect if decimal == unit in the dire total result
// Detect if decimal == unit in the dire total result
}
this.options.resultType = resultType
this.options.isSuccess = resultType === "success"
this.options.isFailure = resultType === "failure"
this.options.isSuccess = resultType === "success"
this.options.isFailure = resultType === "failure"
this.options.isEncumbered = rollData.isEncumbered
this.options.rollData = foundry.utils.duplicate(rollData)
}
@@ -258,6 +293,8 @@ export default class FTLNomadRoll extends Roll {
*/
static createTitle(type, target) {
switch (type) {
case "damage":
return `${game.i18n.localize("FTLNOMAD.Label.titleDamage")}`
case "skill":
return `${game.i18n.localize("FTLNOMAD.Label.titleSkill")}`
case "weapon":
@@ -270,7 +307,7 @@ export default class FTLNomadRoll extends Roll {
/** @override */
async render(chatOptions = {}) {
let chatData = await this._getChatCardData(chatOptions.isPrivate)
return await renderTemplate(this.constructor.CHAT_TEMPLATE, chatData)
return await foundry.applications.handlebars.renderTemplate(this.constructor.CHAT_TEMPLATE, chatData)
}
/**

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

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

View File

@@ -31,7 +31,7 @@ export default class FTLNomadCreature extends foundry.abstract.TypeDataModel {
schema.numberAppearing = new fields.StringField({ required: true, initial: "1d6" })
schema.health = new fields.SchemaField({
staminaValue: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 }),
staminaMax: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 }),
staminaMax: new fields.NumberField({ ...requiredInteger, initial: 1, min: 1 }),
})
schema.damage = new fields.StringField({ required: true, initial: "1d6" })

View File

@@ -7,11 +7,11 @@ export default class FTLNomadEquipment extends foundry.abstract.TypeDataModel {
const requiredInteger = { required: true, nullable: false, integer: true }
schema.description = new fields.HTMLField({ required: true, textSearch: true })
schema.techAge = new fields.StringField({ required: true, choices: SYSTEM.TECH_AGES, initial : "lateatomic" })
schema.enc = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
schema.cost = new fields.NumberField({ required: true, initial: 0, min: 0 })
schema.cost = new fields.NumberField({ required: true, initial: 1, min: 0 })
return schema
}

View File

@@ -7,11 +7,12 @@ export default class FTLNomadImplant extends foundry.abstract.TypeDataModel {
const requiredInteger = { required: true, nullable: false, integer: true }
schema.description = new fields.HTMLField({ required: true, textSearch: true })
schema.techAge = new fields.StringField({ required: true, choices: SYSTEM.TECH_AGES, initial : "lateatomic" })
schema.enc = new fields.NumberField({ ...requiredInteger, required: true, initial: 0, min: 0 })
schema.cost = new fields.NumberField({ required: true, initial: 0, min: 0 })
schema.loss = new fields.NumberField({ required: true, initial: 0, min: 0 })
return schema
}

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

@@ -0,0 +1,96 @@
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.durability + (2 * this.skills.physical.value)
if (encMax !== this.enc.max) {
this.enc.max = encMax
}
let enc = 0
for (let i of this.parent.items) {
if (i.system?.enc) {
enc += i.system.enc
}
}
if (enc !== this.enc.value) {
this.enc.value = enc
}
}
isEncumbered() {
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,16 +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.NumberField({ ...requiredInteger, initial: 1, min: 1 })
schema.cargo = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
schema.crew = new fields.StringField({ required: true, initial: "" })
schema.cargo = new fields.StringField({ required: true, initial: "" })
schema.guns = new fields.StringField({ required: true, initial: "1d6" })
schema.travelMultiplier = new fields.NumberField({ required: true, initial: 1, min: 0 })
schema.cost = new fields.NumberField({ required: true, initial: 0, min: 0 })
schema.monthlyCost = new fields.NumberField({ required: true, initial: 0, min: 0 })
schema.travelMultiplier = new fields.StringField({ required: true, initial: "" })
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 })
schema.modifications = new fields.HTMLField({ required: true, textSearch: true })
schema.notes = new fields.HTMLField({ required: true, textSearch: true })
return schema
@@ -32,5 +33,25 @@ export default class FTLNomadStarship extends foundry.abstract.TypeDataModel {
isEncumbered() {
return false
}
async roll(rollType, rollItem) {
let opponentTarget
const hasTarget = opponentTarget !== undefined
let roll = await FTLNomadRoll.prompt({
rollType,
rollItem,
actorId: this.parent.id,
actorName: this.parent.name,
actorImage: this.parent.img,
isEncumbered: false,
hasTarget,
target: opponentTarget
})
if (!roll) return null
await roll.toMessage({}, { rollMode: roll.options.rollMode })
}
}

View File

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

View File

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

View File

@@ -195,4 +195,561 @@ export default class FTLNomadUtils {
document.documentElement.style.setProperty('--background-image-base', `linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.8)), url("../assets/ui/${era}_background_main.webp")`);
}
static getTechAgeKeyFromLabel(label) {
return Object.keys(SYSTEM.TECH_AGES).find(key => game.i18n.localize(SYSTEM.TECH_AGES[key].label) === label);
}
static async importPsionics() {
// Create a psionics folder if it doesn't exist
const psionicsFolder = game.folders.getName("Psionics") || await Folder.create({
name: "Psionics", type: "Item"
})
if (!psionicsFolder) {
console.error("Failed to create Psionics folder");
return;
}
// Load the psionics JSON file
const psionicsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/psionics.json")
.then(response => response.json())
.catch(error => {
console.error("Failed to load psionics data:", error);
return [];
});
// Import each psionic ability
for (const psionic of psionicsData) {
// Check if the psionic already exists
const existingPsionic = game.items.find(i => i.name === psionic.name && i.type === "psionic");
if (existingPsionic) {
console.warn(`Psionic ${psionic.name} already exists, skipping import.`);
continue;
}
// Create the psionic item
await Item.create({
name: psionic.name,
type: "psionic",
img: "systems/fvtt-ftl-nomad/assets/icons/icon_psionic.svg",
system: {
description: psionic.description,
},
folder: psionicsFolder.id
});
}
}
static async importTalents() {
// Create a talents folder if it doesn't exist
const talentsFolder = game.folders.getName("Talents") || await Folder.create({
name: "Talents", type: "Item"
})
if (!talentsFolder) {
console.error("Failed to create Talents folder");
return;
}
// Load the talents JSON file
const talentsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/talents.json")
.then(response => response.json())
.catch(error => {
console.error("Failed to load talents data:", error);
return [];
});
// Import each talent
for (const talent of talentsData) {
// Check if the talent already exists
const existingTalent = game.items.find(i => i.name === talent.name && i.type === "talent");
if (existingTalent) {
console.warn(`Talent ${talent.name} already exists, skipping import.`);
continue;
}
talent.advantage = false;
if (talent.description.includes(" +1D")) {
talent.advantage = true
}
// Create the talent item
await Item.create({
name: talent.name,
type: "talent",
img: "systems/fvtt-ftl-nomad/assets/icons/icon_talent.svg",
system: {
description: talent.description,
isAdvantage: talent.advantage,
},
folder: talentsFolder.id
});
}
}
static async importImplants() {
// Create a implants folder if it doesn't exist
const implantsFolder = game.folders.getName("Implants") || await Folder.create({
name: "Implants", type: "Item"
})
if (!implantsFolder) {
console.error("Failed to create Implants folder");
return;
}
// Load the implants JSON file
const implantsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/implants.json")
.then(response => response.json())
.catch(error => {
console.error("Failed to load implants data:", error);
return [];
});
// Import each implant
for (const implant of implantsData) {
// Check if the implant already exists
const existingImplant = game.items.find(i => i.name === implant.name && i.type === "implant");
if (existingImplant) {
console.warn(`Implant ${implant.name} already exists, skipping import.`);
continue;
}
if (!Number(implant.cost)) {
implant.cost = 1000000;
}
// Create the implant item
await Item.create({
name: implant.name,
type: "implant",
img: "systems/fvtt-ftl-nomad/assets/icons/icon_implant.svg",
system: {
cost: implant.cost,
loss: implant.loss,
techAge: this.getTechAgeKeyFromLabel(implant.tech_age),
description: implant.description,
},
folder: implantsFolder.id
});
}
}
static async importDrugs() {
// Create a drugs folder if it doesn't exist
const drugsFolder = game.folders.getName("Drugs") || await Folder.create({
name: "Drugs", type: "Item"
})
if (!drugsFolder) {
console.error("Failed to create Drugs folder");
return;
}
// Load the drugs JSON file
const drugsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/drugs.json")
.then(response => response.json())
.catch(error => {
console.error("Failed to load drugs data:", error);
return [];
});
// Import each drug
for (const drug of drugsData) {
// Check if the drug already exists
const existingDrug = game.items.find(i => i.name === drug.name && i.type === "drug");
if (existingDrug) {
console.warn(`Drug ${drug.name} already exists, skipping import.`);
continue;
}
// Create the drug item
await Item.create({
name: drug.name,
type: "equipment",
img: "systems/fvtt-ftl-nomad/assets/icons/icon_equipment.svg",
system: {
description: drug.description,
cost: drug.cost,
techAge: this.getTechAgeKeyFromLabel(drug.tech_age),
},
folder: drugsFolder.id
});
}
}
static async importEquipments() {
// Create a equipments folder if it doesn't exist
const equipmentsFolder = game.folders.getName("Equipments") || await Folder.create({
name: "Equipments", type: "Item"
})
if (!equipmentsFolder) {
console.error("Failed to create Equipments folder");
return;
}
// Load the equipments JSON file
const equipmentsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/exploration_equipment.json")
.then(response => response.json())
.catch(error => {
console.error("Failed to load equipments data:", error);
return [];
});
// Import each equipment
for (const equipment of equipmentsData) {
// Check if the equipment already exists
const existingEquipment = game.items.find(i => i.name === equipment.name && i.type === "equipment");
if (existingEquipment) {
console.warn(`Equipment ${equipment.name} already exists, skipping import.`);
continue;
}
if (!Number(equipment.cost)) {
equipment.cost = 1000000;
}
// Create the equipment item
await Item.create({
name: equipment.name,
type: "equipment",
img: "systems/fvtt-ftl-nomad/assets/icons/icon_equipment.svg",
system: {
description: equipment.description,
cost: equipment.cost,
techAge: this.getTechAgeKeyFromLabel(equipment.tech_age),
},
folder: equipmentsFolder.id
});
}
}
static async importDistanceWeapons() {
// Create a distance weapons folder if it doesn't exist
const distanceWeaponsFolder = game.folders.getName("Vehicle Weapons") || await Folder.create({
name: "Vehicle Weapons", type: "Item"
})
if (!distanceWeaponsFolder) {
console.error("Failed to create Distance Weapons folder");
return;
}
// Load the distance weapons JSON file
const distanceWeaponsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/vehicle_weapons.json")
.then(response => response.json())
.catch(error => {
console.error("Failed to load distance weapons data:", error);
return [];
});
// Import each distance weapon
for (const weapon of distanceWeaponsData) {
// Check if the weapon already exists
const existingWeapon = game.items.find(i => i.name === weapon.name && i.type === "weapon");
if (existingWeapon) {
console.warn(`Weapon ${weapon.name} already exists, skipping import.`);
continue;
}
// Create the weapon item
await Item.create({
name: weapon.name,
type: "weapon",
img: "systems/fvtt-ftl-nomad/assets/icons/icon_weapon.svg",
system: {
description: weapon.description,
damage: weapon.damage,
techAge: this.getTechAgeKeyFromLabel(weapon.tech_age),
weaponType: SYSTEM.WEAPON_TYPES.vehicle.id,
rangeType: weapon.range.toLowerCase(),
enc: 0,
aspect: weapon.aspects.join(", "),
cost: weapon.cost || 0,
ammoCost: weapon.ammo_cost || 0,
magazine: weapon.mag || 1,
},
folder: distanceWeaponsFolder.id
});
}
}
static async importStarships() {
// Create a starships folder if it doesn't exist
const starshipsFolder = game.folders.getName("Starships") || await Folder.create({
name: "Starships", type: "Actor"
})
if (!starshipsFolder) {
console.error("Failed to create Starships folder");
return;
}
// Load the starships JSON file
const starshipsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/starships.json")
.then(response => response.json())
.catch(error => {
console.error("Failed to load starships data:", error);
return [];
});
// Import each starship
for (const starship of starshipsData) {
// Check if the starship already exists
const existingStarship = game.actors.find(a => a.name === starship.name && a.type === "starship");
if (existingStarship) {
console.warn(`Starship ${starship.name} already exists, skipping import.`);
continue;
}
// Create the starship actor
await Actor.create({
name: starship.name,
type: "starship",
img: "systems/fvtt-ftl-nomad/assets/icons/icon_starship.svg",
system: {
description: starship.description,
agility: starship.agility,
hullType: starship.hullType.toLowerCase(),
endurance: starship.endurance,
armor: starship.armor,
crew: starship.crew,
cargo: starship.cargo,
guns: starship.guns,
travelMultiplier: starship.travelMultiplier,
cost: starship.cost || 0,
monthlyCost: starship.monthlyCost || 0,
damages: starship.damages,
},
folder: starshipsFolder.id
});
}
}
static async importVehicles() {
// Create a vehicles folder if it doesn't exist
const vehiclesFolder = game.folders.getName("Vehicles") || await Folder.create({
name: "Vehicles", type: "Actor"
})
if (!vehiclesFolder) {
console.error("Failed to create Vehicles folder");
return;
}
// Load the vehicles JSON file
const vehiclesData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/vehicles.json")
.then(response => response.json())
.catch(error => {
console.error("Failed to load vehicles data:", error);
return [];
});
// Import each vehicle
for (const vehicle of vehiclesData) {
// Check if the vehicle already exists
const existingVehicle = game.items.find(i => i.name === vehicle.name && i.type === "vehicle");
if (existingVehicle) {
console.warn(`Vehicle ${vehicle.name} already exists, skipping import.`);
continue;
}
// Create the vehicle item
await Actor.create({
name: vehicle.name,
type: "vehicle",
img: "systems/fvtt-ftl-nomad/assets/icons/icon_vehicle.svg",
system: {
description: vehicle.description,
agility: vehicle.agility,
armor: vehicle.armor,
cargo: vehicle.cargo,
crew: vehicle.crew,
force: vehicle.force,
range: vehicle.range,
speed: vehicle.speed,
techAge: this.getTechAgeKeyFromLabel(vehicle.tech_age),
tonnage: vehicle.tonnage,
damages: vehicle.damages,
cost: vehicle.cost || 0,
},
folder: vehiclesFolder.id
});
}
}
static async importArmors() {
// Create an armors folder if it doesn't exist
const armorsFolder = game.folders.getName("Armors") || await Folder.create({
name: "Armors", type: "Item"
})
if (!armorsFolder) {
console.error("Failed to create Armors folder");
return;
}
// Load the armors JSON file
const armorsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/armors.json")
.then(response => response.json())
.catch(error => {
console.error("Failed to load armors data:", error);
return [];
});
// Import each armor
for (const armor of armorsData) {
// Check if the armor already exists
const existingArmor = game.items.find(i => i.name === armor.name && i.type === "armor");
if (existingArmor) {
console.warn(`Armor ${armor.name} already exists, skipping import.`);
continue;
}
// Create the armor item
await Item.create({
name: armor.name,
type: "armor",
img: "systems/fvtt-ftl-nomad/assets/icons/icon_armor.svg",
system: {
description: armor.description,
enc: armor.enc || 0,
techAge: this.getTechAgeKeyFromLabel(armor.tech_age),
cost: armor.cost || 0,
protection: armor.protection || 0,
},
folder: armorsFolder.id
});
}
}
static async importGrenadeWeapons() {
// Create a grenade weapons folder if it doesn't exist
const grenadeWeaponsFolder = game.folders.getName("Grenade") || await Folder.create({
name: "Grenade", type: "Item"
})
if (!grenadeWeaponsFolder) {
console.error("Failed to create Grenade Weapons folder");
return;
}
// Load the grenade weapons JSON file
const grenadeWeaponsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/grenades.json")
.then(response => response.json())
.catch(error => {
console.error("Failed to load grenade weapons data:", error);
return [];
});
// Import each grenade weapon
for (const weapon of grenadeWeaponsData) {
// Check if the weapon already exists
const existingWeapon = game.items.find(i => i.name === weapon.name && i.type === "weapon");
if (existingWeapon) {
console.warn(`Weapon ${weapon.name} already exists, skipping import.`);
continue;
}
// Create the weapon item
await Item.create({
name: weapon.name,
type: "weapon",
img: "systems/fvtt-ftl-nomad/assets/icons/icon_weapon.svg",
system: {
description: weapon.description,
damage: weapon.damage,
techAge: this.getTechAgeKeyFromLabel(weapon.tech_age),
weaponType: SYSTEM.WEAPON_TYPES.grenade.id,
rangeType: SYSTEM.WEAPON_RANGE.thrownweapon.id,
enc: 0,
aspect: weapon.aspects.join(", "),
cost: weapon.cost || 0,
ammoCost: 0,
},
folder: grenadeWeaponsFolder.id
});
}
}
static async fixWeaponsEnc() {
// Iterate over all items of type "weapon" from compendium
const weapons = game.items.filter(i => i.type === "weapon");
for (const weapon of weapons) {
// If the weapon's encumbrance is less than 1, set it to 1
if (weapon.system.enc < 1) {
await weapon.update({ "system.enc": 1 });
}
}
}
static async fixEquipmentEnc() {
// Iterate over all items of type "equipment" from compendium
const equipments = game.items.filter(i => i.type === "equipment");
for (const equipment of equipments) {
// If the equipment's encumbrance is less than 1, set it to
if (equipment.system.enc < 1) {
await equipment.update({ "system.enc": 1 });
}
}
}
static async importMeleeWeapons() {
// Create a melee weapons folder if it doesn't exist
const meleeWeaponsFolder = game.folders.getName("Melee Weapons") || await Folder.create({
name: "Melee Weapons", type: "Item"
})
if (!meleeWeaponsFolder) {
console.error("Failed to create Melee Weapons folder");
return;
}
// Load the melee weapons JSON file
const meleeWeaponsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/weapon_melee.json")
.then(response => response.json())
.catch(error => {
console.error("Failed to load melee weapons data:", error);
return [];
});
console.log("Melee Weapons Data", meleeWeaponsData);
// Import each melee weapon
for (const weapon of meleeWeaponsData) {
// Check if the weapon already exists
const existingWeapon = game.items.find(i => i.name === weapon.name && i.type === "weapon");
if (existingWeapon) {
console.warn(`Weapon ${weapon.name} already exists, skipping import.`);
continue;
}
// Create the weapon item
await Item.create({
name: weapon.name,
type: "weapon",
img: "systems/fvtt-ftl-nomad/assets/icons/icon_weapon.svg",
system: {
description: weapon.description,
damage: weapon.damage,
techAge: this.getTechAgeKeyFromLabel(weapon.tech_age),
weaponType: SYSTEM.WEAPON_TYPES.melee.id,
rangeType: SYSTEM.WEAPON_RANGE.melee.id,
enc: 0,
aspect: weapon.aspects.join(", "),
cost: weapon.cost || 0,
ammoCost: 0,
},
folder: meleeWeaponsFolder.id
});
}
}
static async importVehicleWeapons() {
// Create a melee weapons folder if it doesn't exist
const meleeWeaponsFolder = game.folders.getName("Vehicle Weapons") || await Folder.create({
name: "Vehicle Weapons", type: "Item"
})
if (!meleeWeaponsFolder) {
console.error("Failed to create Vehicle Weapons folder");
return;
}
// Load the melee weapons JSON file
const meleeWeaponsData = await fetch("systems/fvtt-ftl-nomad/assets/json_data/vehicleweapons.json")
.then(response => response.json())
.catch(error => {
console.error("Failed to load vehicle weapons data:", error);
return [];
});
console.log("vehicle Weapons Data", meleeWeaponsData);
// Import each melee weapon
for (const weapon of meleeWeaponsData) {
// Check if the weapon already exists
const existingWeapon = game.items.find(i => i.name === weapon.name && i.type === "weapon");
if (existingWeapon) {
console.warn(`Weapon ${weapon.name} already exists, skipping import.`);
}
// Create the weapon item
await Item.create({
name: weapon.name,
type: "weapon",
img: "systems/fvtt-ftl-nomad/assets/icons/icon_weapon.svg",
system: {
description: weapon.description,
damage: weapon.damage,
techAge: this.getTechAgeKeyFromLabel(weapon.tech_age),
weaponType: "vehicle", //SYSTEM.WEAPON_TYPES.melee.id,
rangeType: SYSTEM.WEAPON_RANGE.melee.id,
enc: 0,
aspect: weapon.aspects,
cost: weapon.cost || 0,
ammoCost: weapon.ammo_cost || 0,
magazine: weapon.mag || 1,
},
folder: meleeWeaponsFolder.id
});
}
}
}

Binary file not shown.

View File

View File

@@ -0,0 +1 @@
MANIFEST-000099

View File

View File

@@ -0,0 +1,7 @@
2025/10/18-17:56:08.077097 7f7b75bfa6c0 Recovering log #97
2025/10/18-17:56:08.086491 7f7b75bfa6c0 Delete type=3 #95
2025/10/18-17:56:08.086541 7f7b75bfa6c0 Delete type=0 #97
2025/10/18-18:03:15.510704 7f7b6f3ff6c0 Level-0 table #102: started
2025/10/18-18:03:15.510749 7f7b6f3ff6c0 Level-0 table #102: 0 bytes OK
2025/10/18-18:03:15.548325 7f7b6f3ff6c0 Delete type=0 #100
2025/10/18-18:03:15.624002 7f7b6f3ff6c0 Manual compaction at level-0 from '!folders!AuBtSOj1mJmh88qx' @ 72057594037927935 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at (end)

View File

@@ -0,0 +1,7 @@
2025/10/16-19:48:48.571698 7f18a4ffa6c0 Recovering log #93
2025/10/16-19:48:48.582163 7f18a4ffa6c0 Delete type=3 #91
2025/10/16-19:48:48.582233 7f18a4ffa6c0 Delete type=0 #93
2025/10/16-19:50:49.674486 7f189e7fc6c0 Level-0 table #98: started
2025/10/16-19:50:49.674520 7f189e7fc6c0 Level-0 table #98: 0 bytes OK
2025/10/16-19:50:49.681475 7f189e7fc6c0 Delete type=0 #96
2025/10/16-19:50:49.691929 7f189e7fc6c0 Manual compaction at level-0 from '!folders!AuBtSOj1mJmh88qx' @ 72057594037927935 : 1 .. '!items!zv9dwgL3p7ThQn7j' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

View File

Binary file not shown.

View File

View File

@@ -0,0 +1 @@
MANIFEST-000077

View File

View File

@@ -0,0 +1,7 @@
2025/10/18-17:56:08.089616 7f7b6ffff6c0 Recovering log #75
2025/10/18-17:56:08.099835 7f7b6ffff6c0 Delete type=3 #73
2025/10/18-17:56:08.099933 7f7b6ffff6c0 Delete type=0 #75
2025/10/18-18:03:15.586602 7f7b6f3ff6c0 Level-0 table #80: started
2025/10/18-18:03:15.586654 7f7b6f3ff6c0 Level-0 table #80: 0 bytes OK
2025/10/18-18:03:15.623769 7f7b6f3ff6c0 Delete type=0 #78
2025/10/18-18:03:15.624032 7f7b6f3ff6c0 Manual compaction at level-0 from '!actors!0FQ6XaRi24OorI21' @ 72057594037927935 : 1 .. '!folders!vRnrOJqSMlxbSgyX' @ 0 : 0; will stop at (end)

View File

@@ -0,0 +1,7 @@
2025/10/16-19:48:48.588685 7f189f7fe6c0 Recovering log #71
2025/10/16-19:48:48.599841 7f189f7fe6c0 Delete type=3 #69
2025/10/16-19:48:48.599924 7f189f7fe6c0 Delete type=0 #71
2025/10/16-19:50:49.586198 7f189e7fc6c0 Level-0 table #76: started
2025/10/16-19:50:49.586239 7f189e7fc6c0 Level-0 table #76: 0 bytes OK
2025/10/16-19:50:49.598518 7f189e7fc6c0 Delete type=0 #74
2025/10/16-19:50:49.610365 7f189e7fc6c0 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

@@ -19,6 +19,7 @@
.character-left {
min-width: 180px;
max-width: 180px;
display: flex;
flex-direction: column;
@@ -43,6 +44,19 @@
margin-left: 2px;
margin-right: 4px;
}
.form-group {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 4px;
label {
font-weight: bold;
margin-right: 4px;
min-width: 4rem;
max-width: 4rem;
}
}
.hp-separator {
font-size: calc(var(--font-size-standard) * 1.2);
display: flex;
@@ -76,18 +90,62 @@
gap: 5px;
.character-spec {
label {
max-width: 6rem;
.form-group {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 4px;
label {
font-weight: bold;
margin-right: 4px;
min-width: 4rem;
max-width: 4rem;
}
input {
min-width: 20rem;
max-width: 20rem;
}
}
.hero-armor {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 4px;
label {
min-width: 6rem;
max-width: 6rem;
}
input {
max-width: 3rem;
}
max-width: 5.2rem;
min-width: 5.2rem;
}
}
}
.encumbrance {
display: flex;
gap: 4px;
.form-group {
display: flex;
flex-direction: row;
margin-bottom: 4px;
}
label {
min-width: 3rem;
max-width: 3rem;
}
input {
max-width: 3rem;
min-width: 3rem;
}
.character-credit {
input {
max-width: 9rem;
min-width: 9rem;
}
}
}
.character-name {
display: flex;
input {
@@ -165,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;
@@ -190,8 +248,22 @@
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
label {
min-width: 12rem;
.form-group {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 4px;
label {
font-weight: bold;
margin-right: 4px;
min-width: 5rem;
max-width: 5rem;
}
input {
min-width: 18rem;
max-width: 18rem;
}
}
}
@@ -222,7 +294,7 @@
}
}
.tab.character-skills {
.tab.character-skills .main-div {
background-color: var(--color-light-1);
display: grid;
grid-template-columns: 1fr;
@@ -270,7 +342,7 @@
}
}
.tab.character-status {
.tab.character-status .main-div {
background-color: var(--color-light-1);
display: grid;
grid-template-columns: 1fr;
@@ -402,7 +474,7 @@
}
}
.tab.character-talents {
.tab.character-talents .main-div {
background-color: var(--color-light-1);
display: grid;
grid-template-columns: 1fr;
@@ -520,10 +592,9 @@
}
}
}
}
.tab.character-equipment {
.tab.character-equipment .main-div {
background-color: var(--color-light-1);
display: grid;
grid-template-columns: 1fr;
@@ -582,7 +653,6 @@
}
}
.weapons {
display: grid;
grid-template-columns: repeat(2, 1fr);
@@ -618,7 +688,7 @@
}
}
}
.armors {
display: grid;
grid-template-columns: repeat(2, 1fr);

View File

@@ -19,6 +19,7 @@
.creature-left {
min-width: 180px;
max-width: 180px;
display: flex;
flex-direction: column;
@@ -37,11 +38,15 @@
.creature-hp {
gap: 2px;
align-items: center;
input {
flex: none;
width: 2.5rem;
margin-left: 2px;
label {
font-weight: bold;
margin-right: 4px;
min-width: 4rem;
max-width: 4rem;
}
input {
max-width: 3rem;
min-width: 3rem;
}
.hp-separator {
font-size: calc(var(--font-size-standard) * 1.2);
@@ -81,6 +86,7 @@
}
select {
max-width: 10rem;
min-width: 10rem;
}
input {
max-width: 6rem;
@@ -94,7 +100,7 @@
cursor: pointer;
}
.rollable {
}
}
}
.creature-name {
@@ -195,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);
@@ -231,7 +247,7 @@
}
}
.tab.creature-skills {
.tab.creature-skills .main-div {
background-color: var(--color-light-1);
display: grid;
grid-template-columns: 1fr;
@@ -279,7 +295,7 @@
}
}
.tab.creature-status {
.tab.creature-status .main-div {
background-color: var(--color-light-1);
display: grid;
grid-template-columns: 1fr;
@@ -411,7 +427,7 @@
}
}
.tab.creature-traits {
.tab.creature-traits .main-div {
background-color: var(--color-light-1);
display: grid;
grid-template-columns: 1fr;
@@ -529,10 +545,9 @@
}
}
}
}
.tab.creature-equipment {
.tab.creature-equipment .main-div {
background-color: var(--color-light-1);
display: grid;
grid-template-columns: 1fr;
@@ -591,7 +606,6 @@
}
}
.weapons {
display: grid;
grid-template-columns: repeat(2, 1fr);
@@ -627,7 +641,7 @@
}
}
}
.armors {
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,7 @@
: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";
@@ -15,6 +15,11 @@
/*--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);
}
.d100 {
width: 18px;
height: 18px;

View File

@@ -2,7 +2,8 @@
font-family: var(--font-primary);
font-size: calc(var(--font-size-standard) * 1);
color: var(--color-dark-1);
background-image: var(--background-image-base);
background-color: var(--color-light-1);
/*background-image: var(--background-image-base);*/
background-repeat: no-repeat;
background-size: 100% 100%;
@@ -39,11 +40,11 @@
input,
select {
text-align: center;
font-size: calc(var(--font-size-standard) * 1.0);
font-size: calc(var(--font-size-standard) * 1);
}
select {
font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1.0);
font-size: calc(var(--font-size-standard) * 1);
}
}
@@ -58,21 +59,87 @@
.character-sheet-common {
label {
font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1.0);
font-size: calc(var(--font-size-standard) * 1);
}
}
.vehicle-sheet-common {
label {
font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1.0);
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: 4rem;
max-width: 4rem;
}
}
}
.starship-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;
}
}
}
.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);
font-size: calc(var(--font-size-standard) * 1.0);
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: 12rem;
max-width: 12rem;
}
}
}
@@ -80,13 +147,26 @@
.form-fields {
padding-top: 4px;
}
.form-group {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 4px;
label {
font-weight: bold;
margin-right: 8px;
min-width: 12rem;
max-width: 12rem;
}
}
label {
font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1.0);
font-size: calc(var(--font-size-standard) * 1);
flex: 50%;
}
.align-top {
align-self: flex-start;
padding: 0.1rem;
@@ -99,5 +179,5 @@
.shift-right {
margin-left: 2rem;
}
}
}

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;
gap: 5px;
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

@@ -1,4 +1,4 @@
.application.dialog.fvtt-cthulhu-eternal {
.application.dialog.fvtt-ftl-nomad {
color: var(--color-dark-1);
background-color: var(--color-light-1);

View File

@@ -1,6 +1,6 @@
.starship-content {
.sheet-common();
.character-sheet-common();
.starship-sheet-common();
overflow: scroll;
}
@@ -36,13 +36,12 @@
.spec {
label {
max-width: 5rem;
max-width: 4rem;
}
input {
max-width: 3rem;
max-width: 4rem;
}
}
}
.starship-right {
@@ -68,13 +67,31 @@
.rollable:focus {
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: 10rem;
max-width: 7rem;
min-width: 7rem;
}
.flexrow-guns {
display: flex;
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: 4rem;
max-width: 5rem;
}
select {
max-width: 5rem;
@@ -83,18 +100,17 @@
.cargo {
label {
margin-left: 0.2rem;
max-width: 10rem;
min-width: 4rem;
max-width: 4rem;
}
input {
max-width: 4rem;
max-width: 6rem;
}
select {
max-width: 5rem;
}
}
.starship-infos {
display: flex;
flex-direction: column;
@@ -115,7 +131,7 @@
margin-left: 4px;
font-size: calc(var(--font-size-standard) * 1.4);
}
}
}
.starship-hp-max {
clear: both;
display: flex;
@@ -160,24 +176,32 @@
.field-label {
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;
align-items: center;
gap: 4px;
min-width: 18rem;
max-width: 18rem;
display: flex;
align-items: center;
gap: 4px;
min-width: 18rem;
max-width: 18rem;
}
}
}
.tab.starship-equipment {

View File

@@ -33,7 +33,6 @@
border: none;
}
}
}
.vehicle-right {
@@ -53,12 +52,18 @@
.cargo,
.capacity {
label {
max-width: 5rem;
min-width: 4rem;
max-width: 4rem;
}
input {
max-width: 3.5rem;
max-width: 6rem;
margin-right: 0.5rem;
}
.cargo-content {
display: flex;
align-items: center;
gap: 4px;
}
}
.vehicle-infos {
@@ -81,7 +86,7 @@
margin-left: 4px;
font-size: calc(var(--font-size-standard) * 1.4);
}
}
}
.vehicle-hp-max {
clear: both;
display: flex;
@@ -116,6 +121,10 @@
}
.vehicle-description {
.text-center {
text-align: left;
align-content: center;
}
background-color: var(--color-light-1);
prose-mirror.inactive {
min-height: 40px;
@@ -126,27 +135,35 @@
.field-label {
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;
align-items: center;
gap: 4px;
min-width: 18rem;
max-width: 18rem;
display: flex;
align-items: center;
gap: 4px;
min-width: 18rem;
max-width: 18rem;
}
}
}
.tab.vehicle-equipment {
.tab.vehicle-equipment .main-div {
background-color: var(--color-light-1);
display: grid;
grid-template-columns: 1fr;
@@ -190,7 +207,7 @@
}
}
}
.equipments {
display: grid;
grid-template-columns: repeat(3, 1fr);

View File

@@ -2,11 +2,11 @@
"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",
"version": "12.0.1",
"version": "13.0.0",
"authors": [
{
"name": "Uberwald",
@@ -20,8 +20,8 @@
}
},
"compatibility": {
"minimum": "12",
"verified": "12"
"minimum": "13",
"verified": "13"
},
"esmodules": ["fvtt-ftl-nomad.mjs"],
"styles": ["css/fvtt-ftl-nomad.css"],
@@ -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"] },
@@ -52,6 +53,30 @@
}
},
"packs": [
{
"label": "FTL Nomad - Items",
"type": "Item",
"name": "ftl-nomad-items",
"path": "packs/ftl-nomad-items",
"system": "fvtt-ftl-nomad",
"flags": {},
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
}
},
{
"label": "FTL Nomad - Vehicles",
"type": "Actor",
"name": "ftl-nomad-vehicles",
"path": "packs/ftl-nomad-vehicles",
"system": "fvtt-ftl-nomad",
"flags": {},
"ownership": {
"PLAYER": "NONE",
"ASSISTANT": "OWNER"
}
}
],
"grid": {
"distance": 10,

View File

@@ -1,6 +1,6 @@
<section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}">
<fieldset class="rank">
<div class="main-div">
<fieldset class="rank">
<legend>Rank</legend>
{{formField systemFields.rank.fields.experienced value=system.rank.experienced type="number" rootId=partId disabled=isPlayMode}}
{{formField systemFields.rank.fields.expert value=system.rank.expert type="number" rootId=partId disabled=isPlayMode}}
@@ -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,18 +1,9 @@
<section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}">
<fieldset class="encumbrance">
{{#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}}
{{formField systemFields.enc.fields.max value=system.enc.max rootId=partId disabled=isPlayMode}}
{{formField systemFields.credits value=system.credits rootId=partId }}
</fieldset>
<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
<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">
@@ -43,7 +34,7 @@
<fieldset>
<legend>{{localize "FTLNOMAD.Label.armors"}}{{#if isEditMode}}
<a class="action" data-tooltip="{{localize " FTLNOMAD.Tooltip.addArmor"}}" data-tooltip-direction="UP"><i
<a class="action" data-tooltip="{{localize "FTLNOMAD.Tooltip.addArmor"}}" data-tooltip-direction="UP"><i
class="fas fa-plus" data-action="createArmor"></i></a>{{/if}}
</legend>
<div class="armors">
@@ -67,7 +58,7 @@
<fieldset>
<legend>{{localize "FTLNOMAD.Label.implants"}}{{#if isEditMode}}
<a class="action" data-tooltip="{{localize " FTLNOMAD.Tooltip.addTalent"}}" data-tooltip-direction="UP"><i
<a class="action" data-tooltip="{{localize "FTLNOMAD.Tooltip.addTalent"}}" data-tooltip-direction="UP"><i
class="fas fa-plus" data-action="createImplant"></i></a>{{/if}}
</legend>
<div class="implants">
@@ -76,12 +67,10 @@
<div class="implant 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}}" />
<img src="systems/fvtt-cthulhu-eternal/assets/ui/d100.svg" class="d100" />
<div class="name" data-roll-type="weapon" data-tooltip="{{{item.system.description}}}">
{{item.name}}
</div>
<img src="systems/fvtt-cthulhu-eternal/assets/ui/d100.svg" class="d100" />
<a class="damage rollable" data-item-id="{{item.id}}" data-action="roll" data-roll-type="damage"
data-roll-value="{{item.system.damage}}">
{{#if item.system.isAdvantage}}
@@ -101,8 +90,8 @@
<fieldset>
<legend>{{localize "FTLNOMAD.Label.equipments"}}{{#if isEditMode}}
<a class="action" data-tooltip="{{localize " FTLNOMAD.Tooltip.addGear"}}" data-tooltip-direction="UP"><i
class="fas fa-plus" data-action="createGear"></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|}}
@@ -122,5 +111,5 @@
{{/each}}
</div>
</fieldset>
</div>
</section>

View File

@@ -1,99 +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}}
<div class="hero-armor">
{{formField systemFields.heroPoints value=system.heroPoints rootId=partId disabled=isPlayMode}}
{{formField systemFields.armor.fields.value value=system.armor.value 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
}}
</div>
</fieldset>
<fieldset class="encumbrance">
{{#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}}
{{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

@@ -1,8 +1,8 @@
<section class="tab character-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}">
<div class="main-div">
<fieldset>
<legend>{{localize "FTLNOMAD.Label.talents"}}{{#if isEditMode}}
<a class="action" data-tooltip="{{localize " FTLNOMAD.Tooltip.addTalent"}}" data-tooltip-direction="UP"><i
<a class="action" data-tooltip="{{localize "FTLNOMAD.Tooltip.addTalent"}}" data-tooltip-direction="UP"><i
class="fas fa-plus" data-action="createTalent"></i></a>{{/if}}
</legend>
<div class="talents">
@@ -11,12 +11,10 @@
<div class="talent 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}}" />
<img src="systems/fvtt-cthulhu-eternal/assets/ui/d100.svg" class="d100" />
<div class="name" data-roll-type="weapon" data-tooltip="{{{item.system.description}}}">
{{item.name}}
</div>
<img src="systems/fvtt-cthulhu-eternal/assets/ui/d100.svg" class="d100" />
<a class="damage rollable" data-item-id="{{item.id}}" data-action="roll" data-roll-type="damage"
data-roll-value="{{item.system.damage}}">
{{#if item.system.isAdvantage}}
@@ -36,7 +34,7 @@
<fieldset>
<legend>{{localize "FTLNOMAD.Label.psionics"}}{{#if isEditMode}}
<a class="action" data-tooltip="{{localize " FTLNOMAD.Tooltip.addImplant"}}" data-tooltip-direction="UP"><i
<a class="action" data-tooltip="{{localize "FTLNOMAD.Tooltip.addImplant"}}" data-tooltip-direction="UP"><i
class="fas fa-plus" data-action="createPsionic"></i></a>{{/if}}
</legend>
<div class="psionics">
@@ -45,12 +43,10 @@
<div class="psionic 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}}" />
<img src="systems/fvtt-cthulhu-eternal/assets/ui/d100.svg" class="d100" />
<div class="name" data-roll-type="weapon" data-tooltip="{{{item.system.description}}}">
{{item.name}}
</div>
<img src="systems/fvtt-cthulhu-eternal/assets/ui/d100.svg" class="d100" />
<a class="damage rollable" data-item-id="{{item.id}}" data-action="roll" data-roll-type="damage"
data-roll-value="{{item.system.damage}}">
{{#if item.system.isAdvantage}}
@@ -70,7 +66,7 @@
<fieldset>
<legend>{{localize "FTLNOMAD.Label.languages"}}{{#if isEditMode}}
<a class="action" data-tooltip="{{localize " FTLNOMAD.Tooltip.addLanguage"}}" data-tooltip-direction="UP"><i
<a class="action" data-tooltip="{{localize "FTLNOMAD.Tooltip.addLanguage"}}" data-tooltip-direction="UP"><i
class="fas fa-plus" data-action="createLanguage"></i></a>{{/if}}
</legend>
<div class="languages">
@@ -79,12 +75,10 @@
<div class="language 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}}" />
<img src="systems/fvtt-cthulhu-eternal/assets/ui/d100.svg" class="d100" />
<div class="name" data-roll-type="weapon" data-tooltip="{{{item.system.description}}}">
{{item.name}}
</div>
<img src="systems/fvtt-cthulhu-eternal/assets/ui/d100.svg" class="d100" />
<a class="damage rollable" data-item-id="{{item.id}}" data-action="roll" data-roll-type="damage"
data-roll-value="{{item.system.damage}}">
{{#if item.system.isAdvantage}}
@@ -101,6 +95,6 @@
{{/each}}
</div>
</fieldset>
</div>
</section>

View File

@@ -8,50 +8,67 @@
<ul>
{{#if (eq rollType "skill")}}
<li><strong>{{localize "FTLNOMAD.Label.skillRoll"}}</strong></li>
<li><strong>{{localize "FTLNOMAD.Label.skillRoll"}}</strong></li>
{{/if}}
{{#if weapon}}
<li><strong>Weapon : {{weapon.name}}</strong></li>
{{#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 isEncumbered}}
<li class="red-warning">Encumbered : -1D</li>
{{#if (eq rollType "damage")}}{{else}}
{{#if isEncumbered}}
<li class="red-warning">Encumbered : -1D</li>
{{/if}}
<li>{{localize "FTLNOMAD.Label.modifier"}}
:
{{skillModifier}}D
{{rangeModifier}}D
{{numericModifier}}D</li>
{{/if}}
<li>{{localize "FTLNOMAD.Label.modifier"}} : {{numericModifier}}D</li>
{{#if isSuccess}}
<li class="result-success">
{{localize "FTLNOMAD.Label.success"}}
</li>
{{#if (eq rollType "damage")}}{{else}}
{{#if isSuccess}}
<li class="result-success">
{{localize "FTLNOMAD.Label.success"}}
</li>
{{/if}}
{{#if isFailure}}
<li class="result-failure">
{{localize "FTLNOMAD.Label.failure"}}
</li>
{{/if}}
{{/if}}
{{#if isFailure}}
<li class="result-failure">
{{localize "FTLNOMAD.Label.failure"}}
</li>
{{/if}}
</ul>
</div>
</div>
{{#if isDamage}}
<div>
{{#if (and isGM hasTarget)}}
{{{localize "FTLNOMAD.Roll.displayArmor" targetName=targetName targetArmor=targetArmor
realDamage=realDamage}}}
{{/if}}
</div>
<div>
{{#if (and isGM hasTarget)}}
{{{localize
"FTLNOMAD.Roll.displayArmor"
targetName=targetName
targetArmor=targetArmor
realDamage=realDamage
}}}
{{/if}}
</div>
{{/if}}
{{#unless isPrivate}}
<div class="dice-result">
<h4 class="dice-total">{{total}}</h4>
<div class="dice-formula">{{formula}}</div>
{{{tooltip}}}
</div>
<div class="dice-result">
<h4 class="dice-total">{{total}}</h4>
<div class="dice-formula">{{formula}}</div>
{{{tooltip}}}
</div>
{{/unless}}
</div>

View File

@@ -1,14 +1,33 @@
<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>
<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.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>
</div>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.notes"}}</legend>
{{formInput systemFields.notes enriched=enrichedNotes value=system.notes name="system.notes" toggled=true}}
</fieldset>
</section>

View File

@@ -8,11 +8,14 @@
<img class="creature-img" src="{{actor.img}}" data-edit="img" data-action="editImage"
data-tooltip="{{actor.name}}" />
</div>
<fieldset class="creature-hp">
<legend>{{localize "FTLNOMAD.Label.Stamina"}}</legend>
<div class="flexrow">
Curr. {{formField systemFields.health.fields.staminaValue value=health.staminaValue}}
Max {{formField systemFields.health.fields.staminaMax value=system.health.staminaMax rootId=partId}}
{{formField systemFields.health.fields.staminaValue value=system.health.staminaValue}}
</div>
<div class="flexrow">
{{formField systemFields.health.fields.staminaMax value=system.health.staminaMax rootId=partId}}
</div>
</fieldset>

View File

@@ -0,0 +1,50 @@
<section class="tab creature-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}">
<div class="main-div">
<fieldset>
<legend>{{localize "FTLNOMAD.Label.traits"}}{{#if isEditMode}}
<a class="action" data-tooltip="{{localize "FTLNOMAD.Tooltip.addTrait"}}" data-tooltip-direction="UP"><i
class="fas fa-plus" data-action="createTrait"></i></a>{{/if}}
</legend>
<div class="traits">
{{#each traits as |item|}}
<div class="trait 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-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>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.abilities"}}{{#if isEditMode}}
<a class="action" data-tooltip="{{localize "FTLNOMAD.Tooltip.addAbility"}}" data-tooltip-direction="UP"><i
class="fas fa-plus" data-action="createAbility"></i></a>{{/if}}
</legend>
<div class="abilities">
{{#each abilities as |item|}}
{{!log 'armor' this}}
<div class="ability" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}">
<img class="item-img" src="{{item.img}}" data-tooltip="{{item.name}}" />
<div class="name" data-tooltip="{{{item.system.description}}}">
{{item.name}}
</div>
<div class="controls">
<a data-tooltip="{{localize 'FTLNOMAD.Edit'}}" data-action="edit" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
<a data-tooltip="{{localize 'FTLNOMAD.Delete'}}" data-action="delete" data-item-id="{{item.id}}"
data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
</div>
</div>
{{/each}}
</div>
</fieldset>
</div>
</section>

View File

@@ -1,50 +1,17 @@
<section class="tab creature-{{tab.id}} {{tab.cssClass}}" data-tab="{{tab.id}}" data-group="{{tab.group}}">
<section>
<div class="header">
<img class="item-img" src="{{item.img}}" data-edit="img" data-action="editImage" data-tooltip="{{item.name}}" />
{{formInput fields.name value=source.name}}
</div>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.traits"}}{{#if isEditMode}}
<a class="action" data-tooltip="{{localize " FTLNOMAD.Tooltip.addTrait"}}" data-tooltip-direction="UP"><i
class="fas fa-plus" data-action="createTrait"></i></a>{{/if}}
</legend>
<div class="traits">
{{#each traits as |item|}}
<div class="trait 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-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>
{{formField systemFields.isAdvantage value=system.isAdvantage}}
</fieldset>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.abilities"}}{{#if isEditMode}}
<a class="action" data-tooltip="{{localize " FTLNOMAD.Tooltip.addAbility"}}" data-tooltip-direction="UP"><i
class="fas fa-plus" data-action="createAbility"></i></a>{{/if}}
</legend>
<div class="abilities">
{{#each abilities as |item|}}
{{!log 'armor' this}}
<div class="ability" 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>
<legend>{{localize "FTLNOMAD.Label.description"}}</legend>
{{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description"
toggled=true}}
</fieldset>
</section>

View File

@@ -12,7 +12,7 @@
<fieldset>
<legend>{{localize "FTLNOMAD.Label.description"}}</legend>
{{formInput systemFields.description enriched=description value=system.description name="system.description"
{{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description"
toggled=true}}
</fieldset>

View File

@@ -2,17 +2,17 @@
<div class="header">
<img class="item-img" src="{{item.img}}" data-edit="img" data-action="editImage" data-tooltip="{{item.name}}" />
{{formInput fields.name value=source.name}}
</div>
</div>
<fieldset>
{{formField systemFields.techAge value=system.techAge localize=true}}
{{formField systemFields.enc value=system.enc}}
{{formField systemFields.loss value=system.loss}}
{{formField systemFields.cost value=system.cost}}
</fieldset>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.description"}}</legend>
{{formInput systemFields.description enriched=description value=system.description name="system.description"
{{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description"
toggled=true}}
</fieldset>

View File

@@ -2,11 +2,11 @@
<div class="header">
<img class="item-img era-icon-color" src="{{item.img}}" data-edit="img" data-action="editImage" data-tooltip="{{item.name}}" />
{{formInput fields.name value=source.name}}
</div>
</div>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.description"}}</legend>
{{formInput systemFields.description enriched=description value=system.description name="system.description" toggled=true}}
{{formInput systemFields.description enriched=enrichedDescription value=system.description name="system.description" toggled=true}}
</fieldset>
</section>

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,107 @@
<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}}"
/>
<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"}}
:
{{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

@@ -1,44 +1,108 @@
<div class="fvtt-ftl-nomad-roll-dialog">
<fieldSet>
{{#if (eq rollType "skill")}}
<legend>{{localize "FTLNOMAD.Label.skill"}}</legend>
<legend>{{localize "FTLNOMAD.Label.skill"}}</legend>
{{/if}}
<div class="dialog-skill">{{localize rollItem.label}} : 2d6+{{rollItem.value}}</div>
{{#if (eq rollType "damage")}}
<div class="dialog-skill">Damage : {{weapon.system.damage}}</div>
<div class="dialog-skill">Weapon : {{weapon.name}}</div>
{{else}}
<div class="dialog-skill">{{localize rollItem.label}}
: 2d6+{{rollItem.value}}</div>
{{/if}}
{{#if weapon}}
<div class="dialog-skill">Weapon : {{weapon.name}}</div>
{{#if (eq rollType "weapon")}}
<div class="dialog-skill">Weapon : {{weapon.name}}</div>
{{/if}}
{{#if isEncumbered}}
<div class="dialog-skill red-warning">Encumbered : -1D</div>
<div class="dialog-skill red-warning">Encumbered : -1D</div>
{{/if}}
</fieldSet>
<fieldSet class="dialog-modifier">
<legend>{{localize "FTLNOMAD.Label.modifier"}}</legend>
<select name="modifier" class="roll-skill-modifier">
{{selectOptions choiceModifier selected=modifier localize=true}}
</select>
{{#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>
{{/if}}
{{#if weapon}}
{{#if (eq rollType "weapon")}}
<select name="range-modifier" class="roll-skill-range-modifier">
{{selectOptions choiceRangeModifier selected=rangeModifier}}
</select>
<ul>
<li>Two Attacks : <input type="checkbox" name="isAiming" data-field="two-attacks" class="select-combat-option"></li>
<li>Aiming : <input type="checkbox" data-field="aiming" class="select-combat-option"></li>
<li>Dim Lightning : <input type="checkbox" data-field="dim" class="select-combat-option"></li>
<li>Darkness : <input type="checkbox" data-field="darkness" class="select-combat-option"></li>
<li>Target Prone/Obscured : <input type="checkbox" data-field="prone" class="select-combat-option"></li>
<li>Target Cover : <input type="checkbox" data-field="cover" class="select-combat-option"></li>
<li>1/2 Auto Fire Recoil : <input type="checkbox" data-field="recoil-first" class="select-combat-option"></li>
<li>2+ Auto Fire Recoil : <input type="checkbox" data-field="recoil-third" class="select-combat-option"></li>
<li>Target Aware : <input type="checkbox" data-field="aware" class="select-combat-option"></li>
<li>Two Attacks :
<input
type="checkbox"
name="isAiming"
data-field="two-attacks"
class="select-combat-option"
/>
</li>
<li>Aiming :
<input
type="checkbox"
data-field="aiming"
class="select-combat-option"
/></li>
<li>Dim Lightning :
<input
type="checkbox"
data-field="dim"
class="select-combat-option"
/></li>
<li>Darkness :
<input
type="checkbox"
data-field="darkness"
class="select-combat-option"
/></li>
<li>Target Prone/Obscured :
<input
type="checkbox"
data-field="prone"
class="select-combat-option"
/></li>
<li>Target Cover :
<input
type="checkbox"
data-field="cover"
class="select-combat-option"
/></li>
<li>1/2 Auto Fire Recoil :
<input
type="checkbox"
data-field="recoil-first"
class="select-combat-option"
/></li>
<li>2+ Auto Fire Recoil :
<input
type="checkbox"
data-field="recoil-third"
class="select-combat-option"
/></li>
<li>Target Aware :
<input
type="checkbox"
data-field="aware"
class="select-combat-option"
/></li>
</ul>
{{/if}}
@@ -46,13 +110,16 @@
<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>
<legend>{{localize "FTLNOMAD.Label.rollView"}}</legend>
<select name="visibility">
{{selectOptions rollModes selected=visibility}}
{{selectOptions rollModes localize=true selected=visibility}}
</select>
</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" 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

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

View File

@@ -1,53 +1,112 @@
<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.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 ">
<fieldset class="capacity">
<legend>{{localize "FTLNOMAD.Label.capacity"}}</legend>
<div class="flexrow">
{{formField systemFields.hullType value=system.hullType localize=true}}
<div class="flexrow rollable" data-roll-type="starship-guns">
<i class="fa-regular fa-dice dice-2d6"></i>
{{formField systemFields.guns value=system.guns localize=true}}
</div>
<div class="flexrow hull-field">
{{formField
systemFields.hullType
value=system.hullType
localize=true
disabled=isPlayMode
}}
</div>
<div class="flexrow">
{{formField systemFields.cost value=system.cost localize=true}}
{{formField systemFields.monthlyCost value=system.monthlyCost localize=true}}
</div>
<div class="flexrow">
{{formField systemFields.travelMultiplier value=system.travelMultiplier 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>
<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.crew
value=system.crew
localize=true
disabled=isPlayMode
}}
{{formField
systemFields.cargo
value=system.cargo
localize=true
disabled=isPlayMode
}}
</div>
</fieldset>

View File

@@ -1,19 +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.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" rows="5" name="system.damages"
data-tooltip="{{localize "FTLNOMAD.Tooltip.damages"}}">{{system.damages}}</textarea>
<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}}
{{formInput
systemFields.description
enriched=enrichedDescription
value=system.description
name="system.description"
toggled=true
}}
</fieldset>
<fieldset>
<fieldset class="section-editor">
<legend>{{localize "FTLNOMAD.Label.notes"}}</legend>
{{formInput systemFields.notes enriched=enrichedNotes value=system.notes name="system.notes" toggled=true}}
{{formInput
systemFields.notes
enriched=enrichedNotes
value=system.notes
name="system.notes"
toggled=true
}}
</fieldset>
</section>

View File

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

View File

@@ -5,45 +5,99 @@
<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}}" />
<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}}
{{formField
systemFields.agility
value=system.agility
localize=true
disabled=isPlayMode
}}
</div>
</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>
<fieldset class="capacity ">
<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.armor
value=system.armor
localize=true
disabled=isPlayMode
}}
{{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="flexrow">
{{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-content">
{{formField
systemFields.crew
value=system.crew
localize=true
disabled=isPlayMode
}}
{{formField
systemFields.cargo
value=system.cargo
localize=true
disabled=isPlayMode
}}
{{formField
systemFields.tonnage
value=system.tonnage
localize=true
disabled=isPlayMode
}}
</div>
</fieldset>

View File

@@ -8,18 +8,24 @@
{{formField systemFields.techAge value=system.techAge localize=true}}
{{formField systemFields.weaponType value=system.weaponType localize=true}}
{{formField systemFields.rangeType value=system.rangeType localize=true}}
{{formField systemFields.aspect value=system.aspect localize=true}}
{{formField systemFields.damage value=system.damage}}
{{formField systemFields.enc value=system.enc}}
{{formField systemFields.cost value=system.cost}}
{{formField cost value=system.cost}}
{{#if (eq system.weaponType "vehicle")}}
{{formField systemFields.ammoCost value=system.ammoCost}}
{{formField systemFields.magazine value=system.magazine}}
{{/if}}
</fieldset>
<fieldset>
<legend>{{localize "FTLNOMAD.Label.description"}}</legend>
{{formInput
systemFields.description
enriched=description
enriched=enrichedDescription
value=system.description
name="system.description"
toggled=true