From f4af3aad456bd8c94caad8eb28177a90b5a9a094 Mon Sep 17 00:00:00 2001 From: Mike Magarino Date: Tue, 26 Jan 2021 00:33:21 -0500 Subject: [PATCH 01/18] skills v1 --- module/characterImporter.js | 68 ++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/module/characterImporter.js b/module/characterImporter.js index e5af2c18..d517e4f7 100644 --- a/module/characterImporter.js +++ b/module/characterImporter.js @@ -49,6 +49,63 @@ export default class CharacterImporter { }, }; + const skills = { + acr: { + value: sourceCharacter.attribs.find(e => e.name == 'acrobatics_type').current + }, + ani: { + value: sourceCharacter.attribs.find(e => e.name == 'animal_handling_type').current + }, + ath: { + value: sourceCharacter.attribs.find(e => e.name == 'athletics_type').current + }, + dec: { + value: sourceCharacter.attribs.find(e => e.name == 'deception_type').current + }, + ins: { + value: sourceCharacter.attribs.find(e => e.name == 'insight_type').current + }, + inv: { + value: sourceCharacter.attribs.find(e => e.name == 'investigation_type').current + }, + itm: { + value: sourceCharacter.attribs.find(e => e.name == 'intimidation_type').current + }, + lor: { + value: sourceCharacter.attribs.find(e => e.name == 'lore_type').current + }, + med: { + value: sourceCharacter.attribs.find(e => e.name == 'medicine_type').current + }, + nat: { + value: sourceCharacter.attribs.find(e => e.name == 'nature_type').current + }, + per: { + value: sourceCharacter.attribs.find(e => e.name == 'persuasion_type').current + }, + pil: { + value: sourceCharacter.attribs.find(e => e.name == 'piloting_type').current + }, + prc: { + value: sourceCharacter.attribs.find(e => e.name == 'perception_type').current + }, + prf: { + value: sourceCharacter.attribs.find(e => e.name == 'performance_type').current + }, + slt: { + value: sourceCharacter.attribs.find(e => e.name == 'sleight_of_hand_type').current + }, + ste: { + value: sourceCharacter.attribs.find(e => e.name == 'stealth_type').current + }, + sur: { + value: sourceCharacter.attribs.find(e => e.name == 'survival_type').current + }, + tec: { + value: sourceCharacter.attribs.find(e => e.name == 'technology_type').current + } + }; + const targetCharacter = { name: sourceCharacter.name, type: "character", @@ -58,7 +115,8 @@ export default class CharacterImporter { attributes: { ac: ac, hp: hp - } + }, + skills: skills } }; @@ -77,6 +135,14 @@ export default class CharacterImporter { await actor.createEmbeddedEntity("OwnedItem", assignedClass.data, { displaySheet: false }); } + static async addSkils(){ + // data.skills.skill.value is all that matters + // value = 0 = regular + // value = 0.5 = half-proficient + // value = 1 = proficient + // value = 2 = expertise + } + static addImportButton(html){ const header = $("#actors").find("header.directory-header"); const search = $("#actors").children().find("div.header-search"); From 52fd477d397acea45b9573ad443ba2a5ff2c6046 Mon Sep 17 00:00:00 2001 From: Mike Magarino Date: Tue, 26 Jan 2021 01:24:16 -0500 Subject: [PATCH 02/18] skills v2 --- module/characterImporter.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/module/characterImporter.js b/module/characterImporter.js index d517e4f7..5339522c 100644 --- a/module/characterImporter.js +++ b/module/characterImporter.js @@ -49,6 +49,15 @@ export default class CharacterImporter { }, }; + /* ----------------------------------------------------------------- */ + /* character.data.skills..value is all that matters + /* values can be 0, 0.5, 1 or 2 + /* 0 = regular + /* 0.5 = half-proficient + /* 1 = proficient + /* 2 = expertise + /* foundry takes care of calculating the rest + /* ----------------------------------------------------------------- */ const skills = { acr: { value: sourceCharacter.attribs.find(e => e.name == 'acrobatics_type').current @@ -135,14 +144,6 @@ export default class CharacterImporter { await actor.createEmbeddedEntity("OwnedItem", assignedClass.data, { displaySheet: false }); } - static async addSkils(){ - // data.skills.skill.value is all that matters - // value = 0 = regular - // value = 0.5 = half-proficient - // value = 1 = proficient - // value = 2 = expertise - } - static addImportButton(html){ const header = $("#actors").find("header.directory-header"); const search = $("#actors").children().find("div.header-search"); From 6f90f19ad19ba12a2a92f020cb471b5d2f0cd282 Mon Sep 17 00:00:00 2001 From: Mike Magarino Date: Tue, 26 Jan 2021 02:00:30 -0500 Subject: [PATCH 03/18] Update characterImporter.js --- module/characterImporter.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/module/characterImporter.js b/module/characterImporter.js index 5339522c..3616496c 100644 --- a/module/characterImporter.js +++ b/module/characterImporter.js @@ -3,7 +3,7 @@ export default class CharacterImporter { // transform JSON from sw5e.com to Foundry friendly format // and insert new actor static async transform(rawCharacter){ - const sourceCharacter = JSON.parse(rawCharacter); //source character + const sourceCharacter = JSON.parse(rawCharacter); const details = { species: sourceCharacter.attribs.find(e => e.name == "race").current, @@ -131,12 +131,14 @@ export default class CharacterImporter { let actor = await Actor.create(targetCharacter); + //add class and level const profession = sourceCharacter.attribs.find(e => e.name == "class").current; let professionLevel = sourceCharacter.attribs.find(e => e.name == "class_display").current; professionLevel = parseInt( professionLevel.replace(/[^0-9]/g,'') ); //remove a-z, leaving only integers CharacterImporter.addClasses(profession, professionLevel, actor); } + //currently only works with 1 class static async addClasses(profession, level, actor){ let classes = await game.packs.get('sw5e.classes').getContent(); let assignedClass = classes.find( c => c.name === profession ); From 826f042dbb26de595d4437098a8af80375af2b60 Mon Sep 17 00:00:00 2001 From: Mike Magarino Date: Tue, 26 Jan 2021 10:09:28 -0500 Subject: [PATCH 04/18] skills and multiclass working --- module/characterImporter.js | 62 ++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/module/characterImporter.js b/module/characterImporter.js index 3616496c..c2584527 100644 --- a/module/characterImporter.js +++ b/module/characterImporter.js @@ -130,20 +130,58 @@ export default class CharacterImporter { }; let actor = await Actor.create(targetCharacter); - - //add class and level - const profession = sourceCharacter.attribs.find(e => e.name == "class").current; - let professionLevel = sourceCharacter.attribs.find(e => e.name == "class_display").current; - professionLevel = parseInt( professionLevel.replace(/[^0-9]/g,'') ); //remove a-z, leaving only integers - CharacterImporter.addClasses(profession, professionLevel, actor); + CharacterImporter.addProfessions(sourceCharacter, actor); } - //currently only works with 1 class - static async addClasses(profession, level, actor){ - let classes = await game.packs.get('sw5e.classes').getContent(); - let assignedClass = classes.find( c => c.name === profession ); - assignedClass.data.data.levels = level; - await actor.createEmbeddedEntity("OwnedItem", assignedClass.data, { displaySheet: false }); + static async addProfessions(sourceCharacter, actor){ + // "class" is a reserved word, therefore I use profession where I can. + let result = []; + + // parse all class and multiclassX items + // couldn't get Array.filter to work here for some reason + sourceCharacter.attribs.forEach( (e) => { + if ( CharacterImporter.classOrMulticlass(e.name) ){ + var t = { + profession: CharacterImporter.capitalize(e.current), + type: CharacterImporter.baseOrMulti(e.name), + level: CharacterImporter.getLevel(e, sourceCharacter) + } + result.push(t); + } + }); + + const professionsPack = await game.packs.get('sw5e.classes').getContent(); + result.forEach( (prof) => { + let assignedProfession = professionsPack.find( o => o.name === prof.profession ); + assignedProfession.data.data.levels = prof.level; + actor.createEmbeddedEntity("OwnedItem", assignedProfession.data, { displaySheet: false }); + }); + } + + static classOrMulticlass(name){ + return name === 'class' || (name.includes('multiclass') && name.length <= 12); + } + + static baseOrMulti(name){ + if (name === 'class'){ + return 'base_class'; + } else { + return 'multi_class'; + } + } + + static getLevel(item, sourceCharacter){ + if (item.name === 'class'){ + let result = sourceCharacter.attribs.find( e => e.name === 'base_level' ).current; + return parseInt(result); + } else { + let result = sourceCharacter.attribs.find( e => e.name === `${item.name}_lvl` ).current; + return parseInt(result); + } + } + + static capitalize(str){ + return str.charAt(0).toUpperCase() + str.slice(1); } static addImportButton(html){ From abc65220ec7a43d6c3bc3b10ac9eb974c0163dad Mon Sep 17 00:00:00 2001 From: Mike Magarino Date: Tue, 26 Jan 2021 10:11:52 -0500 Subject: [PATCH 05/18] skills and multiclass working --- module/characterImporter.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/module/characterImporter.js b/module/characterImporter.js index c2584527..b87e50fc 100644 --- a/module/characterImporter.js +++ b/module/characterImporter.js @@ -133,12 +133,15 @@ export default class CharacterImporter { CharacterImporter.addProfessions(sourceCharacter, actor); } + // Parse all classes and add them to already created actor. + // "class" is a reserved word, therefore I use profession where I can. static async addProfessions(sourceCharacter, actor){ - // "class" is a reserved word, therefore I use profession where I can. + let result = []; // parse all class and multiclassX items // couldn't get Array.filter to work here for some reason + // result = array of objects. each object is a separate class sourceCharacter.attribs.forEach( (e) => { if ( CharacterImporter.classOrMulticlass(e.name) ){ var t = { @@ -150,6 +153,7 @@ export default class CharacterImporter { } }); + // pull classes directly from system compendium and add them to current actor const professionsPack = await game.packs.get('sw5e.classes').getContent(); result.forEach( (prof) => { let assignedProfession = professionsPack.find( o => o.name === prof.profession ); From 9bbc9af285faef67dfe80444deaa5c5bbf972a61 Mon Sep 17 00:00:00 2001 From: TJ Date: Wed, 24 Mar 2021 19:55:33 -0500 Subject: [PATCH 06/18] Add species --- module/characterImporter.js | 109 ++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 49 deletions(-) diff --git a/module/characterImporter.js b/module/characterImporter.js index e5af2c18..35b1ec35 100644 --- a/module/characterImporter.js +++ b/module/characterImporter.js @@ -1,52 +1,51 @@ export default class CharacterImporter { - // transform JSON from sw5e.com to Foundry friendly format // and insert new actor - static async transform(rawCharacter){ + static async transform(rawCharacter) { const sourceCharacter = JSON.parse(rawCharacter); //source character - + const details = { - species: sourceCharacter.attribs.find(e => e.name == "race").current, - background: sourceCharacter.attribs.find(e => e.name == "background").current, - alignment: sourceCharacter.attribs.find(e => e.name == "alignment").current - } - + species: sourceCharacter.attribs.find((e) => e.name == "race").current, + background: sourceCharacter.attribs.find((e) => e.name == "background").current, + alignment: sourceCharacter.attribs.find((e) => e.name == "alignment").current + }; + const hp = { - value: sourceCharacter.attribs.find(e => e.name == "hp").current, + value: sourceCharacter.attribs.find((e) => e.name == "hp").current, min: 0, - max: sourceCharacter.attribs.find(e => e.name == "hp").current, - temp: sourceCharacter.attribs.find(e => e.name == "hp_temp").current + max: sourceCharacter.attribs.find((e) => e.name == "hp").current, + temp: sourceCharacter.attribs.find((e) => e.name == "hp_temp").current }; const ac = { - value: sourceCharacter.attribs.find(e => e.name == "ac").current + value: sourceCharacter.attribs.find((e) => e.name == "ac").current }; const abilities = { str: { - value: sourceCharacter.attribs.find(e => e.name == "strength").current, - proficient: sourceCharacter.attribs.find(e => e.name == 'strength_save_prof').current ? 1 : 0 + value: sourceCharacter.attribs.find((e) => e.name == "strength").current, + proficient: sourceCharacter.attribs.find((e) => e.name == "strength_save_prof").current ? 1 : 0 }, dex: { - value: sourceCharacter.attribs.find(e => e.name == "dexterity").current, - proficient: sourceCharacter.attribs.find(e => e.name == 'dexterity_save_prof').current ? 1 : 0 + value: sourceCharacter.attribs.find((e) => e.name == "dexterity").current, + proficient: sourceCharacter.attribs.find((e) => e.name == "dexterity_save_prof").current ? 1 : 0 }, con: { - value: sourceCharacter.attribs.find(e => e.name == "constitution").current, - proficient: sourceCharacter.attribs.find(e => e.name == 'constitution_save_prof').current ? 1 : 0 + value: sourceCharacter.attribs.find((e) => e.name == "constitution").current, + proficient: sourceCharacter.attribs.find((e) => e.name == "constitution_save_prof").current ? 1 : 0 }, int: { - value: sourceCharacter.attribs.find(e => e.name == "intelligence").current, - proficient: sourceCharacter.attribs.find(e => e.name == 'intelligence_save_prof').current ? 1 : 0 + value: sourceCharacter.attribs.find((e) => e.name == "intelligence").current, + proficient: sourceCharacter.attribs.find((e) => e.name == "intelligence_save_prof").current ? 1 : 0 }, wis: { - value: sourceCharacter.attribs.find(e => e.name == "wisdom").current, - proficient: sourceCharacter.attribs.find(e => e.name == 'wisdom_save_prof').current ? 1 : 0 + value: sourceCharacter.attribs.find((e) => e.name == "wisdom").current, + proficient: sourceCharacter.attribs.find((e) => e.name == "wisdom_save_prof").current ? 1 : 0 }, cha: { - value: sourceCharacter.attribs.find(e => e.name == "charisma").current, - proficient: sourceCharacter.attribs.find(e => e.name == 'charisma_save_prof').current ? 1 : 0 - }, + value: sourceCharacter.attribs.find((e) => e.name == "charisma").current, + proficient: sourceCharacter.attribs.find((e) => e.name == "charisma_save_prof").current ? 1 : 0 + } }; const targetCharacter = { @@ -64,58 +63,70 @@ export default class CharacterImporter { let actor = await Actor.create(targetCharacter); - const profession = sourceCharacter.attribs.find(e => e.name == "class").current; - let professionLevel = sourceCharacter.attribs.find(e => e.name == "class_display").current; - professionLevel = parseInt( professionLevel.replace(/[^0-9]/g,'') ); //remove a-z, leaving only integers - CharacterImporter.addClasses(profession, professionLevel, actor); + const profession = sourceCharacter.attribs.find((e) => e.name == "class").current; + let professionLevel = sourceCharacter.attribs.find((e) => e.name == "class_display").current; + professionLevel = parseInt(professionLevel.replace(/[^0-9]/g, "")); //remove a-z, leaving only integers + this.addClasses(profession, professionLevel, actor); + + this.addSpecies(sourceCharacter.attribs.find((e) => e.name == "race").current, actor); } - static async addClasses(profession, level, actor){ - let classes = await game.packs.get('sw5e.classes').getContent(); - let assignedClass = classes.find( c => c.name === profession ); + static async addClasses(profession, level, actor) { + let classes = await game.packs.get("sw5e.classes").getContent(); + let assignedClass = classes.find((c) => c.name === profession); assignedClass.data.data.levels = level; await actor.createEmbeddedEntity("OwnedItem", assignedClass.data, { displaySheet: false }); } - static addImportButton(html){ + static async addSpecies(race, actor) { + let species = await game.packs.get("sw5e.species").getContent(); + let assignedSpecies = species.find((c) => c.name === race); + + await actor.createEmbeddedEntity("OwnedItem", assignedSpecies.data, { displaySheet: false }); + } + + static addImportButton(html) { const header = $("#actors").find("header.directory-header"); const search = $("#actors").children().find("div.header-search"); const newImportButtonDiv = $("#actors").children().find("div.header-actions").clone(); const newSearch = search.clone(); search.remove(); - newImportButtonDiv.attr('id', 'character-sheet-import'); + newImportButtonDiv.attr("id", "character-sheet-import"); header.append(newImportButtonDiv); newImportButtonDiv.children("button").remove(); - newImportButtonDiv.append(""); + newImportButtonDiv.append( + "" + ); newSearch.appendTo(header); let characterImportButton = $("#cs-import-button"); - characterImportButton.click(ev => { - let content = '

Saved Character JSON Import

' - + ' ' - + '
' - + ''; + characterImportButton.click((ev) => { + let content = + "

Saved Character JSON Import

" + + ' ' + + "
" + + ''; let importDialog = new Dialog({ title: "Import Character from SW5e.com", content: content, buttons: { - "Import": { + Import: { icon: '', label: "Import Character", callback: (e) => { - let characterData = $('#character-json').val(); - console.log('Parsing Character JSON'); + let characterData = $("#character-json").val(); + console.log("Parsing Character JSON"); CharacterImporter.transform(characterData); - } + } }, - "Cancel": { + Cancel: { icon: '', label: "Cancel", - callback: () => {}, + callback: () => {} } } - }) + }); importDialog.render(true); }); - } -} \ No newline at end of file + } +} From b0570263288b4434d220e13abdcdbb1f63d977ee Mon Sep 17 00:00:00 2001 From: TJ Date: Sat, 27 Mar 2021 14:45:05 -0500 Subject: [PATCH 07/18] Remove built in species bonuses --- module/characterImporter.js | 45 ++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/module/characterImporter.js b/module/characterImporter.js index 35b1ec35..5dc58b2d 100644 --- a/module/characterImporter.js +++ b/module/characterImporter.js @@ -79,13 +79,48 @@ export default class CharacterImporter { } static async addSpecies(race, actor) { - let species = await game.packs.get("sw5e.species").getContent(); - let assignedSpecies = species.find((c) => c.name === race); + const species = await game.packs.get("sw5e.species").getContent(); + const assignedSpecies = species.find((c) => c.name === race); + const activeEffects = assignedSpecies.data.effects[0].changes; + const actorData = { data: { ...actor.data.abilities } }; + + activeEffects.map((effect) => { + switch (effect.key) { + case "data.abilities.str.value": + actorData.data.abilities.str.value -= effect.value; + break; + + case "data.abilities.dex.value": + actorData.data.abilities.dex.value -= effect.value; + break; + + case "data.abilities.con.value": + actorData.data.abilities.con.value -= effect.value; + break; + + case "data.abilities.int.value": + actorData.data.abilities.int.value -= effect.value; + break; + + case "data.abilities.wis.value": + actorData.data.abilities.wis.value -= effect.value; + break; + + case "data.abilities.cha.value": + actorData.data.abilities.cha.value -= effect.value; + break; + + default: + break; + } + }); + + actor.update(actorData); await actor.createEmbeddedEntity("OwnedItem", assignedSpecies.data, { displaySheet: false }); } - static addImportButton(html) { + static addImportButton() { const header = $("#actors").find("header.directory-header"); const search = $("#actors").children().find("div.header-search"); const newImportButtonDiv = $("#actors").children().find("div.header-actions").clone(); @@ -100,7 +135,7 @@ export default class CharacterImporter { newSearch.appendTo(header); let characterImportButton = $("#cs-import-button"); - characterImportButton.click((ev) => { + characterImportButton.click(() => { let content = "

Saved Character JSON Import

" + ' ' + @@ -113,7 +148,7 @@ export default class CharacterImporter { Import: { icon: '', label: "Import Character", - callback: (e) => { + callback: () => { let characterData = $("#character-json").val(); console.log("Parsing Character JSON"); CharacterImporter.transform(characterData); From 5477f9371d2546eb185a6004fcc0f807fc5f234d Mon Sep 17 00:00:00 2001 From: TJ Date: Sat, 27 Mar 2021 15:23:27 -0500 Subject: [PATCH 08/18] Add force powers --- module/characterImporter.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/module/characterImporter.js b/module/characterImporter.js index 5dc58b2d..0f5dadfa 100644 --- a/module/characterImporter.js +++ b/module/characterImporter.js @@ -69,6 +69,11 @@ export default class CharacterImporter { this.addClasses(profession, professionLevel, actor); this.addSpecies(sourceCharacter.attribs.find((e) => e.name == "race").current, actor); + + this.addForcePowers( + sourceCharacter.attribs.filter((e) => e.name.search(/repeating_power.+_powername/g) != -1).map((e) => e.current), + actor + ); } static async addClasses(profession, level, actor) { @@ -120,6 +125,18 @@ export default class CharacterImporter { await actor.createEmbeddedEntity("OwnedItem", assignedSpecies.data, { displaySheet: false }); } + static async addForcePowers(powers, actor) { + const forcePowers = await game.packs.get("sw5e.forcepowers").getContent(); + + for (const power of powers) { + const selectedPower = forcePowers.find((c) => c.name === power); + + if (selectedPower) { + await actor.createEmbeddedEntity("OwnedItem", selectedPower.data, { displaySheet: false }); + } + } + } + static addImportButton() { const header = $("#actors").find("header.directory-header"); const search = $("#actors").children().find("div.header-search"); From 16d01207a7393c6c5cba3c325eab9824fd67f926 Mon Sep 17 00:00:00 2001 From: TJ Date: Sat, 27 Mar 2021 15:38:37 -0500 Subject: [PATCH 09/18] Added tech powers --- module/characterImporter.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/module/characterImporter.js b/module/characterImporter.js index 0f5dadfa..7bfb4bb9 100644 --- a/module/characterImporter.js +++ b/module/characterImporter.js @@ -70,7 +70,7 @@ export default class CharacterImporter { this.addSpecies(sourceCharacter.attribs.find((e) => e.name == "race").current, actor); - this.addForcePowers( + this.addPowers( sourceCharacter.attribs.filter((e) => e.name.search(/repeating_power.+_powername/g) != -1).map((e) => e.current), actor ); @@ -125,14 +125,18 @@ export default class CharacterImporter { await actor.createEmbeddedEntity("OwnedItem", assignedSpecies.data, { displaySheet: false }); } - static async addForcePowers(powers, actor) { + static async addPowers(powers, actor) { const forcePowers = await game.packs.get("sw5e.forcepowers").getContent(); + const techPowers = await game.packs.get("sw5e.techpowers").getContent(); for (const power of powers) { - const selectedPower = forcePowers.find((c) => c.name === power); + const forcePower = forcePowers.find((c) => c.name === power); + const techPower = techPowers.find((c) => c.name === power); - if (selectedPower) { - await actor.createEmbeddedEntity("OwnedItem", selectedPower.data, { displaySheet: false }); + if (forcePower) { + await actor.createEmbeddedEntity("OwnedItem", forcePower.data, { displaySheet: false }); + } else if (techPower) { + await actor.createEmbeddedEntity("OwnedItem", techPower.data, { displaySheet: false }); } } } From bd94d75086d591c0648de87adde5133d9f63de71 Mon Sep 17 00:00:00 2001 From: TJ Date: Sat, 27 Mar 2021 16:14:50 -0500 Subject: [PATCH 10/18] Add weapons and armors --- module/characterImporter.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/module/characterImporter.js b/module/characterImporter.js index 7bfb4bb9..e89f3b62 100644 --- a/module/characterImporter.js +++ b/module/characterImporter.js @@ -74,6 +74,13 @@ export default class CharacterImporter { sourceCharacter.attribs.filter((e) => e.name.search(/repeating_power.+_powername/g) != -1).map((e) => e.current), actor ); + + this.addItems( + sourceCharacter.attribs + .filter((e) => e.name.search(/repeating_inventory.+_itemname/g) != -1) + .map((e) => e.current), + actor + ); } static async addClasses(profession, level, actor) { @@ -141,6 +148,22 @@ export default class CharacterImporter { } } + static async addItems(items, actor) { + const weapons = await game.packs.get("sw5e.weapons").getContent(); + const armors = await game.packs.get("sw5e.armor").getContent(); + + for (const item of items) { + const weapon = weapons.find((c) => c.name === item); + const armor = armors.find((c) => c.name === item); + + if (weapon) { + await actor.createEmbeddedEntity("OwnedItem", weapon.data, { displaySheet: false }); + } else if (armor) { + await actor.createEmbeddedEntity("OwnedItem", armor.data, { displaySheet: false }); + } + } + } + static addImportButton() { const header = $("#actors").find("header.directory-header"); const search = $("#actors").children().find("div.header-search"); From 9d6fabe8c2dd042af9ce38e9279a1a83520bdf43 Mon Sep 17 00:00:00 2001 From: TJ Date: Sat, 27 Mar 2021 21:48:58 -0500 Subject: [PATCH 11/18] Add adventuring gear --- module/characterImporter.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/module/characterImporter.js b/module/characterImporter.js index e89f3b62..b3d4ce85 100644 --- a/module/characterImporter.js +++ b/module/characterImporter.js @@ -17,10 +17,6 @@ export default class CharacterImporter { temp: sourceCharacter.attribs.find((e) => e.name == "hp_temp").current }; - const ac = { - value: sourceCharacter.attribs.find((e) => e.name == "ac").current - }; - const abilities = { str: { value: sourceCharacter.attribs.find((e) => e.name == "strength").current, @@ -55,7 +51,6 @@ export default class CharacterImporter { abilities: abilities, details: details, attributes: { - ac: ac, hp: hp } } @@ -151,15 +146,19 @@ export default class CharacterImporter { static async addItems(items, actor) { const weapons = await game.packs.get("sw5e.weapons").getContent(); const armors = await game.packs.get("sw5e.armor").getContent(); + const adventuringGears = await game.packs.get("sw5e.adventuringgear").getContent(); for (const item of items) { - const weapon = weapons.find((c) => c.name === item); - const armor = armors.find((c) => c.name === item); + const weapon = weapons.find((c) => c.name.toLowerCase() === item.toLowerCase()); + const armor = armors.find((c) => c.name.toLowerCase() === item.toLowerCase()); + const gear = adventuringGears.find((c) => c.name.toLowerCase() === item.toLowerCase()); if (weapon) { await actor.createEmbeddedEntity("OwnedItem", weapon.data, { displaySheet: false }); } else if (armor) { await actor.createEmbeddedEntity("OwnedItem", armor.data, { displaySheet: false }); + } else if (gear) { + await actor.createEmbeddedEntity("OwnedItem", gear.data, { displaySheet: false }); } } } From 4b1b3bbeed2be5c4760fdc0cac31766f6eeb791f Mon Sep 17 00:00:00 2001 From: TJ Date: Sat, 27 Mar 2021 22:14:57 -0500 Subject: [PATCH 12/18] Fix for species data --- module/characterImporter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/characterImporter.js b/module/characterImporter.js index b3d4ce85..e0383bd8 100644 --- a/module/characterImporter.js +++ b/module/characterImporter.js @@ -89,7 +89,7 @@ export default class CharacterImporter { const species = await game.packs.get("sw5e.species").getContent(); const assignedSpecies = species.find((c) => c.name === race); const activeEffects = assignedSpecies.data.effects[0].changes; - const actorData = { data: { ...actor.data.abilities } }; + const actorData = { data: { abilities: { ...actor.data.data.abilities } } }; activeEffects.map((effect) => { switch (effect.key) { From e942a9b80346cee24a26b28054b0a56aea807dca Mon Sep 17 00:00:00 2001 From: TJ Date: Sat, 27 Mar 2021 23:00:57 -0500 Subject: [PATCH 13/18] Added item quantity handling --- module/characterImporter.js | 47 ++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/module/characterImporter.js b/module/characterImporter.js index e0383bd8..9ef7f85d 100644 --- a/module/characterImporter.js +++ b/module/characterImporter.js @@ -70,12 +70,19 @@ export default class CharacterImporter { actor ); - this.addItems( - sourceCharacter.attribs - .filter((e) => e.name.search(/repeating_inventory.+_itemname/g) != -1) - .map((e) => e.current), - actor + const discoveredItems = sourceCharacter.attribs.filter( + (e) => e.name.search(/repeating_inventory.+_itemname/g) != -1 ); + const items = discoveredItems.map((item) => { + const id = item.name.match(/-\w{19}/g); + + return { + name: item.current, + quantity: sourceCharacter.attribs.find((e) => e.name === `repeating_inventory_${id}_itemcount`).current + }; + }); + + this.addItems(items, actor); } static async addClasses(profession, level, actor) { @@ -132,13 +139,10 @@ export default class CharacterImporter { const techPowers = await game.packs.get("sw5e.techpowers").getContent(); for (const power of powers) { - const forcePower = forcePowers.find((c) => c.name === power); - const techPower = techPowers.find((c) => c.name === power); + const createdPower = forcePowers.find((c) => c.name === power) || techPowers.find((c) => c.name === power); - if (forcePower) { - await actor.createEmbeddedEntity("OwnedItem", forcePower.data, { displaySheet: false }); - } else if (techPower) { - await actor.createEmbeddedEntity("OwnedItem", techPower.data, { displaySheet: false }); + if (createdPower) { + await actor.createEmbeddedEntity("OwnedItem", createdPower.data, { displaySheet: false }); } } } @@ -146,19 +150,20 @@ export default class CharacterImporter { static async addItems(items, actor) { const weapons = await game.packs.get("sw5e.weapons").getContent(); const armors = await game.packs.get("sw5e.armor").getContent(); - const adventuringGears = await game.packs.get("sw5e.adventuringgear").getContent(); + const adventuringGear = await game.packs.get("sw5e.adventuringgear").getContent(); for (const item of items) { - const weapon = weapons.find((c) => c.name.toLowerCase() === item.toLowerCase()); - const armor = armors.find((c) => c.name.toLowerCase() === item.toLowerCase()); - const gear = adventuringGears.find((c) => c.name.toLowerCase() === item.toLowerCase()); + const createdItem = + weapons.find((c) => c.name.toLowerCase() === item.name.toLowerCase()) || + armors.find((c) => c.name.toLowerCase() === item.name.toLowerCase()) || + adventuringGear.find((c) => c.name.toLowerCase() === item.name.toLowerCase()); - if (weapon) { - await actor.createEmbeddedEntity("OwnedItem", weapon.data, { displaySheet: false }); - } else if (armor) { - await actor.createEmbeddedEntity("OwnedItem", armor.data, { displaySheet: false }); - } else if (gear) { - await actor.createEmbeddedEntity("OwnedItem", gear.data, { displaySheet: false }); + if (createdItem) { + if (item.quantity != 1) { + createdItem.data.data.quantity = item.quantity; + } + + await actor.createEmbeddedEntity("OwnedItem", createdItem.data, { displaySheet: false }); } } } From e25140b529bfe9ade0bb472e888991b2b6fddb0b Mon Sep 17 00:00:00 2001 From: TJ Date: Sat, 27 Mar 2021 23:17:31 -0500 Subject: [PATCH 14/18] Add skill proficiencies --- module/characterImporter.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/module/characterImporter.js b/module/characterImporter.js index 9ef7f85d..c02b302b 100644 --- a/module/characterImporter.js +++ b/module/characterImporter.js @@ -44,12 +44,34 @@ export default class CharacterImporter { } }; + const skills = { + acr: { value: sourceCharacter.attribs.find((e) => e.name == "acrobatics_type").current }, + ani: { value: sourceCharacter.attribs.find((e) => e.name == "animal_handling_type").current }, + ath: { value: sourceCharacter.attribs.find((e) => e.name == "athletics_type").current }, + dec: { value: sourceCharacter.attribs.find((e) => e.name == "deception_type").current }, + ins: { value: sourceCharacter.attribs.find((e) => e.name == "insight_type").current }, + inv: { value: sourceCharacter.attribs.find((e) => e.name == "investigation_type").current }, + itm: { value: sourceCharacter.attribs.find((e) => e.name == "intimidation_type").current }, + lor: { value: sourceCharacter.attribs.find((e) => e.name == "lore_type").current }, + med: { value: sourceCharacter.attribs.find((e) => e.name == "medicine_type").current }, + nat: { value: sourceCharacter.attribs.find((e) => e.name == "nature_type").current }, + per: { value: sourceCharacter.attribs.find((e) => e.name == "persuasion_type").current }, + pil: { value: sourceCharacter.attribs.find((e) => e.name == "piloting_type").current }, + prc: { value: sourceCharacter.attribs.find((e) => e.name == "perception_type").current }, + prf: { value: sourceCharacter.attribs.find((e) => e.name == "performance_type").current }, + slt: { value: sourceCharacter.attribs.find((e) => e.name == "sleight_of_hand_type").current }, + ste: { value: sourceCharacter.attribs.find((e) => e.name == "stealth_type").current }, + sur: { value: sourceCharacter.attribs.find((e) => e.name == "survival_type").current }, + tec: { value: sourceCharacter.attribs.find((e) => e.name == "technology_type").current } + }; + const targetCharacter = { name: sourceCharacter.name, type: "character", data: { abilities: abilities, details: details, + skills: skills, attributes: { hp: hp } From 0558cdec49fefe61e25058c9d58cdfc0a78ced76 Mon Sep 17 00:00:00 2001 From: Michael Burgess Date: Mon, 29 Mar 2021 15:05:49 -0400 Subject: [PATCH 15/18] Update classfeatures.db Added Fighter - Exhibitionist class features, updated Scout class features with icons, added scout routines updated Sentinel class features with icons, added force-empowered options, added ideals. --- packs/packs/classfeatures.db | 46 ++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/packs/packs/classfeatures.db b/packs/packs/classfeatures.db index a73d29cc..f4ca46ab 100644 --- a/packs/packs/classfeatures.db +++ b/packs/packs/classfeatures.db @@ -899,3 +899,49 @@ {"_id":"zxw8tBx6Z30RKyLr","name":"Rampage","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

At 6th level, while raging, when you deal damage with a blaster with which you are proficient, and you added your Strength modifier to the damage roll, you can use a bonus action to move up to half your speed towards your target. You must end this movement closer to your target than you started. If you end this movement within 5 feet of your target, you can make one melee weapon attack with your blaster as a part of this bonus action.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"bonus","cost":0,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":""},"consume":{"type":"","target":"","amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{},"img":"icons/svg/mystery-man.svg","effects":[]} {"_id":"zzbwoqUNCb6U0lRK","name":"Unarmored Movement","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Monk: 3rd and 9th level

\n

Your speed increases by 10 feet while you are not wearing armor or wielding a shield. This bonus increases when you reach certain monk levels, as shown in the Unarmored Movement column of the monk table.

\n

At 9th level, you gain the ability to move along vertical surfaces and across liquids on your turn without falling during the move.

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
LevelUnarmored Movement
1st-
2nd-
3rd+10 ft.
4th+10 ft.
5th+15 ft.
6th+15 ft.
7th+15 ft.
8th+15 ft.
9th+20 ft.
10th+20 ft.
11th+20 ft.
12th+20 ft.
13th+25 ft.
14th+25 ft.
15th+25 ft.
16th+25 ft.
17th+30 ft.
18th+30 ft.
19th+30 ft.
20th+30 ft.
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":0,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":"Monk 3"},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/MNK-Passive.webp","effects":[{"_id":"vumU4CBYhXcV5ZZH","flags":{"dae":{"stackable":false,"specialDuration":[],"macroRepeat":"none","transfer":true}},"changes":[{"key":"data.attributes.movement.walk","value":10,"mode":2,"priority":20}],"disabled":false,"duration":{"startTime":null,"seconds":null,"rounds":null,"turns":null,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/MNK-Passive.webp","label":"Unarmored Movement","tint":"","transfer":true}]} {"_id":"zztRtikqjZ4bFjV0","name":"Invasive Presence","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

At 7th level, your spirit can invade another creature’s being. As an action, your spirit can touch a creature within 5 feet of it, forcing it to make a Wisdom saving throw against your universal force save DC. If you or creatures that are friendly to you are fighting it, it has advantage on the saving throw.

\n

On a failed save, your spirit moves into that creatures space, inhabiting its body, for 1 minute. The affected creature has disadvantage on the first attack roll, ability check, or saving throw it makes each turn. At the end of each its turns, the creature repeats this save. On a success, it repels the spirit from its body, and it becomes immune to this feature for 24 hours.

\n

Once you’ve used this feature, you must complete a long rest before you can use it again.

\n

 

","chat":"","unidentified":""},"source":"EC","activation":{"type":"action","cost":0,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":1,"max":1,"per":"lr"},"consume":{"type":"","target":"","amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{},"img":"icons/svg/mystery-man.svg","effects":[]} +{"name":"Bonus Proficiencies (Fighter: Exhibition)","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

Exhibition Specialist: 3rd level

\n

You gain proficiency in one Charisma skill of your choice.

","chat":"","unidentified":""},"source":"EC","activation":{"type":"","cost":0,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":""},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/FGTR-ARCH-Passive.webp","effects":[],"_id":"gUQdFHqjnOS3fzha"} +{"name":"In the Spotlight","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

Exhibition Specialist: 3rd level

\n

You can overwhelm an opponent with your unique blend of skill and style. As a bonus action, you can choose one creature you can see within 30 feet of you. The target is marked for 1 minute. While the target is marked, you gain the following benefits:

\n
    \n
  • You can add half your Charisma modifier (minimum of one) to any weapon damage roll you make against the marked target that doesn't already include that modifier.
  • \n
  • Your critical hit range against the marked target increases by 1.
  • \nIf the marked target is reduced to 0 hit points, you regain hit points equal to your fighter level + your Charisma modifier (minimum of 1).
\n

This effect ends early if you're incapacitated or die. Once you've used this feature, you can't use it again until you finish a short or long rest.

","chat":"","unidentified":""},"source":"EC","activation":{"type":"bonus","cost":null,"condition":""},"duration":{"value":1,"units":"minute"},"target":{"value":1,"width":null,"units":"","type":"enemy"},"range":{"value":30,"long":null,"units":"ft"},"uses":{"value":1,"max":"1","per":"sr"},"consume":{"type":"","target":"","amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/FGTR-ARCH-Bonus.webp","effects":[],"_id":"EPhvB41gDEI8Yww4"} +{"name":"Glory Kill","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

Exhibition Specialist: 7th level

\n

As you defeat your enemies in combat, you can weaken the morale of other foes or bolster the resolve of your allies alike. When you score a critical hit or reduce a creature to 0 hit points, you can choose one or more creatures that you can see within 30 feet of you. up to a number equal to your Charisma modifier (minimum of one creature). Each of the chosen creatures are affected by one of the following effects of your choice:

\n
    \n
  • The creature gains temporary hit points equal to 1d6 + your Charisma modifier (minimum of 1 temporary hit point).
  • \n
  • The creature must succeed on a Wisdom saving throw (DC = 8 + your proficiency bonus + your Charisma modifier) or be frightened of you until the start of your next turn.
  • \n
","chat":"","unidentified":""},"source":"EC","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":""},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/FGTR-ARCH-Passive.webp","effects":[],"_id":"fpXGa9GzfcAfUs61"} +{"name":"Glorious Defense","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

Exhibition Specialist: 15th level

\n

Your glory on the battlefront can misdirect attacks. When a creature you can see hits you with an attack roll, you can use your reaction to gain a bonus to AC against that attack, potentially causing it to miss you. The bonus equals your Charisma modifier (minimum of +1). If the attack misses, you can make one weapon attack against the attacker as part of this reaction.

","chat":"","unidentified":""},"source":"EC","activation":{"type":"reaction","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"","target":"","amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/FGTR-ARCH-Reaction.webp","effects":[],"_id":"YUyOhgOreVbOsOKS"} +{"name":"The Beauty of Violence","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

Exhibition Specialist: 18th level

\n

You've perfected a fighting style that allows you to stylishly dominate the field of battle. When you mark a creature with your In The Spotlight feature, you can enhance it For the duration of the mark, you gain the following additional benefits:

\n
    \n
  • You can add your full Charisma modifier, instead of half, to any weapon damage roll you make against the marked target that doesn't already include that modifier.
  • \n
  • You can add half your Charisma modifier (minimum of one) to any weapon attack roll you make against the marked target that doesn't already include that modifier.
  • \n
  • If the marked target is reduced to 0 hit points, you can use your reaction to mark a new creature within 30 feet of you. The duration of the new mark is equal to the remaining duration of the existing mark.
  • \n
\n

This effect ends early if you're incapacitated or die. Once you've used this feature, you can't use it again until you finish a long rest.

","chat":"","unidentified":""},"source":"EC","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"","target":"","amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/FGTR-ARCH-Passive.webp","effects":[],"_id":"2Pb9OITYFWjfh68F"} +{"_id":"pW0ObQnHARhqg4V0","name":"Scout Routine","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Beginning at 3rd level, you’ve developed one routine, as detailed below. You develop an additional routine at 7th and 15th level.

\n
\n

SCOUT ROUTINES

\n

The routines are presented in alphabetical order. If multiple scouts grant the same routine, affected creatures can only benefit from it once. You must be conscious to grant the benefit of your routines.

\n

At 9th level, the range of your routines increases to 15 feet, and at 17th level, the range of these routines increases to 30 feet.

\n

ADAPTABILITY ROUTINE

\n

At the start of each of your turns, you can choose an ability score with a saving throw in which you are not proficient. Until the start of your next turn, you add half your proficiency bonus, rounded down, to saving throws you make with the chosen ability. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

\n

MAVEN’S ROUTINE

\n

At the start of each of your turns, you can choose to gain resistance to damage from tech powers until the start of your next turn. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

\n

MESMER’S ROUTINE

\n

At the start of each of your turns, you can choose to have advantage on saving throws against effects that would incapacitate you or put you to sleep until the start of your next turn. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

\n

NOMAD’S ROUTINE

\n

At the start of each of your turns, you can choose to gain advantage on Constitution saving throws to avoid exhaustion from unenhanced sources, as well as being naturally adapted to both hot and cold climates. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

\n

RESPONDER’S ROUTINE

\n

When you roll initiative, you can choose to add your proficiency bonus to the initiative roll and have advantage on attack rolls against creatures that have not yet acted. Alternatively, you can choose to allow each creature within 5 feet of you, including you, to add half your proficiency bonus to the initiative roll and have advantage on the first attack roll they make against a creature that has not yet acted.

\n

SHARPSHOOTER’S ROUTINE

\n

At the start of each of your turns, you can choose to gain a bonus to the first weapon attack roll you make before the start of your next turn equal to your Intelligence modifier. Alternatively, you can choose to allow each creature within 5 feet of you, including you, to add half your Intelligence modifier to the first weapon attack roll they make before the start of your next turn.

\n

STRIDER’S ROUTINE

\n

At the start of each of your turns, you can choose to have each slowed level only reduce your speed by 5 feet, unless it would reduce your speed to 0 until the start of your next turn. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

\n

WARDEN’S ROUTINE

\n

At the start of each of your turns, you can choose to gain a climbing and swimming speed equal to your walking speed. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":0,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":""},"flags":{},"img":"icons/svg/mystery-man.svg","effects":[]} +{"$$deleted":true,"_id":"pW0ObQnHARhqg4V0"} +{"$$deleted":true,"_id":"QwDExZ4sYBdx4d4o"} +{"_id":"nov1Wc7APmyVdzJ4","name":"Combat Tech","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Scout: 14th level

\n

When you use your action to cast a tech power, you can make one weapon attack as a bonus action.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"","target":"","amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":"Scout 14","recharge":{"value":null,"charged":false}},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[]} +{"_id":"FzjcJryoe9J0CEkq","name":"Commando","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Scout: 10th level

\n

You can take the Dash or Hide actions as a bonus action on each of your turns. Additionally, you can remain perfectly still for long periods of time to set up ambushes.

\n

When you attempt to hide on your turn, you can opt to not move on that turn. If you avoid moving, creatures that attempt to detect you take a -10 penalty to their Wisdom (Perception) checks until the start of your next turn. You lose this benefit if you move or fall prone, either voluntarily or because of some external effect. You are still automatically detected if any effect or action causes you to no longer be hidden.

\n

If you are still hidden on your next turn, you can continue to remain motionless and gain this benefit until you are detected.

\n

Finally, you can no longer be tracked by unenhanced means, unless you choose to leave a trail.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"bonus","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"","target":"","amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false},"requirements":"Scout 10"},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Bonus.webp","effects":[]} +{"_id":"IB1sPazhmp63mLHF","name":"Expertise (Scout)","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Scout: 6th and 14th level

\n

Choose two of your skill proficiencies, or one of skill proficiencies and one of your tool proficiencies, or two of your tool proficiencies. You gain expertise in those skills or tools.

\n

At 14th level, you can choose another two proficiencies (in skills or tools) to gain this benefit.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":"Scout 6"},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[]} +{"_id":"vzwNHMqfV57Lr252","name":"Fighting Style (Scout)","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Scout: 2nd level

\n

You adopt a particular style of fighting as your specialty. Choose one of the fighting style options, detailed in Chapter 6.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":"Scout 2"},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[]} +{"_id":"mNXuHAozg3qRMjRW","name":"Foe Slayer","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Scout: 20th level

\n

You become an unparalleled hunter. Your Strength or Dexterity score increases by 2, and your Intelligence score increases by 2. Your maximum for those scores increases by 2.

\n

Additionally, once on each of your turns, you can add your Intelligence modifier to the attack roll or the damage roll of an attack you make. You can choose to use this feature before or after the roll, but before any effects of the roll are applied.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":"Scout 20"},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[]} +{"_id":"M6DPXcwX644UAsW3","name":"Pathfinder","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Scout: 1st level

\n

You are skilled at navigating the untamed wilds. You ignore difficult terrain, and when traveling for an hour or more, you gain the following benefits:

\n
    \n
  • Difficult terrain doesn’t slow your group, provided they can see and hear you.
  • \n
  • You can’t become lost by unenhanced means.
  • \n
  • Even when you are engaged in another activity while traveling (such as foraging, navigating, or tracking), you remain alert to danger.
  • \n
  • If you are traveling alone, you can move stealthily at a normal pace.
  • \n
  • When you forage, you find twice as much food.
  • \n
  • You have advantage on Survival checks.
  • \n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":"Scout 1"},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[]} +{"_id":"hWwTW7oKFDE41JWj","name":"Ranger's Quarry","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Scout: 1st, 5th, 9th, and 17th level

\n

You learn how to effectively read and track your prey. Once on each of your turns, you can choose a creature you can see within 120 feet and mark it as your quarry (no action required). For the next hour, you gain the following benefits:

\n
    \n
  • Once per turn, when you hit the target with a weapon attack, you can deal 1d4 additional damage to it of the same type as the weapon’s damage. This die changes as you gain scout levels, as shown in the Ranger’s Quarry column of the scout table.
  • \n
  • You have advantage on any Wisdom (Perception) or Wisdom (Survival) check you make to find it while it’s on the same planet as you.
  • \n
\n

You can only have one creature marked in this way at a time. Beginning at 5th level, you can use your reaction to mark a creature when it enters your line of sight, provided it is within range of your Ranger’s Quarry.

\n

The duration increases to 8 hours at 9th level and 24 hours at 17th level.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"none","cost":null,"condition":""},"duration":{"value":1,"units":"hour"},"target":{"value":1,"width":null,"units":"","type":"creature"},"range":{"value":120,"long":null,"units":"ft"},"uses":{"value":null,"max":"","per":""},"consume":{"type":"","target":"","amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false},"requirements":"Scout 1"},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[]} +{"name":"Scout Routine","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

Scout: 3rd, 7th, 9th, 15th, and 17th level

\n

You’ve developed one routine, as detailed at the end of the class description. You develop an additional routine at 7th and 15th level.

\n

At 9th level, the range of your routines increases to 15 feet, and at 17th level, the range of these routines increases to 30 feet

\n

SCOUT ROUTINES

\n

The routines are presented in alphabetical order. If multiple scouts grant the same routine, affected creatures can only benefit from it once. You must be conscious to grant the benefit of your routines.

\n
\n
\n

ADAPTABILITY ROUTINE

\n

At the start of each of your turns, you can choose an ability score with a saving throw in which you are not proficient. Until the start of your next turn, you add half your proficiency bonus, rounded down, to saving throws you make with the chosen ability. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

\n
\n

MAVEN’S ROUTINE

\n

At the start of each of your turns, you can choose to gain resistance to damage from tech powers until the start of your next turn. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

\n
\n

MESMER’S ROUTINE

\n

At the start of each of your turns, you can choose to have advantage on saving throws against effects that would incapacitate you or put you to sleep until the start of your next turn. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

\n
\n

NOMAD’S ROUTINE

\n

At the start of each of your turns, you can choose to gain advantage on Constitution saving throws to avoid exhaustion from unenhanced sources, as well as being naturally adapted to both hot and cold climates. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

\n
\n

RESPONDER’S ROUTINE

\n

When you roll initiative, you can choose to add your proficiency bonus to the initiative roll and have advantage on attack rolls against creatures that have not yet acted. Alternatively, you can choose to allow each creature within 5 feet of you, including you, to add half your proficiency bonus to the initiative roll and have advantage on the first attack roll they make against a creature that has not yet acted.

\n
\n

SHARPSHOOTER’S ROUTINE

\n

At the start of each of your turns, you can choose to gain a bonus to the first weapon attack roll you make before the start of your next turn equal to your Intelligence modifier. Alternatively, you can choose to allow each creature within 5 feet of you, including you, to add half your Intelligence modifier to the first weapon attack roll they make before the start of your next turn.

\n
\n

STRIDER’S ROUTINE

\n

At the start of each of your turns, you can choose to have each slowed level only reduce your speed by 5 feet, unless it would reduce your speed to 0 until the start of your next turn. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

\n
\n

WARDEN’S ROUTINE

\n

At the start of each of your turns, you can choose to gain a climbing and swimming speed equal to your walking speed. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":0,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":""},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[],"_id":"YfL8MY3JOPJ1Gf1O"} +{"_id":"x1TSm5F0CtGuX7u4","name":"Supreme Awareness","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Scout: 18th level

\n

You gain preternatural senses that help you fight creatures you can’t see. When you attack a creature you can’t see, your inability to see it doesn’t impose disadvantage on your attack rolls against it.

\n

You are also aware of the location of any invisible creature within 30 feet of you, provided that the creature isn’t hidden from you and you aren’t blinded or deafened.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":0,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":"Scout 18"},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[]} +{"_id":"F4I387qfbiqbeaOO","name":"Techcasting (Scout)","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Scout: 2nd level

\n

You have derived powers from schematics with the aid of your wristpad. See chapter 10 or the general rules of techcasting and chapter 12 for the tech powers list.

\n

TECH POWERS KNOWN

\n

You learn 4 tech powers of your choice, and you learn more at higher levels, as shown in the Tech Powers Known column of the scout table. You may not learn a tech power of a level higher than your Max Power Level.

\n

TECH POINTS

\n

You have a number of tech points equal to your scout level, as shown in the Tech Points column of the scout table, + your Intelligence modifier. You use these tech points to cast tech powers. You regain all expended tech points when you finish a short or long rest.

\n

MAX POWER LEVEL

\n

Many tech powers can be overcharged, consuming more tech points to create a greater effect. You can overcharge these powers to a maximum level, which increases at higher levels, as shown in the Max Power Level column of the scout table.

\n

You may only cast tech powers at 4th and 5th-level once. You regain the ability to do so after a long rest.

\n

TECHCASTING ABILITY

\n

Intelligence is your techcasting ability for your tech powers. You use your Intelligence whenever a power refers to your techcasting ability. Additionally, you use your Intelligence modifier when setting the saving throw DC for a tech power you cast and when making an attack roll with one.

\n
\n

Tech save DC = 8 + your proficiency bonus + your Intelligence modifier

\n
\n

Tech attack modifier = your proficiency bonus + your Intelligence modifier

\n
\n

TECHCASTING FOCUS

\n

You use a wristpad (found in chapter 5) as a tech focus for your tech powers.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":"Scout 1"},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[]} +{"_id":"OPmnvVAKt8P3mRzr","name":"Forcecasting (Sentinel)","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Sentinel: 1st level

\n

In your meditations on the force, you have learned powers, fragments of knowledge that imbue you with an abiding force ability. See chapter 10 for the general rules of forcecasting and chapter 11 for the force powers list.

\n

FORCE POWERS KNOWN

\n

You learn 7 force powers of your choice, and you learn more at higher levels, as shown in the Force Powers Known column of the sentinel table. You may not learn a force power of a level higher than your Max Power Level, and you may learn a force power at the same time you learn its prerequisite.

\n

FORCE POINTS

\n

You have a number of force points equal to your sentinel level x 3, as shown in the Force Points column of the sentinel table, + your Wisdom or Charisma modifier (your choice). You use these force points to cast force powers. You regain all expended force points when you finish a long rest.

\n

MAX POWER LEVEL

\n

Many force powers can be overpowered, consuming more force points to create a greater effect. You can overpower these abilities to a maximum level, which increases at higher levels, as shown in the Max Power Level column of the sentinel table.

\n

You may only cast force powers at 5th, 6th, and 7th-level once. You regain the ability to do so after a long rest.

\n

FORCECASTING ABILITY

\n

Your forcecasting ability varies based on the alignment of the powers you cast. You use Wisdom for light side powers, Charisma for dark side powers, and Wisdom or Charisma for universal powers (your choice). You use this ability score modifier whenever a power refers to your forcecasting ability. Additionally, you use this ability score modifier when setting the saving throw DC for a force power you cast and when making an attack roll with one.

\n
\n

Force save DC = 8 + your proficiency bonus + your forcecasting ability modifier

\n
\n

Force attack modifier = your proficiency bonus + your forcecasting ability modifier

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":0,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":"Sentinel 1"},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Passive.webp","effects":[]} +{"_id":"pnIrrDmqB5GosVJC","name":"Led by the Force","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Sentinel: 1st level

\n

You can add half your proficiency bonus, rounded down, to any ability check you make that doesn’t already include your proficiency bonus.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":0,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":"Sentinel 1"},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Passive.webp","effects":[{"_id":"9qOSAGjZr229QFAN","flags":{"dae":{"stackable":false,"transfer":true},"ActiveAuras":{"isAura":false,"ignoreSelf":false,"hidden":false,"height":false,"alignment":"","type":"","aura":"None","radius":null,"save":"","savedc":null,"hostile":false,"onlyOnce":false}},"changes":[{"key":"flags.sw5e.jackOfAllTrades","value":"1","mode":0,"priority":20}],"disabled":false,"duration":{"startTime":null,"seconds":null,"rounds":null,"turns":null,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Passive.webp","label":"Led by the Force","tint":"","transfer":true}]} +{"_id":"2jowNrxwqUrXnIlu","name":"Force-Empowered Self","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Sentinel: 2nd level

\n

Your training allows you to harness the mystical energy of the Force throughout your body. When you hit a creature with a melee weapon attack, you can spend 1 force point to use a Force-Empowered Self effect. Each effect uses a d4, which changes as you gain sentinel levels, as shown in the Kinetic Combat column of the sentinel table. You have three such effects: Deflection, Double Strike, and Slow Time. You can only use each effect once per turn, and you can only use one effect per hit.

\n
\n
\n

DEFLECTION

\n

You can roll a Kinetic Combat die and add it to your AC against one attack before the start of your next turn.

\n
\n

DOUBLE STRIKE

\n

You can roll a Kinetic Combat die and deal additional damage of the same type equal to the amount rolled.

\n
\n

SLOW TIME

\n

You can roll a Kinetic Combat die to increase your speed by 5 x the amount rolled until the end of your turn.

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":0,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":"Sentinel 2"},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Passive.webp","effects":[]} +{"_id":"xFgXRg2qF3SlvNfF","name":"Sentinel Ideals","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Sentinel: 2nd, 6th, 9th, 11th, and 17th level

\n

You adopt ideals that exemplify your bond with the Force. You adopt two ideals of your choice, as detailed at the end of the class description. You adopt an additional ideal at 6th and 11th level.

\n

You can manifest your ideals a combined total of twice. You gain an additional use at 9th and 17th level. You regain all expended uses when you finish a long rest.

\n
\n

SENTINEL IDEALS

\n

The ideals are presented in alphabetical order. You can’t benefit from a Sentinel Ideal option more than once, even if you later get to choose again.

\n
\n
\n

IDEAL OF THE AGILE

\n

You gain a swimming speed and a climbing speed equal to your walking speed. When you make a long jump, you can cover a number of feet up to twice your Wisdom or Charisma score (your choice). When you make a high jump, you can leap a number of feet up into the air equal to 3 + twice your Wisdom or Charisma modifier (your choice).

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, opportunity attacks against you are made with disadvantage.

\n
\n

IDEAL OF THE ARTISAN

\n

Choose one of your skill or tool proficiencies. When you make an ability check with the chosen skill or tool, you can add half your Wisdom or Charisma modifier (your choice, minimum of one) to any check you make that doesn’t already include that modifier.

\n

Additionally, as an action, you can manifest this ideal in a brief surge of energy. For the next 10 minutes, the bonus increases to your Wisdom or Charisma modifier, and you can choose a second skill or tool to extend this feature to.

\n
\n

IDEAL OF THE CONTENDER

\n

You can use Dexterity instead of Strength for the attack and damage rolls of your unarmed strikes, and your unarmed strike damage increases by one step (from 1 to d4, d4 to d6, or d6 to d8).

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, your unarmed strikes count as enhanced for the purpose of overcoming resistance and immunity to unenhanced attacks and damage, and you can use your Wisdom or Charisma modifier (your choice) instead of Strength for checks made to grapple a target or escape a grapple.

\n
\n

IDEAL OF THE FIGHTER

\n

You adopt a particular style of fighting as your specialty. Choose one of the fighting style options, detailed in Chapter 6. You can’t take a fighting style option more than once, even if you later get to choose again.

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, you know the fighting mastery that corresponds with the fighting style you chose with this feature. If you already know that fighting mastery, you instead learn another of your choice for the duration.

\n
\n

IDEAL OF THE HUNTER

\n

You gain darkvision out to a range of 60 feet. If you already have darkvision, this ideal increases its range by 30 feet.

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, you can see normally in enhanced darkness, and you gain blindsight to 10 feet.

\n
\n

IDEAL OF THE STEADFAST

\n

When you would make a melee weapon attack roll, you can instead force the target to make a Dexterity saving throw (DC = 8 + your bonus to attacks with the weapon). If you would have advantage on your attack roll, the creature instead has disadvantage on their saving throw, and if you would have disadvantage on your attack roll, the creature instead has advantage on their saving throw. On a failed save, the target takes normal weapon damage and is subjected to any additional effects that would occur on a hit.

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, when a creature succeeds on the saving throw, they take half the normal weapon damage, and when a creature rolls a 1 on the saving throw, they treat the damage as if you had rolled the maximum.

\n
\n

IDEAL OF THE TITAN

\n

You gain proficiency in medium armor.

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, you have advantage on ability checks and attack rolls that would forcefully move another creature, and the distance they would be moved increases by 5 feet.

\n
\n

IDEAL OF THE TRANQUIL

\n

When you finish a short or long rest, you gain a number of temporary force points equal to half your Wisdom or Charisma modifier (rounded up, your choice, minimum of one). When you would spend a force point while you have temporary force points, the temporary force points are spent first. All temporary force points are lost at the end of your next short or long rest.

\n

Additionally, as an action, you can manifest this ideal in a brief surge of energy. You regain a number of force points equal to half your Wisdom or Charisma modifier (rounded up, your choice, minimum of one).

\n
\n

IDEAL OF THE VIGOROUS

\n

When you roll a Hit Die to regain hit points, you may use your Wisdom or Charisma modifier in place of your Constitution modifier when determining the number of hit points you regain.

\n

Additionally, as an action, you can manifest this ideal in a brief surge of energy. You gain a number of temporary hit points equal to half your sentinel level (rounded down) + your Wisdom or Charisma modifier (your choice, minimum of one).

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":0,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":"Sentinel 2"},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Passive.webp","effects":[]} +{"_id":"6Sr3sIGSmzAIr5mW","name":"Battle Readiness","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Sentinel: 10th level

\n

You have fully learned how to meld your physical self with the Force. When you take the Dodge or Disengage actions, or use your action to cast a force power, you can make one melee weapon attack as a bonus action.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":0,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":""},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Passive.webp","effects":[]} +{"_id":"bfI8uiDYajYnDMXR","name":"Enlightened Evasion","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Sentinel: 15th level

\n

When you are subjected to an effect that forces you to make a saving throw, you can spend 2 force points to add your Wisdom or Charisma modifier (your choice, minimum of one) to the saving throw if doesn’t already include that modifier. If you do so, you instead take no damage if you succeed on the saving throw, and only half damage if you fail. You can wait until after you roll the d20 to use this feature, but you must decide before the GM says it succeeds or fails.

\n
\n

If the GM uses save roll automation they may wish to tweak the rules for this feature.

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"special","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":"self"},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"attribute","target":"","amount":2},"ability":"","actionType":"other","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[["max(@abilities.cha.mod,@abilities.wis.mod)","midi-none"]],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":"","recharge":{"value":null,"charged":false}},"flags":{"midi-qol":{"onUseMacroName":""}},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Passive.webp","effects":[]} +{"_id":"YQbpwkUPMTaSkhNq","name":"Center of the Force","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Sentinel: 20th level

\n

You are perfectly centered with the Force. Your Dexterity and Wisdom or Charisma scores (your choice) increase by 2. Your maximum for those scores increases by 2.

\n

Additionally, once per turn, when you would roll a Kinetic Combat die, you can instead choose the maximum.

\n
\n

By default Dex and Wis are boosted when this feature is on a sheet, edit the effects before placing it on a sheet if the character would choose Cha instead of Wis

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":"Sentinel 20"},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Passive.webp","effects":[{"_id":"SxmhOmW1389OiJoa","flags":{"dae":{"stackable":false,"transfer":true},"ActiveAuras":{"isAura":false,"ignoreSelf":false,"hidden":false,"height":false,"alignment":"","type":"","aura":"None","radius":null,"save":"","savedc":null,"hostile":false,"onlyOnce":false}},"changes":[{"key":"data.abilities.dex.value","value":2,"mode":2,"priority":20},{"key":"data.abilities.wis.value","value":2,"mode":2,"priority":20}],"disabled":false,"duration":{"startTime":null,"seconds":null,"rounds":null,"turns":null,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Passive.webp","label":"Center of the Force","tint":"","transfer":true}]} +{"name":"Adaptability Routine","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

At the start of each of your turns, you can choose an ability score with a saving throw in which you are not proficient. Until the start of your next turn, you add half your proficiency bonus, rounded down, to saving throws you make with the chosen ability. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":0,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":""},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[],"_id":"J6UpfNTBnEhlB6Wv"} +{"name":"Maven's Routine","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

At the start of each of your turns, you can choose to gain resistance to damage from tech powers until the start of your next turn. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":""},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[],"_id":"I5iPvBjc9laxZDt3"} +{"name":"Mesmer's Routine","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

At the start of each of your turns, you can choose to have advantage on saving throws against effects that would incapacitate you or put you to sleep until the start of your next turn. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":""},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[],"_id":"7loKWWYNYlKyD1Ob"} +{"name":"Nomad's Routine","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

At the start of each of your turns, you can choose to gain advantage on Constitution saving throws to avoid exhaustion from unenhanced sources, as well as being naturally adapted to both hot and cold climates. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":""},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[],"_id":"oEk2b1QqJcQ1IuFe"} +{"name":"Responder's Routine","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

When you roll initiative, you can choose to add your proficiency bonus to the initiative roll and have advantage on attack rolls against creatures that have not yet acted. Alternatively, you can choose to allow each creature within 5 feet of you, including you, to add half your proficiency bonus to the initiative roll and have advantage on the first attack roll they make against a creature that has not yet acted.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":""},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[],"_id":"GYtqJYgsY4nKIQdE"} +{"name":"Sharpshooter's Routine","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

At the start of each of your turns, you can choose to gain a bonus to the first weapon attack roll you make before the start of your next turn equal to your Intelligence modifier. Alternatively, you can choose to allow each creature within 5 feet of you, including you, to add half your Intelligence modifier to the first weapon attack roll they make before the start of your next turn.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":""},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[],"_id":"t9484zVzydcwhOwN"} +{"name":"Strider's Routine","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

At the start of each of your turns, you can choose to have each slowed level only reduce your speed by 5 feet, unless it would reduce your speed to 0 until the start of your next turn. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":""},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[],"_id":"ZBBQHebdqGb2LZ6g"} +{"name":"Warden's Routine","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

At the start of each of your turns, you can choose to gain a climbing and swimming speed equal to your walking speed. Alternatively, you can choose to extend this benefit to friendly creatures within 5 feet of you, except for you.

","chat":"","unidentified":""},"source":"PHB","activation":{"type":"","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":0,"max":0,"per":null},"consume":{"type":"","target":null,"amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":""},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SCT-Passive.webp","effects":[],"_id":"uH22SkE5h83Rjg2N"} +{"name":"Double Strike (Force-Empowered Strike)","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

When you hit a target with a melee weapon attack, you can spend 1 force point to roll a Kinetic Combat die and deal additional damage equal to the amount rolled.

\n
\n

After adding this to a player, the GM must go into the Details tab and set the damage formula to match the player's proper kinetic combat die, damage type to mirror their weapon's and also set the Resource Consumption to [attributes.force.points.value].

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"special","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":1,"width":null,"units":"","type":"enemy"},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"attribute","target":"","amount":1},"ability":"","actionType":"other","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[["1d4","energy"]],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{"midi-qol":{"onUseMacroName":""}},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Passive.webp","effects":[],"_id":"W2okaVdBI8rtdf8u"} +{"name":"Deflection(Force-Empowered Strike)","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

When you hit a target with a melee weapon attack, you can spend 1 force point to roll a Kinetic Combat die and add it to your AC against one attack before the start of your next turn.

\n
\n

After adding this to a player, the GM must go into the Details tab and set the damage formula to match the player's proper kinetic combat die, damage type must remain [No Damage] and also set the Resource Consumption to [attributes.force.points.value].

Duration automation requires both DAE and about-time or times-up.

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"special","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":"self"},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"attribute","target":"","amount":1},"ability":"","actionType":"other","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[["1d4","midi-none"]],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{"midi-qol":{"onUseMacroName":""}},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Passive.webp","effects":[{"_id":"nbfZeZnuzwwUIE4M","flags":{"dae":{"stackable":false,"specialDuration":["isAttacked"],"transfer":false},"ActiveAuras":{"isAura":false,"ignoreSelf":false,"hidden":false,"height":false,"alignment":"","type":"","aura":"None","radius":null,"save":"","savedc":null,"hostile":false,"onlyOnce":false}},"changes":[{"key":"data.attributes.ac.value","value":"@damage","mode":2,"priority":20}],"disabled":false,"duration":{"startTime":null,"seconds":null,"rounds":1,"turns":null,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Passive.webp","label":"Deflection(Force-Empowered Strike)","tint":"","transfer":false}],"_id":"PBEmu4pAlPyzDmez"} +{"name":"Slow Time (Force-Empowered Strike)","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

When you hit a target with a melee weapon attack, you can spend 1 force point to roll a Kinetic Combat die to increase your speed by 5 x the amount rolled until the end of your turn.

\n
\n

After adding this to a player, the GM must go into the Details tab and set the damage formula to match the player's proper kinetic combat die * 5, damage type must remain [No Damage] and also set the Resource Consumption to [attributes.force.points.value].

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"special","cost":null,"condition":""},"duration":{"value":1,"units":"turn"},"target":{"value":null,"width":null,"units":"","type":"self"},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"attribute","target":"","amount":1},"ability":"","actionType":"other","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[["1d4*5","midi-none"]],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{"midi-qol":{"onUseMacroName":""}},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Passive.webp","effects":[{"_id":"IWoqDcwboYrb0gD3","flags":{"dae":{"stackable":false,"transfer":false},"ActiveAuras":{"isAura":false,"ignoreSelf":false,"hidden":false,"height":false,"alignment":"","type":"","aura":"None","radius":null,"save":"","savedc":null,"hostile":false,"onlyOnce":false}},"changes":[{"key":"data.attributes.movement.walk","value":"@damage","mode":2,"priority":20}],"disabled":false,"duration":{"startTime":null,"seconds":null,"rounds":null,"turns":1,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Passive.webp","label":"Slow Time (Force-Empowered Strike)","tint":"","transfer":false}],"_id":"52EHtBvyeuBNJuLO"} +{"name":"Ideal of the Agile","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

You gain a swimming speed and a climbing speed equal to your walking speed. When you make a long jump, you can cover a number of feet up to twice your Wisdom or Charisma score (your choice). When you make a high jump, you can leap a number of feet up into the air equal to 3 + twice your Wisdom or Charisma modifier (your choice).

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, opportunity attacks against you are made with disadvantage.

\n
\n

In the Details tab, set Resource Consumption to [Item Uses] [Sentinel Ideals] [1].

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"bonus","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":"self"},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"charges","target":"","amount":1},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","effects":[{"_id":"YI8XCFNh7Xm45hG4","flags":{"dae":{"stackable":false,"transfer":true},"ActiveAuras":{"isAura":false,"ignoreSelf":false,"hidden":false,"height":false,"alignment":"","type":"","aura":"None","radius":null,"save":"","savedc":null,"hostile":false,"onlyOnce":false}},"changes":[{"key":"data.attributes.movement.swim","value":"@attributes.movement.walk","mode":2,"priority":20},{"key":"data.attributes.movement.climb","value":"@attributes.movement.walk","mode":2,"priority":20}],"disabled":false,"duration":{"startTime":null,"seconds":null,"rounds":null,"turns":null,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","label":"Ideal of the Agile","tint":"","transfer":true},{"_id":"LxnPDMWKkCdrIDHz","flags":{"dae":{"stackable":false,"transfer":false},"ActiveAuras":{"isAura":false,"ignoreSelf":false,"hidden":false,"height":false,"alignment":"","type":"","aura":"None","radius":null,"save":"","savedc":null,"hostile":false,"onlyOnce":false}},"changes":[],"disabled":false,"duration":{"startTime":null,"seconds":60,"rounds":10,"turns":null,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","label":"Ideal of the Agile Manefestation","tint":"","transfer":false}],"_id":"M4RvEHMiSwglzPNv"} +{"name":"Ideal of the Artisan","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

Choose one of your skill or tool proficiencies. When you make an ability check with the chosen skill or tool, you can add half your Wisdom or Charisma modifier (your choice, minimum of one) to any check you make that doesn’t already include that modifier.

\n

Additionally, as an action, you can manifest this ideal in a brief surge of energy. For the next 10 minutes, the bonus increases to your Wisdom or Charisma modifier, and you can choose a second skill or tool to extend this feature to.

\n

 

\n
\n

Edit the effects to change the skill(s) this feature applies to. The bonus will not show on the character sheet but will show when the chosen skill(s) are rolled.
In the Details tab, set Resource Consumption to [Item Uses] [Sentinel Ideals] [1].

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"action","cost":null,"condition":""},"duration":{"value":10,"units":"minute"},"target":{"value":null,"width":null,"units":"","type":"self"},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"charges","target":"","amount":1},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Action.webp","effects":[{"_id":"1x38iIN0ZkZTgpTD","flags":{"dae":{"stackable":false,"transfer":false},"ActiveAuras":{"isAura":false,"ignoreSelf":false,"hidden":false,"height":false,"alignment":"","type":"","aura":"None","radius":null,"save":"","savedc":null,"hostile":false,"onlyOnce":false}},"changes":[{"key":"data.skills.acr.mod","value":"(ceil(max(@abilities.cha.mod,@abilities.wis.mod)/2))","mode":2,"priority":20},{"key":"data.skills.ani.mod","value":"(ceil(max(@abilities.cha.mod,@abilities.wis.mod)/2))","mode":2,"priority":20}],"disabled":false,"duration":{"startTime":null,"seconds":600,"rounds":100,"turns":null,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","label":"Ideal of the Artisan Manifestation","tint":"","transfer":false},{"_id":"EWbuKV1vVRnWFLJR","flags":{"dae":{"stackable":false,"transfer":true},"ActiveAuras":{"isAura":false,"ignoreSelf":false,"hidden":false,"height":false,"alignment":"","type":"","aura":"None","radius":null,"save":"","savedc":null,"hostile":false,"onlyOnce":false}},"changes":[{"key":"data.skills.acr.mod","value":"(floor(max(@abilities.cha.mod,@abilities.wis.mod)/2))","mode":2,"priority":20}],"disabled":false,"duration":{"startTime":null,"seconds":null,"rounds":null,"turns":null,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","label":"Ideal of the Artisan","tint":"","transfer":true}],"_id":"nuFQtxutzyHQkMCp"} +{"name":"Ideal of the Contender","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

You can use Dexterity instead of Strength for the attack and damage rolls of your unarmed strikes, and your unarmed strike damage increases by one step (from 1 to d4, d4 to d6, or d6 to d8).

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, your unarmed strikes count as enhanced for the purpose of overcoming resistance and immunity to unenhanced attacks and damage, and you can use your Wisdom or Charisma modifier (your choice) instead of Strength for checks made to grapple a target or escape a grapple.

\n
\n
\n

In the Details tab, set Resource Consumption to [Item Uses] [Sentinel Ideals] [1].

\n
\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"bonus","cost":null,"condition":""},"duration":{"value":1,"units":"minute"},"target":{"value":null,"width":null,"units":"","type":"self"},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"charges","target":"","amount":1},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","effects":[{"_id":"2w7HxesGujLvxWc0","flags":{"dae":{"stackable":false,"transfer":false},"ActiveAuras":{"isAura":false,"ignoreSelf":false,"hidden":false,"height":false,"alignment":"","type":"","aura":"None","radius":null,"save":"","savedc":null,"hostile":false,"onlyOnce":false}},"changes":[],"disabled":false,"duration":{"startTime":null,"seconds":60,"rounds":10,"turns":null,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","label":"Ideal of the Contender Manifestation","tint":"","transfer":false}],"_id":"4oEqg1bENiIvxlpW"} +{"name":"Ideal of the Fighter","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

You adopt a particular style of fighting as your specialty. Choose one of the fighting style options, detailed in Chapter 6.

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, you know the fighting mastery that corresponds with the fighting style you chose with this feature. If you already know that fighting mastery, you instead learn another of your choice for the duration.

\n
\n

In the Details tab, set Resource Consumption to [Item Uses] [Sentinel Ideals] [1].

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"bonus","cost":null,"condition":""},"duration":{"value":1,"units":"minute"},"target":{"value":null,"width":null,"units":"","type":"self"},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"charges","target":"","amount":1},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","effects":[{"_id":"XHCrVmEzofUrSp92","flags":{"dae":{"stackable":false,"transfer":false},"ActiveAuras":{"isAura":false,"ignoreSelf":false,"hidden":false,"height":false,"alignment":"","type":"","aura":"None","radius":null,"save":"","savedc":null,"hostile":false,"onlyOnce":false}},"changes":[],"disabled":false,"duration":{"startTime":null,"seconds":60,"rounds":10,"turns":null,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","label":"Ideal of the Fighter Manifestation","tint":"","transfer":false}],"_id":"YILPj7H9L99CQe66"} +{"name":"Ideal of the Hunter","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

You gain darkvision out to a range of 60 feet. If you already have darkvision, this ideal increases its range by 30 feet.

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, you can see normally in enhanced darkness, and you gain blindsight to 10 feet.

\n
\n

In the Details tab, set Resource Consumption to [Item Uses] [Sentinel Ideals] [1].

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"bonus","cost":null,"condition":""},"duration":{"value":1,"units":"minute"},"target":{"value":null,"width":null,"units":"","type":"self"},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"charges","target":"","amount":1},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","effects":[{"_id":"bf00ymcpwtJ3ZAn8","flags":{"dae":{"stackable":false,"transfer":true},"ActiveAuras":{"isAura":false,"ignoreSelf":false,"hidden":false,"height":false,"alignment":"","type":"","aura":"None","radius":null,"save":"","savedc":null,"hostile":false,"onlyOnce":false}},"changes":[{"key":"data.attributes.senses.darkvision","value":"(@attributes.senses.darkvision === 0 ? 60 : 30)","mode":2,"priority":20}],"disabled":false,"duration":{"startTime":null,"seconds":null,"rounds":null,"turns":null,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","label":"Ideal of the Hunter","tint":"","transfer":true},{"_id":"jr1d82Aoyr2xkFqW","flags":{"dae":{"stackable":false,"transfer":false},"ActiveAuras":{"isAura":false,"ignoreSelf":false,"hidden":false,"height":false,"alignment":"","type":"","aura":"None","radius":null,"save":"","savedc":null,"hostile":false,"onlyOnce":false}},"changes":[{"key":"data.attributes.senses.blindsight","value":10,"mode":4,"priority":20}],"disabled":false,"duration":{"startTime":null,"seconds":60,"rounds":10,"turns":null,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","label":"Ideal of the Hunter Manifestation","tint":"","transfer":false}],"_id":"10x48RWCWobSNXkh"} +{"_id":"xFgXRg2qF3SlvNfF","name":"Sentinel Ideals","permission":{"default":0,"lwoKvFakziGOHjXS":3},"type":"classfeature","data":{"description":{"value":"

Sentinel: 2nd, 6th, 9th, 11th, and 17th level

\n

You adopt ideals that exemplify your bond with the Force. You adopt two ideals of your choice, as detailed at the end of the class description. You adopt an additional ideal at 6th and 11th level.

\n

You can manifest your ideals a combined total of twice. You gain an additional use at 9th and 17th level. You regain all expended uses when you finish a long rest.

\n
\n

SENTINEL IDEALS

\n

The ideals are presented in alphabetical order. You can’t benefit from a Sentinel Ideal option more than once, even if you later get to choose again.

\n
\n
\n

IDEAL OF THE AGILE

\n

You gain a swimming speed and a climbing speed equal to your walking speed. When you make a long jump, you can cover a number of feet up to twice your Wisdom or Charisma score (your choice). When you make a high jump, you can leap a number of feet up into the air equal to 3 + twice your Wisdom or Charisma modifier (your choice).

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, opportunity attacks against you are made with disadvantage.

\n
\n

IDEAL OF THE ARTISAN

\n

Choose one of your skill or tool proficiencies. When you make an ability check with the chosen skill or tool, you can add half your Wisdom or Charisma modifier (your choice, minimum of one) to any check you make that doesn’t already include that modifier.

\n

Additionally, as an action, you can manifest this ideal in a brief surge of energy. For the next 10 minutes, the bonus increases to your Wisdom or Charisma modifier, and you can choose a second skill or tool to extend this feature to.

\n
\n

IDEAL OF THE CONTENDER

\n

You can use Dexterity instead of Strength for the attack and damage rolls of your unarmed strikes, and your unarmed strike damage increases by one step (from 1 to d4, d4 to d6, or d6 to d8).

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, your unarmed strikes count as enhanced for the purpose of overcoming resistance and immunity to unenhanced attacks and damage, and you can use your Wisdom or Charisma modifier (your choice) instead of Strength for checks made to grapple a target or escape a grapple.

\n
\n

IDEAL OF THE FIGHTER

\n

You adopt a particular style of fighting as your specialty. Choose one of the fighting style options, detailed in Chapter 6. You can’t take a fighting style option more than once, even if you later get to choose again.

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, you know the fighting mastery that corresponds with the fighting style you chose with this feature. If you already know that fighting mastery, you instead learn another of your choice for the duration.

\n
\n

IDEAL OF THE HUNTER

\n

You gain darkvision out to a range of 60 feet. If you already have darkvision, this ideal increases its range by 30 feet.

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, you can see normally in enhanced darkness, and you gain blindsight to 10 feet.

\n
\n

IDEAL OF THE STEADFAST

\n

When you would make a melee weapon attack roll, you can instead force the target to make a Dexterity saving throw (DC = 8 + your bonus to attacks with the weapon). If you would have advantage on your attack roll, the creature instead has disadvantage on their saving throw, and if you would have disadvantage on your attack roll, the creature instead has advantage on their saving throw. On a failed save, the target takes normal weapon damage and is subjected to any additional effects that would occur on a hit.

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, when a creature succeeds on the saving throw, they take half the normal weapon damage, and when a creature rolls a 1 on the saving throw, they treat the damage as if you had rolled the maximum.

\n
\n

IDEAL OF THE TITAN

\n

You gain proficiency in medium armor.

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, you have advantage on ability checks and attack rolls that would forcefully move another creature, and the distance they would be moved increases by 5 feet.

\n
\n

IDEAL OF THE TRANQUIL

\n

When you finish a short or long rest, you gain a number of temporary force points equal to half your Wisdom or Charisma modifier (rounded up, your choice, minimum of one). When you would spend a force point while you have temporary force points, the temporary force points are spent first. All temporary force points are lost at the end of your next short or long rest.

\n

Additionally, as an action, you can manifest this ideal in a brief surge of energy. You regain a number of force points equal to half your Wisdom or Charisma modifier (rounded up, your choice, minimum of one).

\n
\n

IDEAL OF THE VIGOROUS

\n

When you roll a Hit Die to regain hit points, you may use your Wisdom or Charisma modifier in place of your Constitution modifier when determining the number of hit points you regain.

\n

Additionally, as an action, you can manifest this ideal in a brief surge of energy. You gain a number of temporary hit points equal to half your sentinel level (rounded down) + your Wisdom or Charisma modifier (your choice, minimum of one).

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"none","cost":null,"condition":""},"duration":{"value":null,"units":""},"target":{"value":null,"width":null,"units":"","type":""},"range":{"value":null,"long":null,"units":""},"uses":{"value":2,"max":"2","per":"lr"},"consume":{"type":"","target":"","amount":null},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","requirements":"","recharge":{"value":null,"charged":false}},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Passive.webp","effects":[]} +{"name":"Ideal of the Steadfast","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

When you would make a melee weapon attack roll, you can instead force the target to make a Dexterity saving throw (DC = 8 + your bonus to attacks with the weapon). If you would have advantage on your attack roll, the creature instead has disadvantage on their saving throw, and if you would have disadvantage on your attack roll, the creature instead has advantage on their saving throw. On a failed save, the target takes normal weapon damage and is subjected to any additional effects that would occur on a hit.

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, when a creature succeeds on the saving throw, they take half the normal weapon damage, and when a creature rolls a 1 on the saving throw, they treat the damage as if you had rolled the maximum.

\n
\n

In the Details tab, set Resource Consumption to [Item Uses] [Sentinel Ideals] [1].

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"bonus","cost":null,"condition":""},"duration":{"value":1,"units":"minute"},"target":{"value":null,"width":null,"units":"","type":"self"},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"charges","target":"","amount":1},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","effects":[{"_id":"Sm735wmrsKZ7HQPB","flags":{"dae":{"stackable":false,"transfer":false},"ActiveAuras":{"isAura":false,"ignoreSelf":false,"hidden":false,"height":false,"alignment":"","type":"","aura":"None","radius":null,"save":"","savedc":null,"hostile":false,"onlyOnce":false}},"changes":[],"disabled":false,"duration":{"startTime":null,"seconds":60,"rounds":10,"turns":null,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","label":"Ideal of the Steadfast Manifestation","tint":"","transfer":false}],"_id":"tFeYRpK4UKKtYJjK"} +{"name":"Ideal of the Titan","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

You gain proficiency in medium armor.

\n

Additionally, as a bonus action, you can manifest this ideal in a brief surge of energy. For the next minute, you have advantage on ability checks and attack rolls that would forcefully move another creature, and the distance they would be moved increases by 5 feet.

\n
\n

In the Details tab, set Resource Consumption to [Item Uses] [Sentinel Ideals] [1].

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"bonus","cost":null,"condition":""},"duration":{"value":1,"units":"minute"},"target":{"value":null,"width":null,"units":"","type":"self"},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"charges","target":"","amount":1},"ability":null,"actionType":"","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","effects":[{"_id":"dR4ipB2mMlCk1jHy","flags":{"dae":{"stackable":false,"transfer":true},"ActiveAuras":{"isAura":false,"ignoreSelf":false,"hidden":false,"height":false,"alignment":"","type":"","aura":"None","radius":null,"save":"","savedc":null,"hostile":false,"onlyOnce":false}},"changes":[{"key":"data.traits.armorProf.value","value":"med","mode":2,"priority":20}],"disabled":false,"duration":{"startTime":null,"seconds":null,"rounds":null,"turns":null,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","label":"Ideal of the Titan","tint":"","transfer":true},{"_id":"mvSs3VXA4rSkpT8b","flags":{"dae":{"stackable":false,"transfer":false},"ActiveAuras":{"isAura":false,"ignoreSelf":false,"hidden":false,"height":false,"alignment":"","type":"","aura":"None","radius":null,"save":"","savedc":null,"hostile":false,"onlyOnce":false}},"changes":[],"disabled":false,"duration":{"startTime":null,"seconds":60,"rounds":10,"turns":null,"startRound":null,"startTurn":null},"icon":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Bonus.webp","label":"Ideal of the Titan Manifestation","tint":"","transfer":false}],"_id":"QL4kNoKCHClr5jFP"} +{"name":"Ideal of the Tranquil","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

When you finish a short or long rest, you gain a number of temporary force points equal to half your Wisdom or Charisma modifier (rounded up, your choice, minimum of one). When you would spend a force point while you have temporary force points, the temporary force points are spent first. All temporary force points are lost at the end of your next short or long rest.

\n

Additionally, as an action, you can manifest this ideal in a brief surge of energy. You regain a number of force points equal to half your Wisdom or Charisma modifier (rounded up, your choice, minimum of one).

\n
\n

In the Details tab, set Resource Consumption to [Item Uses] [Sentinel Ideals] [1].

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"action","cost":null,"condition":""},"duration":{"value":null,"units":"inst"},"target":{"value":null,"width":null,"units":"","type":"self"},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"charges","target":"","amount":1},"ability":"","actionType":"heal","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[["(ceil(max(@abilities.cha.mod,@abilities.wis.mod)/2))","midi-none"]],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{"midi-qol":{"onUseMacroName":""}},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Action.webp","effects":[],"_id":"lc6R3mdiQR6D5lTt"} +{"name":"Ideal of the Vigorous","permission":{"default":0,"sJbOwuXHycdB3CY1":3},"type":"classfeature","data":{"description":{"value":"

When you roll a Hit Die to regain hit points, you may use your Wisdom or Charisma modifier in place of your Constitution modifier when determining the number of hit points you regain.

\n

Additionally, as an action, you can manifest this ideal in a brief surge of energy. You gain a number of temporary hit points equal to half your sentinel level (rounded down) + your Wisdom or Charisma modifier (your choice, minimum of one).

\n
\n

In the Details tab, set Resource Consumption to [Item Uses] [Sentinel Ideals] [1].

\n
","chat":"","unidentified":""},"source":"PHB","activation":{"type":"action","cost":null,"condition":""},"duration":{"value":null,"units":"inst"},"target":{"value":null,"width":null,"units":"","type":"self"},"range":{"value":null,"long":null,"units":""},"uses":{"value":null,"max":"","per":""},"consume":{"type":"charges","target":"","amount":1},"ability":"","actionType":"heal","attackBonus":0,"chatFlavor":"","critical":null,"damage":{"parts":[["(@classes.sentinel.levels/2) + (max(@abilities.cha.mod,@abilities.wis.mod))","temphp"]],"versatile":""},"formula":"","save":{"ability":"","dc":null,"scaling":"power"},"className":"","recharge":{"value":null,"charged":false}},"flags":{"midi-qol":{"onUseMacroName":""}},"img":"systems/sw5e/packs/Icons/Class%20Features/SNTL-Action.webp","effects":[],"_id":"iw9lOFbokDE7ktSn"} From eaac412cb39d25b23448b3b86a84b04075a4d0a7 Mon Sep 17 00:00:00 2001 From: TJ Date: Tue, 13 Apr 2021 21:39:53 -0500 Subject: [PATCH 16/18] Merge clean up --- module/characterImporter.js | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/module/characterImporter.js b/module/characterImporter.js index 3b5633a8..65fa7f6a 100644 --- a/module/characterImporter.js +++ b/module/characterImporter.js @@ -44,27 +44,6 @@ export default class CharacterImporter { } }; - const skills = { - acr: { value: sourceCharacter.attribs.find((e) => e.name == "acrobatics_type").current }, - ani: { value: sourceCharacter.attribs.find((e) => e.name == "animal_handling_type").current }, - ath: { value: sourceCharacter.attribs.find((e) => e.name == "athletics_type").current }, - dec: { value: sourceCharacter.attribs.find((e) => e.name == "deception_type").current }, - ins: { value: sourceCharacter.attribs.find((e) => e.name == "insight_type").current }, - inv: { value: sourceCharacter.attribs.find((e) => e.name == "investigation_type").current }, - itm: { value: sourceCharacter.attribs.find((e) => e.name == "intimidation_type").current }, - lor: { value: sourceCharacter.attribs.find((e) => e.name == "lore_type").current }, - med: { value: sourceCharacter.attribs.find((e) => e.name == "medicine_type").current }, - nat: { value: sourceCharacter.attribs.find((e) => e.name == "nature_type").current }, - per: { value: sourceCharacter.attribs.find((e) => e.name == "persuasion_type").current }, - pil: { value: sourceCharacter.attribs.find((e) => e.name == "piloting_type").current }, - prc: { value: sourceCharacter.attribs.find((e) => e.name == "perception_type").current }, - prf: { value: sourceCharacter.attribs.find((e) => e.name == "performance_type").current }, - slt: { value: sourceCharacter.attribs.find((e) => e.name == "sleight_of_hand_type").current }, - ste: { value: sourceCharacter.attribs.find((e) => e.name == "stealth_type").current }, - sur: { value: sourceCharacter.attribs.find((e) => e.name == "survival_type").current }, - tec: { value: sourceCharacter.attribs.find((e) => e.name == "technology_type").current } - }; - /* ----------------------------------------------------------------- */ /* character.data.skills..value is all that matters /* values can be 0, 0.5, 1 or 2 @@ -140,8 +119,7 @@ export default class CharacterImporter { skills: skills, attributes: { hp: hp - }, - skills: skills + } } }; From fa7b03109fa9ad23c89d00e166df27f1c86471de Mon Sep 17 00:00:00 2001 From: supervj <64861570+supervj@users.noreply.github.com> Date: Tue, 13 Apr 2021 23:01:03 -0400 Subject: [PATCH 17/18] Add Skills to Starships Added skills to the starship sheets and made them rollable. Sorry about the direct commit to Develop, but I forgot to branch it off... --- module/actor/entity.js | 2 +- module/actor/sheets/newSheet/base.js | 14 +- module/actor/sheets/newSheet/starship.js | 4 +- module/actor/sheets/oldSheets/base.js | 1 + sw5e.js | 4 +- template.json | 158 +++++++++++------------ templates/actors/newActor/starship.html | 2 +- 7 files changed, 95 insertions(+), 90 deletions(-) diff --git a/module/actor/entity.js b/module/actor/entity.js index f23d2240..441dc87d 100644 --- a/module/actor/entity.js +++ b/module/actor/entity.js @@ -860,7 +860,7 @@ export default class Actor5e extends Actor { const rollData = mergeObject(options, { parts: parts, data: data, - title: game.i18n.format("SW5E.SkillPromptTitle", {skill: CONFIG.SW5E.skills[skillId]}), + title: game.i18n.format("SW5E.SkillPromptTitle", {skill: CONFIG.SW5E.skills[skillId] || CONFIG.SW5E.starshipSkills[skillId]}), halflingLucky: this.getFlag("sw5e", "halflingLucky"), reliableTalent: reliableTalent, messageData: {"flags.sw5e.roll": {type: "skill", skillId }} diff --git a/module/actor/sheets/newSheet/base.js b/module/actor/sheets/newSheet/base.js index fc74cc8d..2575dad9 100644 --- a/module/actor/sheets/newSheet/base.js +++ b/module/actor/sheets/newSheet/base.js @@ -67,7 +67,7 @@ export default class ActorSheet5e extends ActorSheet { cssClass: isOwner ? "editable" : "locked", isCharacter: this.entity.data.type === "character", isNPC: this.entity.data.type === "npc", - isStarship: this.entity.data.type === "starship", + isStarship: this.entity.data.type === "starship", isVehicle: this.entity.data.type === 'vehicle', config: CONFIG.SW5E, }; @@ -96,7 +96,11 @@ export default class ActorSheet5e extends ActorSheet { skl.ability = CONFIG.SW5E.abilityAbbreviations[skl.ability]; skl.icon = this._getProficiencyIcon(skl.value); skl.hover = CONFIG.SW5E.proficiencyLevels[skl.value]; - skl.label = CONFIG.SW5E.skills[s]; + if (data.actor.type === "starship") { + skl.label = CONFIG.SW5E.starshipSkills[s]; + }else{ + skl.label = CONFIG.SW5E.skills[s]; + } } } @@ -409,11 +413,11 @@ export default class ActorSheet5e extends ActorSheet { html.find('.item-create').click(this._onItemCreate.bind(this)); html.find('.item-edit').click(this._onItemEdit.bind(this)); html.find('.item-delete').click(this._onItemDelete.bind(this)); - html.find('.item-collapse').click(this._onItemCollapse.bind(this)); + html.find('.item-collapse').click(this._onItemCollapse.bind(this)); html.find('.item-uses input').click(ev => ev.target.select()).change(this._onUsesChange.bind(this)); html.find('.slot-max-override').click(this._onPowerSlotOverride.bind(this)); - html.find('.increment-class-level').click(this._onIncrementClassLevel.bind(this)); - html.find('.decrement-class-level').click(this._onDecrementClassLevel.bind(this)); + html.find('.increment-class-level').click(this._onIncrementClassLevel.bind(this)); + html.find('.decrement-class-level').click(this._onDecrementClassLevel.bind(this)); // Active Effect management html.find(".effect-control").click(ev => onManageActiveEffect(ev, this.entity)); diff --git a/module/actor/sheets/newSheet/starship.js b/module/actor/sheets/newSheet/starship.js index d137ab27..d0a65076 100644 --- a/module/actor/sheets/newSheet/starship.js +++ b/module/actor/sheets/newSheet/starship.js @@ -38,8 +38,8 @@ export default class ActorSheet5eStarship extends ActorSheet5e { weapons: { label: game.i18n.localize("SW5E.ItemTypeWeaponPl"), items: [], hasActions: true, dataset: {type: "weapon", "weapon-type": "natural"} }, passive: { label: game.i18n.localize("SW5E.Features"), items: [], dataset: {type: "feat"} }, equipment: { label: game.i18n.localize("SW5E.StarshipEquipment"), items: [], dataset: {type: "equipment"}}, - starshipfeatures: { label: game.i18n.localize("SW5E.StarshipfeaturePl"), items: [], hasActions: true, dataset: {type: "starshipfeature"} }, - starshipmods: { label: game.i18n.localize("SW5E.StarshipmodPl"), items: [], hasActions: false, dataset: {type: "starshipmod"} } + starshipfeatures: { label: game.i18n.localize("SW5E.StarshipfeaturePl"), items: [], hasActions: true, dataset: {type: "starshipfeature"} }, + starshipmods: { label: game.i18n.localize("SW5E.StarshipmodPl"), items: [], hasActions: false, dataset: {type: "starshipmod"} } }; // Start by classifying items into groups for rendering diff --git a/module/actor/sheets/oldSheets/base.js b/module/actor/sheets/oldSheets/base.js index c97dd95a..aaabc84e 100644 --- a/module/actor/sheets/oldSheets/base.js +++ b/module/actor/sheets/oldSheets/base.js @@ -65,6 +65,7 @@ export default class ActorSheet5e extends ActorSheet { cssClass: isOwner ? "editable" : "locked", isCharacter: this.entity.data.type === "character", isNPC: this.entity.data.type === "npc", + isStarship: this.entity.data.type === "starship", isVehicle: this.entity.data.type === 'vehicle', config: CONFIG.SW5E, }; diff --git a/sw5e.js b/sw5e.js index 3d54b6e9..74ee37bc 100644 --- a/sw5e.js +++ b/sw5e.js @@ -161,8 +161,8 @@ Hooks.once("setup", function() { "armorProficiencies", "armorPropertiesTypes", "conditionTypes", "consumableTypes", "cover", "currencies", "damageResistanceTypes", "damageTypes", "distanceUnits", "equipmentTypes", "healingTypes", "itemActionTypes", "languages", "limitedUsePeriods", "movementTypes", "movementUnits", "polymorphSettings", "proficiencyLevels", "senses", "skills", - "powerComponents", "powerLevels", "powerPreparationModes", "powerScalingModes", "powerSchools", "targetTypes", - "timePeriods", "toolProficiencies", "weaponProficiencies", "weaponProperties", "weaponTypes" + "starshipSkills", "powerComponents", "powerLevels", "powerPreparationModes", "powerScalingModes", "powerSchools", "targetTypes", + "timePeriods", "toolProficiencies", "weaponProficiencies", "weaponProperties", "weaponTypes", "weaponSizes" ]; // Exclude some from sorting where the default order matters diff --git a/template.json b/template.json index 49679290..995ee36d 100644 --- a/template.json +++ b/template.json @@ -404,86 +404,86 @@ } }, "starship": { - "templates": ["common"], - "attributes": { - "hp": { - "value": 10, - "max": 10, - "formula": "", - "temp": 0, - "tempmax": 0 - }, - "sp": { - "formula": "" - } - }, - "details": { - "tier": 0, - "role": "", - "source": "" - }, - "skills": { - "ast": { - "value": 0, - "ability": "int" - }, - "bst": { - "value": 0, - "ability": "str" - }, - "dat": { - "value": 0, - "ability": "int" + "templates": ["common"], + "attributes": { + "hp": { + "value": 10, + "max": 10, + "formula": "", + "temp": 0, + "tempmax": 0 + }, + "sp": { + "formula": "" + } }, - "hid": { - "value": 0, - "ability": "dex" - }, - "imp": { - "value": 0, - "ability": "cha" - }, - "int": { - "value": 0, - "ability": "cha" - }, - "man": { - "value": 0, - "ability": "dex" - }, - "men": { - "value": 0, - "ability": "cha" - }, - "pat": { - "value": 0, - "ability": "con" - }, - "prb": { - "value": 0, - "ability": "int" - }, - "ram": { - "value": 0, - "ability": "str" - }, - "reg": { - "value": 0, - "ability": "con" - }, - "scn": { - "value": 0, - "ability": "wis" - }, - "swn": { - "value": 0, - "ability": "cha" - } - }, - "traits": { - "size": "med" - } - }, + "details": { + "tier": 0, + "role": "", + "source": "" + }, + "skills": { + "ast": { + "value": 0, + "ability": "int" + }, + "bst": { + "value": 0, + "ability": "str" + }, + "dat": { + "value": 0, + "ability": "int" + }, + "hid": { + "value": 0, + "ability": "dex" + }, + "imp": { + "value": 0, + "ability": "cha" + }, + "int": { + "value": 0, + "ability": "cha" + }, + "man": { + "value": 0, + "ability": "dex" + }, + "men": { + "value": 0, + "ability": "cha" + }, + "pat": { + "value": 0, + "ability": "con" + }, + "prb": { + "value": 0, + "ability": "int" + }, + "ram": { + "value": 0, + "ability": "str" + }, + "reg": { + "value": 0, + "ability": "con" + }, + "scn": { + "value": 0, + "ability": "wis" + }, + "swn": { + "value": 0, + "ability": "cha" + } + }, + "traits": { + "size": "med" + } + }, "vehicle": { "templates": ["common"], "abilities": { diff --git a/templates/actors/newActor/starship.html b/templates/actors/newActor/starship.html index 7a8fcd01..2caf38a0 100644 --- a/templates/actors/newActor/starship.html +++ b/templates/actors/newActor/starship.html @@ -123,7 +123,7 @@

{{localize "SW5E.Skills"}}

    - {{#each CONFIG.starshipSkills as |skill s|}} + {{#each data.skills as |skill s|}}
  1. From 9de6a8f5c0df84efc1be871d9b6f25088c8fcf01 Mon Sep 17 00:00:00 2001 From: supervj <64861570+supervj@users.noreply.github.com> Date: Fri, 16 Apr 2021 02:05:53 -0400 Subject: [PATCH 18/18] Keep fields from being wiped out updated the template.json to have the fields that were being wiped out. If they don't exist they will be removed when moving to/from a compendium and when duplicating the item. --- lang/en.json | 1 + template.json | 90 ++++++++++++++++++++++++++++------ templates/items/archetype.html | 2 +- 3 files changed, 76 insertions(+), 17 deletions(-) diff --git a/lang/en.json b/lang/en.json index b195c39e..5ff5e1fc 100644 --- a/lang/en.json +++ b/lang/en.json @@ -197,6 +197,7 @@ "SW5E.ChatContextHalfDamage": "Apply Half Damage", "SW5E.ChatContextHealing": "Apply Healing", "SW5E.ChatFlavor": "Chat Message Flavor", + "SW5E.ClassCasterType": "Class Caster Type", "SW5E.ClassLevels": "Class Levels", "SW5E.ClassName": "Class Name", "SW5E.ClassSkillsChosen": "Chosen Class Skills", diff --git a/template.json b/template.json index 995ee36d..156757c6 100644 --- a/template.json +++ b/template.json @@ -544,7 +544,6 @@ "types": ["archetype", "background", "backpack", "class", "classfeature", "consumable", "deployment", "deploymentfeature", "equipment", "feat", "fightingmastery", "fightingstyle", "lightsaberform", "loot", "power", "species", "starshipfeature", "starshipmod", "tool", "venture", "weapon"], "templates": { "archetypeDescription": { - "className": "", "description": "", "source": "" }, @@ -607,12 +606,12 @@ "chat": "", "unidentified": "" }, + "requirements": "", "source": "" }, "classDescription": { - "className": "", - "description": { - "value": "" + "description": { + "value": "" } }, "fightingmasteryDescription": { @@ -646,16 +645,17 @@ "chat": "", "unidentified": "" }, + "source": "", "traits": "" }, - "ventureDescription": { + "ventureDescription": { "description": { "value": "" }, - "prerequisites": [""], - "source": { - "value": "" - } + "prerequisites": [""], + "source": { + "value": "" + } }, "physicalItem": { "quantity": 1, @@ -726,13 +726,39 @@ "dt": null, "conditions": "" } + }, + "starshipEquipment": { + "capx": { + "value":null + }, + "hpperhd": { + "value":null + }, + "regrateco": { + "value":null + }, + "cscap": { + "value":null + }, + "sscap": { + "value":null + }, + "fuelcostsmod": { + "value":null + }, + "powerdicerec": { + "value":null + }, + "hdclass": { + "value":null + } } }, "htmlFields": ["description.value", "description.chat", "description.unidentified"], "archetype": { "templates": ["archetypeDescription"], "className": "", - "description": "" + "classCasterType": "" }, "background": { "templates": ["backgroundDescription"] @@ -760,11 +786,27 @@ "choices": [], "value": [] }, + "source": "", "powercasting": "none" }, "classfeature": { "templates": ["itemDescription", "activatedEffect", "action"], - "className": "" + "recharge": { + "charged": false, + "value": null + } + }, + "deployment": { + "templates": ["classDescription"], + "flavorText": "", + "source": "" + }, + "deploymentfeature": { + "templates": ["itemDescription", "activatedEffect", "action"], + "recharge": { + "charged": false, + "value": null + } }, "fightingmastery": { "templates": ["fightingmasteryDescription"] @@ -786,7 +828,7 @@ } }, "equipment": { - "templates": ["itemDescription", "physicalItem", "activatedEffect", "action", "mountable"], + "templates": ["itemDescription", "physicalItem", "activatedEffect", "action", "mountable", "starshipEquipment"], "armor": { "type": "light", "value": 10, @@ -850,11 +892,27 @@ "starshipfeature": { "templates": ["itemDescription", "activatedEffect", "action"], "size": "med", - "tier": 0 + "tier": 0 + }, + "starshipmod": { + "templates": ["itemDescription", "activatedEffect", "action"], + "recharge": { + "charged": false, + "value": null + }, + "system": { + "value": "" + }, + "grade": { + "value": "" + }, + "basecost": { + "value": "" + }, + "prerequisites": { + "value": "" + } }, - "starshipmod": { - "templates": ["itemDescription"] - }, "weapon": { "templates": ["itemDescription", "physicalItem" ,"activatedEffect", "action", "mountable"], "weaponType": "simpleVW", diff --git a/templates/items/archetype.html b/templates/items/archetype.html index d194a2c7..1da586bd 100644 --- a/templates/items/archetype.html +++ b/templates/items/archetype.html @@ -19,7 +19,7 @@
  2. - +