diff --git a/lang/en.json b/lang/en.json index 8d4493fb..8ca8fdec 100644 --- a/lang/en.json +++ b/lang/en.json @@ -193,7 +193,7 @@ "SW5E.BonusSaveForm": "Update Bonuses", "SW5E.BonusTechPowerDC": "Global Tech Power DC Bonus", "SW5E.BonusTitle": "Configure Actor Bonuses", - "SW5E.BurnFuel": "Burn", + "SW5E.BurnFuel": "Burn", "SW5E.CapacityMultiplier": "Capacity Multiplier", "SW5E.CentStorageCapacity": "Central Storage Capacity", "SW5E.ChallengeRating": "Challenge Rating", @@ -521,9 +521,9 @@ "SW5E.Flaws": "Flaws", "SW5E.ForcePowerbook": "Force Powers", "SW5E.Formula": "Formula", - "SW5E.FuelCapacity": "Fuel Capacity", - "SW5E.FuelCostPerUnit": "Fuel Cost per Unit", + "SW5E.FuelCapacity": "Fuel Capacity", "SW5E.FuelCostsMod": "Fuel Costs Modifier", + "SW5E.FuelCostPerUnit": "Fuel Cost per Unit", "SW5E.GrantedAbilities": "Granted Abilities", "SW5E.HalfProficient": "Half Proficient", "SW5E.HardpointSizeMod": "Hardpoint Size Modifier", diff --git a/less/original/actors.less b/less/original/actors.less index eef86c31..b716fa74 100644 --- a/less/original/actors.less +++ b/less/original/actors.less @@ -671,6 +671,77 @@ .editor { padding: 0 8px; } + .fuel { + flex: 0 0 12px; + background: #7a7971; + margin: 1px 15px 0 1px; + border: 1px solid #191813; + border-radius: 3px; + position: relative; + .fuel-bar { + position: absolute; + top: 1px; + left: 1px; + background: #6c8aa5; + height: 8px; + border: 1px solid #cde4ff; + border-radius: 2px; + } + .fuel-label { + height: 10px; + padding: 0 5px; + position: absolute; + top: 0; + right: 0; + font-size: 13px; + line-height: 12px; + text-align: right; + color: #EEE; + text-shadow: 0 0 5px #000; + } + .fuel-breakpoint { + display: block; + position: absolute; + } + .fuel-breakpoint.fuel-20 { + left: 20%; + } + .fuel-breakpoint.fuel-40 { + left: 40%; + } + .fuel-breakpoint.fuel-60 { + left: 60%; + } + .fuel-breakpoint.fuel-80 { + left: 80%; + } + .arrow-up { + bottom: 0; + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-bottom: 4px solid #000; + } + .arrow-down { + top: 0; + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 4px solid #000; + } + } + .fuel.fueled { + .arrow-up { + border-bottom: 4px solid #fff; + border-bottom: 4px solid #000; + } + .arrow-down { + border-top: 4px solid #fff; + border-top: 4px solid #000; + } + } } #actor-flags { diff --git a/less/update/components/actor-global.less b/less/update/components/actor-global.less index f32ecc4e..49279ff8 100644 --- a/less/update/components/actor-global.less +++ b/less/update/components/actor-global.less @@ -250,7 +250,45 @@ } } } - + + .panel.resources { + .traits { + .fuel-wrapper { + display: grid; + grid-template-columns: 300px 100px; + width: 400px; + justify-self: end; + .fuel-label { + font-size: 12px; + line-height: 14px; + width: 100%; + text-shadow: none; + padding: 0; + margin: 0; + height: auto; + text-align: center; + margin-left: -2px; + border-radius: 0 4px 4px 0; + } + .fuel { + position: relative; + border-radius: 4px; + height: 16px; + margin: 0; + width: 100%; + .fuel-bar { + position: absolute; + top: 0; + left: 0; + height: 100%; + border-radius: 4px; + border: none; + } + } + } + } + } + nav.sheet-navigation { display: grid; grid-template-columns: repeat(7, 1fr); @@ -1123,4 +1161,44 @@ } } } + input[type=range][orient=vertical] { + -webkit-appearance: slider-vertical; + width: 10px; + height: 60px !important; + padding: 0 0 !important; + background-color: #c40f0f !important; + box-sizing: border-box; + &::-webkit-slider-runnable-track { + -webkit-appearance: slider-vertical !important; + height: 60px !important; + width: 10px !important; + line-height: 60px !important; + padding-top: 0 !important; + padding-bottom: 0 !important; + margin-top: 0 0 !important; + border-radius: 3px !important; + background: linear-gradient( to top, #c40f0f 50%, #0dce0d 50% ); + } + &::-webkit-slider-thumb { + -webkit-appearance: none !important; + background-color: #c40f0f !important; + margin-right: -4px !important; + margin-top: 0px !important; + cursor: grab !important; + border-radius: 0 0 0 0 !important; + width: 10px !important; + height: 5px !important; + font-size: 10px; + } + } + output { + display: block; + margin: 5px auto; + font-size: 1.75em; + } + input { + .vertslider { + height: 60px; + } + } } diff --git a/less/update/sw5e-dark.less b/less/update/sw5e-dark.less index 1dc380db..3d96ef34 100644 --- a/less/update/sw5e-dark.less +++ b/less/update/sw5e-dark.less @@ -34,6 +34,28 @@ body.dark-theme { border: 1px solid @blockquoteBorder; box-shadow: @blockquoteShadow; } + + .sw5e.sheet.actor { + .swalt-sheet { + .panel.resources { + .traits { + .fuel-wrapper { + .fuel-label { + background: #D6D6D6; + color: #1C1C1C; + border: 1px solid #1C1C1C; + } + .fuel { + background: #c40f0f; + .fuel-bar { + background: #0dce0d; + } + } + } + } + } + } + } hr { border-width: 0 0 1px 0; diff --git a/less/update/sw5e-light.less b/less/update/sw5e-light.less index 0f898c80..9a9b5f9e 100644 --- a/less/update/sw5e-light.less +++ b/less/update/sw5e-light.less @@ -34,6 +34,28 @@ body.light-theme { border: 1px solid @blockquoteBorder; box-shadow: @blockquoteShadow; } + + .sw5e.sheet.actor { + .swalt-sheet { + .panel.resources { + .traits { + .fuel-wrapper { + .fuel-label { + background: #D6D6D6; + color: #1C1C1C; + border: 1px solid #1C1C1C; + } + .fuel { + background: #c40f0f; + .fuel-bar { + background: #0dce0d; + } + } + } + } + } + } + } hr { border-width: 0 0 1px 0; diff --git a/module/actor/entity.js b/module/actor/entity.js index 9c86d49a..85b2fd06 100644 --- a/module/actor/entity.js +++ b/module/actor/entity.js @@ -118,7 +118,11 @@ export default class Actor5e extends Actor { // Inventory encumbrance data.attributes.encumbrance = this._computeEncumbrance(actorData); - + + if (actorData.type === "starship") { + data.attributes.fuel = this._computeFuel(actorData); + } + // Prepare skills this._prepareSkills(actorData, bonuses, checkBonus, originalSkills); @@ -727,6 +731,19 @@ export default class Actor5e extends Actor { /* -------------------------------------------- */ /* Event Handlers */ /* -------------------------------------------- */ + + _computeFuel(actorData) { + let fuel = actorData.data.attributes.fuel.value; + // Compute Fuel percentage + fuel = fuel.toNearest(0.1); + const max = actorData.data.attributes.fuel.cap; + const pct = Math.clamped((fuel * 100) / max, 0, 100); + return { value: fuel.toNearest(0.1), max, pct, fueled: pct > 0 }; + } + + /* -------------------------------------------- */ + /* Socket Listeners and Handlers + /* -------------------------------------------- */ /** @inheritdoc */ async _preCreate(data, options, user) { diff --git a/module/actor/sheets/newSheet/starship.js b/module/actor/sheets/newSheet/starship.js index e27354d6..8f26c3c7 100644 --- a/module/actor/sheets/newSheet/starship.js +++ b/module/actor/sheets/newSheet/starship.js @@ -17,6 +17,7 @@ export default class ActorSheet5eStarship extends ActorSheet5e { return mergeObject(super.defaultOptions, { classes: ["sw5e", "sheet", "actor", "starship"], width: 800, + height: 775, tabs: [{ navSelector: ".root-tabs", contentSelector: ".sheet-body", @@ -135,6 +136,7 @@ export default class ActorSheet5eStarship extends ActorSheet5e { activateListeners(html) { super.activateListeners(html); html.find(".health .rollable").click(this._onRollHPFormula.bind(this)); + html.find('.refuel').click(this._onIncrementFuelLevel.bind(this)); } /* -------------------------------------------- */ @@ -152,4 +154,82 @@ export default class ActorSheet5eStarship extends ActorSheet5e { AudioHelper.play({src: CONFIG.sounds.dice}); this.actor.update({"data.attributes.hp.value": hp, "data.attributes.hp.max": hp}); } + + /* -------------------------------------------- */ + + /** + * Handle refueling a starship + * @param {Event} event The original click event + * @private + */ + _onIncrementFuelLevel(event) { + event.preventDefault(); + const fuelcaparray = this.actor.data.effects.changes; + var fuelcappos = fuelcaparray.indexOf('fuel.cap'); + const refuel = this.actor.data.effect.changes[fuelcappos].value; + this.actor.update({"data.attributes.fuel.value": refuel}); + } + + function engineSliderUpdate(num) { + var symbol; + var coefficient; + switch(num) { + case "0": + symbol = "↓"; + coefficient = 0.5; + break; + case "1": + symbol = "="; + coefficient = 1; + break; + case "2": + symbol = "↑"; + coefficient = 2; + }; + let slideroutput = symbol; + document.querySelector('#engineslideroutput').value = slideroutput; + this.actor.update({"data.attributes.engpow": coefficient}); + } + + function shieldSliderUpdate(num) { + var symbol; + var coefficient; + switch(num) { + case "0": + symbol = "↓"; + coefficient = 0.5; + break; + case "1": + symbol = "="; + coefficient = 1; + break; + case "2": + symbol = "↑"; + coefficient = 2; + }; + let slideroutput = symbol; + document.querySelector('#shieldslideroutput').value = slideroutput; + this.actor.update({"data.attributes.shieldpow": coefficient}); + } + + function weaponSliderUpdate(num) { + var symbol; + var coefficient; + switch(num) { + case "0": + symbol = "↓"; + coefficient = 0.5; + break; + case "1": + symbol = "="; + coefficient = 1; + break; + case "2": + symbol = "↑"; + coefficient = 2; + }; + let slideroutput = symbol; + document.querySelector('#weaponslideroutput').value = slideroutput; + this.actor.update({"data.attributes.weaponpow": coefficient}); + } } diff --git a/packs/packs/adventuringgear.db b/packs/packs/adventuringgear.db index 1e4f8991..428c31ce 100644 --- a/packs/packs/adventuringgear.db +++ b/packs/packs/adventuringgear.db @@ -111,4 +111,3 @@ {"name":"Headcomm","permission":{"default":0,"vXYkFWX6qzvOu2jc":3},"type":"loot","data":{"description":{"value":"
A headcomm can be installed in a helmet or worn independently. It functions as a hands-free commlink.
","chat":"","unidentified":""},"source":"PHB","quantity":1,"weight":1,"price":200,"attuned":false,"equipped":false,"rarity":"","identified":true,"attributes":{"spelldc":10},"damage":{"parts":[]}},"flags":{},"img":"systems/sw5e/packs/Icons/Communications/Headcomm.webp","_id":"zHERdLuCUPpxzaSJ"} {"name":"Poisoner's Kit","permission":{"default":0,"vXYkFWX6qzvOu2jc":3},"type":"tool","data":{"description":{"value":"A poisoner’s kit includes the vials, chemicals, and other equipment necessary for the creation of poisons. Proficiency with this kit lets you add your proficiency bonus to any ability checks you make to craft or use poisons.
","chat":"","unidentified":""},"source":"PHB","quantity":1,"weight":2,"price":500,"attuned":false,"equipped":false,"rarity":"","identified":true,"ability":"int","chatFlavor":"","proficient":0,"attributes":{"spelldc":10},"damage":{"parts":[]}},"flags":{"dynamiceffects":{"equipActive":false,"alwaysActive":false,"effects":[]}},"img":"systems/sw5e/packs/Icons/Kit/Poisoner_s%20Kit.webp","_id":"zaLzNlsfzRf71Xpl"} {"name":"Mine, Plasma","permission":{"default":0,"vXYkFWX6qzvOu2jc":3},"type":"weapon","data":{"description":{"value":"When you use your action to set it, this mine sets an imperceptible laser line extending up to 15 feet. When the laser is tripped, the mine explodes, coating the area in a 15-foot radius around it in fire that burns for 1 minute. When a creature enters the fire or starts its turn there it must make a DC 13 Dexterity saving throw. On a failed save, the creature takes 2d6 fire damage, or half as much on a successful one. A construct makes this save with disadvantage.
","chat":"","unidentified":""},"source":"PHB","quantity":1,"weight":2,"price":550,"attuned":false,"equipped":false,"rarity":"","identified":true,"activation":{"type":"action","cost":1,"condition":""},"duration":{"value":null,"units":""},"target":{"value":15,"units":"ft","type":"radius"},"range":{"value":null,"long":null,"units":""},"uses":{"value":1,"max":1,"per":"charges"},"consume":{"type":"","target":"","amount":null},"ability":"","actionType":"save","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"dex","dc":13,"scaling":"flat"},"weaponType":"improv","properties":{"amm":false,"fin":false,"fir":false,"foc":false,"hvy":false,"lgt":false,"lod":false,"rch":false,"rel":false,"ret":false,"spc":false,"thr":false,"two":false,"ver":false},"proficient":false,"attributes":{"spelldc":10}},"flags":{"dynamiceffects":{"equipActive":false,"alwaysActive":false,"effects":[]}},"img":"systems/sw5e/packs/Icons/Explosive/Mine%2C%20Plasma.webp","_id":"zrSOUA8dUg9lHVdS"} -{"name":"Power Cell","permission":{"default":0,"vXYkFWX6qzvOu2jc":3},"type":"consumable","data":{"description":{"value":"Power cells fuel blaster weapons that deal energy or ion damage. Additionally, power cells are used to energize certain tools.
","chat":"","unidentified":""},"source":"PHB","quantity":1,"weight":1,"price":10,"attuned":false,"equipped":false,"rarity":"","identified":true,"activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":240,"max":240,"per":"charges","autoDestroy":false},"consume":{"type":"","target":"","amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"spell"},"consumableType":"ammo","attributes":{"spelldc":10}},"flags":{"dynamiceffects":{"equipActive":false,"alwaysActive":false,"effects":[]}},"img":"systems/sw5e/packs/Icons/Ammunition/Power%20Cell.webp","_id":"VUkO1T2aYMuUcBZM"} diff --git a/sw5e-dark.css b/sw5e-dark.css index 424da398..5506c78c 100644 --- a/sw5e-dark.css +++ b/sw5e-dark.css @@ -797,3 +797,14 @@ body.dark-theme .sw5e.sheet.actor.npc .swalt-sheet header div.creature-type:hove body.dark-theme .sw5e.sheet.actor.npc .swalt-sheet header .experience { color: #4f4f4f; } +body.dark-theme .sw5e.sheet.actor .swalt-sheet .panel.resources .traits .fuel-wrapper .fuel-label { + background: #D6D6D6; + color: #1C1C1C; + border: 1px solid #1C1C1C; +} +body.dark-theme .sw5e.sheet.actor .swalt-sheet .panel.resources .traits .fuel-wrapper .fuel { + background: #c40f0f; +} +body.dark-theme .sw5e.sheet.actor .swalt-sheet .panel.resources .traits .fuel-wrapper .fuel .fuel-bar { + background: #0dce0d; +} \ No newline at end of file diff --git a/sw5e-global.css b/sw5e-global.css index 9f890ada..9c5943a1 100644 --- a/sw5e-global.css +++ b/sw5e-global.css @@ -1757,3 +1757,78 @@ input[type="reset"]:disabled { transform: rotate(360deg); } } +.sw5e.sheet.actor .swalt-sheet .panel.resources .traits .fuel-wrapper { + display: grid; + grid-template-columns: 300px 100px; + width: 400px; + justify-self: end; +} +.sw5e.sheet.actor .swalt-sheet .panel.resources .traits .fuel-wrapper .fuel-label { + font-size: 12px; + line-height: 14px; + width: 100%; + text-shadow: none; + padding: 0; + margin: 0; + height: auto; + text-align: center; + margin-left: -2px; + border-radius: 0 4px 4px 0; +} +.sw5e.sheet.actor .swalt-sheet .panel.resources .traits .fuel-wrapper .fuel { + position: relative; + border-radius: 4px; + height: 16px; + margin: 0; + width: 100%; +} +.sw5e.sheet.actor .swalt-sheet .panel.resources .traits .fuel-wrapper .fuel .fuel-bar { + position: absolute; + top: 0; + left: 0; + height: 100%; + border-radius: 4px; + border: none; +} +input[type=range][orient=vertical] { + -webkit-appearance: slider-vertical; + width: 10px; + height: 60px !important; + padding: 0 0 !important; + background-color: #c40f0f !important; + box-sizing: border-box; +} +input[type=range][orient=vertical]::-webkit-slider-runnable-track { + -webkit-appearance: slider-vertical !important; + height: 60px !important; + width: 10px !important; + line-height: 60px !important; + padding-top: 0 !important; + padding-bottom: 0 !important; + margin-top: 0 0 !important; + border-radius: 3px !important; + background: linear-gradient( + to top, + #c40f0f 50%, + #0dce0d 50% + ); +} +input[type=range][orient=vertical]::-webkit-slider-thumb { + -webkit-appearance: none !important; + background-color: #c40f0f !important; + margin-right: -4px !important; + margin-top: 0px !important; + cursor: grab !important; + border-radius: 0 0 0 0 !important; + width: 10px !important; + height: 5px !important; + font-size: 10px; +} +output { + display: block; + margin: 5px auto; + font-size:1.75em; +} +input .vertslider { + height: 60px; +} \ No newline at end of file diff --git a/sw5e-light.css b/sw5e-light.css index 20f09b81..d1635367 100644 --- a/sw5e-light.css +++ b/sw5e-light.css @@ -784,3 +784,14 @@ body.light-theme .sw5e.sheet.actor.npc .swalt-sheet header div.creature-type:hov body.light-theme .sw5e.sheet.actor.npc .swalt-sheet header .experience { color: #4f4f4f; } +body.light-theme .sw5e.sheet.actor .swalt-sheet .panel.resources .traits .fuel-wrapper .fuel-label { + background: #D6D6D6; + color: #1C1C1C; + border: 1px solid #1C1C1C; +} +body.light-theme .sw5e.sheet.actor .swalt-sheet .panel.resources .traits .fuel-wrapper .fuel { + background: #c40f0f; +} +body.light-theme .sw5e.sheet.actor .swalt-sheet .panel.resources .traits .fuel-wrapper .fuel .fuel-bar { + background: #0dce0d; +} \ No newline at end of file diff --git a/sw5e.css b/sw5e.css index 51b2e6f4..e41c90da 100644 --- a/sw5e.css +++ b/sw5e.css @@ -429,6 +429,7 @@ list-style: none; margin: 0; padding: 0; + display: block; } .sw5e.sheet .items-list .item-name { flex: 2; diff --git a/sw5e.js b/sw5e.js index 5bef2a6f..394af593 100644 --- a/sw5e.js +++ b/sw5e.js @@ -288,6 +288,10 @@ Handlebars.registerHelper('getProperty', function (data, property) { return getProperty(data, property); }); +Handlebars.registerHelper('round', function(value) { + return Math.floor(value); +}); + function setFolderBackground(html) { html.find("header.folder-header").each(function() { diff --git a/template.json b/template.json index 4e026efc..d8b2fccf 100644 --- a/template.json +++ b/template.json @@ -446,6 +446,11 @@ "dr": 0, "engpow": 1, "exhaustion": 0, + "fuel": { + "cap": 0, + "cost": 0, + "value": 0 + }, "hsm": 1, "hull": { "die": "", @@ -508,7 +513,7 @@ }, "details": { "tier": 0, - "role": "", + "role": [], "source": "" }, "skills": { diff --git a/templates/actors/newActor/starship.html b/templates/actors/newActor/starship.html index fa905c46..3f64ddf2 100644 --- a/templates/actors/newActor/starship.html +++ b/templates/actors/newActor/starship.html @@ -53,10 +53,10 @@