2021-01-19 20:47:48 -05:00
/ * *
* The SW5e game system for Foundry Virtual Tabletop
* A system for playing the fifth edition of the worlds most popular roleplaying game .
* Author : Atropos
* Software License : GNU GPLv3
* Content License : https : //media.wizards.com/2016/downloads/DND/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" ;
2021-05-18 09:11:03 -04:00
import { measureDistances } from "./module/canvas.js" ;
2021-01-19 20:47:48 -05:00
2021-05-18 09:11:03 -04:00
// Import Documents
2021-01-19 20:47:48 -05:00
import Actor5e from "./module/actor/entity.js" ;
import Item5e from "./module/item/entity.js" ;
2021-05-18 09:11:03 -04:00
import { TokenDocument5e , Token5e } from "./module/token.js" ;
2021-01-19 20:47:48 -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/character.js" ;
import ActorSheet5eNPC from "./module/actor/sheets/npc.js" ;
import ActorSheet5eVehicle from "./module/actor/sheets/vehicle.js" ;
import ItemSheet5e from "./module/item/sheet.js" ;
import ShortRestDialog from "./module/apps/short-rest.js" ;
import TraitSelector from "./module/apps/trait-selector.js" ;
2021-01-19 20:52:33 -05:00
import ActorMovementConfig from "./module/apps/movement-config.js" ;
import ActorSensesConfig from "./module/apps/senses-config.js" ;
2021-01-19 20:47:48 -05:00
// 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 the SW5e Game System \n ${ SW5E . ASCII } ` ) ;
// Create a namespace within the game global
game . sw5e = {
applications : {
AbilityUseDialog ,
ActorSheetFlags ,
ActorSheet5eCharacter ,
ActorSheet5eNPC ,
ActorSheet5eVehicle ,
ItemSheet5e ,
ShortRestDialog ,
TraitSelector ,
2021-05-18 09:11:03 -04:00
ActorMovementConfig ,
ActorSensesConfig
2021-01-19 20:47:48 -05:00
} ,
canvas : {
AbilityTemplate
} ,
config : SW5E ,
dice : dice ,
entities : {
Actor5e ,
Item5e ,
2021-05-18 09:11:03 -04:00
TokenDocument5e ,
Token5e ,
2021-01-19 20:47:48 -05:00
} ,
macros : macros ,
migrations : migrations ,
rollItemMacro : macros . rollItemMacro
} ;
// Record Configuration Values
CONFIG . SW5E = SW5E ;
2021-05-18 09:11:03 -04:00
CONFIG . Actor . documentClass = Actor5e ;
CONFIG . Item . documentClass = Item5e ;
CONFIG . Token . documentClass = TokenDocument5e ;
CONFIG . Token . objectClass = Token5e ;
2021-01-19 20:47:48 -05:00
CONFIG . time . roundTime = 6 ;
2021-05-18 09:11:03 -04:00
CONFIG . Dice . DamageRoll = dice . DamageRoll ;
CONFIG . Dice . D20Roll = dice . D20Roll ;
2021-01-19 20:54:45 -05:00
// 5e cone RAW should be 53.13 degrees
CONFIG . MeasuredTemplate . defaults . angle = 53.13 ;
2021-01-19 20:47:48 -05:00
// Register System Settings
registerSystemSettings ( ) ;
// Patch Core Functions
CONFIG . Combat . initiative . formula = "1d20 + @attributes.init.mod + @attributes.init.prof + @attributes.init.bonus" ;
2021-05-18 09:11:03 -04:00
Combatant . prototype . _getInitiativeFormula = _getInitiativeFormula ;
// Register Roll Extensions
CONFIG . Dice . rolls . push ( dice . D20Roll ) ;
CONFIG . Dice . rolls . push ( dice . DamageRoll ) ;
2021-01-19 20:47:48 -05:00
// Register sheet application classes
Actors . unregisterSheet ( "core" , ActorSheet ) ;
Actors . registerSheet ( "sw5e" , ActorSheet5eCharacter , {
types : [ "character" ] ,
makeDefault : true ,
label : "SW5E.SheetClassCharacter"
} ) ;
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 , {
makeDefault : true ,
label : "SW5E.SheetClassItem"
} ) ;
// Preload Handlebars Templates
2021-05-18 09:11:03 -04:00
return preloadHandlebarsTemplates ( ) ;
2021-01-19 20:47:48 -05:00
} ) ;
/* -------------------------------------------- */
/* 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" , "conditionTypes" , "consumableTypes" , "cover" , "currencies" , "damageResistanceTypes" ,
"damageTypes" , "distanceUnits" , "equipmentTypes" , "healingTypes" , "itemActionTypes" , "languages" ,
2021-01-19 20:54:45 -05:00
"limitedUsePeriods" , "movementTypes" , "movementUnits" , "polymorphSettings" , "proficiencyLevels" , "senses" , "skills" ,
2021-01-19 20:47:48 -05:00
"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 ;
} , { } ) ;
}
} ) ;
/* -------------------------------------------- */
/ * *
* 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" ) ;
2021-05-18 09:11:03 -04:00
const NEEDS _MIGRATION _VERSION = "1.3.4" ;
2021-01-19 20:47:48 -05:00
const COMPATIBLE _MIGRATION _VERSION = 0.80 ;
2021-05-18 09:11:03 -04:00
const totalDocuments = game . actors . size + game . scenes . size + game . items . size ;
if ( ! currentVersion && totalDocuments === 0 ) return game . settings . set ( "sw5e" , "systemMigrationVersion" , game . system . data . version ) ;
const needsMigration = ! currentVersion || isNewerVersion ( NEEDS _MIGRATION _VERSION , currentVersion ) ;
2021-01-19 20:47:48 -05:00
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 ;
} ) ;
/* -------------------------------------------- */
/* 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 ) ;
2021-05-18 09:11:03 -04:00
// FIXME: This helper is needed for the vehicle sheet. It should probably be refactored.
2021-01-19 20:47:48 -05:00
Handlebars . registerHelper ( 'getProperty' , function ( data , property ) {
return getProperty ( data , property ) ;
} ) ;