88 getOtherUnit ,
99 getUnitFromString ,
1010 getUnitSystem ,
11+ isEmpty ,
12+ UNITS ,
1113} from "../utils.mjs" ;
1214import { convertActorData } from "./actor.mjs" ;
1315
@@ -20,7 +22,7 @@ import { convertActorData } from "./actor.mjs";
2022 * @returns {object } The update data
2123 */
2224export const convertSceneData = ( scene , options = { } ) => {
23- const updateData = { } ;
25+ const sceneUpdateData = { } ;
2426 const { target } = getConversionOptions ( options ) ;
2527
2628 // Convert grid distance and units if necessary
@@ -30,43 +32,123 @@ export const convertSceneData = (scene, options = {}) => {
3032 const currentSystem = getUnitSystem ( units ) ;
3133 if ( units && currentSystem !== target ) {
3234 if ( game . release . generation < 10 ) {
33- updateData . gridUnits = getOtherUnit ( units ) ;
34- updateData . gridDistance = convertDistance ( currentGridDistance , units ) ;
35+ sceneUpdateData . gridUnits = getOtherUnit ( units ) ;
36+ sceneUpdateData . gridDistance = convertDistance ( currentGridDistance , units ) ;
3537 } else {
36- updateData . grid = {
38+ sceneUpdateData . grid = {
3739 units : getOtherUnit ( units ) ,
3840 distance : convertDistance ( scene . grid . distance , units ) ,
3941 } ;
4042 }
4143 }
4244
43- const tokens = scene . tokens
44- . map ( ( token ) => {
45- const tokenData = "toObject" in token ? token . toObject ( ) : token ;
46- if ( ! tokenData . actorId || tokenData . actorLink ) {
47- tokenData . actorData = { } ;
48- } else if ( ! game . actors . has ( tokenData . actorId ) ) {
49- tokenData . actorId = null ;
50- tokenData . actorData = { } ;
51- } else if ( ! tokenData . actorLink ) {
52- const actorData = tokenData . actorData ;
53- const actorUpdate = convertActorData ( actorData , options ) ;
45+ const sceneTokens = Array . isArray ( scene . tokens ) ? scene . tokens : scene . tokens . contents ;
46+ const tokens = sceneTokens . flatMap ( ( token ) => {
47+ const tokenData = "toObject" in token ? token . toObject ( ) : token ;
48+ const tokenActorData = convertTokenActorData ( tokenData , { target } ) ?? { } ;
49+ const tokenVisionData =
50+ convertTokenVisionData ( tokenData , { target : target , current : units } ) ?? { } ;
51+ const updateData = { ...tokenActorData , ...tokenVisionData } ;
52+ if ( ! isEmpty ( updateData ) ) {
53+ return [ { _id : tokenData . _id , ...updateData } ] ;
54+ } else {
55+ return [ ] ;
56+ }
57+ } ) ;
58+
59+ const sceneLights = Array . isArray ( scene . lights ) ? scene . lights : scene . lights . contents ;
60+ const lights = sceneLights . flatMap ( ( light ) => {
61+ const updateData = convertLightData ( light , { target, current : units } ) ;
62+ if ( ! isEmpty ( updateData ) ) {
63+ return [ { _id : light . _id , ...updateData } ] ;
64+ } else {
65+ return [ ] ;
66+ }
67+ } ) ;
5468
55- // Handle item updates
56- if ( ! actorUpdate . items ?. length ) return ;
57- const updates = new Map ( actorUpdate . items . map ( ( item ) => [ item . _id , item ] ) ) ;
58- tokenData . actorData . items ?. forEach ( ( original ) => {
59- const update = updates . get ( original . _id ) ;
60- if ( update ) foundry . utils . mergeObject ( original , update ) ;
61- } ) ;
62- delete actorUpdate . items ;
63- foundry . utils . mergeObject ( tokenData . actorData , actorUpdate ) ;
64- }
65- return tokenData ;
66- } )
67- . filter ( Boolean ) ;
69+ return { ...sceneUpdateData , tokens, lights } ;
70+ } ;
6871
69- return { ...updateData , tokens } ;
72+ /**
73+ * Converts a token's `actorData` to the other unit system.
74+ *
75+ *
76+ * @param {object } tokenData - A token's complete data object
77+ * @param {ConversionOptions } [options] - Options for conversion
78+ * @returns {{actorData: object} } A partial update object
79+ */
80+ const convertTokenActorData = ( tokenData , options = { } ) => {
81+ if ( ! tokenData . actorId || tokenData . actorLink ) {
82+ tokenData . actorData = { } ;
83+ } else if ( ! game . actors . has ( tokenData . actorId ) ) {
84+ tokenData . actorId = null ;
85+ tokenData . actorData = { } ;
86+ } else if ( ! tokenData . actorLink ) {
87+ const actorData = tokenData . actorData ;
88+ const actorUpdate = convertActorData ( actorData , options ) ;
89+
90+ // Handle item updates
91+ if ( actorUpdate . items ?. length ) {
92+ const updates = new Map ( actorUpdate . items . map ( ( item ) => [ item . _id , item ] ) ) ;
93+ tokenData . actorData . items ?. forEach ( ( original ) => {
94+ const update = updates . get ( original . _id ) ;
95+ if ( update ) foundry . utils . mergeObject ( original , update ) ;
96+ } ) ;
97+ delete actorUpdate . items ;
98+ }
99+ foundry . utils . mergeObject ( tokenData . actorData , actorUpdate ) ;
100+ }
101+ return isEmpty ( tokenData . actorData ) ? { } : { actorData : tokenData . actorData } ;
102+ } ;
103+
104+ /**
105+ * Converts a token's `sight` data
106+ *
107+ * @param {object } tokenData - A {@link TokenDocument} or its data object
108+ * @param {ConversionOptions } [options] - Options for conversion
109+ * @returns {{sight?: TokenSightData} } A partial update object
110+ */
111+ export const convertTokenVisionData = ( tokenData , options = { } ) => {
112+ const { target, current = UNITS . FEET } = options ;
113+ const currentUnitSystem = getUnitSystem ( current ) ;
114+ if ( target === currentUnitSystem ) return { } ;
115+ if ( game . release . generation < 10 ) {
116+ const { dimSight, brightSight } = tokenData ;
117+ const updateData = { } ;
118+ if ( dimSight ) updateData . dimSight = convertDistance ( dimSight , current ) ;
119+ if ( brightSight ) updateData . brightSight = convertDistance ( brightSight , current ) ;
120+ return updateData ;
121+ } else {
122+ const sight = tokenData . sight ;
123+ if ( ! sight ) return { } ;
124+ const { range } = sight ;
125+ if ( range ) {
126+ sight . range = convertDistance ( range , current ) ;
127+ }
128+ return { sight } ;
129+ }
130+ } ;
131+
132+ /**
133+ * Converts a light's `dim` and `bright` values
134+ *
135+ * @param {AmbientLight | object } light
136+ * @param {ConversionOptions } [options]
137+ * @returns {{dim?: number, bright?: number} } A partial update object
138+ */
139+ const convertLightData = ( light , options = { } ) => {
140+ const lightData = "toObject" in light ? light . toObject ( ) : light ;
141+ const { target, current = UNITS . FEET } = options ;
142+ const currentUnitSystem = getUnitSystem ( current ) ;
143+ if ( target === currentUnitSystem ) return { } ;
144+ const { dim, bright } = lightData . config ;
145+ if ( dim ) {
146+ lightData . config . dim = convertDistance ( dim , current ) ;
147+ }
148+ if ( bright ) {
149+ lightData . config . bright = convertDistance ( bright , current ) ;
150+ }
151+ return lightData ;
70152} ;
71153
72154export const convertScene = async ( scene , options ) => {
0 commit comments