@@ -1178,10 +1178,26 @@ self.onmessage = ({ data: msg }) => {
11781178 }
11791179
11801180 _getSpriteMenuItems ( ) {
1181+ const editingTarget = Scratch . vm . editingTarget ;
1182+ const myselfName = ( editingTarget && ! editingTarget . isStage )
1183+ ? editingTarget . sprite . name
1184+ : null ;
11811185 const sprites = Scratch . vm . runtime . targets
1182- . filter ( t => ! t . isStage )
1186+ . filter ( t => ! t . isStage && t . sprite . name !== myselfName )
11831187 . map ( t => t . sprite . name ) ;
1184- return sprites . length > 0 ? sprites : [ '' ] ;
1188+ const items = [ { text : 'myself' , value : '_myself_' } ] ;
1189+ for ( const name of sprites ) items . push ( { text : name , value : name } ) ;
1190+ return items ;
1191+ }
1192+
1193+ _resolveSpriteName ( raw ) {
1194+ if ( Scratch . Cast . toString ( raw ) === '_myself_' ) {
1195+ const editingTarget = Scratch . vm . editingTarget ;
1196+ if ( editingTarget && ! editingTarget . isStage ) return editingTarget . sprite . name ;
1197+ // fallback: use the current thread's target at runtime
1198+ return null ;
1199+ }
1200+ return Scratch . Cast . toString ( raw ) ;
11851201 }
11861202
11871203 _setupResizeObserver ( ) {
@@ -1314,7 +1330,7 @@ self.onmessage = ({ data: msg }) => {
13141330 }
13151331
13161332 setSpriteExcluded ( args ) {
1317- const name = Scratch . Cast . toString ( args . SPRITE ) ;
1333+ const name = this . _resolveSpriteName ( args . SPRITE ) || Scratch . Cast . toString ( args . SPRITE ) ;
13181334 const state = Scratch . Cast . toString ( args . STATE ) ;
13191335 if ( state === 'excluded' ) {
13201336 this . _excludedSprites . add ( name ) ;
@@ -1325,7 +1341,52 @@ self.onmessage = ({ data: msg }) => {
13251341 }
13261342
13271343 isSpriteExcluded ( args ) {
1328- return this . _excludedSprites . has ( Scratch . Cast . toString ( args . SPRITE ) ) ;
1344+ const name = this . _resolveSpriteName ( args . SPRITE ) ;
1345+ return this . _excludedSprites . has ( name || Scratch . Cast . toString ( args . SPRITE ) ) ;
1346+ }
1347+
1348+ spriteTouchingLight ( args , util ) {
1349+ const lightId = Scratch . Cast . toString ( args . LIGHT ) ;
1350+ const li = this . lights [ lightId ] ;
1351+ if ( ! li ) return false ;
1352+
1353+ // Resolve sprite name (handles "_myself_")
1354+ let spriteName = Scratch . Cast . toString ( args . SPRITE ) ;
1355+ if ( spriteName === '_myself_' ) {
1356+ const t = util && util . target ? util . target : Scratch . vm . editingTarget ;
1357+ spriteName = t ? t . sprite . name : null ;
1358+ }
1359+ if ( ! spriteName ) return false ;
1360+
1361+ const target = Scratch . vm . runtime . targets . find (
1362+ t => ! t . isStage && t . sprite . name === spriteName
1363+ ) ;
1364+ if ( ! target ) return false ;
1365+
1366+ const sx = target . x ;
1367+ const sy = target . y ;
1368+ const lx = li . x ;
1369+ const ly = li . y ;
1370+
1371+ if ( li . type === 'point' ) {
1372+ const dist = Math . sqrt ( ( sx - lx ) ** 2 + ( sy - ly ) ** 2 ) ;
1373+ return dist <= li . radius ;
1374+ } else if ( li . type === 'area' ) {
1375+ const hw = ( li . width || 0 ) / 2 ;
1376+ const hh = ( li . height || 0 ) / 2 ;
1377+ return sx >= lx - hw && sx <= lx + hw && sy >= ly - hh && sy <= ly + hh ;
1378+ } else if ( li . type === 'spot' ) {
1379+ const dx = sx - lx ;
1380+ const dy = sy - ly ;
1381+ const dist = Math . sqrt ( dx * dx + dy * dy ) ;
1382+ if ( dist >= li . radius ) return false ;
1383+ const angle = Math . atan2 ( dy , dx ) ;
1384+ // li.direction is Scratch degrees (0=up, clockwise), convert to math radians
1385+ const dirRad = ( 90 - li . direction ) * ( Math . PI / 180 ) ;
1386+ let delta = Math . abs ( ( ( angle - dirRad + Math . PI ) % ( 2 * Math . PI ) ) - Math . PI ) ;
1387+ return delta <= li . arc * ( Math . PI / 180 ) ;
1388+ }
1389+ return false ;
13291390 }
13301391
13311392 hexToRgb ( hex ) {
@@ -1823,6 +1884,21 @@ self.onmessage = ({ data: msg }) => {
18231884 }
18241885 }
18251886 } ,
1887+ {
1888+ opcode : 'spriteTouchingLight' ,
1889+ blockType : Scratch . BlockType . BOOLEAN ,
1890+ text : '[SPRITE] touching light [LIGHT]?' ,
1891+ arguments : {
1892+ SPRITE : {
1893+ type : Scratch . ArgumentType . STRING ,
1894+ menu : 'spriteMenu'
1895+ } ,
1896+ LIGHT : {
1897+ type : Scratch . ArgumentType . STRING ,
1898+ defaultValue : 'light1'
1899+ }
1900+ }
1901+ } ,
18261902 '---' ,
18271903 {
18281904 blockType : Scratch . BlockType . LABEL ,
0 commit comments