forked from GitHub-Mirrors/foundry-sw5e
Merge pull request #109 from unrealkakeman89/professorbunbury-sw5e
Updates to CSS/LESS and New Character Sheet
This commit is contained in:
commit
a66fc9e5ac
13 changed files with 516 additions and 393 deletions
BIN
fonts/EngliBesh-KG3W.ttf
Normal file
BIN
fonts/EngliBesh-KG3W.ttf
Normal file
Binary file not shown.
|
@ -486,4 +486,41 @@
|
|||
height: 24px;
|
||||
margin: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------- */
|
||||
/* HUD
|
||||
/* ----------------------------------------- */
|
||||
|
||||
.placeable-hud .control-icon {
|
||||
box-sizing: content-box;
|
||||
width: 40px;
|
||||
flex: 0 0 40px;
|
||||
margin: 8px 0;
|
||||
font-size: 28px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
color: #FBF4F4;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
box-shadow: 0 0 15px #000;
|
||||
border: 1px solid #333;
|
||||
border-radius: 8px;
|
||||
pointer-events: all;
|
||||
}
|
||||
#token-hud .status-effects {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
left: 50px;
|
||||
top: 0;
|
||||
display: grid;
|
||||
padding: 3px;
|
||||
box-sizing: content-box;
|
||||
width: 100px;
|
||||
color: #FBF4F4;
|
||||
grid-template-columns: 25px 25px 25px 25px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
box-shadow: 0 0 15px #000;
|
||||
border: 1px solid #333;
|
||||
border-radius: 4px;
|
||||
pointer-events: all;
|
||||
}
|
|
@ -19,15 +19,15 @@
|
|||
font-size: @font-size;
|
||||
font-weight: 400;
|
||||
}
|
||||
/* bungee-inline-regular - latin */
|
||||
/* engli-besh */
|
||||
@font-face {
|
||||
font-family: 'Bungee Inline';
|
||||
font-family: 'Engli-Besh';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('./fonts/BungeeInline.ttf');
|
||||
src: url('./fonts/EngliBesh-KG3W.ttf');
|
||||
}
|
||||
.bungeeInline {
|
||||
font-family: 'Bungee Inline';
|
||||
.engli-Besh {
|
||||
font-family: 'Engli-Besh';
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
.dropShadow1();
|
||||
}
|
||||
.sw5e.sheet.actor.character {
|
||||
min-width: 800px;
|
||||
min-width: 850px;
|
||||
min-height: 720px;
|
||||
}
|
||||
.sw5e.sheet .window-content {
|
||||
|
@ -54,7 +54,7 @@
|
|||
grid-template-rows: 1fr 26px auto;
|
||||
grid-template-columns: 128px 1fr;
|
||||
column-gap: 8px;
|
||||
row-gap: 8px;
|
||||
grid-row-gap: 8px;
|
||||
|
||||
img {
|
||||
grid-column-start: 1;
|
||||
|
@ -683,7 +683,7 @@
|
|||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-gap: 16px;
|
||||
row-gap: 8px;
|
||||
grid-row-gap: 8px;
|
||||
|
||||
input,
|
||||
select {
|
||||
|
@ -715,7 +715,7 @@
|
|||
}
|
||||
|
||||
.languages {
|
||||
grid-column-end: span 2;
|
||||
grid-column-end: span 1;
|
||||
label {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
|
@ -745,7 +745,7 @@
|
|||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-gap: 4px;
|
||||
row-gap: 4px;
|
||||
grid-row-gap: 4px;
|
||||
|
||||
strong {
|
||||
font-size: 13px;
|
||||
|
@ -994,7 +994,7 @@
|
|||
}
|
||||
&.limited {
|
||||
grid-template-rows: 144px auto;
|
||||
row-gap: 8px;
|
||||
grid-row-gap: 8px;
|
||||
header {
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,12 @@
|
|||
font-weight: 400;
|
||||
src: url('./fonts/Aurebesh.ttf');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Engli-Besh';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('./fonts/EngliBesh-KG3W.ttf');
|
||||
}
|
||||
@import "_variables.less";
|
||||
|
||||
html {
|
||||
|
|
|
@ -21,7 +21,6 @@ export const preloadHandlebarsTemplates = async function() {
|
|||
"systems/sw5e/templates/actors/newActor/parts/swalt-active-effects.html",
|
||||
"systems/sw5e/templates/actors/newActor/parts/swalt-features.html",
|
||||
"systems/sw5e/templates/actors/newActor/parts/swalt-inventory.html",
|
||||
"systems/sw5e/templates/actors/newActor/parts/swalt-notes.html",
|
||||
"systems/sw5e/templates/actors/newActor/parts/swalt-powerbook.html",
|
||||
"systems/sw5e/templates/actors/newActor/parts/swalt-resources.html",
|
||||
"systems/sw5e/templates/actors/newActor/parts/swalt-traits.html",
|
||||
|
|
|
@ -48,6 +48,17 @@
|
|||
font-weight: 400;
|
||||
src: url('./fonts/Aurebesh.ttf');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Engli-Besh';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('./fonts/EngliBesh-KG3W.ttf');
|
||||
}
|
||||
.engli-Besh {
|
||||
font-family: 'Engli-Besh';
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
}
|
||||
/* ----------------------------------------- */
|
||||
/* Fonts */
|
||||
/* ----------------------------------------- */
|
||||
|
@ -705,7 +716,7 @@ input[type="reset"]:disabled {
|
|||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12), 0 1px 5px 0 rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.sw5e.sheet.actor.character {
|
||||
min-width: 800px;
|
||||
min-width: 850px;
|
||||
min-height: 720px;
|
||||
}
|
||||
.sw5e.sheet .window-content {
|
||||
|
@ -1330,7 +1341,7 @@ input[type="reset"]:disabled {
|
|||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-gap: 16px;
|
||||
row-gap: 8px;
|
||||
grid-row-gap: 8px;
|
||||
}
|
||||
.sw5e.sheet.actor .swalt-sheet .tab.attributes .traits-resources section.traits input,
|
||||
.sw5e.sheet.actor .swalt-sheet .tab.attributes .traits-resources section.traits select {
|
||||
|
@ -1357,7 +1368,7 @@ input[type="reset"]:disabled {
|
|||
text-shadow: none;
|
||||
}
|
||||
.sw5e.sheet.actor .swalt-sheet .tab.attributes .traits-resources section.traits .languages {
|
||||
grid-column-end: span 2;
|
||||
grid-column-end: span 1;
|
||||
}
|
||||
.sw5e.sheet.actor .swalt-sheet .tab.attributes .traits-resources section.traits .languages label:hover {
|
||||
cursor: pointer;
|
||||
|
|
42
sw5e.css
42
sw5e.css
|
@ -9,15 +9,15 @@
|
|||
font-weight: 400;
|
||||
src: url('./fonts/RussoOne.ttf');
|
||||
}
|
||||
/* bungee-inline-regular - latin */
|
||||
/* engli-besh */
|
||||
@font-face {
|
||||
font-family: 'Bungee Inline';
|
||||
font-family: 'Engli-Besh';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('./fonts/BungeeInline.ttf');
|
||||
src: url('./fonts/EngliBesh-KG3W.ttf');
|
||||
}
|
||||
.bungeeInline {
|
||||
font-family: 'Bungee Inline';
|
||||
.engli-Besh {
|
||||
font-family: 'Engli-Besh';
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
@ -1837,3 +1837,35 @@
|
|||
max-width: 40px;
|
||||
text-align: right;
|
||||
}
|
||||
.placeable-hud .control-icon {
|
||||
box-sizing: content-box;
|
||||
width: 40px;
|
||||
flex: 0 0 40px;
|
||||
margin: 8px 0;
|
||||
font-size: 28px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
color: #FBF4F4;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
box-shadow: 0 0 15px #000;
|
||||
border: 1px solid #333;
|
||||
border-radius: 8px;
|
||||
pointer-events: all;
|
||||
}
|
||||
#token-hud .status-effects {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
left: 50px;
|
||||
top: 0;
|
||||
display: grid;
|
||||
padding: 3px;
|
||||
box-sizing: content-box;
|
||||
width: 100px;
|
||||
color: #FBF4F4;
|
||||
grid-template-columns: 25px 25px 25px 25px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
box-shadow: 0 0 15px #000;
|
||||
border: 1px solid #333;
|
||||
border-radius: 4px;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
|
540
sw5e.js
540
sw5e.js
|
@ -1,272 +1,270 @@
|
|||
/**
|
||||
* The Star Wars 5th Edition game system for Foundry Virtual Tabletop
|
||||
* Author: Kakeman89
|
||||
* Software License: GNU GPLv3
|
||||
* Content License: https://media.wizards.com/2016/downloads/SW5E/SRD-OGL_V5.1.pdf
|
||||
* Repository: https://gitlab.com/foundrynet/sw5e
|
||||
* Issue Tracker: https://gitlab.com/foundrynet/sw5e/issues
|
||||
*/
|
||||
|
||||
// Import Modules
|
||||
import { SW5E } from "./module/config.js";
|
||||
import { registerSystemSettings } from "./module/settings.js";
|
||||
import { preloadHandlebarsTemplates } from "./module/templates.js";
|
||||
import { _getInitiativeFormula } from "./module/combat.js";
|
||||
import { measureDistances, getBarAttribute } from "./module/canvas.js";
|
||||
|
||||
// Import Entities
|
||||
import Actor5e from "./module/actor/entity.js";
|
||||
import Item5e from "./module/item/entity.js";
|
||||
|
||||
// Import Applications
|
||||
import AbilityTemplate from "./module/pixi/ability-template.js";
|
||||
import AbilityUseDialog from "./module/apps/ability-use-dialog.js";
|
||||
import ActorSheetFlags from "./module/apps/actor-flags.js";
|
||||
import ActorSheet5eCharacter from "./module/actor/sheets/oldSheets/character.js";
|
||||
import ActorSheet5eNPC from "./module/actor/sheets/oldSheets/npc.js";
|
||||
import ActorSheet5eVehicle from "./module/actor/sheets/oldSheets/vehicle.js";
|
||||
import ActorSheet5eCharacterNew from "./module/actor/sheets/newSheet/character.js";
|
||||
import ActorSheet5eNPCNew from "./module/actor/sheets/newSheet/npc.js";
|
||||
import ItemSheet5e from "./module/item/sheet.js";
|
||||
import ShortRestDialog from "./module/apps/short-rest.js";
|
||||
import TraitSelector from "./module/apps/trait-selector.js";
|
||||
import ActorMovementConfig from "./module/apps/movement-config.js";
|
||||
import ActorSensesConfig from "./module/apps/senses-config.js";
|
||||
|
||||
// Import Helpers
|
||||
import * as chat from "./module/chat.js";
|
||||
import * as dice from "./module/dice.js";
|
||||
import * as macros from "./module/macros.js";
|
||||
import * as migrations from "./module/migration.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Initialization */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
Hooks.once("init", function() {
|
||||
console.log(`SW5e | Initializing SW5E System\n${SW5E.ASCII}`);
|
||||
|
||||
// Create a SW5E namespace within the game global
|
||||
game.sw5e = {
|
||||
applications: {
|
||||
AbilityUseDialog,
|
||||
ActorSheetFlags,
|
||||
ActorSheet5eCharacter,
|
||||
ActorSheet5eCharacterNew,
|
||||
ActorSheet5eNPC,
|
||||
ActorSheet5eNPCNew,
|
||||
ActorSheet5eVehicle,
|
||||
ItemSheet5e,
|
||||
ShortRestDialog,
|
||||
TraitSelector,
|
||||
ActorMovementConfig
|
||||
},
|
||||
canvas: {
|
||||
AbilityTemplate
|
||||
},
|
||||
config: SW5E,
|
||||
dice: dice,
|
||||
entities: {
|
||||
Actor5e,
|
||||
Item5e,
|
||||
},
|
||||
macros: macros,
|
||||
migrations: migrations,
|
||||
rollItemMacro: macros.rollItemMacro
|
||||
};
|
||||
|
||||
// Record Configuration Values
|
||||
CONFIG.SW5E = SW5E;
|
||||
CONFIG.Actor.entityClass = Actor5e;
|
||||
CONFIG.Item.entityClass = Item5e;
|
||||
CONFIG.time.roundTime = 6;
|
||||
|
||||
// 5e cone RAW should be 53.13 degrees
|
||||
CONFIG.MeasuredTemplate.defaults.angle = 53.13;
|
||||
|
||||
// Add DND5e namespace for module compatability
|
||||
game.dnd5e = game.sw5e;
|
||||
CONFIG.DND5E = CONFIG.SW5E;
|
||||
|
||||
// Register System Settings
|
||||
registerSystemSettings();
|
||||
|
||||
// Patch Core Functions
|
||||
CONFIG.Combat.initiative.formula = "1d20 + @attributes.init.mod + @attributes.init.prof + @attributes.init.bonus";
|
||||
Combat.prototype._getInitiativeFormula = _getInitiativeFormula;
|
||||
|
||||
// Register sheet application classes
|
||||
Actors.unregisterSheet("core", ActorSheet);
|
||||
Actors.registerSheet("sw5e", ActorSheet5eCharacterNew, {
|
||||
types: ["character"],
|
||||
makeDefault: true,
|
||||
label: "SW5E.SheetClassCharacter"
|
||||
});
|
||||
Actors.registerSheet("sw5e", ActorSheet5eCharacter, {
|
||||
types: ["character"],
|
||||
makeDefault: false,
|
||||
label: "SW5E.SheetClassCharacterOld"
|
||||
});
|
||||
Actors.registerSheet("sw5e", ActorSheet5eNPCNew, {
|
||||
types: ["npc"],
|
||||
makeDefault: true,
|
||||
label: "SW5E.SheetClassNPC"
|
||||
});
|
||||
Actors.registerSheet("sw5e", ActorSheet5eNPC, {
|
||||
types: ["npc"],
|
||||
makeDefault: false,
|
||||
label: "SW5E.SheetClassNPCOld"
|
||||
});
|
||||
Actors.registerSheet('sw5e', ActorSheet5eVehicle, {
|
||||
types: ['vehicle'],
|
||||
makeDefault: true,
|
||||
label: "SW5E.SheetClassVehicle"
|
||||
});
|
||||
Items.unregisterSheet("core", ItemSheet);
|
||||
Items.registerSheet("sw5e", ItemSheet5e, {
|
||||
types: ['weapon', 'equipment', 'consumable', 'tool', 'loot', 'class', 'power', 'feat', 'species', 'backpack', 'archetype', 'classfeature', 'background', 'fightingmastery', 'fightingstyle', 'lightsaberform'],
|
||||
makeDefault: true,
|
||||
label: "SW5E.SheetClassItem"
|
||||
});
|
||||
|
||||
// Preload Handlebars Templates
|
||||
preloadHandlebarsTemplates();
|
||||
});
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Setup */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* This function runs after game data has been requested and loaded from the servers, so entities exist
|
||||
*/
|
||||
Hooks.once("setup", function() {
|
||||
|
||||
// Localize CONFIG objects once up-front
|
||||
const toLocalize = [
|
||||
"abilities", "abilityAbbreviations", "abilityActivationTypes", "abilityConsumptionTypes", "actorSizes", "alignments",
|
||||
"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"
|
||||
];
|
||||
|
||||
// Exclude some from sorting where the default order matters
|
||||
const noSort = [
|
||||
"abilities", "alignments", "currencies", "distanceUnits", "movementUnits", "itemActionTypes", "proficiencyLevels",
|
||||
"limitedUsePeriods", "powerComponents", "powerLevels", "powerPreparationModes", "weaponTypes"
|
||||
];
|
||||
|
||||
// Localize and sort CONFIG objects
|
||||
for ( let o of toLocalize ) {
|
||||
const localized = Object.entries(CONFIG.SW5E[o]).map(e => {
|
||||
return [e[0], game.i18n.localize(e[1])];
|
||||
});
|
||||
if ( !noSort.includes(o) ) localized.sort((a, b) => a[1].localeCompare(b[1]));
|
||||
CONFIG.SW5E[o] = localized.reduce((obj, e) => {
|
||||
obj[e[0]] = e[1];
|
||||
return obj;
|
||||
}, {});
|
||||
}
|
||||
// add DND5E translation for module compatability
|
||||
game.i18n.translations.DND5E = game.i18n.translations.SW5E;
|
||||
// console.log(game.settings.get("sw5e", "colorTheme"));
|
||||
let theme = game.settings.get("sw5e", "colorTheme") + '-theme';
|
||||
document.body.classList.add(theme);
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Once the entire VTT framework is initialized, check to see if we should perform a data migration
|
||||
*/
|
||||
Hooks.once("ready", function() {
|
||||
|
||||
// Wait to register hotbar drop hook on ready so that modules could register earlier if they want to
|
||||
Hooks.on("hotbarDrop", (bar, data, slot) => macros.create5eMacro(data, slot));
|
||||
|
||||
// Determine whether a system migration is required and feasible
|
||||
if ( !game.user.isGM ) return;
|
||||
const currentVersion = game.settings.get("sw5e", "systemMigrationVersion");
|
||||
const NEEDS_MIGRATION_VERSION = "1.2.1";
|
||||
const COMPATIBLE_MIGRATION_VERSION = 0.80;
|
||||
const needsMigration = currentVersion && isNewerVersion(NEEDS_MIGRATION_VERSION, currentVersion);
|
||||
if ( !needsMigration ) return;
|
||||
|
||||
// Perform the migration
|
||||
if ( currentVersion && isNewerVersion(COMPATIBLE_MIGRATION_VERSION, currentVersion) ) {
|
||||
const warning = `Your SW5e system data is from too old a Foundry version and cannot be reliably migrated to the latest version. The process will be attempted, but errors may occur.`;
|
||||
ui.notifications.error(warning, {permanent: true});
|
||||
}
|
||||
migrations.migrateWorld();
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Canvas Initialization */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
Hooks.on("canvasInit", function() {
|
||||
|
||||
// Extend Diagonal Measurement
|
||||
canvas.grid.diagonalRule = game.settings.get("sw5e", "diagonalMovement");
|
||||
SquareGrid.prototype.measureDistances = measureDistances;
|
||||
|
||||
// Extend Token Resource Bars
|
||||
Token.prototype.getBarAttribute = getBarAttribute;
|
||||
});
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Other Hooks */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
Hooks.on("renderChatMessage", (app, html, data) => {
|
||||
|
||||
// Display action buttons
|
||||
chat.displayChatActionButtons(app, html, data);
|
||||
|
||||
// Highlight critical success or failure die
|
||||
chat.highlightCriticalSuccessFailure(app, html, data);
|
||||
|
||||
// Optionally collapse the content
|
||||
if (game.settings.get("sw5e", "autoCollapseItemCards")) html.find(".card-content").hide();
|
||||
});
|
||||
Hooks.on("getChatLogEntryContext", chat.addChatMessageContextOptions);
|
||||
Hooks.on("renderChatLog", (app, html, data) => Item5e.chatListeners(html));
|
||||
Hooks.on("renderChatPopout", (app, html, data) => Item5e.chatListeners(html));
|
||||
Hooks.on('getActorDirectoryEntryContext', Actor5e.addDirectoryContextOptions);
|
||||
Hooks.on("renderSceneDirectory", (app, html, data)=> {
|
||||
//console.log(html.find("header.folder-header"));
|
||||
setFolderBackground(html);
|
||||
});
|
||||
Hooks.on("renderActorDirectory", (app, html, data)=> {
|
||||
setFolderBackground(html);
|
||||
});
|
||||
Hooks.on("renderItemDirectory", (app, html, data)=> {
|
||||
setFolderBackground(html);
|
||||
});
|
||||
Hooks.on("renderJournalDirectory", (app, html, data)=> {
|
||||
setFolderBackground(html);
|
||||
});
|
||||
Hooks.on("renderRollTableDirectory", (app, html, data)=> {
|
||||
setFolderBackground(html);
|
||||
});
|
||||
Hooks.on("ActorSheet5eCharacterNew", (app, html, data) => {
|
||||
console.log("renderSwaltSheet");
|
||||
});
|
||||
// TODO I should remove this
|
||||
Handlebars.registerHelper('getProperty', function (data, property) {
|
||||
return getProperty(data, property);
|
||||
});
|
||||
|
||||
|
||||
function setFolderBackground(html) {
|
||||
html.find("header.folder-header").each(function() {
|
||||
let bgColor = $(this).css("background-color");
|
||||
if(bgColor == undefined)
|
||||
bgColor = "rgb(255,255,255)";
|
||||
$(this).closest('li').css("background-color", bgColor);
|
||||
})
|
||||
/**
|
||||
* The Star Wars 5th Edition game system for Foundry Virtual Tabletop
|
||||
* Author: Kakeman89
|
||||
* Software License: GNU GPLv3
|
||||
* Content License: https://media.wizards.com/2016/downloads/SW5E/SRD-OGL_V5.1.pdf
|
||||
* Repository: https://gitlab.com/foundrynet/sw5e
|
||||
* Issue Tracker: https://gitlab.com/foundrynet/sw5e/issues
|
||||
*/
|
||||
|
||||
// Import Modules
|
||||
import { SW5E } from "./module/config.js";
|
||||
import { registerSystemSettings } from "./module/settings.js";
|
||||
import { preloadHandlebarsTemplates } from "./module/templates.js";
|
||||
import { _getInitiativeFormula } from "./module/combat.js";
|
||||
import { measureDistances, getBarAttribute } from "./module/canvas.js";
|
||||
|
||||
// Import Entities
|
||||
import Actor5e from "./module/actor/entity.js";
|
||||
import Item5e from "./module/item/entity.js";
|
||||
|
||||
// Import Applications
|
||||
import AbilityTemplate from "./module/pixi/ability-template.js";
|
||||
import AbilityUseDialog from "./module/apps/ability-use-dialog.js";
|
||||
import ActorSheetFlags from "./module/apps/actor-flags.js";
|
||||
import ActorSheet5eCharacter from "./module/actor/sheets/oldSheets/character.js";
|
||||
import ActorSheet5eNPC from "./module/actor/sheets/oldSheets/npc.js";
|
||||
import ActorSheet5eVehicle from "./module/actor/sheets/oldSheets/vehicle.js";
|
||||
import ActorSheet5eCharacterNew from "./module/actor/sheets/newSheet/character.js";
|
||||
import ItemSheet5e from "./module/item/sheet.js";
|
||||
import ShortRestDialog from "./module/apps/short-rest.js";
|
||||
import TraitSelector from "./module/apps/trait-selector.js";
|
||||
import ActorMovementConfig from "./module/apps/movement-config.js";
|
||||
import ActorSensesConfig from "./module/apps/senses-config.js";
|
||||
|
||||
// Import Helpers
|
||||
import * as chat from "./module/chat.js";
|
||||
import * as dice from "./module/dice.js";
|
||||
import * as macros from "./module/macros.js";
|
||||
import * as migrations from "./module/migration.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Initialization */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
Hooks.once("init", function() {
|
||||
console.log(`SW5e | Initializing SW5E System\n${SW5E.ASCII}`);
|
||||
|
||||
// Create a SW5E namespace within the game global
|
||||
game.sw5e = {
|
||||
applications: {
|
||||
AbilityUseDialog,
|
||||
ActorSheetFlags,
|
||||
ActorSheet5eCharacter,
|
||||
ActorSheet5eCharacterNew,
|
||||
ActorSheet5eNPC,
|
||||
ActorSheet5eVehicle,
|
||||
ItemSheet5e,
|
||||
ShortRestDialog,
|
||||
TraitSelector,
|
||||
ActorMovementConfig
|
||||
},
|
||||
canvas: {
|
||||
AbilityTemplate
|
||||
},
|
||||
config: SW5E,
|
||||
dice: dice,
|
||||
entities: {
|
||||
Actor5e,
|
||||
Item5e,
|
||||
},
|
||||
macros: macros,
|
||||
migrations: migrations,
|
||||
rollItemMacro: macros.rollItemMacro
|
||||
};
|
||||
|
||||
// Record Configuration Values
|
||||
CONFIG.SW5E = SW5E;
|
||||
CONFIG.Actor.entityClass = Actor5e;
|
||||
CONFIG.Item.entityClass = Item5e;
|
||||
CONFIG.time.roundTime = 6;
|
||||
CONFIG.fontFamilies = [
|
||||
"Engli-Besh",
|
||||
"Open Sans",
|
||||
"Russo One"
|
||||
];
|
||||
|
||||
// 5e cone RAW should be 53.13 degrees
|
||||
CONFIG.MeasuredTemplate.defaults.angle = 53.13;
|
||||
|
||||
// Add DND5e namespace for module compatability
|
||||
game.dnd5e = game.sw5e;
|
||||
CONFIG.DND5E = CONFIG.SW5E;
|
||||
|
||||
// Register System Settings
|
||||
registerSystemSettings();
|
||||
|
||||
// Patch Core Functions
|
||||
CONFIG.Combat.initiative.formula = "1d20 + @attributes.init.mod + @attributes.init.prof + @attributes.init.bonus";
|
||||
Combat.prototype._getInitiativeFormula = _getInitiativeFormula;
|
||||
|
||||
// Register sheet application classes
|
||||
Actors.unregisterSheet("core", ActorSheet);
|
||||
Actors.registerSheet("sw5e", ActorSheet5eCharacterNew, {
|
||||
types: ["character"],
|
||||
makeDefault: true,
|
||||
label: "SW5E.SheetClassCharacter"
|
||||
});
|
||||
Actors.registerSheet("sw5e", ActorSheet5eCharacter, {
|
||||
types: ["character"],
|
||||
makeDefault: false,
|
||||
label: "SW5E.SheetClassCharacterOld"
|
||||
});
|
||||
Actors.registerSheet("sw5e", ActorSheet5eNPC, {
|
||||
types: ["npc"],
|
||||
makeDefault: true,
|
||||
label: "SW5E.SheetClassNPC"
|
||||
});
|
||||
Actors.registerSheet('sw5e', ActorSheet5eVehicle, {
|
||||
types: ['vehicle'],
|
||||
makeDefault: true,
|
||||
label: "SW5E.SheetClassVehicle"
|
||||
});
|
||||
Items.unregisterSheet("core", ItemSheet);
|
||||
Items.registerSheet("sw5e", ItemSheet5e, {
|
||||
types: ['weapon', 'equipment', 'consumable', 'tool', 'loot', 'class', 'power', 'feat', 'species', 'backpack', 'archetype', 'classfeature', 'background', 'fightingmastery', 'fightingstyle', 'lightsaberform'],
|
||||
makeDefault: true,
|
||||
label: "SW5E.SheetClassItem"
|
||||
});
|
||||
|
||||
// Preload Handlebars Templates
|
||||
preloadHandlebarsTemplates();
|
||||
});
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Setup */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* This function runs after game data has been requested and loaded from the servers, so entities exist
|
||||
*/
|
||||
Hooks.once("setup", function() {
|
||||
|
||||
// Localize CONFIG objects once up-front
|
||||
const toLocalize = [
|
||||
"abilities", "abilityAbbreviations", "abilityActivationTypes", "abilityConsumptionTypes", "actorSizes", "alignments",
|
||||
"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"
|
||||
];
|
||||
|
||||
// Exclude some from sorting where the default order matters
|
||||
const noSort = [
|
||||
"abilities", "alignments", "currencies", "distanceUnits", "movementUnits", "itemActionTypes", "proficiencyLevels",
|
||||
"limitedUsePeriods", "powerComponents", "powerLevels", "powerPreparationModes", "weaponTypes"
|
||||
];
|
||||
|
||||
// Localize and sort CONFIG objects
|
||||
for ( let o of toLocalize ) {
|
||||
const localized = Object.entries(CONFIG.SW5E[o]).map(e => {
|
||||
return [e[0], game.i18n.localize(e[1])];
|
||||
});
|
||||
if ( !noSort.includes(o) ) localized.sort((a, b) => a[1].localeCompare(b[1]));
|
||||
CONFIG.SW5E[o] = localized.reduce((obj, e) => {
|
||||
obj[e[0]] = e[1];
|
||||
return obj;
|
||||
}, {});
|
||||
}
|
||||
// add DND5E translation for module compatability
|
||||
game.i18n.translations.DND5E = game.i18n.translations.SW5E;
|
||||
// console.log(game.settings.get("sw5e", "colorTheme"));
|
||||
let theme = game.settings.get("sw5e", "colorTheme") + '-theme';
|
||||
document.body.classList.add(theme);
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Once the entire VTT framework is initialized, check to see if we should perform a data migration
|
||||
*/
|
||||
Hooks.once("ready", function() {
|
||||
|
||||
// Wait to register hotbar drop hook on ready so that modules could register earlier if they want to
|
||||
Hooks.on("hotbarDrop", (bar, data, slot) => macros.create5eMacro(data, slot));
|
||||
|
||||
// Determine whether a system migration is required and feasible
|
||||
if ( !game.user.isGM ) return;
|
||||
const currentVersion = game.settings.get("sw5e", "systemMigrationVersion");
|
||||
const NEEDS_MIGRATION_VERSION = "1.2.1";
|
||||
const COMPATIBLE_MIGRATION_VERSION = 0.80;
|
||||
const needsMigration = currentVersion && isNewerVersion(NEEDS_MIGRATION_VERSION, currentVersion);
|
||||
if ( !needsMigration ) return;
|
||||
|
||||
// Perform the migration
|
||||
if ( currentVersion && isNewerVersion(COMPATIBLE_MIGRATION_VERSION, currentVersion) ) {
|
||||
const warning = `Your SW5e system data is from too old a Foundry version and cannot be reliably migrated to the latest version. The process will be attempted, but errors may occur.`;
|
||||
ui.notifications.error(warning, {permanent: true});
|
||||
}
|
||||
migrations.migrateWorld();
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Canvas Initialization */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
Hooks.on("canvasInit", function() {
|
||||
|
||||
// Extend Diagonal Measurement
|
||||
canvas.grid.diagonalRule = game.settings.get("sw5e", "diagonalMovement");
|
||||
SquareGrid.prototype.measureDistances = measureDistances;
|
||||
|
||||
// Extend Token Resource Bars
|
||||
Token.prototype.getBarAttribute = getBarAttribute;
|
||||
});
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Other Hooks */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
Hooks.on("renderChatMessage", (app, html, data) => {
|
||||
|
||||
// Display action buttons
|
||||
chat.displayChatActionButtons(app, html, data);
|
||||
|
||||
// Highlight critical success or failure die
|
||||
chat.highlightCriticalSuccessFailure(app, html, data);
|
||||
|
||||
// Optionally collapse the content
|
||||
if (game.settings.get("sw5e", "autoCollapseItemCards")) html.find(".card-content").hide();
|
||||
});
|
||||
Hooks.on("getChatLogEntryContext", chat.addChatMessageContextOptions);
|
||||
Hooks.on("renderChatLog", (app, html, data) => Item5e.chatListeners(html));
|
||||
Hooks.on("renderChatPopout", (app, html, data) => Item5e.chatListeners(html));
|
||||
Hooks.on('getActorDirectoryEntryContext', Actor5e.addDirectoryContextOptions);
|
||||
Hooks.on("renderSceneDirectory", (app, html, data)=> {
|
||||
//console.log(html.find("header.folder-header"));
|
||||
setFolderBackground(html);
|
||||
});
|
||||
Hooks.on("renderActorDirectory", (app, html, data)=> {
|
||||
setFolderBackground(html);
|
||||
});
|
||||
Hooks.on("renderItemDirectory", (app, html, data)=> {
|
||||
setFolderBackground(html);
|
||||
});
|
||||
Hooks.on("renderJournalDirectory", (app, html, data)=> {
|
||||
setFolderBackground(html);
|
||||
});
|
||||
Hooks.on("renderRollTableDirectory", (app, html, data)=> {
|
||||
setFolderBackground(html);
|
||||
});
|
||||
Hooks.on("ActorSheet5eCharacterNew", (app, html, data) => {
|
||||
console.log("renderSwaltSheet");
|
||||
});
|
||||
// TODO I should remove this
|
||||
Handlebars.registerHelper('getProperty', function (data, property) {
|
||||
return getProperty(data, property);
|
||||
});
|
||||
|
||||
|
||||
function setFolderBackground(html) {
|
||||
html.find("header.folder-header").each(function() {
|
||||
let bgColor = $(this).css("background-color");
|
||||
if(bgColor == undefined)
|
||||
bgColor = "rgb(255,255,255)";
|
||||
$(this).closest('li').css("background-color", bgColor);
|
||||
})
|
||||
}
|
|
@ -115,7 +115,7 @@
|
|||
<button class="item" data-tab="powerbook">{{ localize "SW5E.Powerbook" }}</button>
|
||||
<button class="item" data-tab="effects">{{ localize "SW5E.Effects" }}</button>
|
||||
<button class="item" data-tab="biography">{{ localize "SW5E.Biography" }}</button>
|
||||
<button class="item" data-tab="notes">{{ localize "SW5E.Notes" }}</button>
|
||||
<!-- <button class="item" data-tab="notes">{{ localize "SW5E.Notes" }}</button> -->
|
||||
</nav>
|
||||
{{!-- PC Sheet Body --}}
|
||||
<section class="sheet-body">
|
||||
|
@ -143,8 +143,8 @@
|
|||
<section class="tab biography" data-group="primary" data-tab="biography">
|
||||
{{> "systems/sw5e/templates/actors/newActor/parts/swalt-biography.html"}}
|
||||
</section>
|
||||
{{!-- Notes Tab --}}
|
||||
<!-- {{!-- Notes Tab --}}
|
||||
<section class="tab notes" data-group="primary" data-tab="notes">
|
||||
{{> "systems/sw5e/templates/actors/newActor/parts/swalt-notes.html"}}
|
||||
</section>
|
||||
</section> -->
|
||||
</form>
|
|
@ -44,8 +44,8 @@
|
|||
</section>
|
||||
<section class="panel traits-resources">
|
||||
<nav class="core-tabs tab-list" data-subgroup-selection>
|
||||
<button type="button" class="item active" data-subgroup="coreattributes" data-target="traits">Traits</button>
|
||||
<button type="button" class="item" data-subgroup="coreattributes" data-target="resources">Resources</button>
|
||||
<button type="button" class="item active" data-subgroup="coreattributes" data-target="traits">Resources & Traits</button>
|
||||
<button type="button" class="item" data-subgroup="coreattributes" data-target="resources">Favorites & Notes</button>
|
||||
</nav>
|
||||
<div class="tab core-traits active" data-subgroup="coreattributes" data-target="traits">
|
||||
{{> "systems/sw5e/templates/actors/newActor/parts/swalt-traits.html"}}
|
||||
|
|
|
@ -1,65 +1,36 @@
|
|||
{{!-- Resources, Counters, & Favorites --}}
|
||||
<section class="resources">
|
||||
<section class="resource-items">
|
||||
{{#each resources as |res|}}
|
||||
<div class="resource">
|
||||
<h1>
|
||||
<input name="data.resources.{{res.name}}.label" type="text" value="{{res.label}}"
|
||||
placeholder="{{res.placeholder}}" />
|
||||
</h1>
|
||||
<div class="attribute-value">
|
||||
<input name="data.resources.{{res.name}}.value" type="text" value="{{res.value}}" data-dtype="Number"
|
||||
placeholder="0" class="value-number" />
|
||||
<span class="value-separator">/</span>
|
||||
<input name="data.resources.{{res.name}}.max" type="text" value="{{res.max}}" data-dtype="Number"
|
||||
placeholder="0" class="value-number" />
|
||||
</div>
|
||||
<footer class="attribute-footer">
|
||||
<label class="recharge checkbox">
|
||||
{{ localize "SW5E.AbbreviationSR" }} <input name="data.resources.{{res.name}}.sr" type="checkbox"
|
||||
{{checked res.sr}} />
|
||||
</label>
|
||||
<label class="recharge checkbox">
|
||||
{{ localize "SW5E.AbbreviationLR" }} <input name="data.resources.{{res.name}}.lr" type="checkbox"
|
||||
{{checked res.lr}} />
|
||||
</label>
|
||||
</footer>
|
||||
</div>
|
||||
{{/each}}
|
||||
</section>
|
||||
<section class="counters">
|
||||
<div class="counter">
|
||||
<h4 class="death-save rollable">{{ localize "SW5E.DeathSave" }}</h4>
|
||||
<div class="counter-value">
|
||||
<div class="death-success">
|
||||
<i class="fas fa-check"></i>
|
||||
<input type="text" name="data.attributes.death.success" data-dtype="Number" placeholder="0"
|
||||
value="{{data.attributes.death.success}}" />
|
||||
</div>
|
||||
<div class="death-fail">
|
||||
<i class="fas fa-times"></i>
|
||||
<input type="text" name="data.attributes.death.failure" data-dtype="Number" placeholder="0"
|
||||
value="{{data.attributes.death.failure}}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="counter">
|
||||
<h4>{{ localize "SW5E.Exhaustion" }}</h4>
|
||||
<div class="counter-value">
|
||||
<input type="text" name="data.attributes.exhaustion" data-dtype="Number" placeholder="0"
|
||||
value="{{data.attributes.exhaustion}}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="counter">
|
||||
<h4>{{ localize "SW5E.Inspiration" }}</h4>
|
||||
<div class="counter-value">
|
||||
<input type="checkbox" name="data.attributes.inspiration" data-dtype="Boolean"
|
||||
{{checked data.attributes.inspiration}} />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="favorites">
|
||||
<h1>Favorites</h1>
|
||||
<section class="favorites">
|
||||
<h1>Favorites</h1>
|
||||
<div class="favtabtarget"></div>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
<p> </p>
|
||||
<section class="background">
|
||||
<h1>Journal and Notes</h1>
|
||||
<input type="text" name="data.details.notesname" value="{{data.details.notesname}}"
|
||||
placeholder="Personal Journal" />
|
||||
|
||||
{{editor content=data.details.notes.value target="data.details.notes.value" button=true owner=owner editable=editable}}
|
||||
</section>
|
||||
<section>
|
||||
<input type="text" name="data.details.notes1name" value="{{data.details.notes1name}}"
|
||||
placeholder="Additional Notes" />
|
||||
{{editor content=data.details.notes1.value target="data.details.notes1.value" button=true owner=owner editable=editable}}
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<input type="text" name="data.details.notes2name" value="{{data.details.notes2name}}"
|
||||
placeholder="Additional Notes" />
|
||||
{{editor content=data.details.notes2.value target="data.details.notes2.value" button=true owner=owner editable=editable}}
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<input type="text" name="data.details.notes3name" value="{{data.details.notes3name}}"
|
||||
placeholder="Additional Notes" />
|
||||
{{editor content=data.details.notes3.value target="data.details.notes3.value" button=true owner=owner editable=editable}}
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<input type="text" name="data.details.notes4name" value="{{data.details.notes4name}}"
|
||||
placeholder="Additional Notes" />
|
||||
{{editor content=data.details.notes4.value target="data.details.notes4.value" button=true owner=owner editable=editable}}
|
||||
</section>
|
|
@ -1,3 +1,63 @@
|
|||
<section class="resources">
|
||||
<section class="resource-items">
|
||||
{{#each resources as |res|}}
|
||||
<div class="resource">
|
||||
<h1>
|
||||
<input name="data.resources.{{res.name}}.label" type="text" value="{{res.label}}"
|
||||
placeholder="{{res.placeholder}}" />
|
||||
</h1>
|
||||
<div class="attribute-value">
|
||||
<input name="data.resources.{{res.name}}.value" type="text" value="{{res.value}}" data-dtype="Number"
|
||||
placeholder="0" class="value-number" />
|
||||
<span class="value-separator">/</span>
|
||||
<input name="data.resources.{{res.name}}.max" type="text" value="{{res.max}}" data-dtype="Number"
|
||||
placeholder="0" class="value-number" />
|
||||
</div>
|
||||
<footer class="attribute-footer">
|
||||
<label class="recharge checkbox">
|
||||
{{ localize "SW5E.AbbreviationSR" }} <input name="data.resources.{{res.name}}.sr" type="checkbox"
|
||||
{{checked res.sr}} />
|
||||
</label>
|
||||
<label class="recharge checkbox">
|
||||
{{ localize "SW5E.AbbreviationLR" }} <input name="data.resources.{{res.name}}.lr" type="checkbox"
|
||||
{{checked res.lr}} />
|
||||
</label>
|
||||
</footer>
|
||||
</div>
|
||||
{{/each}}
|
||||
|
||||
</section>
|
||||
<section class="counters">
|
||||
<div class="counter">
|
||||
<h4 class="death-save rollable">{{ localize "SW5E.DeathSave" }}</h4>
|
||||
<div class="counter-value">
|
||||
<div class="death-success">
|
||||
<i class="fas fa-check"></i>
|
||||
<input type="text" name="data.attributes.death.success" data-dtype="Number" placeholder="0"
|
||||
value="{{data.attributes.death.success}}" />
|
||||
</div>
|
||||
<div class="death-fail">
|
||||
<i class="fas fa-times"></i>
|
||||
<input type="text" name="data.attributes.death.failure" data-dtype="Number" placeholder="0"
|
||||
value="{{data.attributes.death.failure}}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="counter">
|
||||
<h4>{{ localize "SW5E.Exhaustion" }}</h4>
|
||||
<div class="counter-value">
|
||||
<input type="text" name="data.attributes.exhaustion" data-dtype="Number" placeholder="0"
|
||||
value="{{data.attributes.exhaustion}}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="counter">
|
||||
<h4>{{ localize "SW5E.Inspiration" }}</h4>
|
||||
<div class="counter-value">
|
||||
<input type="checkbox" name="data.attributes.inspiration" data-dtype="Boolean"
|
||||
{{checked data.attributes.inspiration}} />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="traits">
|
||||
<label>
|
||||
{{localize "SW5E.Size"}}
|
||||
|
@ -20,6 +80,16 @@
|
|||
</ul>
|
||||
{{/unless}}
|
||||
</label>
|
||||
<div>
|
||||
<label>{{localize "SW5E.MovementConfig"}}</label>
|
||||
<a class="configure-movement" title="{{localize 'SW5E.MovementConfig'}}"><i class="fas fa-cog"></i></a>
|
||||
</div>
|
||||
<div>
|
||||
{{#unless isVehicle}}
|
||||
<label>{{localize "SW5E.SpecialTraits"}}</label>
|
||||
<a class="configure-flags"><i class="fas fa-cog"></i></a>
|
||||
{{/unless}}
|
||||
</div>
|
||||
<div class="languages">
|
||||
<label data-options="share-languages" class="languages">{{localize "SW5E.Languages"}}</label>
|
||||
<a class="trait-selector" data-options="languages" data-target="data.traits.languages">
|
||||
|
@ -30,7 +100,40 @@
|
|||
<li>{{v}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<label>{{localize "SW5E.TraitArmorProf"}}</label>
|
||||
<a class="trait-selector" data-options="armorProficiencies" data-target="data.traits.armorProf">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<ul class="traits-list">
|
||||
{{#each data.traits.armorProf.selected as |v k|}}
|
||||
<li>{{v}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<label>{{localize "SW5E.TraitToolProf"}}</label>
|
||||
<a class="trait-selector" data-options="toolProficiencies" data-target="data.traits.toolProf">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<ul class="traits-list">
|
||||
{{#each data.traits.toolProf.selected as |v k|}}
|
||||
<li>{{v}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<label>{{localize "SW5E.TraitWeaponProf"}}</label>
|
||||
<a class="trait-selector" data-options="weaponProficiencies" data-target="data.traits.weaponProf">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<ul class="traits-list">
|
||||
{{#each data.traits.weaponProf.selected as |v k|}}
|
||||
<li>{{v}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<label>{{localize "SW5E.DamImm"}}</label>
|
||||
<a class="trait-selector" data-options="damageResistanceTypes" data-target="data.traits.di">
|
||||
|
@ -76,42 +179,8 @@
|
|||
{{/each}}
|
||||
</ul>
|
||||
</div>{{#if isCharacter}}
|
||||
<div>
|
||||
<label>{{localize "SW5E.TraitWeaponProf"}}</label>
|
||||
<a class="trait-selector" data-options="weaponProficiencies" data-target="data.traits.weaponProf">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<ul class="traits-list">
|
||||
{{#each data.traits.weaponProf.selected as |v k|}}
|
||||
<li>{{v}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<label>{{localize "SW5E.TraitArmorProf"}}</label>
|
||||
<a class="trait-selector" data-options="armorProficiencies" data-target="data.traits.armorProf">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<ul class="traits-list">
|
||||
{{#each data.traits.armorProf.selected as |v k|}}
|
||||
<li>{{v}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>{{localize "SW5E.TraitToolProf"}}</label>
|
||||
<a class="trait-selector" data-options="toolProficiencies" data-target="data.traits.toolProf">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<ul class="traits-list">
|
||||
{{#each data.traits.toolProf.selected as |v k|}}
|
||||
<li>{{v}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#unless isVehicle}}
|
||||
<div>
|
||||
<label>{{localize "SW5E.SpecialTraits"}}</label>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue