@@ -50,6 +50,7 @@ export default class TemplatePlacement {
5050 const activeLayer = canvas . activeLayer ;
5151 try {
5252 const results = [ ] ;
53+ const attachToToken = this . config . shapes . some ( s => s . type === "emanation" ) ;
5354 await canvas . regions . placeRegion ( {
5455 name : RegionDocument . implementation . defaultName ( { parent : canvas . scene } ) ,
5556 color : this . config . color ,
@@ -58,12 +59,11 @@ export default class TemplatePlacement {
5859 shapes : this . config . shapes . map ( s => this . #createShapeData( s ) ) ,
5960 "flags.core.MeasuredTemplate" : true
6061 } , {
61- // TODO: ` attachToToken: true` if emanation
62+ attachToToken,
6263 create : false ,
6364 preConfirm : ( { document, index } ) => {
6465 const obj = document . toObject ( ) ;
65- results . push ( { ...obj . shapes . at ( - 1 ) } ) ;
66- // TODO: Set token ID if emanation attached to token
66+ results . push ( { ...obj . shapes . at ( - 1 ) , token : obj . attachment . token } ) ;
6767 }
6868 } ) ;
6969 return results ;
@@ -87,7 +87,10 @@ export default class TemplatePlacement {
8787 switch ( type ) {
8888 case "circle" : return { ...data , radius : size } ;
8989 case "cone" : return { ...data , angle : CONFIG . MeasuredTemplate . defaults . angle , radius : size } ;
90- case "emanation" : return { base : { ...data } , radius : size } ; // TODO: Make this work properly
90+ case "emanation" : return {
91+ base : { ...data , width : 1 , height : 1 , shape : 4 , type : "token" } ,
92+ radius : size , type : "emanation"
93+ } ;
9194 case "ray" :
9295 case "line" : return { ...data , length : size , width, type : "line" } ;
9396 case "rect" :
@@ -135,18 +138,27 @@ export default class TemplatePlacement {
135138 */
136139 if ( Hooks . call ( "dnd5e.preCreateMeasuredTemplate" , activity , config ) === false ) return null ;
137140
138- const shapes = await TemplatePlacement . place ( config ) ;
139- if ( ! shapes ?. length ) return null ;
141+ const placements = await TemplatePlacement . place ( config ) ;
142+ if ( ! placements ?. length ) return null ;
140143
141- // TODO: If type=emanation and stationary=false, create multiple templates
142- // Otherwise only a single template is created with multiple shapes
144+ const combinedShapes = [ ] ;
145+ const splitShapes = [ ] ;
146+ for ( const placement of placements ) {
147+ if ( placement . token ) {
148+ const { x, y, width, height, shape } = canvas . scene . tokens . get ( placement . token ) ;
149+ Object . assign ( placement . base , { x, y, width, height, shape } ) ;
150+ }
151+ if ( ! placement . token || target . stationary ) combinedShapes . push ( placement ) ;
152+ else splitShapes . push ( [ placement ] ) ;
153+ }
143154
144155 const rollData = activity . getRollData ( ) ;
145- const regionData = [ foundry . utils . mergeObject ( {
156+ const regionData = [ combinedShapes , ... splitShapes ] . map ( shapes => shapes . length ? foundry . utils . mergeObject ( {
146157 // TODO: Should the activity name be included?
158+ // TODO: Include count if more than one created?
147159 name : `${ activity . item . name } [${ game . user . name } ]` ,
148160 color : game . user . color ,
149- shapes : shapes . map ( ( { index, ...data } ) => data ) ,
161+ shapes : shapes . map ( ( { index, token , ...data } ) => data ) ,
150162 // TODO: Set elevation based on shape's height
151163 levels : [ canvas . level . id ] ,
152164 restriction : {
@@ -155,7 +167,9 @@ export default class TemplatePlacement {
155167 // TODO: What about templates like Fireball that flow around walls?
156168 type : "move"
157169 } ,
158- // TODO: Set attachedToken if type=emanation and stationary=false and token clicked on
170+ attachment : {
171+ token : target . stationary ? undefined : shapes [ 0 ] . token
172+ } ,
159173 visibility : CONST . REGION_VISIBILITY . ALWAYS ,
160174 highlightMode : "coverage" ,
161175 flags : {
@@ -171,7 +185,7 @@ export default class TemplatePlacement {
171185 spellLevel : rollData . item . level
172186 }
173187 }
174- } , createData ) ] ;
188+ } , createData ) : null ) . filter ( _ => _ ) ;
175189
176190 /**
177191 * A hook event that fires after templates have been placed by the player but before they have been created.
0 commit comments