@@ -998,18 +998,25 @@ func (dl *DrawList) add(sd *SprData) {
998998}
999999
10001000func (dl DrawList ) draw (cameraX , cameraY , cameraScl float32 ) {
1001- // Sort drawing order
1002- sort .Slice (dl , func (i , j int ) bool {
1003- // If different priority, draw lower priority first
1001+ if len (dl ) == 0 {
1002+ return
1003+ }
1004+
1005+ // Sort by descending sprpriority
1006+ sort .SliceStable (dl , func (i , j int ) bool {
10041007 if dl [i ].priority != dl [j ].priority {
1005- return dl [i ].priority < dl [j ].priority
1008+ return dl [i ].priority > dl [j ].priority
10061009 }
1007- // Else draw newer sprite first
1008- return i > j
1010+ return false
10091011 })
10101012
1011- // Draw the entire list
1012- for _ , s := range dl {
1013+ // Common variables
1014+ shake := sys .envShake .getOffset ()
1015+
1016+ // Draw the entire list in reverse
1017+ for i := len (dl ) - 1 ; i >= 0 ; i -- {
1018+ s := dl [i ]
1019+
10131020 // Skip blank SprData
10141021 // https://github.com/ikemen-engine/Ikemen-GO/issues/2433
10151022 if s .isBlank () {
@@ -1030,9 +1037,8 @@ func (dl DrawList) draw(cameraX, cameraY, cameraScl float32) {
10301037 pos = [2 ]float32 {s .pos [0 ], s .pos [1 ] + float32 (sys .gameHeight - 240 )}
10311038 cs = 1
10321039 } else {
1033- es := sys .envShake .getOffset ()
1034- pos = [2 ]float32 {(sys .cam .Offset [0 ]- es [0 ])/ cs - (cameraX - s .pos [0 ]),
1035- (sys .cam .GroundLevel ()+ (sys .cam .Offset [1 ]- es [1 ]))/ cs -
1040+ pos = [2 ]float32 {(sys .cam .Offset [0 ]- shake [0 ])/ cs - (cameraX - s .pos [0 ]),
1041+ (sys .cam .GroundLevel ()+ (sys .cam .Offset [1 ]- shake [1 ]))/ cs -
10361042 (cameraY / cs - s .pos [1 ])}
10371043 }
10381044
@@ -1082,15 +1088,6 @@ type ShadowSprite struct {
10821088 shadowRot Rotation
10831089 shadowProjection int32
10841090 shadowfLength float32
1085- reflectColor int32
1086- reflectIntensity int32
1087- reflectOffset [2 ]float32
1088- reflectWindow [4 ]float32
1089- reflectXshear float32
1090- reflectYscale float32
1091- reflectRot Rotation
1092- reflectProjection int32
1093- reflectfLength float32
10941091 fadeOffset float32
10951092}
10961093
@@ -1126,16 +1123,25 @@ func (sl *ShadowList) add(ss *ShadowSprite) {
11261123}
11271124
11281125func (sl ShadowList ) draw (x , y , scl float32 ) {
1129- // Sort drawing order
1130- sort .Slice (sl , func (i , j int ) bool {
1126+ if len (sl ) == 0 {
1127+ return
1128+ }
1129+
1130+ // Sort by descending sprpriority
1131+ sort .SliceStable (sl , func (i , j int ) bool {
11311132 if sl [i ].priority != sl [j ].priority {
1132- return sl [i ].priority < sl [j ].priority
1133+ return sl [i ].priority > sl [j ].priority
11331134 }
1134- return i > j
1135+ return false
11351136 })
11361137
1137- // Draw the entire list
1138- for _ , s := range sl {
1138+ // Common variables
1139+ shake := sys .envShake .getOffset ()
1140+
1141+ // Draw the entire list in reverse
1142+ for i := len (sl ) - 1 ; i >= 0 ; i -- {
1143+ s := sl [i ]
1144+
11391145 // Skip blank shadows
11401146 if s == nil || s .anim == nil || s .anim .isBlank () {
11411147 continue
@@ -1243,7 +1249,7 @@ func (sl ShadowList) draw(x, y, scl float32) {
12431249 }
12441250
12451251 drawwindow := & sys .scrrect
1246- es := sys . envShake . getOffset ()
1252+
12471253 // TODO: If the char has an active window sctrl, shadows should also be affected, in addition to the stage window
12481254 if sys .stage .sdw .window != [4 ]float32 {0 , 0 , 0 , 0 } || s .shadowWindow != [4 ]float32 {0 , 0 , 0 , 0 } {
12491255 var w [4 ]float32
@@ -1267,25 +1273,73 @@ func (sl ShadowList) draw(x, y, scl float32) {
12671273 w [i ] *= sys .stage .localscl
12681274 }
12691275
1270- window [0 ] = int32 (((sys .cam .Offset [0 ] - es [0 ]) - (x * scl ) + w [0 ]* scl + float32 (sys .gameWidth )/ 2 ) * sys .widthScale )
1271- window [1 ] = int32 ((sys .cam .GroundLevel () + (sys .cam .Offset [1 ] - es [1 ]) - y + w [1 ]* SignF (yscale )* scl ) * sys .heightScale )
1276+ window [0 ] = int32 (((sys .cam .Offset [0 ] - shake [0 ]) - (x * scl ) + w [0 ]* scl + float32 (sys .gameWidth )/ 2 ) * sys .widthScale )
1277+ window [1 ] = int32 ((sys .cam .GroundLevel () + (sys .cam .Offset [1 ] - shake [1 ]) - y + w [1 ]* SignF (yscale )* scl ) * sys .heightScale )
12721278 window [2 ] = int32 (scl * (w [2 ] - w [0 ]) * sys .widthScale )
12731279 window [3 ] = int32 (scl * (w [3 ] - w [1 ]) * sys .heightScale * SignF (yscale ))
12741280
12751281 drawwindow = & window
12761282 }
12771283
12781284 s .anim .ShadowDraw (drawwindow ,
1279- (sys .cam .Offset [0 ]- es [0 ])- ((x - s .pos [0 ]- offsetX )* scl ),
1280- sys .cam .GroundLevel ()+ (sys .cam .Offset [1 ]- es [1 ])- y - (s .pos [1 ]* yscale - offsetY )* scl ,
1285+ (sys .cam .Offset [0 ]- shake [0 ])- ((x - s .pos [0 ]- offsetX )* scl ),
1286+ sys .cam .GroundLevel ()+ (sys .cam .Offset [1 ]- shake [1 ])- y - (s .pos [1 ]* yscale - offsetY )* scl ,
12811287 scl * s .scl [0 ], scl * - s .scl [1 ],
12821288 yscale , xshear , rot ,
12831289 s .fx , s .oldVer , uint32 (color ), intensity , s .facing , s .airOffsetFix , projection , fLength )
12841290 }
12851291}
12861292
1287- func (sl ShadowList ) drawReflection (x , y , scl float32 ) {
1288- for _ , s := range sl {
1293+ type ReflectionSprite struct {
1294+ * SprData
1295+ reflectColor int32
1296+ reflectIntensity int32
1297+ reflectOffset [2 ]float32
1298+ reflectWindow [4 ]float32
1299+ reflectXshear float32
1300+ reflectYscale float32
1301+ reflectRot Rotation
1302+ reflectProjection int32
1303+ reflectfLength float32
1304+ fadeOffset float32
1305+ }
1306+
1307+ type ReflectionList []* ReflectionSprite
1308+
1309+ func (rl * ReflectionList ) add (rs * ReflectionSprite ) {
1310+ if sys .frameSkip || rs .SprData == nil || rs .SprData .isBlank () {
1311+ return
1312+ }
1313+
1314+ // Stage without reflections
1315+ // TODO: Maybe ModifyReflection should be able to bypass this
1316+ if sys .stage .reflection .intensity == 0 {
1317+ return
1318+ }
1319+
1320+ * rl = append (* rl , rs )
1321+ }
1322+
1323+
1324+ func (rl ReflectionList ) draw (x , y , scl float32 ) {
1325+ if len (rl ) == 0 {
1326+ return
1327+ }
1328+
1329+ // Sort by descending sprpriority
1330+ sort .SliceStable (rl , func (i , j int ) bool {
1331+ if rl [i ].priority != rl [j ].priority {
1332+ return rl [i ].priority > rl [j ].priority
1333+ }
1334+ return false
1335+ })
1336+
1337+ // Common variables
1338+ shake := sys .envShake .getOffset ()
1339+
1340+ // Draw the entire list in reverse
1341+ for i := len (rl ) - 1 ; i >= 0 ; i -- {
1342+ s := rl [i ]
12891343
12901344 // Skip blank reflections
12911345 if s == nil || s .anim == nil || s .anim .isBlank () {
@@ -1397,7 +1451,7 @@ func (sl ShadowList) drawReflection(x, y, scl float32) {
13971451 }
13981452
13991453 drawwindow := & sys .scrrect
1400- es := sys . envShake . getOffset ()
1454+
14011455 // TODO: If the char has an active window sctrl, reflections should also be affected, in addition to the stage window
14021456 if sys .stage .reflection .window != [4 ]float32 {0 , 0 , 0 , 0 } || s .reflectWindow != [4 ]float32 {0 , 0 , 0 , 0 } {
14031457 var w [4 ]float32
@@ -1421,17 +1475,17 @@ func (sl ShadowList) drawReflection(x, y, scl float32) {
14211475 w [i ] *= sys .stage .localscl
14221476 }
14231477
1424- window [0 ] = int32 (((sys .cam .Offset [0 ] - es [0 ]) - (x * scl ) + w [0 ]* scl + float32 (sys .gameWidth )/ 2 ) * sys .widthScale )
1425- window [1 ] = int32 ((sys .cam .GroundLevel () + (sys .cam .Offset [1 ] - es [1 ]) - y + w [1 ]* SignF (yscale )* scl ) * sys .heightScale )
1478+ window [0 ] = int32 (((sys .cam .Offset [0 ] - shake [0 ]) - (x * scl ) + w [0 ]* scl + float32 (sys .gameWidth )/ 2 ) * sys .widthScale )
1479+ window [1 ] = int32 ((sys .cam .GroundLevel () + (sys .cam .Offset [1 ] - shake [1 ]) - y + w [1 ]* SignF (yscale )* scl ) * sys .heightScale )
14261480 window [2 ] = int32 (scl * (w [2 ] - w [0 ]) * sys .widthScale )
14271481 window [3 ] = int32 (scl * (w [3 ] - w [1 ]) * sys .heightScale * SignF (yscale ))
14281482
14291483 drawwindow = & window
14301484 }
14311485
14321486 s .anim .Draw (drawwindow ,
1433- (sys .cam .Offset [0 ]- es [0 ])/ scl - (x - s .pos [0 ]- offsetX ),
1434- (sys .cam .GroundLevel ()+ sys .cam .Offset [1 ]- es [1 ])/ scl - y / scl - (s .pos [1 ]* yscale - offsetY ),
1487+ (sys .cam .Offset [0 ]- shake [0 ])/ scl - (x - s .pos [0 ]- offsetX ),
1488+ (sys .cam .GroundLevel ()+ sys .cam .Offset [1 ]- shake [1 ])/ scl - y / scl - (s .pos [1 ]* yscale - offsetY ),
14351489 scl , scl , s .scl [0 ], s .scl [0 ],
14361490 - s .scl [1 ]* yscale , xshear , rot , float32 (sys .gameWidth )/ 2 ,
14371491 s .fx , s .oldVer , s .facing , s .airOffsetFix , projection , fLength , color , true )
0 commit comments