2021-01-19 12:32:32 -05:00
/ * *
* The Star Wars 5 th 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
2021-03-24 19:41:50 -05:00
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" ;
2021-01-19 12:32:32 -05:00
// Import Entities
import Actor5e from "./module/actor/entity.js" ;
import Item5e from "./module/item/entity.js" ;
2021-02-23 22:42:20 -06:00
import CharacterImporter from "./module/characterImporter.js" ;
2021-01-19 12:32:32 -05:00
// 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" ;
2021-01-19 21:47:38 -05:00
import ActorSheet5eNPCNew from "./module/actor/sheets/newSheet/npc.js" ;
2021-01-19 12:32:32 -05:00
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 */
/* -------------------------------------------- */
2021-03-24 19:41:50 -05:00
Hooks . once ( "init" , function ( ) {
2021-01-19 12:32:32 -05:00
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 ,
2021-01-19 21:47:38 -05:00
ActorSheet5eNPCNew ,
2021-01-19 12:32:32 -05:00
ActorSheet5eVehicle ,
ItemSheet5e ,
ShortRestDialog ,
TraitSelector ,
ActorMovementConfig
} ,
canvas : {
AbilityTemplate
} ,
config : SW5E ,
dice : dice ,
entities : {
Actor5e ,
2021-03-24 19:41:50 -05:00
Item5e
2021-01-19 12:32:32 -05:00
} ,
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 ;
2021-03-24 19:41:50 -05:00
CONFIG . fontFamilies = [ "Engli-Besh" , "Open Sans" , "Russo One" ] ;
2021-01-19 12:32:32 -05:00
// 5e cone RAW should be 53.13 degrees
CONFIG . MeasuredTemplate . defaults . angle = 53.13 ;
2021-01-19 21:47:38 -05:00
2021-01-19 12:32:32 -05:00
// 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"
2021-03-24 19:41:50 -05:00
} ) ;
2021-01-19 12:32:32 -05:00
Actors . registerSheet ( "sw5e" , ActorSheet5eCharacter , {
types : [ "character" ] ,
makeDefault : false ,
label : "SW5E.SheetClassCharacterOld"
2021-03-24 19:41:50 -05:00
} ) ;
2021-01-19 21:47:38 -05:00
Actors . registerSheet ( "sw5e" , ActorSheet5eNPCNew , {
2021-01-19 12:32:32 -05:00
types : [ "npc" ] ,
makeDefault : true ,
label : "SW5E.SheetClassNPC"
} ) ;
2021-01-19 21:47:38 -05:00
Actors . registerSheet ( "sw5e" , ActorSheet5eNPC , {
types : [ "npc" ] ,
makeDefault : false ,
label : "SW5E.SheetClassNPCOld"
} ) ;
2021-03-24 19:41:50 -05:00
Actors . registerSheet ( "sw5e" , ActorSheet5eVehicle , {
types : [ "vehicle" ] ,
2021-01-19 12:32:32 -05:00
makeDefault : true ,
label : "SW5E.SheetClassVehicle"
} ) ;
Items . unregisterSheet ( "core" , ItemSheet ) ;
Items . registerSheet ( "sw5e" , ItemSheet5e , {
2021-03-24 19:41:50 -05:00
types : [
"weapon" ,
"equipment" ,
"consumable" ,
"tool" ,
"loot" ,
"class" ,
"power" ,
"feat" ,
"species" ,
"backpack" ,
"archetype" ,
"classfeature" ,
"background" ,
"fightingmastery" ,
"fightingstyle" ,
"lightsaberform"
] ,
2021-01-19 12:32:32 -05:00
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
* /
2021-03-24 19:41:50 -05:00
Hooks . once ( "setup" , function ( ) {
2021-01-19 12:32:32 -05:00
// Localize CONFIG objects once up-front
const toLocalize = [
2021-03-24 19:41:50 -05:00
"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"
2021-01-19 12:32:32 -05:00
] ;
// Exclude some from sorting where the default order matters
const noSort = [
2021-03-24 19:41:50 -05:00
"abilities" ,
"alignments" ,
"currencies" ,
"distanceUnits" ,
"movementUnits" ,
"itemActionTypes" ,
"proficiencyLevels" ,
"limitedUsePeriods" ,
"powerComponents" ,
"powerLevels" ,
"powerPreparationModes" ,
"weaponTypes"
2021-01-19 12:32:32 -05:00
] ;
// Localize and sort CONFIG objects
2021-03-24 19:41:50 -05:00
for ( let o of toLocalize ) {
2021-01-19 12:32:32 -05:00
const localized = Object . entries ( CONFIG . SW5E [ o ] ) . map ( e => {
return [ e [ 0 ] , game . i18n . localize ( e [ 1 ] ) ] ;
} ) ;
2021-03-24 19:41:50 -05:00
if ( ! noSort . includes ( o ) ) localized . sort ( ( a , b ) => a [ 1 ] . localeCompare ( b [ 1 ] ) ) ;
2021-01-19 12:32:32 -05:00
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"));
2021-03-24 19:41:50 -05:00
let theme = game . settings . get ( "sw5e" , "colorTheme" ) + "-theme" ;
2021-01-19 12:32:32 -05:00
document . body . classList . add ( theme ) ;
} ) ;
/* -------------------------------------------- */
/ * *
* Once the entire VTT framework is initialized , check to see if we should perform a data migration
* /
2021-03-24 19:41:50 -05:00
Hooks . once ( "ready" , function ( ) {
2021-01-19 12:32:32 -05:00
// 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
2021-03-24 19:41:50 -05:00
if ( ! game . user . isGM ) return ;
2021-01-19 12:32:32 -05:00
const currentVersion = game . settings . get ( "sw5e" , "systemMigrationVersion" ) ;
2021-03-12 16:47:24 -05:00
const NEEDS _MIGRATION _VERSION = "1.2.4.R1-A5" ;
2021-03-11 01:30:03 -05:00
// Check for R1 SW5E versions
const SW5E _NEEDS _MIGRATION _VERSION = "R1-A5" ;
2021-03-24 19:41:50 -05:00
const COMPATIBLE _MIGRATION _VERSION = 0.8 ;
const needsMigration =
currentVersion &&
( isNewerVersion ( SW5E _NEEDS _MIGRATION _VERSION , currentVersion ) ||
isNewerVersion ( NEEDS _MIGRATION _VERSION , currentVersion ) ) ;
if ( ! needsMigration ) return ;
2021-01-19 12:32:32 -05:00
// Perform the migration
2021-03-24 19:41:50 -05:00
if ( currentVersion && isNewerVersion ( COMPATIBLE _MIGRATION _VERSION , currentVersion ) ) {
2021-03-11 01:30:03 -05:00
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 } ) ;
}
2021-01-19 12:32:32 -05:00
migrations . migrateWorld ( ) ;
} ) ;
/* -------------------------------------------- */
/* Canvas Initialization */
/* -------------------------------------------- */
2021-03-24 19:41:50 -05:00
Hooks . on ( "canvasInit" , function ( ) {
2021-01-19 12:32:32 -05:00
// 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 ) ) ;
2021-03-24 19:41:50 -05:00
Hooks . on ( "getActorDirectoryEntryContext" , Actor5e . addDirectoryContextOptions ) ;
Hooks . on ( "renderSceneDirectory" , ( app , html , data ) => {
2021-01-19 12:32:32 -05:00
//console.log(html.find("header.folder-header"));
setFolderBackground ( html ) ;
} ) ;
2021-03-24 19:41:50 -05:00
Hooks . on ( "renderActorDirectory" , ( app , html , data ) => {
2021-01-19 12:32:32 -05:00
setFolderBackground ( html ) ;
2021-02-23 22:42:20 -06:00
CharacterImporter . addImportButton ( html ) ;
2021-01-19 12:32:32 -05:00
} ) ;
2021-03-24 19:41:50 -05:00
Hooks . on ( "renderItemDirectory" , ( app , html , data ) => {
2021-01-19 12:32:32 -05:00
setFolderBackground ( html ) ;
} ) ;
2021-03-24 19:41:50 -05:00
Hooks . on ( "renderJournalDirectory" , ( app , html , data ) => {
2021-01-19 12:32:32 -05:00
setFolderBackground ( html ) ;
} ) ;
2021-03-24 19:41:50 -05:00
Hooks . on ( "renderRollTableDirectory" , ( app , html , data ) => {
2021-01-19 12:32:32 -05:00
setFolderBackground ( html ) ;
} ) ;
Hooks . on ( "ActorSheet5eCharacterNew" , ( app , html , data ) => {
console . log ( "renderSwaltSheet" ) ;
} ) ;
// TODO I should remove this
2021-03-24 19:41:50 -05:00
Handlebars . registerHelper ( "getProperty" , function ( data , property ) {
2021-01-19 12:32:32 -05:00
return getProperty ( data , property ) ;
} ) ;
function setFolderBackground ( html ) {
2021-03-24 19:41:50 -05:00
html . find ( "header.folder-header" ) . each ( function ( ) {
2021-01-19 12:32:32 -05:00
let bgColor = $ ( this ) . css ( "background-color" ) ;
2021-03-24 19:41:50 -05:00
if ( bgColor == undefined ) bgColor = "rgb(255,255,255)" ;
$ ( this ) . closest ( "li" ) . css ( "background-color" , bgColor ) ;
} ) ;
}