diff --git a/coinkiller_data/icons/render_controllers.png b/coinkiller_data/icons/render_controllers.png new file mode 100644 index 00000000..6c90cc7d Binary files /dev/null and b/coinkiller_data/icons/render_controllers.png differ diff --git a/coinkiller_data/spritedata.xml b/coinkiller_data/spritedata.xml index ed72d28c..5b1dd987 100644 --- a/coinkiller_data/spritedata.xml +++ b/coinkiller_data/spritedata.xml @@ -2,7 +2,7 @@ - + Lock All Camera Movement @@ -12,25 +12,25 @@ Unlocks Camera Movement - Move To Target Node + Repeat Camera Movement Maintain Existing Locks Lock Backwards X-Axis Movement - + + - - - + + - + - - Strongest (7 Blocks) - Strong (6 Blocks) - Weak (5 Blocks) - Weakest (4 Blocks) - Large Bubbles (4 Blocks) + + 7 Tiles + 6 Tiles + 5 Tiles + 4 Tiles + 4 Tiles (Line of Bubbles) Pipe Up @@ -40,9 +40,9 @@ - - 10 blocks - 5 blocks + + 10 Tiles + 5 Tiles @@ -86,6 +86,13 @@ + + + Fire Flower + Gold Flower Card + Gold Flower Card (No 1-Up) + Super Leaf + One Two @@ -105,11 +112,16 @@ Red Coin Ring Coins Moon Coin + ScCourse 0x0010 (Crash) + BsRoot? 0x0000 (smoke) - - Walks - Still + + + Left + Right + Towards Player + @@ -133,8 +145,9 @@ - - + + + No Movement Up - Normal Up - Fast @@ -155,12 +168,12 @@ - - + - + + No Movement Up - Normal @@ -182,12 +195,13 @@ - + - + + No Movement Up - Normal @@ -209,8 +223,14 @@ - + + + + Normal + Transparent + Very Transparent + @@ -219,7 +239,7 @@ - + @@ -231,6 +251,7 @@ Slow Medium Fast + Static Clockwise @@ -246,31 +267,27 @@ - - + + All Tiles Alternating Alternating type 2 - - Red Block - Brick Block - Coin - Stone Block - Wood Block - Same as 4? - Blue Block - Mini Mario Passageway (Right) - Up-facing Vertical Blue Pipe - Top Left - Broken Vertical Blue Pipe - Top Right - Horizontal Mini Pipe Center - Left-facing/Right-facing [which?] Horizontal Green Pipe - Bottom Left + + Red Block (ID 27) + Brick Block (ID 20) + Coin (ID 15) + Stone Block (ID 24) + Wood Block (ID 23) + Wood Block (ID 23) + Blue Block (ID 19) Destroy Create + @@ -322,6 +339,7 @@ Walk right Walk left + None On vine @@ -390,6 +408,7 @@ + Fire Flower and Star Gold Flower and Super Leaf @@ -397,21 +416,39 @@ Super Star Fire Flower and Gold Flower + + - + + Up + Down + Left + Right + + Normal Jump When Spawned Shot From Cannon Frozen - + + + + Up-Right + Up-Left + Down-Right + Down-Left + Higher Up-Right + Higher Up-Left + + @@ -474,13 +511,13 @@ - 12 Blocks Horizontal - 6 Vertical - 10 Blocks Horizontal - 8 Vertical - 18 Blocks Horizontal - 6 Vertical - 18 Blocks Horizontal - 7 Vertical (Fast) - 9 Blocks Horizontal - 7 Vertical (Fast) - 6 Blocks Horizontal - 9 Vertical - 16 Blocks Horizontal - 9 Vertical + 12 Tiles Horizontal - 6 Vertical + 10 Tiles Horizontal - 8 Vertical + 18 Tiles Horizontal - 6 Vertical + 18 Tiles Horizontal - 7 Vertical (Fast) + 9 Tiles Horizontal - 7 Vertical (Fast) + 6 Tiles Horizontal - 9 Vertical + 16 Tiles Horizontal - 9 Vertical Up (Permanent) Nothing? Up (Permanent and Fast) @@ -488,6 +525,7 @@ Static and Facing Drection Static and Facing Drection Up (Permanent) + No @@ -508,20 +546,42 @@ + + Right + Left + Up + Down + + + Right + Left + Up + Down + - + + Right + Left + Up + Down + - + + Right + Left + Up + Down + @@ -650,6 +710,11 @@ + + + Spawn + Despawn + Slowest @@ -678,12 +743,34 @@ - - + Counterclockwise Clockwise - + + Auto Start + Event Triggered (One Swing) + Event Triggered + + + + No Arc + 22.5 + 45 + 67.5 + 90 (Clockwise) + 112.5 (Clockwise) + 135 (Clockwise) + 157.5 (Clockwise) + 180 (Clockwise) + 202.5 (Clockwise) + 225 (Clockwise) + 247.5 (Clockwise) + 270 + 292.5,14 + 337.5 + + None 22.5 45 @@ -697,7 +784,8 @@ 225 247.5 270 - 292.5,14 + 292.5 + 315 337.5 @@ -767,11 +855,8 @@ Event Triggered - Rotates Back When Deactivated (Slowest) - - None - Screen Shake For Direction Change - Coin Sound - + + Slowest Slower @@ -788,7 +873,7 @@ - + Normal Smoke Effect @@ -801,7 +886,7 @@ - + Normal Moves Down Floats in Place @@ -811,13 +896,15 @@ 45 degree Down 80 degree Down + - + + Small Height / Medium Width Small Height / Small Width @@ -829,20 +916,24 @@ Down Left Right + Up-Right (Bone Lift) None Sparkes With Smoke Sparkles + + Left Right + @@ -855,8 +946,6 @@ - - @@ -869,14 +958,35 @@ + + Normal + Coin Starts Upside Down + Coin Faces Screen (Broken) + Coin Faces Controller + + - - Normal/Falling + + Normal Paracoin 1 Paracoin 2 - - + + Stationary + Falling + Falling (Medium) + Falling (Fast) + Falling (Fastest) + Gravity Affected + + + Above Layer 1 + Above Layer 2 + Further Above Layer 1 + + + + @@ -885,9 +995,27 @@ Coin Faces Screen Coin Faces Controller - + - + + Normal + Paracoin 1 (Broken) + Paracoin 2 (Broken) + + + Stationary + Falling + Falling (Medium) + Falling (Fast) + Falling (Fastest) + Gravity Affected + + + Above Layer 1 + Above Layer 2 + Further Above Layer 1 + + @@ -897,10 +1025,13 @@ Medium Slow - - No Offset - Launch delayed - Spawn launched + + Synced + Not Synced + Start Launched (Not Synced) + Delayed Start (Synced) + Delayed Start (Not Synced) + Delayed Start (Start Launched) 16 Tiles @@ -919,10 +1050,13 @@ Medium Slow - - No Offset - Launch delayed - Spawn launched + + Synced + Not Synced + Start Launched (Not Synced) + Delayed Start (Synced) + Delayed Start (Not Synced) + Delayed Start (Start Launched) 16 Tiles @@ -936,6 +1070,7 @@ + 30 degrees right 30 degrees left @@ -949,14 +1084,13 @@ - + Short Medium Long Spawn once - Goomba Bob-omb @@ -968,7 +1102,7 @@ Left Right - + @@ -986,19 +1120,19 @@ - - + + Normal - ??? - Automaticaly Fall + Wide Detection Range? [Broken] + Automatically Fall - - + + Normal - ??? + Wide Detection Range? [Broken] Automatically Fall @@ -1008,7 +1142,7 @@ Counterclockwise Clockwise - + One Bar Two Bars Three Bars @@ -1090,9 +1224,10 @@ + - + Right @@ -1104,7 +1239,7 @@ - + Target Event Enables After Delay Target Event Disables After Delay @@ -1113,8 +1248,9 @@ Activate On Triggering Event Disabled - Single Use + Single Use Only While Start Event Is Active + Only While Status is Satisfied Enables Event @@ -1123,6 +1259,12 @@ + + All Players Contribute to Requirements + Only Mario Contributes + Only Luigi Contributes + Both Players Must Contribute (Movement-only) + @@ -1134,7 +1276,7 @@ Fire Mini Super Leaf - Unknown 6 + Small Mega Mario Star @@ -1194,9 +1336,6 @@ - - - @@ -1206,6 +1345,10 @@ + + Spawn + Despawn + Slowest Slower @@ -1223,13 +1366,13 @@ - + Already Climbing Falls - + Right Swings Down Left Swings Down @@ -1243,7 +1386,7 @@ - Normal + Normal From Pipe Facing Up - 45° Right From Pipe Facing Right - 45° Up From Pipe Facing Right @@ -1259,59 +1402,59 @@ - Default (9 Blocks) - 2 Blocks - 3 Blocks - 4 Blocks - 5 Blocks - 6 Blocks - 7 Blocks - 8 Blocks - 9 Blocks - 10 Blocks - 11 Blocks - 12 Blocks - 13 Blocks - 14 Blocks - 15 Blocks - 16 Blocks + Default (9 Tiles) + 2 Tiles + 3 Tiles + 4 Tiles + 5 Tiles + 6 Tiles + 7 Tiles + 8 Tiles + 9 Tiles + 10 Tiles + 11 Tiles + 12 Tiles + 13 Tiles + 14 Tiles + 15 Tiles + 16 Tiles - Default (7 Blocks) - 2 Blocks - 3 Blocks - 4 Blocks - 5 Blocks - 6 Blocks - 7 Blocks - 8 Blocks - 9 Blocks - 10 Blocks - 11 Blocks - 12 Blocks - 13 Blocks - 14 Blocks - 15 Blocks - 16 Blocks + Default (7 Tiles) + 2 Tiles + 3 Tiles + 4 Tiles + 5 Tiles + 6 Tiles + 7 Tiles + 8 Tiles + 9 Tiles + 10 Tiles + 11 Tiles + 12 Tiles + 13 Tiles + 14 Tiles + 15 Tiles + 16 Tiles Default (Unlimited) - 2 Blocks - 3 Blocks - 4 Blocks - 5 Blocks - 6 Blocks - 7 Blocks - 8 Blocks - 9 Blocks - 10 Blocks - 11 Blocks - 12 Blocks - 13 Blocks - 14 Blocks - 15 Blocks - 16 Blocks + 2 Tiles + 3 Tiles + 4 Tiles + 5 Tiles + 6 Tiles + 7 Tiles + 8 Tiles + 9 Tiles + 10 Tiles + 11 Tiles + 12 Tiles + 13 Tiles + 14 Tiles + 15 Tiles + 16 Tiles Towards Player @@ -1336,59 +1479,59 @@ - Default (9 Blocks) - 2 Blocks - 3 Blocks - 4 Blocks - 5 Blocks - 6 Blocks - 7 Blocks - 8 Blocks - 9 Blocks - 10 Blocks - 11 Blocks - 12 Blocks - 13 Blocks - 14 Blocks - 15 Blocks - 16 Blocks + Default (9 Tiles) + 2 Tiles + 3 Tiles + 4 Tiles + 5 Tiles + 6 Tiles + 7 Tiles + 8 Tiles + 9 Tiles + 10 Tiles + 11 Tiles + 12 Tiles + 13 Tiles + 14 Tiles + 15 Tiles + 16 Tiles - Default (7 Blocks) - 2 Blocks - 3 Blocks - 4 Blocks - 5 Blocks - 6 Blocks - 7 Blocks - 8 Blocks - 9 Blocks - 10 Blocks - 11 Blocks - 12 Blocks - 13 Blocks - 14 Blocks - 15 Blocks - 16 Blocks + Default (7 Tiles) + 2 Tiles + 3 Tiles + 4 Tiles + 5 Tiles + 6 Tiles + 7 Tiles + 8 Tiles + 9 Tiles + 10 Tiles + 11 Tiles + 12 Tiles + 13 Tiles + 14 Tiles + 15 Tiles + 16 Tiles Default (Unlimited) - 2 Blocks - 3 Blocks - 4 Blocks - 5 Blocks - 6 Blocks - 7 Blocks - 8 Blocks - 9 Blocks - 10 Blocks - 11 Blocks - 12 Blocks - 13 Blocks - 14 Blocks - 15 Blocks - 16 Blocks + 2 Tiles + 3 Tiles + 4 Tiles + 5 Tiles + 6 Tiles + 7 Tiles + 8 Tiles + 9 Tiles + 10 Tiles + 11 Tiles + 12 Tiles + 13 Tiles + 14 Tiles + 15 Tiles + 16 Tiles Towards Player @@ -1408,10 +1551,11 @@ Normal Start Upside Down - Gimbal Rotation + Face The Screen + Nothing @@ -1452,7 +1596,7 @@ - + Normal Fly In From Background @@ -1465,26 +1609,38 @@ - + Fly In From Background Fly In From Right + Above Other Sprites Below Other Sprites - - + + + + Moves when Touched Already Moving Moves when Touched Already Moving - + + Forwards + Backwards + + + Falls Off + Go Back + Stops + + @@ -1516,19 +1672,19 @@ - + - + - + Unlimited 3 Rocks 5 Rocks - + @@ -1537,14 +1693,14 @@ - + Normal Upside Down Shifted Up A Tile - + - + Chase Chase & Explode @@ -1560,6 +1716,8 @@ + + @@ -1575,7 +1733,7 @@ - + Show Hide @@ -1600,7 +1758,7 @@ - + Show Hide @@ -1627,7 +1785,7 @@ - + Colored Stem Gray Stem @@ -1639,7 +1797,7 @@ - + Colored Stem @@ -1652,7 +1810,7 @@ - + @@ -1691,9 +1849,13 @@ Dry Bowser - - + + + + Left + Right + @@ -1701,9 +1863,9 @@ - + - + @@ -1713,36 +1875,68 @@ + + Above layer 1 Tiles Below Layer 1 Tiles - + Normal Spin (Death Animation) From Pipe - + Normal Blue - + Up Down Left Right + Right (facing left) + Spawn normally + Down (Falling very fast) + Up (Ascending very fast) + Up (Ascending very fast) + Down (Falling very fast) + Left (Flies across the screen) + Left (Flies across the screen) - + + Above layer 1 Tiles Below Layer 1 Tiles - + + + Normal + Spin (Death Animation) + From Pipe + + + + + Up + Down + Left + Right + Right (facing left) + Spawn normally + Down (Falling very fast) + Up (Ascending very fast) + Up (Ascending very fast) + Down (Falling very fast) + Left (Flies across the screen) + Left (Flies across the screen) + @@ -1781,7 +1975,7 @@ - + @@ -1792,7 +1986,7 @@ - + @@ -1826,9 +2020,10 @@ Faster Fastest - + + - + @@ -1836,7 +2031,7 @@ Big - + Right Left @@ -1860,30 +2055,30 @@ - + - - Up/Down - Up/Down Right (speed 0) - Up/Down Right (speed 1) - Up/Down Right (speed 2) - Up/Down Right (speed 3) - Up/Down Right (speed 4) - Up/Down Right (speed 5) - Up/Down Right (speed 6) - Up/Down Right (speed 7) - Up/Down Right (speed 8) - Up/Down Right (speed 9) - Up/Down Right (speed 10) - Up/Down Right (speed 11) - Up/Down Right (speed 12) - Up/Down Right (speed 13) - Up/Down + + Normal (Default) + Diagonal (speed 0) + Diagonal (speed 1) + Diagonal (speed 2) + Diagonal (speed 3) + Diagonal (speed 4) + Diagonal (speed 5) + Diagonal (speed 6) + Diagonal (speed 7) + Diagonal (speed 8) + Diagonal (speed 9) + Diagonal (speed 10) + Diagonal (speed 11) + Diagonal (speed 12) + Diagonal (speed 13) + Normal - - + + - + @@ -1893,6 +2088,7 @@ + @@ -1900,7 +2096,7 @@ - + Moves when Touched (Default) Already Moving Moves when Touched @@ -1909,7 +2105,7 @@ Forwards Backwards - + Falls Changes Direction Stops @@ -1918,6 +2114,7 @@ Appear While on Lift Only + Appear and Rotate Lift While on Lift Only Shown based on Start Behavior @@ -1934,9 +2131,10 @@ Left + - + @@ -1957,7 +2155,6 @@ - Camera Stays Above Camera Stays Below @@ -1968,13 +2165,12 @@ Limit in Co-op Play Unknown Value 3 - + - Camera Stays Above Camera Stays Below @@ -1985,21 +2181,31 @@ Limit in Co-op Play Unknown Value 3 - + - + - + Face Player Right Left + + Normal (Default) + Lowest + Low + Medium + Normal + High + Higher + Highest + Normal On Ceiling @@ -2027,6 +2233,7 @@ Limit Until Both Players Cross Unknown Value 3 + @@ -2042,6 +2249,7 @@ Limit Until Both Players Cross Unknown Value 3 + @@ -2080,6 +2288,7 @@ Green Red + @@ -2087,7 +2296,12 @@ Left Up Down + Right (Delayed) + Left (Delayed) + Up (Delayed) + Down (Delayed) + @@ -2139,12 +2353,13 @@ - + + - - + + @@ -2156,24 +2371,35 @@ - - + + - + + + + Towards Player + Right + Right (Facing Screen) + Fall Normally Fly Upwards Then Fall + + Right + Left + + Above layer 1 Tiles @@ -2199,11 +2425,11 @@ Green Red - + - + @@ -2227,15 +2453,15 @@ - + - - - Down - Up + + + Up + Down - + None Top @@ -2246,7 +2472,7 @@ Left/Right - + Slow Medium @@ -2257,51 +2483,54 @@ - + - + - + Stops - Goes Backwards + Repeat Movement Falls down - Stops - Goes Backwards - Falls down + Stops (Linear) + Repeat Movement (Linear) + Falls down (Linear) - + - + - + Already moving Disabled By Event Enabled By Event - + Right Left Up Down - Right - Left - Up - Down - Right - Left - Up - Down - Right - Left - Up - Down - - + Right (Above Layer 1) + Left (Above Layer 1) + Up (Above Layer 1) + Down (Above Layer 1) + Right (Delayed) + Left (Delayed) + Up (Delayed) + Down (Delayed) + Right (Delayed and Above Layer 1) + Left (Delayed and Above Layer 1) + Up (Delayed and Above Layer 1) + Down (Delayed and Above Layer 1) + + + + + None Top Bottom @@ -2310,11 +2539,16 @@ Right Left/Right - - - - - + + Normal + Unload if far from start of zone + Unload when loaded + + + + + + Slow Medium Fast @@ -2324,45 +2558,53 @@ - + - + Already moving Disabled By Event Enabled By Event - + Right Left Up Down - Right - Left - Up - Down - Right - Left - Up - Down - Right - Left - Up - Down - - + Right (Above Layer 1) + Left (Above Layer 1) + Up (Above Layer 1) + Down (Above Layer 1) + Right (Delayed) + Left (Delayed) + Up (Delayed) + Down (Delayed) + Right (Delayed and Above Layer 1) + Left (Delayed and Above Layer 1) + Up (Delayed and Above Layer 1) + Down (Delayed and Above Layer 1) + + + + + None Top Bottom - Top and Bottom + Top/Bottom Left Right - Left and Right + Left/Right - - - - - + + Normal + Unload if far from start of zone + Unload when loaded + + + + + + Slow Medium Fast @@ -2372,45 +2614,53 @@ - + - + Already moving Disabled By Event Enabled By Event - + Right Left Up Down - Right - Left - Up - Down - Right - Left - Up - Down - Right - Left - Up - Down - - + Right (Above Layer 1) + Left (Above Layer 1) + Up (Above Layer 1) + Down (Above Layer 1) + Right (Delayed) + Left (Delayed) + Up (Delayed) + Down (Delayed) + Right (Delayed and Above Layer 1) + Left (Delayed and Above Layer 1) + Up (Delayed and Above Layer 1) + Down (Delayed and Above Layer 1) + + + + + None Top Bottom - Top and Bottom + Top/Bottom Left Right - Left and Right + Left/Right - - - - - + + Normal + Unload if far from start of zone + Unload when loaded + + + + + + Slow Medium Fast @@ -2420,87 +2670,109 @@ - + - + Already moving Disabled By Event Enabled By Event - + Right Left Up Down - Right - Left - Up - Down - Right - Left - Up - Down - Right - Left - Up - Down - - + Right (Above Layer 1) + Left (Above Layer 1) + Up (Above Layer 1) + Down (Above Layer 1) + Right (Delayed) + Left (Delayed) + Up (Delayed) + Down (Delayed) + Right (Delayed and Above Layer 1) + Left (Delayed and Above Layer 1) + Up (Delayed and Above Layer 1) + Down (Delayed and Above Layer 1) + + + + + None Top Bottom - Top and Bottom + Top/Bottom Left Right - Left and Right + Left/Right + + + Normal + Unload if far from start of zone + Unload when loaded + + + + + + + Slow + Medium + Fast + Very Fast + Fastest (Glitchy) - - - - - - + - + Already moving Disabled By Event Enabled By Event - + Right Left Up Down - Right - Left - Up - Down - Right - Left - Up - Down - Right - Left - Up - Down - - + Right (Above Layer 1) + Left (Above Layer 1) + Up (Above Layer 1) + Down (Above Layer 1) + Right (Delayed) + Left (Delayed) + Up (Delayed) + Down (Delayed) + Right (Delayed and Above Layer 1) + Left (Delayed and Above Layer 1) + Up (Delayed and Above Layer 1) + Down (Delayed and Above Layer 1) + + + + + None Top Bottom - Top and Bottom + Top/Bottom Left Right - Left and Right + Left/Right - - - - - + + Normal + Unload if far from start of zone + Unload when loaded + + + + + + Slow Medium Fast @@ -2565,9 +2837,12 @@ Towards Player Away From Player - - - + + + One + Two + + Always Spawn If Gold Ring Isn't Active If Gold Ring Is Active @@ -2581,14 +2856,23 @@ - - - - + + One + Two + Three + + + + + Normal + Slower + Faster + All At Once + - + @@ -2596,9 +2880,22 @@ Blue Coin + Slowest + 4 + 3 + 9 Slow + 6 + 7 + 8 Medium Fast + Static + Static + Static + Same as 9 + Same as 9 + Same as 9 Clockwise @@ -2620,31 +2917,39 @@ Right + + Left + Right + Ignores Patrol Range + - - - - + + + + - - + + Camera Stays Above Camera Stays Below - - - + + Left + Right + + Normal Start Upside Down - Gimbal Rotation + Face The Screen + Nothing Coin @@ -2683,17 +2988,17 @@ Fire Flower Gold Flower Card - Gold Flower + Gold Flower Card Always Super Leaf - + - + - + Left @@ -2706,7 +3011,7 @@ Fast Super Fast - + Normal Stationary Pass Through Walls @@ -2714,7 +3019,7 @@ - + Left @@ -2727,7 +3032,7 @@ Fast Super Fast - + Normal Stationary Pass Through Walls @@ -2798,8 +3103,8 @@ - - + + 3 4 @@ -2819,7 +3124,7 @@ - + @@ -2845,12 +3150,13 @@ Right Left + - + Normal Faster @@ -2880,14 +3186,18 @@ Stops Jumps Right Falls Down - Changes Direction - Warps to First Node + Falls (All at once) 4 + Warp to First Node + + + Once Stepped On + Already Moving + Once Stepped On (All Players) - - + Normal @@ -2918,14 +3228,19 @@ Stops Jumps Right Falls Down - Changes Direction + Falls (All at once) 4 Warp to First Node - + + Once Stepped On + Already Moving + Once Stepped On (All Players) + + @@ -2950,6 +3265,7 @@ + One @@ -2968,7 +3284,16 @@ - + + 0 Frames + 20 Frames + 40 Frames + 60 Frames + 80 Frames + 100 Frames + 120 Frames + 140 Frames + @@ -2987,7 +3312,16 @@ - + + 0 Frames + 20 Frames + 40 Frames + 60 Frames + 80 Frames + 100 Frames + 120 Frames + 140 Frames + Activates Event @@ -3005,7 +3339,16 @@ - + + 0 Frames + 20 Frames + 40 Frames + 60 Frames + 80 Frames + 100 Frames + 120 Frames + 140 Frames + @@ -3024,7 +3367,16 @@ - + + 0 Frames + 20 Frames + 40 Frames + 60 Frames + 80 Frames + 100 Frames + 120 Frames + 140 Frames + Activates Event @@ -3084,7 +3436,7 @@ - + @@ -3134,8 +3486,11 @@ Already Falling - - + + + + + Left Right @@ -3148,9 +3503,9 @@ Fast Super Fast - + - + Normal Stationary Pass Through Walls @@ -3158,7 +3513,8 @@ - + + Left Right @@ -3171,9 +3527,9 @@ Fast Super Fast - + - + Normal Stationary Pass Through Walls @@ -3181,8 +3537,9 @@ - - + + + Left Right @@ -3198,7 +3555,7 @@ - + Normal Stationary Pass Through Walls @@ -3229,7 +3586,7 @@ Normal Only Spawn When Above Snakeblock - + Normal Stationary Pass Through Walls @@ -3261,7 +3618,7 @@ Normal Only Spawn When Above Snakeblock - + Normal Stationary Pass Through Walls @@ -3270,7 +3627,7 @@ - + @@ -3320,7 +3677,7 @@ - + Appear After Stopping Always Visible @@ -3330,8 +3687,7 @@ Right Side With Offset Left Side - - + @@ -3353,6 +3709,12 @@ Down + + Normal + Keeps Moving + Doesn't Go Back + + Slow @@ -3362,25 +3724,28 @@ Fastest (Glitchy) - - - Above layer 1 Tiles + + + Above Layer 1 Tiles Below Layer 1 Tiles + - - - Above layer 1 Tiles + + + Above Layer 1 Tiles Below Layer 1 Tiles + - + + Super Mushroom Super Mushroom @@ -3417,6 +3782,7 @@ From Pipe Thrown + @@ -3437,8 +3803,15 @@ - - + + + + + + Up + Down + + @@ -3448,30 +3821,34 @@ Right - + Normal Flame No Flame - Purple Flame (Broken) - Blue Flame (Broken) + Purple Flame + Purple Flame (Broken) - + - - + + + One Two - - + + + Start Height + Sway Down Distance + Start Height + Head Long Middle Piece @@ -3491,6 +3868,7 @@ Gimbal Rotation + Stone Rotation Pivot @@ -3525,53 +3903,74 @@ Mushroom/Coin - + - + Already moving Disabled By Event Enabled By Event - + Right Left Up Down - Right - Left - Up - Down - Right - Left - Up - Down - Right - Left - Up - Down - - - - - + Right (Above Layer 1) + Left (Above Layer 1) + Up (Above Layer 1) + Down (Above Layer 1) + Right (Delayed) + Left (Delayed) + Up (Delayed) + Down (Delayed) + Right (Delayed and Above Layer 1) + Left (Delayed and Above Layer 1) + Up (Delayed and Above Layer 1) + Down (Delayed and Above Layer 1) + + + + + + None + Top + Bottom + Top/Bottom + Left + Right + Left/Right + + + Normal + Unload if far from start of zone + Unload when loaded + + + + + + Slow Medium Fast Very Fast Fastest (Glitchy) - - + + Normal Tall and Skinny - - + + - + + + + Left Right @@ -3584,9 +3983,9 @@ Fast Super Fast - + - + Normal Stationary Pass Through Walls @@ -3594,7 +3993,8 @@ - + + Left Right @@ -3607,9 +4007,9 @@ Fast Super Fast - + - + Normal Stationary Pass Through Walls @@ -3628,12 +4028,12 @@ - + One Two - + Flies Away Flies side to side Flies in place @@ -3688,7 +4088,12 @@ - + + + Towards Player + Left + Right + @@ -3697,35 +4102,38 @@ 10 Mario Seconds (Blue) - + - + - + Already moving Disabled By Event Enabled By Event - + Right Left Up Down - Right - Left - Up - Down - Right - Left - Up - Down - Right - Left - Up - Down - - + Right (Above Layer 1) + Left (Above Layer 1) + Up (Above Layer 1) + Down (Above Layer 1) + Right (Delayed) + Left (Delayed) + Up (Delayed) + Down (Delayed) + Right (Delayed and Above Layer 1) + Left (Delayed and Above Layer 1) + Up (Delayed and Above Layer 1) + Down (Delayed and Above Layer 1) + + + + + None Top Bottom @@ -3734,10 +4142,16 @@ Right Left/Right - - - - + + Normal + Unload if far from start of zone + Unload when loaded + + + + + + Slow Medium Fast @@ -3747,42 +4161,51 @@ - + - - Already moving + + Already Moving Disabled By Event + Enabled By Event - + Right Left Up Down - Right - Left - Up - Down - Right - Left - Up - Down - Right - Left - Up - Down + Right (Above Layer 1) + Left (Above Layer 1) + Up (Above Layer 1) + Down (Above Layer 1) + Right (Delayed) + Left (Delayed) + Up (Delayed) + Down (Delayed) + Right (Delayed and Above Layer 1) + Left (Delayed and Above Layer 1) + Up (Delayed and Above Layer 1) + Down (Delayed and Above Layer 1) + + + + + Normal + Unload if far from start of zone + Unload when loaded + - - + + Slow Medium Fast Very Fast Fastest (Glitchy) - - + + @@ -3795,31 +4218,51 @@ - + - - - - + + + + + Already Moving + Move when Touched + Move when Touched (All Players) + + + Forwards + Backwards + + Falls Off Go Back - Stop + Stops + - - - - - Fall Off + + + + + Already Moving + Move when Touched + Move when Touched (All Players) + + + Forwards + Backwards + + + Falls Off Go Back - Stop + Stops + @@ -3827,16 +4270,20 @@ - + - + + Already Moving + Move when Touched + Move when Touched (All Players) + - + No Switching Fall When Hit Start on Bottom @@ -3860,7 +4307,7 @@ - + @@ -3868,11 +4315,15 @@ Not Visible - - + + + Random + Pattern + + One Two @@ -3895,6 +4346,7 @@ + One @@ -3912,10 +4364,10 @@ - + - - + + One Platform Two Platforms @@ -3923,7 +4375,7 @@ - + @@ -3938,81 +4390,133 @@ Blue Flame (Broken) - - - - Does Nothing + + + + Already Moving + Disabled By Event Enabled By Event - + Right Left Up Down - Right - Left - Up - Down - Right - Left - Up - Down - Right - Left - Up - Down - - - + Right (Above Layer 1) + Left (Above Layer 1) + Up (Above Layer 1) + Down (Above Layer 1) + Right (Delayed) + Left (Delayed) + Up (Delayed) + Down (Delayed) + Right (Delayed and Above Layer 1) + Left (Delayed and Above Layer 1) + Up (Delayed and Above Layer 1) + Down (Delayed and Above Layer 1) + + + + + + None + Top + Bottom + Top/Bottom + Left + Right + Left/Right + + + Normal + Unload if far from start of zone + Unload when loaded + + + + + + Slow Medium Fast Very Fast Fastest (Glitchy) - - + + - - - - Does Nothing + + + + Already moving + Disabled By Event Enabled By Event - + Right Left Up Down - Right - Left - Up - Down - Right - Left - Up - Down - Right - Left - Up - Down - - - + Right (Above Layer 1) + Left (Above Layer 1) + Up (Above Layer 1) + Down (Above Layer 1) + Right (Delayed) + Left (Delayed) + Up (Delayed) + Down (Delayed) + Right (Delayed and Above Layer 1) + Left (Delayed and Above Layer 1) + Up (Delayed and Above Layer 1) + Down (Delayed and Above Layer 1) + + + + + + None + Top + Bottom + Top/Bottom + Left + Right + Left/Right + + + Normal + Unload if far from start of zone + Unload when loaded + + + + + + Slow Medium Fast Very Fast Fastest (Glitchy) - - + + - + - - + + + Normal / Slow + Lower / Medium + Lowest / Fast + No Delay / Slower + + + Small + Medium + Long + @@ -4022,52 +4526,73 @@ Left Right - - + + 10 100 - - - - Does Nothing + + + + Already moving + Disabled By Event Enabled By Event - + Right Left Up Down - Right - Left - Up - Down - Right - Left - Up - Down - Right - Left - Up - Down - - - + Right (Above Layer 1) + Left (Above Layer 1) + Up (Above Layer 1) + Down (Above Layer 1) + Right (Delayed) + Left (Delayed) + Up (Delayed) + Down (Delayed) + Right (Delayed and Above Layer 1) + Left (Delayed and Above Layer 1) + Up (Delayed and Above Layer 1) + Down (Delayed and Above Layer 1) + + + + + + None + Top + Bottom + Top/Bottom + Left + Right + Left/Right + + + Normal + Unload if far from start of zone + Unload when loaded + + + + + + Slow Medium Fast Very Fast Fastest (Glitchy) - - 2 Tiles - 4 Tiles + + 2x11 Tiles + 4x9 Tiles - + @@ -4080,42 +4605,63 @@ - - - - Does Nothing + + + + Already moving + Disabled By Event Enabled By Event - + Right Left Up Down - Right - Left - Up - Down - Right - Left - Up - Down - Right - Left - Up - Down - - - + Right (Above Layer 1) + Left (Above Layer 1) + Up (Above Layer 1) + Down (Above Layer 1) + Right (Delayed) + Left (Delayed) + Up (Delayed) + Down (Delayed) + Right (Delayed and Above Layer 1) + Left (Delayed and Above Layer 1) + Up (Delayed and Above Layer 1) + Down (Delayed and Above Layer 1) + + + + + + None + Top + Bottom + Top/Bottom + Left + Right + Left/Right + + + Normal + Unload if far from start of zone + Unload when loaded + + + + + + Slow Medium Fast Very Fast Fastest(Glitchy) - - 3 Blocks Tall - 2 Blocks Tall - 4 Blocks Tall + + 2 Tiles + 3 Tiles + 4 Tiles @@ -4123,7 +4669,7 @@ - + Moves when Touched (Default) Already Moving Moves when Touched @@ -4132,14 +4678,17 @@ Forwards Backwards - + Falls Changes Direction Stops Disappears - + + Always + When On Lift Only + @@ -4166,8 +4715,12 @@ - + + + Spawn + Despawn + Slowest Slower @@ -4182,6 +4735,8 @@ - + + + diff --git a/coinkiller_data/sprites/big_icy_spiked_ball.png b/coinkiller_data/sprites/big_icy_spiked_ball.png new file mode 100644 index 00000000..9c919ff5 Binary files /dev/null and b/coinkiller_data/sprites/big_icy_spiked_ball.png differ diff --git a/coinkiller_data/sprites/bowser_flame.png b/coinkiller_data/sprites/bowser_flame.png index 29f9d30e..e624efac 100644 Binary files a/coinkiller_data/sprites/bowser_flame.png and b/coinkiller_data/sprites/bowser_flame.png differ diff --git a/coinkiller_data/sprites/dry_bowser_flame.png b/coinkiller_data/sprites/bowser_flame_blue.png similarity index 100% rename from coinkiller_data/sprites/dry_bowser_flame.png rename to coinkiller_data/sprites/bowser_flame_blue.png diff --git a/coinkiller_data/sprites/bowser_flame_purple.png b/coinkiller_data/sprites/bowser_flame_purple.png new file mode 100644 index 00000000..f16dd870 Binary files /dev/null and b/coinkiller_data/sprites/bowser_flame_purple.png differ diff --git a/coinkiller_data/sprites/bowser_lift/l.png b/coinkiller_data/sprites/bowser_lift/l.png new file mode 100644 index 00000000..28bae9df Binary files /dev/null and b/coinkiller_data/sprites/bowser_lift/l.png differ diff --git a/coinkiller_data/sprites/bowser_lift/m.png b/coinkiller_data/sprites/bowser_lift/m.png new file mode 100644 index 00000000..9d1528f5 Binary files /dev/null and b/coinkiller_data/sprites/bowser_lift/m.png differ diff --git a/coinkiller_data/sprites/bowser_lift/s.png b/coinkiller_data/sprites/bowser_lift/s.png new file mode 100644 index 00000000..0bf2dcb9 Binary files /dev/null and b/coinkiller_data/sprites/bowser_lift/s.png differ diff --git a/coinkiller_data/sprites/fire_snake_hidden.png b/coinkiller_data/sprites/fire_snake_hidden.png new file mode 100644 index 00000000..b11ba709 Binary files /dev/null and b/coinkiller_data/sprites/fire_snake_hidden.png differ diff --git a/coinkiller_data/sprites/lava_top.png b/coinkiller_data/sprites/lava_top.png index 72fc437a..8faa7b33 100644 Binary files a/coinkiller_data/sprites/lava_top.png and b/coinkiller_data/sprites/lava_top.png differ diff --git a/coinkiller_data/sprites/poison_top.png b/coinkiller_data/sprites/poison_top.png index 3ba5d9bd..038690c2 100644 Binary files a/coinkiller_data/sprites/poison_top.png and b/coinkiller_data/sprites/poison_top.png differ diff --git a/coinkiller_data/sprites/totem_lift/l.png b/coinkiller_data/sprites/totem_lift/l.png new file mode 100644 index 00000000..e33ad98b Binary files /dev/null and b/coinkiller_data/sprites/totem_lift/l.png differ diff --git a/coinkiller_data/sprites/totem_lift/m.png b/coinkiller_data/sprites/totem_lift/m.png new file mode 100644 index 00000000..fa20b9de Binary files /dev/null and b/coinkiller_data/sprites/totem_lift/m.png differ diff --git a/coinkiller_data/sprites/totem_lift/r.png b/coinkiller_data/sprites/totem_lift/r.png new file mode 100644 index 00000000..3ea3dd5b Binary files /dev/null and b/coinkiller_data/sprites/totem_lift/r.png differ diff --git a/coinkiller_data/sprites/whomp_big_walk.png b/coinkiller_data/sprites/whomp_big_walk.png new file mode 100644 index 00000000..0de927f1 Binary files /dev/null and b/coinkiller_data/sprites/whomp_big_walk.png differ diff --git a/coinkiller_data/sprites/whomp_walk.png b/coinkiller_data/sprites/whomp_walk.png new file mode 100644 index 00000000..5b32233d Binary files /dev/null and b/coinkiller_data/sprites/whomp_walk.png differ diff --git a/leveleditor/leveleditorwindow.cpp b/leveleditor/leveleditorwindow.cpp index 29e77e77..849d1270 100644 --- a/leveleditor/leveleditorwindow.cpp +++ b/leveleditor/leveleditorwindow.cpp @@ -75,6 +75,7 @@ LevelEditorWindow::LevelEditorWindow(LevelManager* lvlMgr, int initialArea) : ui->actionGrid->setIcon(QIcon(basePath + "grid.png")); ui->actionCheckerboard->setIcon(QIcon(basePath + "checkerboard.png")); ui->actionRenderLiquids->setIcon(QIcon(basePath + "render_liquids.png")); + ui->actionRenderControllers->setIcon(QIcon(basePath + "render_controllers.png")); ui->actionRenderCameraLimits->setIcon(QIcon(basePath + "render_camera_limits.png")); ui->actionAddArea->setIcon(QIcon(basePath + "add.png")); ui->actionDeleteCurrentArea->setIcon(QIcon(basePath + "remove.png")); @@ -166,6 +167,7 @@ LevelEditorWindow::LevelEditorWindow(LevelManager* lvlMgr, int initialArea) : ui->actionGrid->setChecked(settings->get("grid", false).toBool()); ui->actionCheckerboard->setChecked(settings->get("checkerboard", false).toBool()); ui->actionRenderLiquids->setChecked(settings->get("renderLiquids", true).toBool()); + ui->actionRenderControllers->setChecked(settings->get("renderControllers", true).toBool()); ui->actionRenderCameraLimits->setChecked(settings->get("renderCameraLimits", true).toBool()); loadSettings(); @@ -485,6 +487,12 @@ void LevelEditorWindow::on_actionRenderLiquids_toggled(bool toggle) settings->set("renderLiquids", toggle); } +void LevelEditorWindow::on_actionRenderControllers_toggled(bool toggle) +{ + levelView->toggleRenderControllers(toggle); + settings->set("renderControllers", toggle); +} + void LevelEditorWindow::on_actionRenderCameraLimits_toggled(bool toggle) { levelView->toggleRenderCameraLimits(toggle); @@ -743,6 +751,7 @@ void LevelEditorWindow::loadArea(int id, bool closeLevel, bool init) levelView->toggleGrid(ui->actionGrid->isChecked()); levelView->toggleCheckerboard(ui->actionCheckerboard->isChecked()); levelView->toggleRenderLiquids(ui->actionRenderLiquids->isChecked()); + levelView->toggleRenderControllers(ui->actionRenderControllers->isChecked()); levelView->toggleRenderCameraLimits(ui->actionRenderCameraLimits->isChecked()); #ifdef USE_KDE_BLUR diff --git a/leveleditor/leveleditorwindow.h b/leveleditor/leveleditorwindow.h index 6c0da87e..24d81ace 100644 --- a/leveleditor/leveleditorwindow.h +++ b/leveleditor/leveleditorwindow.h @@ -98,6 +98,8 @@ private slots: void on_actionRenderLiquids_toggled(bool arg1); + void on_actionRenderControllers_toggled(bool arg1); + void on_actionRenderCameraLimits_toggled(bool arg1); void on_actionPaste_triggered(); diff --git a/leveleditor/leveleditorwindow.ui b/leveleditor/leveleditorwindow.ui index 5728d5f4..8febba71 100644 --- a/leveleditor/leveleditorwindow.ui +++ b/leveleditor/leveleditorwindow.ui @@ -6,8 +6,8 @@ 0 0 - 1280 - 700 + 1237 + 529 @@ -46,8 +46,8 @@ 0 0 - 1278 - 624 + 1235 + 448 @@ -60,8 +60,8 @@ 0 0 - 1280 - 21 + 1237 + 23 @@ -161,6 +161,7 @@ + @@ -561,6 +562,20 @@ Ctrl+Shift+A + + + true + + + Render Controller Indicators + + + Render Controller Indicators + + + QAction::TextHeuristicRole + + diff --git a/leveleditor/levelview.cpp b/leveleditor/levelview.cpp index 23f1bc07..dbe50cf5 100644 --- a/leveleditor/levelview.cpp +++ b/leveleditor/levelview.cpp @@ -15,13 +15,15 @@ with CoinKiller. If not, see http://www.gnu.org/licenses/. */ +#include "is.h" #include "leveleditorwindow.h" #include "levelview.h" #include "unitsconvert.h" #include "objectrenderer.h" -#include "is.h" +#include "settingsmanager.h" #include +#include #include #include #include @@ -29,8 +31,8 @@ #include #include #include -#include #include +#include LevelView::LevelView(QWidget *parent, Level *level, QUndoStack *undoStack) : @@ -44,8 +46,9 @@ LevelView::LevelView(QWidget *parent, Level *level, QUndoStack *undoStack) : zoom = 1; grid = false; checkerboard = false; - renderLiquids = false; - renderCameraLimits = false; + renderLiquids = true; + renderControllers = true; + renderCameraLimits = true; render2DTile = true; render3DOverlay = true; @@ -135,6 +138,32 @@ void LevelView::paint(QPainter& painter, QRect rect, float zoomLvl, bool selecti painter.setOpacity(1); } + // Render Translucent Liquid Indicators (if set to appear under tiles) + if (renderLiquids && editManager->spriteInteractionEnabled() && !SettingsManager::getInstance()->getLERenderTransparentLiquidAboveTiles()) + { + for (int i = 0; i < level->zones.size(); i++) + { + const Zone* zone = level->zones.at(i); + + QRect zonerect(zone->getx(), zone->gety(), zone->getwidth(), zone->getheight()); + + if (!drawrect.intersects(zonerect)) + continue; + + foreach (Sprite* s, level->sprites) + { + if (s->getid() != 12 && s->getid() != 13 && s->getid() != 15) + continue; + + if (zonerect.contains(s->getx(), s->gety(), false)) + { + LiquidRenderer liquidRend(s, zone); + liquidRend.renderTranslucent(&painter, &drawrect); + } + } + } + } + // Render Tiles for (int l = 1; l >= 0; l--) { @@ -172,6 +201,7 @@ void LevelView::paint(QPainter& painter, QRect rect, float zoomLvl, bool selecti // Render Locations if (editManager->locationInteractionEnabled()) { + painter.save(); for (int i = 0; i < level->locations.size(); i++) { const Location* loc = level->locations.at(i); @@ -191,8 +221,10 @@ void LevelView::paint(QPainter& painter, QRect rect, float zoomLvl, bool selecti painter.setPen(QColor(255,255,255)); painter.drawText(locrect.adjusted(5,5,0,0), locText); } + painter.restore(); } + // Render anything that falls under "sprites" if (editManager->spriteInteractionEnabled()) { // Render Liquids @@ -215,6 +247,8 @@ void LevelView::paint(QPainter& painter, QRect rect, float zoomLvl, bool selecti if (zonerect.contains(s->getx(), s->gety(), false)) { LiquidRenderer liquidRend(s, zone); + if (SettingsManager::getInstance()->getLERenderTransparentLiquidAboveTiles()) + liquidRend.renderTranslucent(&painter, &drawrect); liquidRend.render(&painter, &drawrect); } } @@ -319,6 +353,71 @@ void LevelView::paint(QPainter& painter, QRect rect, float zoomLvl, bool selecti } } + // Render Movement Controller - Back & Forth Indicators + static const QSet supportsMovBackForth{28, 60, 101, 204, 293}; + for (int i = 0; renderControllers && i < level->zones.size(); i++) + { + const Zone* zone = level->zones.at(i); + QRect zonerect(zone->getx() - 80, zone->gety() - 80, zone->getwidth() + 160, zone->getheight() + 160); + + if (!drawrect.intersects(zonerect)) + continue; + + foreach (Sprite* s, level->sprites) + { + if (!zonerect.contains(s->getx(), s->gety(), false)) + continue; + + if (!supportsMovBackForth.contains(s->getid())) + continue; + + int distance; + int direction = -1; + + // Find the correct associated Back & Forth movement controller & note its data + foreach (Sprite* m, level->sprites) + { + if (!zonerect.contains(m->getx(), m->gety(), false)) + continue; + + if (m->getid() != 166 || m->getNybbleData(20, 21) != s->getNybbleData(20, 21)) + continue; + + distance = m->getNybble(14) * 20; + direction = m->getNybble(7) % 4; + break; + } + + if (direction == -1 || distance == 0) + continue; + + // Render a movement indicator for the sprite + QColor color = QColor(244, 250, 255); + int x = s->getx() + s->getOffsetX(); + int y = s->gety() + s->getOffsetY(); + + MovIndicatorRenderer *indicator; + switch (direction) + { + case 0: // Right + indicator = new MovIndicatorRenderer(x + s->getwidth(), y + s->getheight()/2, x + s->getwidth() + distance, y + s->getheight()/2, 2, 6, false, false, color); + break; + case 1: // Left + indicator = new MovIndicatorRenderer(x, y + s->getheight()/2, x - distance, y + s->getheight()/2, 2, 6, false, false, color); + break; + case 2: // Up + indicator = new MovIndicatorRenderer(x + s->getwidth()/2, y, x + s->getwidth()/2, y - distance, 2, 6, false, true, color); + break; + default: // Down + indicator = new MovIndicatorRenderer(x + s->getwidth()/2, y + s->getheight(), x + s->getwidth()/2, y + s->getheight() + distance, 2, 6, false, true, color); + break; + } + + indicator->render(&painter); + delete indicator; + } + } + // Render Sprites for (int i = 0; i < level->sprites.size(); i++) { @@ -575,7 +674,7 @@ void LevelView::paint(QPainter& painter, QRect rect, float zoomLvl, bool selecti painter.drawText(zonerect.adjusted(adjustX,adjustY,100,20), zoneText); } - // Render Edition Mode Stuff + // Render Stuff if (selections) editManager->render(&painter); diff --git a/leveleditor/levelview.h b/leveleditor/levelview.h index 983e822d..19cf3549 100644 --- a/leveleditor/levelview.h +++ b/leveleditor/levelview.h @@ -39,6 +39,7 @@ class LevelView : public QWidget void toggleGrid(bool toggle) { grid = toggle; update(); } void toggleCheckerboard(bool toggle) { checkerboard = toggle; update(); } void toggleRenderLiquids(bool toggle) { renderLiquids = toggle; update(); } + void toggleRenderControllers(bool toggle) { renderControllers = toggle; update(); } void toggleRenderCameraLimits(bool toggle) { renderCameraLimits = toggle; update(); } void toggle3DOverlay(bool toggle) { render3DOverlay = toggle; update(); } void toggle2DTile(bool toggle) { render2DTile = toggle; update(); } @@ -96,6 +97,7 @@ public slots: bool grid; bool checkerboard; bool renderLiquids; + bool renderControllers; bool renderCameraLimits; bool render2DTile; bool render3DOverlay; diff --git a/leveleditor/settingsdialog.cpp b/leveleditor/settingsdialog.cpp index 90d41399..57525121 100644 --- a/leveleditor/settingsdialog.cpp +++ b/leveleditor/settingsdialog.cpp @@ -12,6 +12,7 @@ SettingsDialog::SettingsDialog(QWidget *parent) : connect(ui->backgroundColorPickerButton, &QPushButton::clicked, this, &SettingsDialog::changeBackgroundColor); connect(ui->undoLimitSpinBox, &QSpinBox::valueChanged, this, &SettingsDialog::changeUndoLimit); + connect(ui->renderTransparentLiquidAboveTilesComboBox, &QComboBox::currentIndexChanged, this, &SettingsDialog::changeRenderTransparentLiquidAboveTiles); connect(ui->selectOnPlacedCheckBox, &QCheckBox::clicked, this, &SettingsDialog::changeSelectOnPlaced); connect(ui->showStatusBarCheckBox, &QCheckBox::clicked, this, &SettingsDialog::changeShowStatusbar); connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &SettingsDialog::handleButtonClicked); @@ -28,6 +29,9 @@ void SettingsDialog::loadSettings() { undoLimit = SettingsManager::getInstance()->getLEUndoLimit(); ui->undoLimitSpinBox->setValue(static_cast(undoLimit)); + renderTransparentLiquidAboveTiles = SettingsManager::getInstance()->getLERenderTransparentLiquidAboveTiles(); + ui->renderTransparentLiquidAboveTilesComboBox->setCurrentIndex(renderTransparentLiquidAboveTiles); + selectOnPlaced = SettingsManager::getInstance()->getLESelectOnPlace(); ui->selectOnPlacedCheckBox->setChecked(selectOnPlaced); @@ -42,6 +46,9 @@ void SettingsDialog::restoreDefaults() { undoLimit = SettingsManager::LE_UNDO_LIMIT_DEFAULT; ui->undoLimitSpinBox->setValue(static_cast(undoLimit)); + renderTransparentLiquidAboveTiles = SettingsManager::LE_RENDER_TRANSPARENT_LIQUID_ABOVE_TILES_DEFAULT; + ui->renderTransparentLiquidAboveTilesComboBox->setCurrentIndex(renderTransparentLiquidAboveTiles); + selectOnPlaced = SettingsManager::LE_SELECT_ON_PLACE_DEFAULT; ui->selectOnPlacedCheckBox->setChecked(selectOnPlaced); @@ -52,6 +59,7 @@ void SettingsDialog::restoreDefaults() { void SettingsDialog::applyChanges() { SettingsManager::getInstance()->setLEWindowColor(backgroundColor); SettingsManager::getInstance()->setLEUndoLimit(undoLimit); + SettingsManager::getInstance()->setLERenderTransparentLiquidAboveTiles(renderTransparentLiquidAboveTiles); SettingsManager::getInstance()->setLESelectOnPlace(selectOnPlaced); SettingsManager::getInstance()->setLEShowStatusbar(showStatusbar); @@ -92,6 +100,10 @@ void SettingsDialog::changeUndoLimit() { undoLimit = ui->undoLimitSpinBox->value(); } +void SettingsDialog::changeRenderTransparentLiquidAboveTiles() { + renderTransparentLiquidAboveTiles = ui->renderTransparentLiquidAboveTilesComboBox->currentIndex(); +} + void SettingsDialog::changeSelectOnPlaced() { selectOnPlaced = ui->selectOnPlacedCheckBox->isChecked(); } diff --git a/leveleditor/settingsdialog.h b/leveleditor/settingsdialog.h index 6d87ce1e..d67d9bb4 100644 --- a/leveleditor/settingsdialog.h +++ b/leveleditor/settingsdialog.h @@ -21,6 +21,7 @@ class SettingsDialog : public QDialog { private slots: void changeBackgroundColor(); void changeUndoLimit(); + void changeRenderTransparentLiquidAboveTiles(); void changeSelectOnPlaced(); void changeShowStatusbar(); void handleButtonClicked(QAbstractButton *button); @@ -36,6 +37,7 @@ private slots: QColor backgroundColor; quint32 undoLimit; + bool renderTransparentLiquidAboveTiles; bool selectOnPlaced; bool showStatusbar; }; diff --git a/leveleditor/settingsdialog.ui b/leveleditor/settingsdialog.ui index c2a89c2f..aacb77f2 100644 --- a/leveleditor/settingsdialog.ui +++ b/leveleditor/settingsdialog.ui @@ -98,10 +98,57 @@ background-color: rgb(119, 136, 153); + + + + + + + + + Liquid Movement Indicator Position: + + + + + + + Chooses whether to render the transparent indicator for liquids above or below tiles. + + + false + + + false + + + 10 + + + + Below Tiles + + + + + Above Tiles + + + + + + + + + + Qt::Horizontal + + + - Show Statusbar + Show status bar diff --git a/leveleditor/zoneeditorwidget.cpp b/leveleditor/zoneeditorwidget.cpp index 4a730b2a..376b2e21 100644 --- a/leveleditor/zoneeditorwidget.cpp +++ b/leveleditor/zoneeditorwidget.cpp @@ -266,7 +266,11 @@ void ZoneEditorWidget::updateInfo() multiplayerTracking->setCurrentText(multiplayerTrackings.value(editZone->getMultiplayerTracking())); progPathId->setValue(editZone->getProgPathId()); unk1->setValue(editZone->getUnk1()); + boundingId->setDisabled(true); + boundingId->setStyleSheet("color: gray"); boundingId->setValue(editZone->getBoundingId()); + backgroundId->setDisabled(true); + backgroundId->setStyleSheet("color: gray"); backgroundId->setValue(editZone->getBackgroundId()); handleChanges = true; diff --git a/objectrenderer.cpp b/objectrenderer.cpp index 9bf962e0..6b0846dc 100644 --- a/objectrenderer.cpp +++ b/objectrenderer.cpp @@ -200,7 +200,7 @@ SpriteRenderer::SpriteRenderer(const Sprite *spr, Tileset *tilesets[]) ret = new NormalImageRenderer(spr, "fireballpipe_junction.png"); break; case 82: // Fire Snake - ret = new NormalImageRenderer(spr, "fire_snake.png"); + ret = new FireSnakeRenderer(spr); break; case 83: // Fish Bone ret = new NormalImageRenderer(spr, "fish_bone.png"); @@ -362,10 +362,10 @@ SpriteRenderer::SpriteRenderer(const Sprite *spr, Tileset *tilesets[]) ret = new NormalImageRenderer(spr, "conveyor_belt_switch.png"); break; case 144: // Horizontal Lift - ret = new LiftRenderer(spr); + ret = new LiftRenderer(spr, "lift_platform"); break; case 145: // Vertical Lift - ret = new LiftRenderer(spr); + ret = new LiftRenderer(spr, "lift_platform"); break; case 146: // Track Controlled Lift ret = new TrackLiftRenderer(spr); @@ -643,6 +643,9 @@ SpriteRenderer::SpriteRenderer(const Sprite *spr, Tileset *tilesets[]) case 253: // Larry Battle Platform ret = new LarryPlatformRenderer(spr, tilesets[0]); break; + case 254: // Vertical Lift - Totem + ret = new LiftRenderer(spr, "totem_lift"); + break; case 255: // Bowser Head Statue ret = new NormalImageRenderer(spr, "bowser_head_statue.png"); break; @@ -664,6 +667,9 @@ SpriteRenderer::SpriteRenderer(const Sprite *spr, Tileset *tilesets[]) case 270: // Icy Spiked Ball ret = new NormalImageRenderer(spr, "icy_spiked_ball.png"); break; + case 271: // Big Icy Spiked Ball + ret = new NormalImageRenderer(spr, "big_icy_spiked_ball.png"); + break; case 272: // Peach Cage ret = new NormalImageRenderer(spr, "peach_cage.png"); break; @@ -757,6 +763,9 @@ SpriteRenderer::SpriteRenderer(const Sprite *spr, Tileset *tilesets[]) case 308: // Event Activated Rectangle Lift - Sand ret = new EventRecLiftRenderer(spr, "rect_lift_sand"); break; + case 310: // Big Bowser Battle Lift + ret = new BowserLiftRenderer(spr); + break; case 311: // Coin Meteor ret = new CoinMeteorRenderer(spr); break; @@ -860,61 +869,67 @@ void CircleRenderer::render(QPainter *painter, QRect *) painter->setPen(Qt::NoPen); } -MovIndicatorRenderer::MovIndicatorRenderer(int x, int y, int distX, int distY, bool vertical, QColor color) +MovIndicatorRenderer::MovIndicatorRenderer(int startX, int startY, int endX, int endY, bool vertical, QColor color) +: MovIndicatorRenderer::MovIndicatorRenderer(startX, startY, endX, endY, 4, 10, true, vertical, color) +{} + +MovIndicatorRenderer::MovIndicatorRenderer(int startX, int startY, int endX, int endY, int thickness, int radius, bool applyOffset, bool vertical, QColor color) { - this->x = x; - this->y = y; - this->distX = distX; - this->distY = distY; + this->startX = startX; + this->startY = startY; + this->endX = endX; + this->endY = endY; + this->thickness = thickness; + this->radius = radius; + this->applyOffset = applyOffset; this->vertical = vertical; this->color = color; } void MovIndicatorRenderer::render(QPainter *painter) { - QPen outline(QColor(0,0,0,150), 8, Qt::SolidLine); - QPen fill(color, 4, Qt::SolidLine); + QPen outline(QColor(0,0,0,150), thickness * 2, Qt::SolidLine); + QPen fill(color, thickness, Qt::SolidLine); painter->setPen(outline); - if (vertical && distY == y) + if (vertical && endY == startY) return; - else if (!vertical && distX == x) + else if (!vertical && endX == startX) return; for (int i = 0; i <= 1; i++) { - - if ( i == 1) + if (i == 1) painter->setPen(fill); else painter->setPen(outline); if (vertical) { - if (distY < y) // Go Up + if (endY < startY) // Go Up { - painter->drawLine(x, y+20, x, distY+18); - painter->drawEllipse(x-5, distY+5, 10, 10); + painter->drawLine(startX, startY+(20*applyOffset)+(radius/2*!applyOffset), startX, endY+(20*applyOffset)+(radius*2*!applyOffset)-2); + painter->drawEllipse(startX-(radius/2), endY+(radius/2), radius, radius); } else // Go Down { - painter->drawLine(x, y-20, x, distY-18); - painter->drawEllipse(x-5, distY-15, 10, 10); + painter->drawLine(startX, startY-(20*applyOffset), startX, endY-(20*applyOffset)-(radius*2*!applyOffset)+2); + painter->drawEllipse(startX-(radius/2), endY-(1.5*radius), radius, radius); } } else { - if (distX < x) // Go Left + if (endX < startX) // Go Left { - painter->drawLine(x+20, y, distX+18, y); - painter->drawEllipse(distX+5, y-5, 10, 10); + painter->drawLine(startX+(20*applyOffset), startY, endX+(20*applyOffset)+(radius*2*!applyOffset)-2, startY); + painter->drawEllipse(endX+(radius/2), startY-(radius/2), radius, radius); } else // Go Right { - painter->drawLine(x-20, y, distX-18, y); - painter->drawEllipse(distX-15, y-5, 10, 10); + painter->drawLine(startX-(20*applyOffset), startY, endX-(20*applyOffset)-(radius*2*!applyOffset)+2, startY); + painter->drawEllipse(endX-(1.5*radius), startY-(radius/2), radius, radius); } } } @@ -1020,18 +1035,40 @@ void BurnerRenderer::render(QPainter *painter, QRect *) WhompRenderer::WhompRenderer(const Sprite *spr) { this->spr = spr; +} + +void WhompRenderer::render(QPainter *painter, QRect *) +{ + this->spr = spr; + int x = spr->getx() + spr->getOffsetX(); + int y = spr->gety() + spr->getOffsetY(); + + QString img_name = "whomp"; if (spr->getNybble(11) == 1) - filename = "whomp_big.png"; - else - filename = "whomp.png"; + img_name += "_big"; - img = new NormalImageRenderer(spr, filename); -} + if (spr->getNybble(10) == 0) + { + img_name += "_walk"; -void WhompRenderer::render(QPainter *painter, QRect *drawrect) -{ - img->render(painter, drawrect); + // Show a distance indicator for patrol distance + int dist = spr->getNybble(8) * 20; + + if (spr->getNybble(8) > 0) + { + int offsetXL = (spr->getNybble(11) == 1) ? 0: -10; + int offsetXR = spr->getwidth() + 10; + + MovIndicatorRenderer leftIndicator(x + spr->getwidth()/2, y + spr->getheight()/2, x + offsetXL - dist, y + spr->getheight()/2, false, QColor(244, 250, 255)); + leftIndicator.render(painter); + + MovIndicatorRenderer rightIndicator(x + spr->getwidth()/2, y + spr->getheight()/2, x + offsetXR + dist, y + spr->getheight()/2, false, QColor(244, 250, 255)); + rightIndicator.render(painter); + } + } + + painter->drawPixmap(QRect(x, y, spr->getwidth(), spr->getheight()), ImageCache::getInstance()->get(SpriteImg, img_name + ".png")); } // Sprite 18: Tile God @@ -1587,6 +1624,20 @@ void FireBarRenderer::render(QPainter *painter, QRect *drawrect) painter->drawPixmap(spr->getx(), spr->gety(), 20, 20, ImageCache::getInstance()->get(SpriteImg, "firebar_fire.png")); } +// Sprite 82: Fire Snake +FireSnakeRenderer::FireSnakeRenderer(const Sprite *spr) +{ + if (spr->getNybble(11) == 1) + img = new NormalImageRenderer(spr, "fire_snake_hidden.png"); + else + img = new NormalImageRenderer(spr, "fire_snake.png"); +} + +void FireSnakeRenderer::render(QPainter *painter, QRect *drawrect) +{ + img->render(painter, drawrect); +} + // Sprite 84/85/86/87/88: Flags FlagRenderer::FlagRenderer(const Sprite *spr) { @@ -2098,13 +2149,20 @@ void MushroomPlatformRenderer::render(QPainter *painter, QRect *) // Sprite 127: Bowser Flame BowserFlameRenderer::BowserFlameRenderer(const Sprite *spr) { - if (spr->getNybble(11) == 1) img = new NormalImageRenderer(spr, "dry_bowser_flame.png"); - else img = new NormalImageRenderer(spr, "bowser_flame.png"); + this->spr = spr; } void BowserFlameRenderer::render(QPainter *painter, QRect *drawrect) { - img->render(painter, drawrect); + QString filename = "bowser_flame.png"; + + if (spr->getNybble(11) == 1) filename = "bowser_flame_blue.png"; + if (spr->getNybble(8) == 1) filename = "bowser_flame_purple.png"; + + QPixmap img = ImageCache::getInstance()->get(SpriteImg, filename); + if (spr->getNybble(10) == 1) img = img.transformed(QTransform().scale(-1, 1)); + + painter->drawPixmap(QRect(spr->getx() + spr->getOffsetX(), spr->gety() + spr->getOffsetY(), spr->getwidth(), spr->getheight()), img); } @@ -2157,10 +2215,11 @@ void GoombaTowerRenderer::render(QPainter *painter, QRect *drawrect) } -// Sprite 144/145: Horizontal/Vertical Moving Lift -LiftRenderer::LiftRenderer(const Sprite *spr) +// Sprite 144/145/254: Horizontal/Vertical/Totem Lift +LiftRenderer::LiftRenderer(const Sprite *spr, QString dirname) { this->spr = spr; + this->dirname = dirname; } void LiftRenderer::render(QPainter *painter, QRect *) @@ -2169,7 +2228,7 @@ void LiftRenderer::render(QPainter *painter, QRect *) if (spr->getNybble(7) == 1 && distance > 0) { - if (spr->getid() == 145) + if (spr->getid() == 145 || spr->getid() == 254) { MovIndicatorRenderer track(spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight()+13, spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight()+distance, true, QColor(244,250,255)); track.render(painter); @@ -2182,7 +2241,7 @@ void LiftRenderer::render(QPainter *painter, QRect *) } else if (distance > 0) { - if (spr->getid() == 145) + if (spr->getid() == 145 || spr->getid() == 254) { MovIndicatorRenderer track(spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight()-27, spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight()-20-distance, true, QColor(244,250,255)); track.render(painter); @@ -2195,13 +2254,13 @@ void LiftRenderer::render(QPainter *painter, QRect *) } - painter->drawPixmap(QRect(spr->getx()+spr->getOffsetX(), spr->gety(), 20, 22), ImageCache::getInstance()->get(SpriteImg, "lift_platform/l.png")); - if(spr->getNybble(11) == 0) - painter->drawPixmap(QRect(spr->getx()-spr->getOffsetX()+(spr->getNybble(11))*20+20, spr->gety(), 22, 22), ImageCache::getInstance()->get(SpriteImg, "lift_platform/r.png")); + painter->drawPixmap(QRect(spr->getx()+spr->getOffsetX(), spr->gety(), 20, 22), ImageCache::getInstance()->get(SpriteImg, dirname + "/l.png")); + if (spr->getNybble(11) == 0) + painter->drawPixmap(QRect(spr->getx()-spr->getOffsetX()+(spr->getNybble(11))*20+20, spr->gety(), 22, 22), ImageCache::getInstance()->get(SpriteImg, dirname + "/r.png")); else - painter->drawPixmap(QRect(spr->getx()-spr->getOffsetX()+(spr->getNybble(11)-1)*20+20, spr->gety(), 22, 22), ImageCache::getInstance()->get(SpriteImg, "lift_platform/r.png")); + painter->drawPixmap(QRect(spr->getx()-spr->getOffsetX()+(spr->getNybble(11)-1)*20+20, spr->gety(), 22, 22), ImageCache::getInstance()->get(SpriteImg, dirname + "/r.png")); for (int i = 20; i < spr->getwidth()-20; i += 20) - painter->drawPixmap(QRect(spr->getx()+spr->getOffsetX()+i, spr->gety(), 20, 22), ImageCache::getInstance()->get(SpriteImg, "lift_platform/m.png")); + painter->drawPixmap(QRect(spr->getx()+spr->getOffsetX()+i, spr->gety(), 20, 22), ImageCache::getInstance()->get(SpriteImg, dirname + "/m.png")); } @@ -2891,50 +2950,77 @@ void PathRecLiftRenderer::render(QPainter *painter, QRect *) { QString path = "tower_rectangle_lift/"; - int blockWidth = spr->getNybble(17)*20; - int blockHeight = spr->getNybble(19)*20; + bool movesDown = (spr->getNybble(9) == 1); + int posOffset = spr->getNybble(7); - if (blockHeight == 0 || blockWidth == 0) + int vOffX = 0; + int vOffY = 0; + + switch (spr->getNybble(11)) { - if (tileset == nullptr) - { - painter->drawPixmap(spr->getx(), spr->gety(), spr->getwidth(), spr->getheight(), ImageCache::getInstance()->get(TileOverride, "error.png")); - } - else - { - QPixmap block(20, 20); - block.fill(QColor(0,0,0,0)); - QPainter tempPainter(&block); + case 1: + vOffY = -20; + break; + case 3: + vOffY = -20; + break; + case 4: + vOffX = -10; + break; + case 5: + vOffX = 10; + break; + default: + break; + } - TileGrid tileGrid; - tileGrid[0xFFFFFFFF] = 1; + // Render Movement Indicators + int distance = spr->getNybble(14)*20; + int distOff = 0; - tileset->drawTile(tempPainter, tileGrid, 22, 0, 0, 1, 0); - painter->drawPixmap(spr->getx()+spr->getOffsetX(), spr->gety()+spr->getOffsetY(), 20+blockWidth, 20+blockHeight, block); - } + if ((0 < spr->getNybble(11) && spr->getNybble(11) < 3) && movesDown) + distOff = 20; + else if ((spr->getNybble(11) == 3) && movesDown) + distOff = 40; + + if (movesDown && distance > 0) + { + MovIndicatorRenderer track(spr->getx()+vOffX+posOffset+spr->getwidth()/2, spr->gety()+vOffY+posOffset+spr->getheight(), spr->getx()+vOffX+posOffset+spr->getwidth()/2, spr->gety()+vOffY+posOffset+spr->getheight()+distance+distOff, true, QColor(244,250,255)); + track.render(painter); } - else + else if (distance > 0) { - painter->drawPixmap(QRect(spr->getx(), spr->gety(), 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "tl.png")); - painter->drawPixmap(QRect(spr->getx(), spr->gety()+blockHeight, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "bl.png")); - painter->drawPixmap(QRect(spr->getx()+blockWidth, spr->gety(), 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "tr.png")); - painter->drawPixmap(QRect(spr->getx()+blockWidth, spr->gety()+blockHeight, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "br.png")); + MovIndicatorRenderer track(spr->getx()+posOffset+vOffX+spr->getwidth()/2, spr->gety()+posOffset+vOffY, spr->getx()+posOffset+vOffX+spr->getwidth()/2, spr->gety()+posOffset+vOffY-distance+distOff, true, QColor(244,250,255)); + track.render(painter); + } - for (int i = 0; i < spr->getNybble(17)-1; i++) - { - painter->drawPixmap(QRect(spr->getx() + i*20+20, spr->gety(), 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "t.png")); - painter->drawPixmap(QRect(spr->getx() + i*20+20, spr->gety()+blockHeight, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "b.png")); - } - for (int i = 0; i < spr->getNybble(19)-1; i++) - { - painter->drawPixmap(QRect(spr->getx(), spr->gety() + i*20+20, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "l.png")); - painter->drawPixmap(QRect(spr->getx()+blockWidth, spr->gety() + i*20+20, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "r.png")); - } + int blockWidth = spr->getNybble(17) > 0 ? spr->getNybble(17)*20 : 20; + int blockHeight = spr->getNybble(19) > 0 ? spr->getNybble(19)*20 : 20; - for (int x = 20; x < blockWidth; x+=20) - for (int y = 20; y < blockHeight; y+=20) - painter->drawPixmap(QRect(spr->getx()+x, spr->gety()+y, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "c.png")); + painter->drawPixmap(QRect(spr->getx()+posOffset, spr->gety()+posOffset, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "tl.png")); + painter->drawPixmap(QRect(spr->getx()+posOffset, spr->gety()+blockHeight+posOffset, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "bl.png")); + painter->drawPixmap(QRect(spr->getx()+blockWidth+posOffset, spr->gety()+posOffset, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "tr.png")); + painter->drawPixmap(QRect(spr->getx()+blockWidth+posOffset, spr->gety()+blockHeight+posOffset, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "br.png")); + + for (int i = 0; i < spr->getNybble(17)-1; i++) + { + painter->drawPixmap(QRect(spr->getx()+posOffset + i*20+20, spr->gety()+posOffset, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "t.png")); + painter->drawPixmap(QRect(spr->getx()+posOffset + i*20+20, spr->gety()+posOffset+blockHeight, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "b.png")); + } + for (int i = 0; i < spr->getNybble(19)-1; i++) + { + painter->drawPixmap(QRect(spr->getx()+posOffset, spr->gety()+posOffset + i*20+20, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "l.png")); + painter->drawPixmap(QRect(spr->getx()+posOffset+blockWidth, spr->gety()+posOffset + i*20+20, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "r.png")); } + + for (int x = 20; x < blockWidth; x+=20) + for (int y = 20; y < blockHeight; y+=20) + painter->drawPixmap(QRect(spr->getx()+x+posOffset, spr->gety()+y+posOffset, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "c.png")); + + if (spr->getNybble(11) == 1 || spr->getNybble(11) == 3) for (int x = 0; x < blockWidth+20; x+=20) painter->drawPixmap(QRect(spr->getx()+x+posOffset, spr->gety()-20+posOffset, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "s_t.png")); + if (spr->getNybble(11) == 2 || spr->getNybble(11) == 3) for (int x = 0; x < blockWidth+20; x+=20) painter->drawPixmap(QRect(spr->getx()+x+posOffset, spr->gety()+blockHeight+20+posOffset, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "s_b.png")); + if (spr->getNybble(11) == 4 || spr->getNybble(11) == 6) for (int y = 0; y < blockHeight+20; y+=20) painter->drawPixmap(QRect(spr->getx()+posOffset-20, spr->gety()+y+posOffset, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "s_l.png")); + if (spr->getNybble(11) == 5 || spr->getNybble(11) == 6) for (int y = 0; y < blockHeight+20; y+=20) painter->drawPixmap(QRect(spr->getx()+blockWidth+20+posOffset, spr->gety()+y+posOffset, 20, 20), ImageCache::getInstance()->get(SpriteImg, path + "s_r.png")); } // RecLiftRenderer @@ -2946,12 +3032,15 @@ RecLiftRenderer::RecLiftRenderer(const Sprite *spr, QString path) } void RecLiftRenderer::render(QPainter *painter, QRect *) { + Direction direction = (Direction)(spr->getNybble(5) % 4); + int hOffX = 0; int hOffY = 0; int vOffX = 0; int vOffY = 0; - switch (spr->getNybble(7)) { + switch (spr->getNybble(7)) + { case 1: hOffY = -10; vOffY = -20; @@ -2975,49 +3064,84 @@ void RecLiftRenderer::render(QPainter *painter, QRect *) default: hOffX = 0; hOffY = 0; + break; } // Render Movement Indicators int distance = spr->getNybble(14)*20; int eventDistance = spr->getNybbleData(10, 11)*20; + int distOff = 0; - - switch (spr->getNybble(5)) { - case 1: case 5: case 9: case 13: // Left + if (((0 < spr->getNybble(7) && spr->getNybble(7) < 3) && (direction == DOWN)) || + ((3 < spr->getNybble(7) && spr->getNybble(7) < 6) && (direction == RIGHT))) { - MovIndicatorRenderer track(spr->getx()+hOffX, spr->gety()+hOffY+spr->getheight()/2, spr->getx()+hOffX-distance, spr->gety()+hOffY+spr->getheight()/2, false, QColor(244,250,255)); - track.render(painter); - - MovIndicatorRenderer eventTrack(spr->getx()+hOffX, spr->gety()+hOffY+spr->getheight()/2, spr->getx()+hOffX-eventDistance, spr->gety()+hOffY+spr->getheight()/2, false, QColor(243,156,18)); - eventTrack.render(painter); + distOff = 20; } - break; - case 2: case 6: case 10: case 14: // Up + else if (((spr->getNybble(7) == 3) && (direction == DOWN)) || + ((spr->getNybble(7) == 6) && (direction == RIGHT))) { - MovIndicatorRenderer track(spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY, spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY-distance, true, QColor(244,250,255)); - track.render(painter); - - MovIndicatorRenderer eventTrack(spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY, spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY-eventDistance, true, QColor(243,156,18)); - eventTrack.render(painter); + distOff = 40; } + + switch (direction) + { + case LEFT: + { + if (distance > 0) + { + MovIndicatorRenderer track(spr->getx()+hOffX, spr->gety()+hOffY+spr->getheight()/2, spr->getx()+hOffX-distance+distOff, spr->gety()+hOffY+spr->getheight()/2, false, QColor(244,250,255)); + track.render(painter); + } + if (eventDistance > 0) + { + MovIndicatorRenderer eventTrack(spr->getx()+hOffX, spr->gety()+hOffY+spr->getheight()/2, spr->getx()+hOffX-eventDistance+distOff, spr->gety()+hOffY+spr->getheight()/2, false, QColor(243,156,18)); + eventTrack.render(painter); + } break; - case 3: case 7: case 11: case 15: // Down + } + case UP: { - MovIndicatorRenderer track(spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY+spr->getheight(), spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY+spr->getheight()+distance, true, QColor(244,250,255)); - track.render(painter); - - MovIndicatorRenderer eventTrack(spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY+spr->getheight(), spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY+spr->getheight()+eventDistance, true, QColor(243,156,18)); - eventTrack.render(painter); + if (distance > 0) + { + MovIndicatorRenderer track(spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY, spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY-distance+distOff, true, QColor(244,250,255)); + track.render(painter); + } + if (eventDistance > 0) + { + MovIndicatorRenderer eventTrack(spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY, spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY-eventDistance+distOff, true, QColor(243,156,18)); + eventTrack.render(painter); + } + break; } + case DOWN: + { + if (distance > 0) + { + MovIndicatorRenderer track(spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY+spr->getheight(), spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY+spr->getheight()+distance+distOff, true, QColor(244,250,255)); + track.render(painter); + } + if (eventDistance > 0) + { + MovIndicatorRenderer eventTrack(spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY+spr->getheight(), spr->getx()+vOffX-sideOffset+spr->getwidth()/2, spr->gety()+vOffY+spr->getheight()+eventDistance+distOff, true, QColor(243,156,18)); + eventTrack.render(painter); + } break; - default: // Right + } + case RIGHT: { - MovIndicatorRenderer track(spr->getx()+hOffX+spr->getwidth(), spr->gety()+hOffY+spr->getheight()/2, spr->getx()+hOffX+spr->getwidth()+distance, spr->gety()+hOffY+spr->getheight()/2, false, QColor(244,250,255)); - track.render(painter); - - MovIndicatorRenderer eventTrack(spr->getx()+hOffX+spr->getwidth(), spr->gety()+hOffY+spr->getheight()/2, spr->getx()+hOffX+spr->getwidth()+eventDistance, spr->gety()+hOffY+spr->getheight()/2, false, QColor(243,156,18)); - eventTrack.render(painter); + if (distance > 0) + { + MovIndicatorRenderer track(spr->getx()+hOffX+spr->getwidth(), spr->gety()+hOffY+spr->getheight()/2, spr->getx()+hOffX+spr->getwidth()+distance+distOff, spr->gety()+hOffY+spr->getheight()/2, false, QColor(244,250,255)); + track.render(painter); + } + if (eventDistance > 0) + { + MovIndicatorRenderer eventTrack(spr->getx()+hOffX+spr->getwidth(), spr->gety()+hOffY+spr->getheight()/2, spr->getx()+hOffX+spr->getwidth()+eventDistance+distOff, spr->gety()+hOffY+spr->getheight()/2, false, QColor(243,156,18)); + eventTrack.render(painter); + } + break; } + default: break; } @@ -3807,47 +3931,67 @@ LavaRectLiftRenderer::LavaRectLiftRenderer(const Sprite *spr) void LavaRectLiftRenderer::render(QPainter *painter, QRect *) { // Render Movement Indicators - int distance = spr->getNybbleData(17, 14)*20; + int distance = spr->getNybble(14)*20; int eventDistance = spr->getNybbleData(10, 11)*20; - - switch (spr->getNybble(5)) { - case 1: case 5: case 9: case 13: // Left + switch (spr->getNybble(5)) { - MovIndicatorRenderer track(spr->getx(), spr->gety()+spr->getheight()/2, spr->getx()-distance, spr->gety()+spr->getheight()/2, false, QColor(244,250,255)); - track.render(painter); - - MovIndicatorRenderer eventTrack(spr->getx(), spr->gety()+spr->getheight()/2, spr->getx()-eventDistance, spr->gety()+spr->getheight()/2, false, QColor(243,156,18)); - eventTrack.render(painter); - } - break; - case 2: case 6: case 10: case 14: // Up - { - MovIndicatorRenderer track(spr->getx()+spr->getwidth()/2, spr->gety(), spr->getx()+spr->getwidth()/2, spr->gety()-distance, true, QColor(244,250,255)); - track.render(painter); - - MovIndicatorRenderer eventTrack(spr->getx()+spr->getwidth()/2, spr->gety(), spr->getx()+spr->getwidth()/2, spr->gety()-eventDistance, true, QColor(243,156,18)); - eventTrack.render(painter); - } - break; - case 3: case 7: case 11: case 15: // Down - { - MovIndicatorRenderer track(spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight(), spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight()+distance, true, QColor(244,250,255)); - track.render(painter); - - MovIndicatorRenderer eventTrack(spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight(), spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight()+eventDistance, true, QColor(243,156,18)); - eventTrack.render(painter); - } - break; - default: // Right - { - MovIndicatorRenderer track(spr->getx()+spr->getwidth(), spr->gety()+spr->getheight()/2, spr->getx()+spr->getwidth()+distance, spr->gety()+spr->getheight()/2, false, QColor(244,250,255)); - track.render(painter); - - MovIndicatorRenderer eventTrack(spr->getx()+spr->getwidth(), spr->gety()+spr->getheight()/2, spr->getx()+spr->getwidth()+eventDistance, spr->gety()+spr->getheight()/2, false, QColor(243,156,18)); - eventTrack.render(painter); - } - break; + case 1: case 5: case 9: case 13: // Left + { + if (distance != 0) + { + MovIndicatorRenderer track(spr->getx(), spr->gety()+spr->getheight()/2, spr->getx()+spr->getOffsetX()-distance, spr->gety()+spr->getheight()/2, false, QColor(244,250,255)); + track.render(painter); + } + if (eventDistance != 0) + { + MovIndicatorRenderer eventTrack(spr->getx(), spr->gety()+spr->getheight()/2, spr->getx()+spr->getOffsetX()-eventDistance, spr->gety()+spr->getheight()/2, false, QColor(243,156,18)); + eventTrack.render(painter); + } + break; + } + case 2: case 6: case 10: case 14: // Up + { + if (distance != 0) + { + MovIndicatorRenderer track(spr->getx() + spr->getOffsetX()+spr->getwidth()/2, spr->gety(), spr->getx()+spr->getwidth()/2, spr->gety()-distance, true, QColor(244,250,255)); + track.render(painter); + } + if (eventDistance != 0) + { + MovIndicatorRenderer eventTrack(spr->getx() + spr->getOffsetX()+spr->getwidth()/2, spr->gety(), spr->getx()+spr->getwidth()/2, spr->gety()-eventDistance, true, QColor(243,156,18)); + eventTrack.render(painter); + } + break; + } + case 3: case 7: case 11: case 15: // Down + { + if (distance != 0) + { + MovIndicatorRenderer track(spr->getx() + spr->getOffsetX()+spr->getwidth()/2, spr->gety()+spr->getheight(), spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight()+distance, true, QColor(244,250,255)); + track.render(painter); + } + if (eventDistance != 0) + { + MovIndicatorRenderer eventTrack(spr->getx() + spr->getOffsetX()+spr->getwidth()/2, spr->gety()+spr->getheight(), spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight()+eventDistance, true, QColor(243,156,18)); + eventTrack.render(painter); + } + break; + } + default: // Right + { + if (distance != 0) + { + MovIndicatorRenderer track(spr->getx()+spr->getwidth(), spr->gety()+spr->getheight()/2, spr->getx()+spr->getOffsetX()+spr->getwidth()+distance, spr->gety()+spr->getheight()/2, false, QColor(244,250,255)); + track.render(painter); + } + if (eventDistance != 0) + { + MovIndicatorRenderer eventTrack(spr->getx()+spr->getwidth(), spr->gety()+spr->getheight()/2, spr->getx()+spr->getOffsetX()+spr->getwidth()+eventDistance, spr->gety()+spr->getheight()/2, false, QColor(243,156,18)); + eventTrack.render(painter); + } + break; + } } if (spr->getNybble(19) == 1) @@ -3907,15 +4051,15 @@ EventRecLiftRenderer::EventRecLiftRenderer(const Sprite *spr, QString path) { switch (spr->getNybble(19)) { - case 1: - type = "_small.png"; - break; - case 2: - type = "_big.png"; - break; - default: - type = ".png"; - break; + case 1: + type = "_small.png"; + break; + case 2: + type = "_big.png"; + break; + default: + type = ".png"; + break; } } @@ -3926,38 +4070,67 @@ void EventRecLiftRenderer::render(QPainter *painter, QRect *drawrect) { // Render Movement Indicators - int distance = 0; - - if (spr->getid() == 283) - distance = spr->getNybble(14)*20; - else - distance = spr->getNybbleData(4,5)*20; + int distance = spr->getNybble(14)*20; + int eventDistance = spr->getNybbleData(10, 11)*20; - switch (spr->getNybble(5)) { - case 1: case 5: case 9: case 13: // Left + switch (spr->getNybble(5)) { - MovIndicatorRenderer track(spr->getx(), spr->gety()+spr->getheight()/2, spr->getx()-distance, spr->gety()+spr->getheight()/2, false, QColor(243,156,18)); - track.render(painter); - } - break; - case 2: case 6: case 10: case 14: // Up - { - MovIndicatorRenderer track(spr->getx()+spr->getwidth()/2, spr->gety(), spr->getx()+spr->getwidth()/2, spr->gety()-distance, true, QColor(243,156,18)); - track.render(painter); - } - break; - case 3: case 7: case 11: case 15: // Down - { - MovIndicatorRenderer track(spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight(), spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight()+distance, true, QColor(243,156,18)); - track.render(painter); - } - break; - default: // Right - { - MovIndicatorRenderer track(spr->getx()+spr->getwidth(), spr->gety()+spr->getheight()/2, spr->getx()+spr->getwidth()+distance, spr->gety()+spr->getheight()/2, false, QColor(243,156,18)); - track.render(painter); - } - break; + case 1: case 5: case 9: case 13: // Left + { + if (distance > 0) + { + MovIndicatorRenderer track(spr->getx(), spr->gety()+spr->getheight()/2, spr->getx()-distance, spr->gety()+spr->getheight()/2, false, QColor(244,250,255)); + track.render(painter); + } + if (eventDistance > 0) + { + MovIndicatorRenderer eventTrack(spr->getx(), spr->gety()+spr->getheight()/2, spr->getx()-eventDistance, spr->gety()+spr->getheight()/2, false, QColor(243,156,18)); + eventTrack.render(painter); + } + break; + } + case 2: case 6: case 10: case 14: // Up + { + if (distance > 0) + { + MovIndicatorRenderer track(spr->getx()+spr->getwidth()/2, spr->gety(), spr->getx()+spr->getwidth()/2, spr->gety()-distance, true, QColor(244,250,255)); + track.render(painter); + } + if (eventDistance > 0) + { + MovIndicatorRenderer eventTrack(spr->getx()+spr->getwidth()/2, spr->gety(), spr->getx()+spr->getwidth()/2, spr->gety()-eventDistance, true, QColor(243,156,18)); + eventTrack.render(painter); + } + break; + } + case 3: case 7: case 11: case 15: // Down + { + if (distance > 0) + { + MovIndicatorRenderer track(spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight(), spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight()+distance, true, QColor(244,250,255)); + track.render(painter); + } + if (eventDistance > 0) + { + MovIndicatorRenderer eventTrack(spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight(), spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight()+eventDistance, true, QColor(243,156,18)); + eventTrack.render(painter); + } + break; + } + default: // Right + { + if (distance > 0) + { + MovIndicatorRenderer track(spr->getx()+spr->getwidth(), spr->gety()+spr->getheight()/2, spr->getx()+spr->getwidth()+distance, spr->gety()+spr->getheight()/2, false, QColor(244,250,255)); + track.render(painter); + } + if (eventDistance > 0) + { + MovIndicatorRenderer eventTrack(spr->getx()+spr->getwidth(), spr->gety()+spr->getheight()/2, spr->getx()+spr->getwidth()+eventDistance, spr->gety()+spr->getheight()/2, false, QColor(243,156,18)); + eventTrack.render(painter); + } + break; + } } img->render(painter, drawrect); @@ -4045,6 +4218,22 @@ void IceLiftRenderer::render(QPainter *painter, QRect *drawrect) img->render(painter, drawrect); } +// Sprite 310: Big Bowser Battle Lift +BowserLiftRenderer::BowserLiftRenderer(const Sprite *spr) +{ + switch (spr->getNybble(11)) + { + case 1: img = new NormalImageRenderer(spr, "bowser_lift/m.png"); break; + case 2: img = new NormalImageRenderer(spr, "bowser_lift/l.png"); break; + default: img = new NormalImageRenderer(spr, "bowser_lift/s.png"); break; + } +} + +void BowserLiftRenderer::render(QPainter *painter, QRect *drawrect) +{ + img->render(painter, drawrect); +} + // Sprite 311: Coin Meteor CoinMeteorRenderer::CoinMeteorRenderer(const Sprite *spr) { @@ -4070,34 +4259,68 @@ UnderwaterRecLiftRenderer::UnderwaterRecLiftRenderer(const Sprite *spr) void UnderwaterRecLiftRenderer::render(QPainter *painter, QRect *drawrect) { - int distance = spr->getNybbleData(10, 11)*20; + int distance = spr->getNybble(14)*20; + int eventDistance = spr->getNybbleData(10, 11)*20; - switch (spr->getNybble(5)) { + switch (spr->getNybble(5)) + { case 1: case 5: case 9: case 13: // Left + { + if (distance > 0) { - MovIndicatorRenderer track(spr->getx(), spr->gety()+spr->getheight()/2, spr->getx()-distance, spr->gety()+spr->getheight()/2, false, QColor(243,156,18)); + MovIndicatorRenderer track(spr->getx(), spr->gety()+spr->getheight()/2, spr->getx()-distance, spr->gety()+spr->getheight()/2, false, QColor(244,250,255)); track.render(painter); } + if (eventDistance > 0) + { + MovIndicatorRenderer eventTrack(spr->getx(), spr->gety()+spr->getheight()/2, spr->getx()-eventDistance, spr->gety()+spr->getheight()/2, false, QColor(243,156,18)); + eventTrack.render(painter); + } break; + } case 2: case 6: case 10: case 14: // Up + { + if (distance > 0) { - MovIndicatorRenderer track(spr->getx()+spr->getwidth()/2, spr->gety(), spr->getx()+spr->getwidth()/2, spr->gety()-distance, true, QColor(243,156,18)); + MovIndicatorRenderer track(spr->getx()+spr->getwidth()/2, spr->gety(), spr->getx()+spr->getwidth()/2, spr->gety()-distance, true, QColor(244,250,255)); track.render(painter); } + if (eventDistance > 0) + { + MovIndicatorRenderer eventTrack(spr->getx()+spr->getwidth()/2, spr->gety(), spr->getx()+spr->getwidth()/2, spr->gety()-eventDistance, true, QColor(243,156,18)); + eventTrack.render(painter); + } break; + } case 3: case 7: case 11: case 15: // Down + { + if (distance > 0) { - MovIndicatorRenderer track(spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight(), spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight()+distance, true, QColor(243,156,18)); + MovIndicatorRenderer track(spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight(), spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight()+distance, true, QColor(244,250,255)); track.render(painter); } + if (eventDistance > 0) + { + MovIndicatorRenderer eventTrack(spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight(), spr->getx()+spr->getwidth()/2, spr->gety()+spr->getheight()+eventDistance, true, QColor(243,156,18)); + eventTrack.render(painter); + } break; + } default: // Right + { + if (distance > 0) { - MovIndicatorRenderer track(spr->getx()+spr->getwidth(), spr->gety()+spr->getheight()/2, spr->getx()+spr->getwidth()+distance, spr->gety()+spr->getheight()/2, false, QColor(243,156,18)); + MovIndicatorRenderer track(spr->getx()+spr->getwidth(), spr->gety()+spr->getheight()/2, spr->getx()+spr->getwidth()+distance, spr->gety()+spr->getheight()/2, false, QColor(244,250,255)); track.render(painter); } + if (eventDistance > 0) + { + MovIndicatorRenderer eventTrack(spr->getx()+spr->getwidth(), spr->gety()+spr->getheight()/2, spr->getx()+spr->getwidth()+eventDistance, spr->gety()+spr->getheight()/2, false, QColor(243,156,18)); + eventTrack.render(painter); + } break; } + } img->render(painter, drawrect); } @@ -4415,37 +4638,21 @@ LiquidRenderer::LiquidRenderer(const Sprite *liquid, const Zone *zone) void LiquidRenderer::render(QPainter *painter, QRect *drawrect) { + this->painter = painter; + this->drawrect = drawrect; + if (liquid->getid() != 14) { - QPixmap top = ImageCache::getInstance()->get(SpriteImg, filename + "_top.png"); - QPixmap base = ImageCache::getInstance()->get(SpriteImg, filename + ".png"); - - int currY = liquid->gety() - 20; - - for (int x = zone->getx(); x < zone->getx() + zone->getwidth(); x += top.width()) - { - QRect rect = QRect(x, currY, qMin(zone->getx() + zone->getwidth() - x, top.width()), qMin(zone->gety() + zone->getheight() - currY, top.height())); - - if (!drawrect->intersects(rect)) - continue; - - painter->drawPixmap(rect, top, QRect(0, 0, rect.right()-rect.left(), rect.bottom()-rect.top())); - } + bool topless = (liquid->getid() != 15 && liquid->getNybble(9) >= 8); - currY += top.height(); + bool movingDown = (liquid->getNybble(4) > 8); + int directedDistance = liquid->getNybbleData(7,8) * 20 * (movingDown ? 1 : -1); + bool moving = (liquid->getNybble(4) % 8 != 0) && (directedDistance != 0); - for (; currY < zone->gety() + zone->getheight(); currY += base.height()) - { - for (int x = zone->getx(); x < zone->getx() + zone->getwidth(); x += base.width()) - { - QRect rect = QRect(x, currY, qMin(zone->getx() + zone->getwidth() - x, base.width()), qMin(zone->gety() + zone->getheight() - currY, base.height())); - - if (!drawrect->intersects(rect)) - continue; - - painter->drawPixmap(rect, base, QRect(0, 0, rect.right()-rect.left(), rect.bottom()-rect.top())); - } - } + if (moving && movingDown) + drawLiquid(false, directedDistance, topless); + else + drawLiquid(false, 0, topless); } else { @@ -4465,3 +4672,89 @@ void LiquidRenderer::render(QPainter *painter, QRect *drawrect) } } +void LiquidRenderer::renderTranslucent(QPainter *painter, QRect *drawrect) +{ + this->painter = painter; + this->drawrect = drawrect; + + bool topless = (liquid->getid() != 15 && liquid->getNybble(9) >= 8); + + bool movingDown = (liquid->getNybble(4) > 8); + int directedDistance = liquid->getNybbleData(7,8) * 20 * (movingDown ? 1 : -1); + bool moving = (liquid->getNybble(4) % 8 != 0) && (directedDistance != 0); + + if (!moving) + return; + else if (movingDown) + drawLiquid(true, 0, topless); + else + drawLiquid(true, directedDistance, topless); +} + +void LiquidRenderer::drawLiquid(bool transparent, int yOffset, bool topless) +{ + painter->save(); + + if (transparent) + { + painter->setOpacity(0.25); + painter->setCompositionMode(QPainter::CompositionMode_Lighten); + } + + QPixmap top = ImageCache::getInstance()->get(SpriteImg, filename + "_top.png"); + QPixmap base = ImageCache::getInstance()->get(SpriteImg, filename + ".png"); + + // Calculate dimensions that never change + int x = qMax(zone->getx(), drawrect->x()); + int width = qMin(zone->getx() + zone->getwidth(), drawrect->x() + drawrect->width()) - qMax(zone->getx(), drawrect->x()); + + // Draw the top part of the liquid + int yWithOffset = liquid->getid() >= 15 ? liquid->gety() - 25 + yOffset: liquid->gety() - 7 + yOffset; + + if (!topless) + { + QRect topRect(x, yWithOffset, width, 0); + topRect.setHeight(qMin(top.height(), zone->gety() + zone->getheight() - yWithOffset)); + + // Move the texture with the sprite (as opposed to being masked by position) + int textureYOffset = yWithOffset % top.height() - 1;; + + // Check if the liquid top is past the top zone edge (i.e. needs to be cropped) + bool topNeedsCropping = (0 < zone->gety() - yWithOffset && zone->gety() - yWithOffset < top.height()); + + // "Fake" a crop when the liquid top is above the top zone edge + if (topNeedsCropping) + topRect.setY(topRect.y() + (zone->gety() - yWithOffset)); + + QBrush topBrush = QBrush(top); + topBrush.setTransform(QTransform().translate(0, textureYOffset)); + + // Ensure the liquid top doesn't render past the bottom of the zone, or past the cutoff point for cropping + if (yWithOffset > zone->gety() + zone->getheight() || zone->gety() - yWithOffset >= top.height()) + topRect.setHeight(0); + + painter->setBrush(topBrush); + painter->drawRect(topRect); + + yWithOffset += top.height() - 1; + } + else + yWithOffset += 7; + + // Draw the base (fill) part of the liquid + QBrush baseBrush = QBrush(base); + baseBrush.setTransform(QTransform().translate(0, yWithOffset % base.height())); + painter->setBrush(baseBrush); + + QRect baseRect(x, 0, width, 0); + baseRect.setY(qMax(yWithOffset, qMax(zone->gety(), drawrect->y()))); + + // Correctly resize the height to only where the liquid base is visible + int baseBottomBound = qMin(zone->gety() + zone->getheight(), drawrect->y() + drawrect->height()); + int baseTopBound = qMax(yWithOffset, qMax(zone->gety(), drawrect->y())); + baseRect.setHeight(qMax(baseBottomBound - baseTopBound, 0)); + + painter->drawRect(baseRect); + + painter->restore(); +} diff --git a/objectrenderer.h b/objectrenderer.h index 4693764f..c1633333 100644 --- a/objectrenderer.h +++ b/objectrenderer.h @@ -32,10 +32,15 @@ class LiquidRenderer: public ObjectRenderer LiquidRenderer() {} LiquidRenderer(const Sprite *liquid, const Zone *zone); void render(QPainter *painter, QRect *drawrect); + void renderTranslucent(QPainter *painter, QRect *drawrect); protected: const Sprite *liquid; const Zone *zone; QString filename; + QPainter *painter; + QRect *drawrect; +private: + void drawLiquid(bool transparent, int yOffset, bool topless); }; class NormalImageRenderer: public ObjectRenderer @@ -82,14 +87,18 @@ class MovIndicatorRenderer: public ObjectRenderer { public: MovIndicatorRenderer(); - MovIndicatorRenderer(int x, int y, int distX, int distY, bool vertical, QColor color); + MovIndicatorRenderer(int startX, int startY, int endX, int endY, bool vertical, QColor color); + MovIndicatorRenderer(int startX, int startY, int endX, int endY, int thickness, int radius, bool applyOffset, bool vertical, QColor color); using ObjectRenderer::render; void render(QPainter *painter); protected: - int x; - int y; - int distX; - int distY; + int startX; + int startY; + int endX; + int endY; + int thickness; + int radius; + bool applyOffset; bool vertical; QColor color; }; @@ -128,11 +137,7 @@ class WhompRenderer: public SpriteRenderer { public: WhompRenderer(const Sprite *spr); - ~WhompRenderer() { delete img; } void render(QPainter *painter, QRect *drawrect); -protected: - NormalImageRenderer *img; - QString filename; }; // Sprite 18: Tile God @@ -298,6 +303,17 @@ class FireBarRenderer: public SpriteRenderer CircleRenderer *radius; }; +// Sprite 82: Fire Snake +class FireSnakeRenderer: public SpriteRenderer +{ +public: + FireSnakeRenderer(const Sprite *spr); + ~FireSnakeRenderer() { delete img; } + void render(QPainter *painter, QRect *drawrect); +protected: + NormalImageRenderer *img; +}; + // Sprites 84/85/86/87/88: Flags class FlagRenderer: public SpriteRenderer { @@ -463,10 +479,7 @@ class BowserFlameRenderer: public SpriteRenderer { public: BowserFlameRenderer(const Sprite *spr); - ~BowserFlameRenderer() { delete img; } void render(QPainter *painter, QRect *drawrect); -protected: - NormalImageRenderer *img; }; // Sprite 131: Bowser Block @@ -530,8 +543,10 @@ class GoombaTowerRenderer: public SpriteRenderer class LiftRenderer: public SpriteRenderer { public: - LiftRenderer(const Sprite *spr); + LiftRenderer(const Sprite *spr, QString dirname); void render(QPainter *painter, QRect *drawrect); +protected: + QString dirname; }; // Sprite 146: Track Controlled Lift @@ -705,6 +720,7 @@ class RecLiftRenderer: public SpriteRenderer RecLiftRenderer(const Sprite *spr, QString path); void render(QPainter *painter, QRect *drawrect); protected: + enum Direction {RIGHT, LEFT, UP, DOWN}; QString path; int sideOffset = 0; }; @@ -1072,6 +1088,17 @@ class IceLiftRenderer: public SpriteRenderer NormalImageRenderer* img; }; +// Sprite 310: Big Bowser Battle Lift +class BowserLiftRenderer: public SpriteRenderer +{ +public: + BowserLiftRenderer(const Sprite *spr); + ~BowserLiftRenderer() { delete img; } + void render(QPainter *painter, QRect *drawrect); +protected: + NormalImageRenderer* img; +}; + // Sprite 311: Coin Meteor class CoinMeteorRenderer: public SpriteRenderer { diff --git a/objects.cpp b/objects.cpp index 93c5964a..3fa313ff 100644 --- a/objects.cpp +++ b/objects.cpp @@ -253,18 +253,38 @@ void Sprite::setRect() height = 25; break; case 9: // Whomp - if (getNybble(11) == 1) + if (getNybble(11) == 1) // Big { - width = 140; - height = 100; - offsetx = -50; - offsety = -40; + if (getNybble(10) == 0) // Big, walking + { + width = 105; + height = 102; + offsetx = -36; + offsety = -42; + } + else + { + width = 140; + height = 100; + offsetx = -50; + offsety = -40; + } } - else + else // Normal { - width = 80; - height = 60; - offsetx = -20; + if (getNybble(10) == 0) // Normal, walking + { + width = 58; + height = 56; + offsetx = -9; + offsety = 4; + } + else + { + width = 80; + height = 60; + offsetx = -20; + } } break; case 10: // Switchable Conveyor Belt - Lemmy Battle @@ -745,10 +765,19 @@ void Sprite::setRect() height = 40; break; case 82: // Fire Snake + { width = 19; height = 26; offsety = -5; + if (getNybble(11) == 1) + { + width = 15; + height = 17; + offsetx = 2; + offsety = 3; + } break; + } case 83: // Fish Bone width = 33; height = 21; @@ -1164,7 +1193,7 @@ void Sprite::setRect() case 127: // Bowser Flame width = 57; height = 36; - offsetx = 28; + offsetx = (getNybble(10) == 1) ? 8 : 28; offsety = -20; break; case 128: // Dry Bowser @@ -1258,42 +1287,44 @@ void Sprite::setRect() offsetx = -4; offsety = -21; break; - case 144: case 145: // Horizontal/Vertical Lift - if(getNybble(11) == 0) + case 144: case 145: case 254: // Horizontal/Vertical/Totem Lift + { + if (getNybble(11) == 0) width = 40; else width = (getNybble(11)-1)*20 + 40; height = 22; - //Down and right + + // Down and right if (getNybble(7) == 1) { - if(getid() == 145) - renderOffsetH = (getNybble(9)*20); + if (getid() == 145 || getid() == 254) + renderOffsetH = (getNybble(9)*20); else - renderOffsetW = -(getNybble(9)*20); + renderOffsetW = -(getNybble(9)*20); } else { - if(getid() == 145) - renderOffsetH = -(getNybble(9)*20); + if (getid() == 145 || getid() == 254) + renderOffsetH = -(getNybble(9)*20); else - renderOffsetW = (getNybble(9)*20); + renderOffsetW = (getNybble(9)*20); } - - //renderOffsetX = width/2; - //renderOffsetY = height/2; break; + } case 146: // Track Controlled Lift - if(getNybble(17) == 0) + { + if (getNybble(17) == 0) width = 84; - else if(getNybble(17) == 1) + else if (getNybble(17) == 1) width = 35; else width = (getNybble(17)-2)*20 + 44; height = 22; - offsetx = 40 -(width / 2); + offsetx = 40 - (width / 2); offsety = 10; break; + } case 147: // 3 plat rickshaw if (getNybble(11) != 1) { @@ -1693,6 +1724,8 @@ void Sprite::setRect() case 187: // Path controlled rect block width = 20 + getNybble(17)*20; height = 20 + getNybble(19)*20; + offsetx = getNybble(7); + offsety = offsetx; break; case 189: case 190: case 191: case 192: case 193: case 282: // Rect Blocks { @@ -1888,15 +1921,23 @@ void Sprite::setRect() break; case 205: // Red Ring + { width = 39; height = 56; offsety = 2; + if (getNybble(11) & 1) + offsetx = 10; break; + } case 206: // Gold Ring + { width = 40; height = 56; offsety = 2; + if (getNybble(11) & 1) + offsetx = 10; break; + } case 207: // Underwater Rock width = 80; height = 82; @@ -2439,10 +2480,12 @@ void Sprite::setRect() { width = 250; height = 80; + offsetx = -10; if (getNybble(19) == 1) { width = 100; height = 603; + offsetx = 0; } int distance = qMax((getNybbleData(17, 14)*20), (getNybbleData(10, 11)*20)); @@ -2475,6 +2518,11 @@ void Sprite::setRect() offsetx = 1; offsety = 1; break; + case 271: // Big Icy Spiked Ball + width = 73; + height = 73; + offsetx = 20; + break; case 272: // Peach Cage width = 68; height = 108; @@ -2723,55 +2771,77 @@ void Sprite::setRect() } break; case 307: // Event Activated Rect Lift - Ruins - { - width = 80; - height = 80; + { + width = 80; + height = 80; - int distance = getNybbleData(10, 11)*20; - switch (getNybble(5)) - { - case 1: case 5: case 9: case 13: // Left - renderOffsetW = width + distance; - renderOffsetX = -(width + distance); - break; - case 2: case 6: case 10: case 14: // Up - renderOffsetH = height + distance; - renderOffsetY = -(height + distance); - break; - case 3: case 7: case 11: case 15: // Down - renderOffsetH = height + distance; - break; - default: // Right - renderOffsetW = width + distance; - break; - } + int distance = getNybbleData(10, 11)*20; + switch (getNybble(5)) + { + case 1: case 5: case 9: case 13: // Left + renderOffsetW = width + distance; + renderOffsetX = -(width + distance); + break; + case 2: case 6: case 10: case 14: // Up + renderOffsetH = height + distance; + renderOffsetY = -(height + distance); + break; + case 3: case 7: case 11: case 15: // Down + renderOffsetH = height + distance; + break; + default: // Right + renderOffsetW = width + distance; break; } + break; + } case 308: // Event Activated Rect Lift - Sand - { - width = 120; - height = 140; + { + width = 120; + height = 140; - int distance = getNybbleData(10, 11)*20; - switch (getNybble(5)) - { - case 1: case 5: case 9: case 13: // Left - renderOffsetW = width + distance; - renderOffsetX = -(width + distance); - break; - case 2: case 6: case 10: case 14: // Up - renderOffsetH = height + distance; - renderOffsetY = -(height + distance); - break; - case 3: case 7: case 11: case 15: // Down - renderOffsetH = height + distance; - break; - default: // Right - renderOffsetW = width + distance; - break; - } + int distance = getNybbleData(10, 11)*20; + switch (getNybble(5)) + { + case 1: case 5: case 9: case 13: // Left + renderOffsetW = width + distance; + renderOffsetX = -(width + distance); + break; + case 2: case 6: case 10: case 14: // Up + renderOffsetH = height + distance; + renderOffsetY = -(height + distance); + break; + case 3: case 7: case 11: case 15: // Down + renderOffsetH = height + distance; + break; + default: // Right + renderOffsetW = width + distance; break; } + break; + } + case 310: // Big Bowser Battle Lift + { + switch (getNybble(11)) + { + case 1: + width = 82; + offsetx = -41; + break; + case 2: + width = 102; + offsetx = -51; + break; + default: + width = 62; + offsetx = -31; + break; + } + + height = 24; + offsety = -10; + break; + } case 311: // Coin Meteor if(getNybble(11) == 1) { diff --git a/settingsmanager.cpp b/settingsmanager.cpp index f0e3ca3d..90d98714 100644 --- a/settingsmanager.cpp +++ b/settingsmanager.cpp @@ -173,6 +173,14 @@ void SettingsManager::setLEUndoLimit(const quint32 &value) { settings.setValue("LE_UNDO_LIMIT", value); } +bool SettingsManager::getLERenderTransparentLiquidAboveTiles() { + return settings.value("LE_RENDER_TRANSPARENT_LIQUID_ABOVE_TILES", LE_RENDER_TRANSPARENT_LIQUID_ABOVE_TILES_DEFAULT).toBool(); +} + +void SettingsManager::setLERenderTransparentLiquidAboveTiles(const bool &value) { + settings.setValue("LE_RENDER_TRANSPARENT_LIQUID_ABOVE_TILES", value); +} + bool SettingsManager::getLESelectOnPlace() { return settings.value("LE_SELECT_ON_PLACE", LE_SELECT_ON_PLACE_DEFAULT).toBool(); } diff --git a/settingsmanager.h b/settingsmanager.h index 60e0bdb8..d5410c7f 100644 --- a/settingsmanager.h +++ b/settingsmanager.h @@ -61,6 +61,9 @@ class SettingsManager : public QObject quint32 getLEUndoLimit(); void setLEUndoLimit(const quint32 &value); + bool getLERenderTransparentLiquidAboveTiles(); + void setLERenderTransparentLiquidAboveTiles(const bool &value); + bool getLESelectOnPlace(); void setLESelectOnPlace(const bool &value); @@ -70,6 +73,7 @@ class SettingsManager : public QObject // Defaults - Level Editor static constexpr QColor LE_WINDOW_COLOR_DEFAULT = QColor(119, 136, 153); static constexpr int LE_UNDO_LIMIT_DEFAULT = 200; + static constexpr bool LE_RENDER_TRANSPARENT_LIQUID_ABOVE_TILES_DEFAULT = false; static constexpr bool LE_SELECT_ON_PLACE_DEFAULT = true; static constexpr bool LE_SHOW_STATUSBAR_DEFAULT = true;