diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0dd010549df..d1e0fcfd901 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -54,4 +54,4 @@ jobs: --check-level=exhaustive \ --quiet --inline-suppr --language=c++ --error-exitcode=10 \ -j"$(nproc)" --std=c++17 --enable=warning,style \ - --suppress=useStlAlgorithm src/ + --suppress=useStlAlgorithm -UEMSCRIPTEN src/ diff --git a/.gitignore b/.gitignore index 01ec19375c7..e091f09e3ff 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,13 @@ language.settings.xml # JetBrains IDE project files .idea/ +# Emacs +*~ +\#*\# +.\#* +.dir-locals.el +.projectile + # Windows build dependencies dependencies*/ diff --git a/data/images/autotiles.satc b/data/images/autotiles.satc index 3990953e3e4..dc7009ef6f5 100644 --- a/data/images/autotiles.satc +++ b/data/images/autotiles.satc @@ -14,7 +14,7 @@ ;; | ;; V ;; Contains : -;; The autotileset name (unused as of writing these lines) : (name "snow") +;; The autotileset name (used as an indicator in the editor) : (name "snow") ;; The name of the autotileset is "snow". ;; The default tile ID (used if no tile matches any mask) : (default 11) ;; If a very special tile is needed (and it doesn't exist), it will use this tile (it's a center tile) by default. @@ -75,7 +75,7 @@ ;; (Contributor, 2020) ;; ;; -;; NOTE : A single id MUST NOT OCCUR MORE THAN ONE AUTOTILE IN THE ENTIRE FILE. +;; NOTE : A single id MUST NOT OCCUR IN MORE THAN ONE AUTOTILE IN AN AUTOTILESET. ;; Otherwise, the behavior is UNDEFINED. (supertux-autotiles @@ -479,6 +479,7 @@ (mask "01011***") ) ) + (autotileset (name "block_horiz") (default 47) @@ -6109,7 +6110,7 @@ ) (autotileset - (name "jrock_a") + (name "jagged_rock") (default 7317) ;; CENTER @@ -6144,98 +6145,98 @@ (mask "***00010") ) - ;; B LEFT + ;; BOTTOM LEFT (autotile (id 7320) (solid #t) (mask "***01*0*") ) - ;; B CENTER + ;; BOTTOM CENTER (autotile (id 7321) (solid #t) (mask "***11*0*") ) - ;; B RIGHT + ;; BOTTOM RIGHT (autotile (id 7322) (solid #t) (mask "***10*0*") ) - ;; B THIN + ;; BOTTOM THIN (autotile (id 7323) (solid #t) (mask "***00*0*") ) - ;; CORNER TL + ;; CORNER TOP LEFT (autotile (id 7325) (solid #t) (mask "***11110") ) - ;; CORNER TR + ;; CORNER TOP RIGHT (autotile (id 7326) (solid #t) (mask "***11011") ) - ;; CORNER BL + ;; CORNER BOTTOM LEFT (autotile (id 7327) (solid #t) (mask "***10111") ) - ;; CORNER BR + ;; CORNER BOTTOM RIGHT (autotile (id 7328) (solid #t) (mask "***01111") ) - ;; CORNER THIN TL + ;; CORNER THIN TOP LEFT (autotile (id 7329) (solid #t) (mask "***01010") ) - ;; CORNER THIN TR + ;; CORNER THIN TOP RIGHT (autotile (id 7330) (solid #t) (mask "***10010") ) - ;; CORNER THIN TC + ;; CORNER THIN TOP CENTER (autotile (id 7331) (solid #t) (mask "***11010") ) - ;; CORNER THIN BL + ;; CORNER THIN BOTTOM LEFT (autotile (id 7332) (solid #t) (mask "***00011") ) - ;; CORNER THIN BR + ;; CORNER THIN BOTTOM RIGHT (autotile (id 7333) (solid #t) (mask "***00110") ) - ;; CORNER THIN BC + ;; CORNER THIN BOTTOM CENTER (autotile (id 7334) (solid #t) @@ -6256,8 +6257,6 @@ (mask "***10011") ) - ;; DECO TILES ----------- - ;; DECO LEFT (autotile (id 7312) @@ -6288,4 +6287,2314 @@ ) + (autotileset + (name "rock_block_horizontal") + (default 7378) + + (autotile + (id 7375) + (solid #t) + (mask "***01***") + ) + + (autotile + (id 7376) + (solid #t) + (mask "***11***") + ) + + (autotile + (id 7377) + (solid #t) + (mask "***10***") + ) + + (autotile + (id 7378) + (solid #t) + (mask "***00***") + ) + + ) + + (autotileset + (name "rock_block_vertical") + (default 7378) + + (autotile + (id 7382) + (solid #t) + (mask "*0****1*") + ) + + (autotile + (id 7386) + (solid #t) + (mask "*1****1*") + ) + + (autotile + (id 7390) + (solid #t) + (mask "*1****0*") + ) + + (autotile + (id 7378) + (solid #t) + (mask "*0****0*") + ) + + ) + + (autotileset + (name "ice_castle") + (default 4566) + + ;; CENTER + (autotile + (id 4566) + (alt-id + (id 4565) + (weight -1) + ) + (solid #t) + (mask "11111111") + (mask "*0*11*0*") + + (mask "0*0110*0") + (mask "11011110") + (mask "01111011") + + (mask "01011*0*") + (mask "*0*11010") + + + ) + + ;; LEFT + (autotile + (id 4564) + (alt-id + (id 4557) + (weight -1) + ) + (solid #t) + (mask "*1101*11") + (mask "*0*01*0*") + + (mask "**001**0") + + (mask "*0101*10") + (mask "*1001*01") + ) + + ;; RIGHT + (autotile + (id 4567) + (alt-id + (id 4558) + (weight -1) + ) + (solid #t) + (mask "11*1011*") + (mask "*0*10*0*") + + (mask "0**100**") + + (mask "10*1001*") + (mask "01*1010*") + ) + + ;; THIN + (autotile + (id 4572) + (solid #t) + (mask "*1*00*1*") + (mask "*0*00*0*") + ) + + ;; TOP LEFT + (autotile + (id 4553) + (solid #t) + (mask "*0*01*11") + (mask "01001*11") + + ) + + ;; TOP CENTER + (autotile + (id 4569) + (alt-id + (id 4555) + (weight -1) + ) + (alt-id + (id 4554) + (weight -1) + ) + (alt-id + (id 4568) + (weight -1) + ) + (solid #t) + (mask "*0*11111") + + (mask "01011111") + + ) + + ;; TOP RIGHT + (autotile + (id 4556) + (solid #t) + (mask "*0*1011*") + (mask "0101011*") + ) + + ;; TOP THIN + (autotile + (id 4561) + (solid #t) + (mask "*0*00*1*") + ) + + ;; BOTTOM LEFT + (autotile + (id 4575) + (solid #t) + (mask "*1101*0*") + (mask "*1101010") + ) + + ;; BOTTOM CENTER + (autotile + (id 4580) + (alt-id + (id 4577) + (weight -1) + ) + (alt-id + (id 4579) + (weight -1) + ) + (alt-id + (id 4576) + (weight -1) + ) + (solid #t) + (mask "11111*0*") + + (mask "11111010") + ) + + ;; BOTTOM RIGHT + (autotile + (id 4578) + (solid #t) + (mask "11*10*0*") + (mask "11*10010") + ) + + ;; BOTTOM THIN + (autotile + (id 4583) + (solid #t) + (mask "*1*00*0*") + ) + + ;; CORNER TOP LEFT + (autotile + (id 4592) + (alt-id + (id 4570) + (weight -1) + ) + (solid #t) + (mask "11111110") + (mask "01111*00") + + (mask "01111010") + (mask "01111001") + + ;;(mask "*1101110") + (mask "01111101") + ) + + ;; CORNER THIN TOP LEFT + (autotile + (id 7455) + (solid #t) + (mask "*1101110") + ) + + ;; CORNER TOP RIGHT + (autotile + (id 4593) + (alt-id + (id 4571) + (weight -1) + ) + (solid #t) + (mask "11111011") + (mask "1101100*") + + (mask "11011100") + (mask "11011010") + + ;;(mask "11*10011") + (mask "11011101") + ) + + ;; CORNER THIN TOP RIGHT + (autotile + (id 7456) + (solid #t) + (mask "11*10011") + ) + + ;; CORNER BOTTOM LEFT + (autotile + (id 4581) + (alt-id + (id 4559) + (weight -1) + ) + (solid #t) + (mask "11011111") + (mask "*0011011") + + (mask "00111011") + (mask "01011011") + + ;;(mask "11001*11") + (mask "10111011") + ) + + ;; CORNER THIN BOTTOM LEFT + (autotile + (id 7452) + (solid #t) + (mask "11001*11") + ) + + ;; CORNER BOTTOM RIGHT + (autotile + (id 4582) + (alt-id + (id 4560) + (weight -1) + ) + (solid #t) + (mask "01111111") + (mask "00*11110") + + (mask "10011110") + (mask "01011110") + + ;;(mask "0111011*") + (mask "10111110") + ) + + ;; CORNER THIN BOTTOM RIGHT + (autotile + (id 7453) + (solid #t) + (mask "0111011*") + ) + + ;; CORNER "8 COUNTER CLOCKWISE" + (autotile + (id 7451) + (solid #t) + (mask "11011011") + ) + + ;; CORNER "8 CLOCKWISE" + (autotile + (id 7454) + (solid #t) + (mask "01111110") + ) + + ) + + (autotileset + (name "chain_horizontal_attached") + (default 4663) + + (autotile + (id 4667) + (solid #t) + (mask "***01***") + ) + + (autotile + (id 4663) + (solid #t) + (mask "***11***") + (mask "***00***") + ) + + (autotile + (id 4668) + (solid #t) + (mask "***10***") + ) + + ) + + (autotileset + (name "chain_vertical_attached") + (default 4665) + + (autotile + (id 4666) + (solid #t) + (mask "*0****1*") + ) + + (autotile + (id 4665) + (solid #t) + (mask "*1****1*") + (mask "*0****0*") + ) + + (autotile + (id 4670) + (solid #t) + (mask "*1****0*") + ) + + ) + + (autotileset + (name "small_chain_horizontal") + (default 7469) + + (autotile + (id 7463) + (solid #t) + (mask "***01***") + ) + + (autotile + (id 7465) + (solid #t) + (mask "***11***") + ) + + (autotile + (id 7467) + (solid #t) + (mask "***10***") + ) + + (autotile + (id 7469) + (solid #t) + (mask "***00***") + ) + + ) + + (autotileset + (name "small_chain_vertical") + (default 7470) + + (autotile + (id 7464) + (solid #t) + (mask "*0****1*") + ) + + (autotile + (id 7466) + (solid #t) + (mask "*1****1*") + ) + + (autotile + (id 7468) + (solid #t) + (mask "*1****0*") + ) + + (autotile + (id 7470) + (solid #t) + (mask "*0****0*") + ) + + ) + + (autotileset + (name "forest_castle") + (default 4480) + + ;; CENTER + (autotile + (id 4480) + (alt-id + (id 4479) + (weight -1) + ) + (solid #t) + (mask "11111111") + (mask "*0*11*0*") + + (mask "0*0110*0") + (mask "11011110") + (mask "01111011") + + (mask "01011*0*") + (mask "*0*11010") + + + ) + + ;; LEFT + (autotile + (id 4478) + (alt-id + (id 4467) + (weight -1) + ) + (solid #t) + (mask "*1101*11") + (mask "*0*01*0*") + + (mask "**001**0") + + (mask "*0101*10") + (mask "*1001*01") + ) + + ;; RIGHT + (autotile + (id 4481) + (alt-id + (id 4468) + (weight -1) + ) + (solid #t) + (mask "11*1011*") + (mask "*0*10*0*") + + (mask "0**100**") + + (mask "10*1001*") + (mask "01*1010*") + ) + + ;; THIN + (autotile + (id 4486) + (solid #t) + (mask "*1*00*1*") + (mask "*0*00*0*") + ) + + ;; TOP LEFT + (autotile + (id 4463) + (solid #t) + (mask "*0*01*11") + (mask "01001*11") + + ) + + ;; TOP CENTER + (autotile + (id 4483) + (alt-id + (id 4465) + (weight -1) + ) + (alt-id + (id 4482) + (weight -1) + ) + (alt-id + (id 4464) + (weight -1) + ) + (solid #t) + (mask "*0*11111") + + (mask "01011111") + + ) + + ;; TOP RIGHT + (autotile + (id 4466) + (solid #t) + (mask "*0*1011*") + (mask "0101011*") + ) + + ;; TOP THIN + (autotile + (id 4471) + (solid #t) + (mask "*0*00*1*") + ) + + ;; BOTTOM LEFT + (autotile + (id 4493) + (solid #t) + (mask "*1101*0*") + (mask "*1101010") + ) + + ;; BOTTOM CENTER + (autotile + (id 4498) + (alt-id + (id 4495) + (weight -1) + ) + (alt-id + (id 4497) + (weight -1) + ) + (alt-id + (id 4494) + (weight -1) + ) + (solid #t) + (mask "11111*0*") + + (mask "11111010") + ) + + ;; BOTTOM RIGHT + (autotile + (id 4496) + (solid #t) + (mask "11*10*0*") + (mask "11*10010") + ) + + ;; BOTTOM THIN + (autotile + (id 4501) + (solid #t) + (mask "*1*00*0*") + ) + + ;; CORNER TOP LEFT + (autotile + (id 4514) + (alt-id + (id 4484) + (weight -1) + ) + (solid #t) + (mask "11111110") + (mask "01111*00") + + (mask "01111010") + (mask "01111001") + + ;;(mask "*1101110") + (mask "01111101") + ) + + ;; CORNER THIN TOP LEFT + (autotile + (id 7461) + (solid #t) + (mask "*1101110") + ) + + ;; CORNER TOP RIGHT + (autotile + (id 4515) + (alt-id + (id 4485) + (weight -1) + ) + (solid #t) + (mask "11111011") + (mask "1101100*") + + (mask "11011100") + (mask "11011010") + + ;;(mask "11*10011") + (mask "11011101") + ) + + ;; CORNER THIN TOP RIGHT + (autotile + (id 7462) + (solid #t) + (mask "11*10011") + ) + + ;; CORNER BOTTOM LEFT + (autotile + (id 4499) + (alt-id + (id 4469) + (weight -1) + ) + (solid #t) + (mask "11011111") + (mask "*0011011") + + (mask "00111011") + (mask "01011011") + + ;;(mask "11001*11") + (mask "10111011") + ) + + ;; CORNER THIN BOTTOM LEFT + (autotile + (id 7458) + (solid #t) + (mask "11001*11") + ) + + ;; CORNER BOTTOM RIGHT + (autotile + (id 4500) + (alt-id + (id 4470) + (weight -1) + ) + (solid #t) + (mask "01111111") + (mask "00*11110") + + (mask "10011110") + (mask "01011110") + + ;;(mask "0111011*") + (mask "10111110") + ) + + ;; CORNER THIN BOTTOM RIGHT + (autotile + (id 7459) + (solid #t) + (mask "0111011*") + ) + + ;; CORNER "8 COUNTER CLOCKWISE" + (autotile + (id 7457) + (solid #t) + (mask "11011011") + ) + + ;; CORNER "8 CLOCKWISE" + (autotile + (id 7460) + (solid #t) + (mask "01111110") + ) + + ) + + ;; SUPPORT MULTIPLE AUTOTILESETS PER TILE - START + + (autotileset + (name "snow_ice_floor") + (default 11) + + ;; CENTER + (autotile + (id 11) + (alt-id + (id 19) + (weight 0.002) + ) + (alt-id + (id 1539) + (weight 0.002) + ) + (alt-id + (id 5368) + (weight 0.2) + ) + (alt-id + (id 5369) + (weight 0.2) + ) + (solid #t) + (mask "***11***") + ) + + ;; LEFT + (autotile + (id 10) + (solid #t) + (mask "0**010**") + (mask "0**0110*") + (mask "10*010**") + (mask "10*0110*") + ) + + ;; RIGHT + (autotile + (id 12) + (solid #t) + (mask "**010**0") + (mask "**010*01") + (mask "*0110**0") + (mask "*0110*01") + ) + + ;; THIN + (autotile + (id 206) + (solid #t) + (mask "01000*0*") + (mask "*0*00010") + (mask "01000010") + (mask "*0*00*0*") + + ;; Placeholder masks + ;;(mask "*0*00110") + ;;(mask "*0*00011") + ;;(mask "*1000110") + ;;(mask "01*00011") + ) + + ;; CORNER THIN BOTTOM CENTER + (autotile + (id 5244) + (solid #t) + (mask "0*000111") + (mask "*0*00111") + ) + + ;; CORNER THIN "C" + (autotile + (id 7425) + (solid #t) + (mask "01100011") + ) + + ;; CORNER THIN "D" + (autotile + (id 7424) + (solid #t) + (mask "11000110") + ) + + ;; CORNER "I" + (autotile + (id 7432) + (solid #t) + (mask "11100111") + ) + + ;; CORNER "S" + (autotile + (id 7426) + (solid #t) + (mask "01100110") + ) + + ;; CORNER "Z" + (autotile + (id 7427) + (solid #t) + (mask "11000011") + ) + + ;; CORNER "J" + (autotile + (id 7428) + (solid #t) + (mask "11100110") + ) + + ;; CORNER "t" + (autotile + (id 7429) + (solid #t) + (mask "11100011") + ) + + ;; CORNER "f" + (autotile + (id 7430) + (solid #t) + (mask "01100111") + ) + + ;; CORNER "1" + (autotile + (id 7431) + (solid #t) + (mask "11000111") + ) + + ;; CORNER THIN BOTTOM RIGHT + (autotile + (id 7433) + (solid #t) + (mask "01000110") + (mask "*0*00110") + ) + + ;; CORNER THIN BOTTOM LEFT + (autotile + (id 7434) + (solid #t) + (mask "01000011") + (mask "*0*00011") + ) + + ;; CORNER BOTTOM RIGHT + (autotile + (id 5245) + (solid #t) + (mask "0**0111*") + (mask "10*0111*") + + ) + + ;; CORNER BOTTOM LEFT + (autotile + (id 5247) + (solid #t) + (mask "**010*11") + (mask "*0110*11") + ) + + ;; CORNER "C" + (autotile + (id 7422) + (solid #t) + (mask "*1110*11") + ) + + ;; CORNER "D" + (autotile + (id 7423) + (solid #t) + (mask "11*0111*") + ) + + ;; CORNER TOP LEFT + (autotile + (id 30) + (solid #t) + (mask "*1110**0") + (mask "*1110*01") + ) + + ;; CORNER TOP RIGHT + (autotile + (id 31) + (solid #t) + (mask "11*010**") + (mask "11*0110*") + ) + + ;; CORNER THIN TOP CENTER + (autotile + (id 3055) + (solid #t) + (mask "11100*0*") + (mask "11100010") + ) + + ;; CORNER THIN TOP RIGHT + (autotile + (id 3057) + (solid #t) + (mask "11000010") + (mask "11000*0*") + ) + + ;; CORNER THIN TOP LEFT + (autotile + (id 3053) + (solid #t) + (mask "01100010") + (mask "01100*0*") + + ) + + ;; DECO TOP LEFT + (autotile + (id 5239) + (solid #f) + (mask "*0***011") + ) + + ;; DECO TOP CENTER + (autotile + (id 5240) + (solid #f) + (mask "*0***111") + ) + + ;; DECO TOP RIGHT + (autotile + (id 5241) + (solid #f) + (mask "*0***110") + ) + + ;; DECO TOP THIN + (autotile + (id 5238) + (solid #f) + (mask "*0***010") + ) + + ;; DECO BOTTOM LEFT + (autotile + (id 16) + (solid #f) + (mask "011***0*") + ) + + ;; DECO BOTTOM CENTER + (autotile + (id 17) + (alt-id + (id 3991) + (weight 0.2) + ) + (solid #f) + (mask "111***0*") + ) + + ;; DECO BOTTOM RIGHT + (autotile + (id 18) + (solid #f) + (mask "110***0*") + ) + + ;; DECO BOTTOM THIN + (autotile + (id 3059) + (solid #f) + (mask "010***0*") + ) + + ;; DECO LEFT-LEFT + (autotile + (id 7435) + (solid #f) + (mask "011**011") + ) + + ;; DECO LEFT-CENTER + (autotile + (id 7436) + (solid #f) + (mask "111**011") + ) + + ;; DECO LEFT-RIGHT + (autotile + (id 7437) + (solid #f) + (mask "110**011") + ) + + ;; DECO LEFT-THIN + (autotile + (id 7438) + (solid #f) + (mask "010**011") + ) + + ;; DECO CENTER-LEFT + (autotile + (id 7439) + (solid #f) + (mask "011**111") + ) + + ;; DECO CENTER-CENTER + (autotile + (id 7440) + (solid #f) + (mask "111**111") + ) + + ;; DECO CENTER-RIGHT + (autotile + (id 7441) + (solid #f) + (mask "110**111") + ) + + ;; DECO CENTER-THIN + (autotile + (id 7442) + (solid #f) + (mask "010**111") + ) + + ;; DECO RIGHT-LEFT + (autotile + (id 7443) + (solid #f) + (mask "011**110") + ) + + ;; DECO RIGHT-CENTER + (autotile + (id 7444) + (solid #f) + (mask "111**110") + ) + + ;; DECO RIGHT-RIGHT + (autotile + (id 7445) + (solid #f) + (mask "110**110") + ) + + ;; DECO RIGHT-THIN + (autotile + (id 7446) + (solid #f) + (mask "010**110") + ) + + ;; DECO THIN-LEFT + (autotile + (id 7447) + (solid #f) + (mask "011**010") + ) + + ;; DECO THIN-CENTER + (autotile + (id 7448) + (solid #f) + (mask "111**010") + ) + + ;; DECO THIN-RIGHT + (autotile + (id 7449) + (solid #f) + (mask "110**010") + ) + + ;; DECO THIN-THIN + (autotile + (id 7450) + (solid #f) + (mask "010**010") + ) + + ) + + (autotileset + (name "snow_holes") + (default 11) + + ;; CENTER + (autotile + (id 11) + (alt-id + (id 19) + (weight 0.002) + ) + (alt-id + (id 1539) + (weight 0.002) + ) + (alt-id + (id 5368) + (weight 0.2) + ) + (alt-id + (id 5369) + (weight 0.2) + ) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) + + ;; DECO TOP LEFT + (autotile + (id 2121) + (solid #f) + (mask "00000001") + ) + + ;; DECO TOP + (autotile + (id 2122) + (solid #f) + (mask "00000*1*") + ) + + ;; DECO TOP RIGHT + (autotile + (id 2123) + (solid #f) + (mask "00000100") + ) + + ;; DECO LEFT + (autotile + (id 2126) + (solid #f) + (mask "00*0100*") + ) + + ;; DECO RIGHT + (autotile + (id 2128) + (solid #f) + (mask "*0010*00") + ) + + ;; DECO BOTTOM LEFT + (autotile + (id 2131) + (solid #f) + (mask "00100000") + ) + + ;; DECO BOTTOM + (autotile + (id 2132) + (solid #f) + (mask "*1*00000") + ) + + ;; DECO BOTTOM RIGHT + (autotile + (id 2133) + (solid #f) + (mask "10000000") + ) + + ;; DECO CORNER BOTTOM RIGHT + (autotile + (id 2130) + (solid #f) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + + ;; DECO CORNER BOTTOM LEFT + (autotile + (id 2129) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + + ;; DECO CORNER TOP RIGHT + (autotile + (id 2125) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + + ;; DECO CORNER TOP LEFT + (autotile + (id 2124) + (solid #f) + (mask "*1*10*00") + (mask "*1*00100") + (mask "*0110*00") + ) + ) + + (autotileset + (name "snow_underground_holes") + (default 2391) + + ;; CENTER + (autotile + (id 2391) + (alt-id + (id 2396) + (weight 0.1) + ) + (alt-id + (id 2397) + (weight 0.1) + ) + (alt-id + (id 2398) + (weight 0.1) + ) + (alt-id + (id 2399) + (weight 0.1) + ) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) + + ;; DECO TOP LEFT + (autotile + (id 7039) + (solid #f) + (mask "00000001") + ) + + ;; DECO TOP + (autotile + (id 7033) + (solid #f) + (mask "00000*1*") + ) + + ;; DECO TOP RIGHT + (autotile + (id 7040) + (solid #f) + (mask "00000100") + ) + + ;; DECO LEFT + (autotile + (id 7027) + (solid #f) + (mask "00*0100*") + ) + + ;; DECO RIGHT + (autotile + (id 7025) + (solid #f) + (mask "*0010*00") + ) + + ;; DECO BOTTOM LEFT + (autotile + (id 7046) + (solid #f) + (mask "00100000") + ) + + ;; DECO BOTTOM + (autotile + (id 7019) + (solid #f) + (mask "*1*00000") + ) + + ;; DECO BOTTOM RIGHT + (autotile + (id 7047) + (solid #f) + (mask "10000000") + ) + + ;; DECO CORNER BOTTOM RIGHT + (autotile + (id 7034) + (solid #f) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + + ;; DECO CORNER BOTTOM LEFT + (autotile + (id 7032) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + + ;; DECO CORNER TOP RIGHT + (autotile + (id 7020) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + + ;; DECO CORNER TOP LEFT + (autotile + (id 7018) + (solid #f) + (mask "*1*10*00") + (mask "*1*00100") + (mask "*0110*00") + ) + ) + + (autotileset + (name "forest_earth_floor") + (default 1009) + + ;; CENTER + (autotile + (id 1009) + (alt-id + (id 1010) + (weight 0.1) + ) + (alt-id + (id 1013) + (weight 0.3) + ) + (alt-id + (id 1014) + (weight 0.3) + ) + (solid #t) + (mask "***11111") + ) + + ;; LEFT + (autotile + (id 1008) + (alt-id + (id 1012) + (weight 0.5) + ) + (solid #t) + (mask "***01011") + ) + + ;; RIGHT + (autotile + (id 1011) + (alt-id + (id 1015) + (weight 0.5) + ) + (solid #t) + (mask "***10110") + ) + + ;; THIN + (autotile + (id 1738) + (solid #t) + (mask "***00010") + ) + + ;; BOTTOM LEFT + (autotile + (id 1016) + (solid #t) + (mask "***01*0*") + ) + + ;; BOTTOM CENTER + (autotile + (id 1017) + (alt-id + (id 1018) + (weight 0.5) + ) + (solid #t) + (mask "***11*0*") + ) + + ;; BOTTOM RIGHT + (autotile + (id 1019) + (solid #t) + (mask "***10*0*") + ) + + ;; BOTTOM THIN + (autotile + (id 3472) + (solid #t) + (mask "***00*0*") + ) + + ;; CORNER TOP LEFT + (autotile + (id 4317) + (solid #t) + (mask "***11110") + ) + + ;; CORNER TOP RIGHT + (autotile + (id 4318) + (solid #t) + (mask "***11011") + ) + + ;; CORNER BOTTOM LEFT + (autotile + (id 1820) + (solid #t) + (mask "***10111") + ) + + ;; CORNER BOTTOM RIGHT + (autotile + (id 1817) + (solid #t) + (mask "***01111") + ) + + ;; CORNER THIN TOP + (autotile + (id 4312) + (solid #t) + (mask "***11010") + ) + + ;; CORNER THIN BOTTOM + (autotile + (id 1818) + (solid #t) + (mask "***00111") + ) + + ;; CORNER THIN TOP LEFT + (autotile + (id 4302) + (solid #t) + (mask "***01010") + ) + + ;; CORNER THIN TOP RIGHT + (autotile + (id 4303) + (solid #t) + (mask "***10010") + ) + + ;; CORNER THIN BOTTOM LEFT + (autotile + (id 5599) + (solid #t) + (mask "***00011") + ) + + ;; CORNER THIN BOTTOM RIGHT + (autotile + (id 5598) + (solid #t) + (mask "***00110") + ) + + ;; CORNER "S" + (autotile + (id 5588) + (solid #t) + (mask "***01110") + ) + + ;; CORNER "Z" + (autotile + (id 5589) + (solid #t) + (mask "***10011") + ) + + ;; DECO LEFT + (autotile + (id 1723) + (solid #f) + (mask "*****011") + ) + + ;; DECO CENTER + (autotile + (id 1724) + (alt-id + (id 1725) + (weight 0.5) + ) + (solid #f) + (mask "*****111") + ) + + ;; DECO RIGHT + (autotile + (id 1726) + (solid #f) + (mask "*****110") + ) + + ;; DECO THIN + (autotile + (id 1819) + (solid #f) + (mask "*****010") + ) + + ) + + (autotileset + (name "corrupted_forest_earth_floor") + (default 1432) + + ;; CENTER + (autotile + (id 1432) + (alt-id + (id 1433) + (weight 0.1) + ) + (alt-id + (id 1436) + (weight 0.3) + ) + (alt-id + (id 1437) + (weight 0.3) + ) + (solid #t) + (mask "***11111") + ) + + ;; LEFT + (autotile + (id 1431) + (alt-id + (id 1435) + (weight 0.5) + ) + (solid #t) + (mask "***01011") + ) + + ;; RIGHT + (autotile + (id 1434) + (alt-id + (id 1438) + (weight 0.5) + ) + (solid #t) + (mask "***10110") + ) + + ;; THIN + (autotile + (id 6544) + (solid #t) + (mask "***00010") + ) + + ;; BOTTOM LEFT + (autotile + (id 1439) + (solid #t) + (mask "***01*0*") + ) + + ;; BOTTOM CENTER + (autotile + (id 1440) + (alt-id + (id 1441) + (weight 0.5) + ) + (solid #t) + (mask "***11*0*") + ) + + ;; BOTTOM RIGHT + (autotile + (id 1442) + (solid #t) + (mask "***10*0*") + ) + + ;; BOTTOM THIN + (autotile + (id 6547) + (solid #t) + (mask "***00*0*") + ) + + ;; CORNER TOP LEFT + (autotile + (id 3414) + (solid #t) + (mask "***11110") + ) + + ;; CORNER TOP RIGHT + (autotile + (id 3415) + (solid #t) + (mask "***11011") + ) + + ;; CORNER BOTTOM LEFT + (autotile + (id 6202) + (solid #t) + (mask "***10111") + ) + + ;; CORNER BOTTOM RIGHT + (autotile + (id 6199) + (solid #t) + (mask "***01111") + ) + + ;; CORNER THIN TOP + (autotile + (id 6545) + (solid #t) + (mask "***11010") + ) + + ;; CORNER THIN BOTTOM + (autotile + (id 6200) + (solid #t) + (mask "***00111") + ) + + ;; CORNER THIN TOP LEFT + (autotile + (id 6558) + (solid #t) + (mask "***01010") + ) + + ;; CORNER THIN TOP RIGHT + (autotile + (id 6559) + (solid #t) + (mask "***10010") + ) + + ;; CORNER THIN BOTTOM LEFT + (autotile + (id 6592) + (solid #t) + (mask "***00011") + ) + + ;; CORNER THIN BOTTOM RIGHT + (autotile + (id 6591) + (solid #t) + (mask "***00110") + ) + + ;; CORNER "S" + (autotile + (id 6573) + (solid #t) + (mask "***01110") + ) + + ;; CORNER "Z" + (autotile + (id 6574) + (solid #t) + (mask "***10011") + ) + + ;; DECO LEFT + (autotile + (id 6193) + (solid #f) + (mask "*****011") + ) + + ;; DECO CENTER + (autotile + (id 6194) + (alt-id + (id 6195) + (weight 0.5) + ) + (solid #f) + (mask "*****111") + ) + + ;; DECO RIGHT + (autotile + (id 6196) + (solid #f) + (mask "*****110") + ) + + ;; DECO THIN + (autotile + (id 6201) + (solid #f) + (mask "*****010") + ) + + ) + + (autotileset + (name "forest_holes") + (default 1009) + + ;; CENTER + (autotile + (id 1009) + (alt-id + (id 1010) + (weight 0.1) + ) + (alt-id + (id 1013) + (weight 0.3) + ) + (alt-id + (id 1014) + (weight 0.3) + ) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) + + ;; DECO TOP LEFT + (autotile + (id 5627) + (solid #f) + (mask "00000001") + ) + + ;; DECO TOP + (autotile + (id 5621) + (solid #f) + (mask "00000*1*") + ) + + ;; DECO TOP RIGHT + (autotile + (id 5628) + (solid #f) + (mask "00000100") + ) + + ;; DECO LEFT + (autotile + (id 5615) + (solid #f) + (mask "00*0100*") + ) + + ;; DECO RIGHT + (autotile + (id 5613) + (solid #f) + (mask "*0010*00") + ) + + ;; DECO BOTTOM LEFT + (autotile + (id 5634) + (solid #f) + (mask "00100000") + ) + + ;; DECO BOTTOM + (autotile + (id 5607) + (solid #f) + (mask "*1*00000") + ) + + ;; DECO BOTTOM RIGHT + (autotile + (id 5635) + (solid #f) + (mask "10000000") + ) + + ;; DECO CORNER BOTTOM RIGHT + (autotile + (id 5622) + (solid #f) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + + ;; DECO CORNER BOTTOM LEFT + (autotile + (id 5620) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + + ;; DECO CORNER TOP RIGHT + (autotile + (id 5608) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + + ;; DECO CORNER TOP LEFT + (autotile + (id 5606) + (solid #f) + (mask "*1*10*00") + (mask "*1*00100") + (mask "*0110*00") + ) + ) + + (autotileset + (name "underground_forest_holes") + (default 1869) + + ;; CENTER + (autotile + (id 1869) + (alt-id + (id 1870) + (weight 0.1) + ) + (alt-id + (id 1873) + (weight 0.3) + ) + (alt-id + (id 1874) + (weight 0.3) + ) + (alt-id + (id 7050) + (weight 0.1) + ) + (alt-id + (id 7041) + (weight 0.1) + ) + (alt-id + (id 7167) + (weight 0.1) + ) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) + + ;; DECO TOP LEFT + (autotile + (id 7093) + (solid #f) + (mask "00000001") + ) + + ;; DECO TOP + (autotile + (id 7087) + (solid #f) + (mask "00000*1*") + ) + + ;; DECO TOP RIGHT + (autotile + (id 7094) + (solid #f) + (mask "00000100") + ) + + ;; DECO LEFT + (autotile + (id 7081) + (solid #f) + (mask "00*0100*") + ) + + ;; DECO RIGHT + (autotile + (id 7079) + (solid #f) + (mask "*0010*00") + ) + + ;; DECO BOTTOM LEFT + (autotile + (id 7100) + (solid #f) + (mask "00100000") + ) + + ;; DECO BOTTOM + (autotile + (id 7073) + (solid #f) + (mask "*1*00000") + ) + + ;; DECO BOTTOM RIGHT + (autotile + (id 7101) + (solid #f) + (mask "10000000") + ) + + ;; DECO CORNER BOTTOM RIGHT + (autotile + (id 7088) + (solid #f) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + + ;; DECO CORNER BOTTOM LEFT + (autotile + (id 7086) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + + ;; DECO CORNER TOP RIGHT + (autotile + (id 7074) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + + ;; DECO CORNER TOP LEFT + (autotile + (id 7072) + (solid #f) + (mask "*1*10*00") + (mask "*1*00100") + (mask "*0110*00") + ) + ) + + (autotileset + (name "corrupted_forest_holes") + (default 1432) + + ;; CENTER + (autotile + (id 1432) + (alt-id + (id 1433) + (weight 0.1) + ) + (alt-id + (id 1436) + (weight 0.3) + ) + (alt-id + (id 1437) + (weight 0.3) + ) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) + + ;; DECO TOP LEFT + (autotile + (id 6332) + (solid #f) + (mask "00000001") + ) + + ;; DECO TOP + (autotile + (id 6326) + (solid #f) + (mask "00000*1*") + ) + + ;; DECO TOP RIGHT + (autotile + (id 6333) + (solid #f) + (mask "00000100") + ) + + ;; DECO LEFT + (autotile + (id 6320) + (solid #f) + (mask "00*0100*") + ) + + ;; DECO RIGHT + (autotile + (id 6318) + (solid #f) + (mask "*0010*00") + ) + + ;; DECO BOTTOM LEFT + (autotile + (id 6339) + (solid #f) + (mask "00100000") + ) + + ;; DECO BOTTOM + (autotile + (id 6312) + (solid #f) + (mask "*1*00000") + ) + + ;; DECO BOTTOM RIGHT + (autotile + (id 6340) + (solid #f) + (mask "10000000") + ) + + ;; DECO CORNER BOTTOM RIGHT + (autotile + (id 6327) + (solid #f) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + + ;; DECO CORNER BOTTOM LEFT + (autotile + (id 6325) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + + ;; DECO CORNER TOP RIGHT + (autotile + (id 6313) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + + ;; DECO CORNER TOP LEFT + (autotile + (id 6311) + (solid #f) + (mask "*1*10*00") + (mask "*1*00100") + (mask "*0110*00") + ) + ) + + (autotileset + (name "underground_corrupted_holes") + (default 6837) + + ;; CENTER + (autotile + (id 6837) + (alt-id + (id 6838) + (weight 0.1) + ) + (alt-id + (id 6851) + (weight 0.3) + ) + (alt-id + (id 6852) + (weight 0.3) + ) + (alt-id + (id 6952) + (weight 0.1) + ) + (alt-id + (id 6955) + (weight 0.1) + ) + (alt-id + (id 6958) + (weight 0.1) + ) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) + + ;; DECO TOP LEFT + (autotile + (id 6790) + (solid #f) + (mask "00000001") + ) + + ;; DECO TOP + (autotile + (id 6784) + (solid #f) + (mask "00000*1*") + ) + + ;; DECO TOP RIGHT + (autotile + (id 6791) + (solid #f) + (mask "00000100") + ) + + ;; DECO LEFT + (autotile + (id 6778) + (solid #f) + (mask "00*0100*") + ) + + ;; DECO RIGHT + (autotile + (id 6776) + (solid #f) + (mask "*0010*00") + ) + + ;; DECO BOTTOM LEFT + (autotile + (id 6797) + (solid #f) + (mask "00100000") + ) + + ;; DECO BOTTOM + (autotile + (id 6770) + (solid #f) + (mask "*1*00000") + ) + + ;; DECO BOTTOM RIGHT + (autotile + (id 6798) + (solid #f) + (mask "10000000") + ) + + ;; DECO CORNER BOTTOM RIGHT + (autotile + (id 6785) + (solid #f) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + + ;; DECO CORNER BOTTOM LEFT + (autotile + (id 6783) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + + ;; DECO CORNER TOP RIGHT + (autotile + (id 6771) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + + ;; DECO CORNER TOP LEFT + (autotile + (id 6769) + (solid #f) + (mask "*1*10*00") + (mask "*1*00100") + (mask "*0110*00") + ) + ) + + (autotileset + (name "chain_horizontal_loose") + (default 4663) + + (autotile + (id 4662) + (solid #t) + (mask "***01***") + ) + + (autotile + (id 4663) + (solid #t) + (mask "***11***") + (mask "***00***") + ) + + (autotile + (id 4664) + (solid #t) + (mask "***10***") + ) + + ) + + (autotileset + (name "chain_vertical_loose") + (default 4665) + + (autotile + (id 4661) + (solid #t) + (mask "*0****1*") + ) + + (autotile + (id 4665) + (solid #t) + (mask "*1****1*") + (mask "*0****0*") + ) + + (autotile + (id 4669) + (solid #t) + (mask "*1****0*") + ) + + ) + + ;; SUPPORT MULTIPLE AUTOTILESETS PER TILE - END + ) diff --git a/data/images/autotiles_ice_world.satc b/data/images/autotiles_ice_world.satc index 6d03488863c..1c6bf3ebe2e 100644 --- a/data/images/autotiles_ice_world.satc +++ b/data/images/autotiles_ice_world.satc @@ -1,6 +1,7 @@ ;; See autotiles.satc for instructions (supertux-autotiles + (autotileset (name "invisible_paths") (default 45) @@ -337,89 +338,87 @@ (mask "*0*00*0*") ) ) + (autotileset (name "snow") (default 105) (autotile - (id 105) - (solid #t) - (mask "********") - ) + (id 109) + (solid #f) + (mask "10000000") + ) (autotile - (id 105) + (id 113) (solid #f) - (mask "*1****1*") - (mask "***11***") - ) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + (autotile + (id 112) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + (autotile + (id 111) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + (autotile + (id 110) + (solid #f) + (mask "*1*10*00") + (mask "*1*00100") + (mask "*0110*00") + ) (autotile (id 101) (solid #f) (mask "00000001") - ) + ) (autotile (id 102) (solid #f) (mask "00000*1*") - ) + ) (autotile (id 103) (solid #f) (mask "00000100") - ) + ) (autotile (id 104) (solid #f) (mask "00*0100*") - ) + ) + (autotile + (id 105) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) (autotile (id 106) (solid #f) (mask "*0010*00") - ) + ) (autotile (id 107) (solid #f) (mask "00100000") - ) + ) (autotile (id 108) (solid #f) (mask "*1*00000") ) - (autotile - (id 109) - (solid #f) - (mask "10000000") - ) - (autotile - (id 110) - (solid #f) - (mask "*1*10*00") - (mask "*0110*00") - (mask "*1*00100") - ) - (autotile - (id 111) - (solid #f) - (mask "*1*0100*") - (mask "10*0100*") - (mask "*1*00001") - ) - (autotile - (id 112) - (solid #f) - (mask "*0010*1*") - (mask "*0010*01") - (mask "10000*1*") - ) - (autotile - (id 113) - (solid #f) - (mask "00*01*1*") - (mask "00100*1*") - (mask "00*0110*") - ) ) + (autotileset (name "crystal") (default 238) @@ -590,6 +589,7 @@ (mask "*1*00000") ) ) + (autotileset (name "ice_cave_ceiling") (default 689) @@ -669,6 +669,7 @@ (mask "00000100") ) ) + (autotileset (name "trees") (default 140) @@ -1617,4 +1618,779 @@ (mask "*1*00001") ) ) + + (autotileset + (name "snow_layer") + (default 105) + (autotile + (id 252) + (solid #f) + (mask "10000000") + ) + (autotile + (id 256) + (solid #f) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + (autotile + (id 255) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + (autotile + (id 254) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + (autotile + (id 253) + (solid #f) + (mask "*1*10*00") + (mask "*1*00100") + (mask "*0110*00") + ) + (autotile + (id 249) + (solid #f) + (mask "00000001") + ) + (autotile + (id 125) + (solid #f) + (mask "00000*1*") + ) + (autotile + (id 250) + (solid #f) + (mask "00000100") + ) + (autotile + (id 128) + (solid #f) + (mask "00*0100*") + ) + (autotile + (id 105) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) + (autotile + (id 134) + (solid #f) + (mask "*0010*00") + ) + (autotile + (id 251) + (solid #f) + (mask "00100000") + ) + (autotile + (id 131) + (solid #f) + (mask "*1*00000") + ) + ) + + (autotileset + (name "ice_holes") + (default 689) + (autotile + (id 222) + (solid #f) + (mask "00*0100*") + ) + (autotile + (id 689) + (alt-id + (id 223) + (weight 0.02) + ) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) + (autotile + (id 224) + (solid #f) + (mask "*0010*00") + ) + (autotile + (id 225) + (solid #f) + (mask "00100000") + ) + (autotile + (id 226) + (solid #f) + (mask "*1*00000") + ) + (autotile + (id 227) + (solid #f) + (mask "10000000") + ) + (autotile + (id 232) + (solid #f) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + (autotile + (id 231) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + (autotile + (id 229) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + (autotile + (id 228) + (solid #f) + (mask "*1*10*00") + (mask "*1*00100") + (mask "*0110*00") + ) + (autotile + (id 219) + (solid #f) + (mask "00000001") + ) + (autotile + (id 220) + (solid #f) + (mask "00000*1*") + ) + (autotile + (id 221) + (solid #f) + (mask "00000100") + ) + ) + + (autotileset + (name "snow_cliff") + (default 105) + (autotile + (id 449) + (solid #f) + (mask "10000000") + ) + (autotile + (id 113) + (solid #f) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + (autotile + (id 112) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + (autotile + (id 456) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + (autotile + (id 457) + (solid #f) + (mask "*1*10*00") + (mask "*1*00100") + (mask "*0110*00") + ) + (autotile + (id 101) + (solid #f) + (mask "00000001") + ) + (autotile + (id 102) + (solid #f) + (mask "00000*1*") + ) + (autotile + (id 103) + (solid #f) + (mask "00000100") + ) + (autotile + (id 104) + (solid #f) + (mask "00*0100*") + ) + (autotile + (id 105) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) + (autotile + (id 106) + (solid #f) + (mask "*0010*00") + ) + (autotile + (id 447) + (solid #f) + (mask "00100000") + ) + (autotile + (id 448) + (solid #f) + (mask "*1*00000") + ) + ) + + (autotileset + (name "ice_cave_cliff") + (default 652) + (autotile + (id 663) + (solid #f) + (mask "10000000") + ) + (autotile + (id 657) + (solid #f) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + (autotile + (id 658) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + (autotile + (id 670) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + (autotile + (id 671) + (solid #f) + (mask "*1*10*00") + (mask "*1*00100") + (mask "*0110*00") + ) + (autotile + (id 648) + (solid #f) + (mask "00000001") + ) + (autotile + (id 649) + (solid #f) + (mask "00000*1*") + ) + (autotile + (id 650) + (solid #f) + (mask "00000100") + ) + (autotile + (id 651) + (solid #f) + (mask "00*0100*") + ) + (autotile + (id 652) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) + (autotile + (id 653) + (solid #f) + (mask "*0010*00") + ) + (autotile + (id 661) + (solid #f) + (mask "00100000") + ) + (autotile + (id 662) + (solid #f) + (mask "*1*00000") + ) + ) + + (autotileset + (name "forest_cliff") + (default 261) + (autotile + (id 257) + (solid #f) + (mask "00000001") + ) + (autotile + (id 258) + (solid #f) + (mask "00000*1*") + ) + (autotile + (id 259) + (solid #f) + (mask "00000100") + ) + (autotile + (id 260) + (solid #f) + (mask "00*0100*") + ) + (autotile + (id 261) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) + (autotile + (id 262) + (solid #f) + (mask "*0010*00") + ) + (autotile + (id 270) + (solid #f) + (mask "00100000") + ) + (autotile + (id 271) + (solid #f) + (mask "*1*00000") + ) + (autotile + (id 272) + (solid #f) + (mask "10000000") + ) + (autotile + (id 266) + (solid #f) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + (autotile + (id 267) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + (autotile + (id 285) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + (autotile + (id 286) + (solid #f) + (mask "*1*10*00") + (mask "*1*00100") + (mask "*0110*00") + ) + ) + + (autotileset + (name "corrupted_forest_cliff") + (default 304) + (autotile + (id 304) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) + (autotile + (id 305) + (solid #f) + (mask "*0010*00") + ) + (autotile + (id 313) + (solid #f) + (mask "00100000") + ) + (autotile + (id 314) + (solid #f) + (mask "*1*00000") + ) + (autotile + (id 315) + (solid #f) + (mask "10000000") + ) + (autotile + (id 309) + (solid #f) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + (autotile + (id 310) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + (autotile + (id 322) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + (autotile + (id 323) + (solid #f) + (mask "*1*10*00") + (mask "01*00100") + (mask "*0110*00") + ) + (autotile + (id 300) + (solid #f) + (mask "00000001") + ) + (autotile + (id 301) + (solid #f) + (mask "00000*1*") + ) + (autotile + (id 302) + (solid #f) + (mask "00000100") + ) + (autotile + (id 303) + (solid #f) + (mask "00*0100*") + ) + ) + + (autotileset + (name "corrupted_forest_transition") + (default 304) + (autotile + (id 304) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) + (autotile + (id 562) + (solid #f) + (mask "*0010*00") + ) + (autotile + (id 569) + (solid #f) + (mask "00100000") + ) + (autotile + (id 560) + (solid #f) + (mask "*1*00000") + ) + (autotile + (id 570) + (solid #f) + (mask "10000000") + ) + (autotile + (id 566) + (solid #f) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + (autotile + (id 564) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + (autotile + (id 561) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + (autotile + (id 559) + (solid #f) + (mask "*1*10*00") + (mask "01*00100") + (mask "*0110*00") + ) + (autotile + (id 567) + (solid #f) + (mask "00000001") + ) + (autotile + (id 565) + (solid #f) + (mask "00000*1*") + ) + (autotile + (id 568) + (solid #f) + (mask "00000100") + ) + (autotile + (id 563) + (solid #f) + (mask "00*0100*") + ) + ) + + (autotileset + (name "water_waves_horizontal") + (default 5) + (autotile + (id 5) + (solid #t) + (mask "***00***") + ) + (autotile + (id 2) + (solid #t) + (mask "***01***") + ) + (autotile + (id 3) + (solid #t) + (mask "***11***") + ) + (autotile + (id 4) + (solid #t) + (mask "***10***") + ) + ) + + (autotileset + (name "water_waves_vertical") + (default 5) + (autotile + (id 5) + (solid #t) + (mask "*0****0*") + ) + (autotile + (id 6) + (solid #t) + (mask "*0****1*") + ) + (autotile + (id 7) + (solid #t) + (mask "*1****1*") + ) + (autotile + (id 8) + (solid #t) + (mask "*1****0*") + ) + ) + + (autotileset + (name "underground_forest_cliff") + (default 583) + (autotile + (id 579) + (solid #f) + (mask "00000001") + ) + (autotile + (id 580) + (solid #f) + (mask "00000*1*") + ) + (autotile + (id 581) + (solid #f) + (mask "00000100") + ) + (autotile + (id 582) + (solid #f) + (mask "00*0100*") + ) + (autotile + (id 583) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) + (autotile + (id 584) + (solid #f) + (mask "*0010*00") + ) + (autotile + (id 592) + (solid #f) + (mask "00100000") + ) + (autotile + (id 593) + (solid #f) + (mask "*1*00000") + ) + (autotile + (id 594) + (solid #f) + (mask "10000000") + ) + (autotile + (id 588) + (solid #f) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + (autotile + (id 589) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + (autotile + (id 610) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + (autotile + (id 611) + (solid #f) + (mask "*1*10*00") + (mask "01*00100") + (mask "*0110*00") + ) + ) + + (autotileset + (name "underground_corrupted_forest_cliff") + (default 729) + (autotile + (id 747) + (solid #f) + (mask "10*0100*") + (mask "*1*0100*") + (mask "*1*00001") + ) + (autotile + (id 748) + (solid #f) + (mask "*1*10*00") + (mask "01*00100") + (mask "*0110*00") + ) + (autotile + (id 725) + (solid #f) + (mask "00000001") + ) + (autotile + (id 726) + (solid #f) + (mask "00000*1*") + ) + (autotile + (id 727) + (solid #f) + (mask "00000100") + ) + (autotile + (id 728) + (solid #f) + (mask "00*0100*") + ) + (autotile + (id 729) + (solid #t) + (mask "********") + (mask "*1****1*") + (mask "***11***") + ) + (autotile + (id 730) + (solid #f) + (mask "*0010*00") + ) + (autotile + (id 738) + (solid #f) + (mask "00100000") + ) + (autotile + (id 739) + (solid #f) + (mask "*1*00000") + ) + (autotile + (id 740) + (solid #f) + (mask "10000000") + ) + (autotile + (id 734) + (solid #f) + (mask "00*0110*") + (mask "00100*1*") + (mask "00*01*1*") + ) + (autotile + (id 735) + (solid #f) + (mask "10000*1*") + (mask "*0010*1*") + (mask "*0010*01") + ) + ) + ) diff --git a/data/images/engine/editor/README b/data/images/engine/editor/README deleted file mode 100644 index 7f3714b1e5a..00000000000 --- a/data/images/engine/editor/README +++ /dev/null @@ -1,4 +0,0 @@ -The following images are taken from other open source projects: - -arrow.png from inkscape - diff --git a/data/images/engine/editor/add.png b/data/images/engine/editor/add.png index 3db48622c64..caf87dd7910 100644 Binary files a/data/images/engine/editor/add.png and b/data/images/engine/editor/add.png differ diff --git a/data/images/engine/editor/arrow.png b/data/images/engine/editor/arrow.png index cb74346d9d1..81cb2423e0b 100644 Binary files a/data/images/engine/editor/arrow.png and b/data/images/engine/editor/arrow.png differ diff --git a/data/images/engine/editor/color_picker_2d.png b/data/images/engine/editor/color_picker_2d.png new file mode 100644 index 00000000000..64c2a26f007 Binary files /dev/null and b/data/images/engine/editor/color_picker_2d.png differ diff --git a/data/images/ice_world.strf b/data/images/ice_world.strf index 508ff8d1885..b6b4e75a9f5 100644 --- a/data/images/ice_world.strf +++ b/data/images/ice_world.strf @@ -190,7 +190,7 @@ 215 216 218 0 219 220 221 0 - 222 223 224 0 + 222 689 224 223 225 226 227 0 228 229 230 0 231 232 233 0 diff --git a/data/images/tiles.strf b/data/images/tiles.strf index 72318274418..b0f14067bc5 100644 --- a/data/images/tiles.strf +++ b/data/images/tiles.strf @@ -19,7 +19,7 @@ (source "autotiles.satc") ) - ;; next-id: 7422 + ;; next-id: 7474 ;; free/skipped ids (please use before any other): 101 ;; 2080-2084 are empty tiles, 4619-4660, 4719-4722, 5037-5092, 5205, 5268-5283, 5433-5527, 6962-6977, 7002 7005 7007 7008 7173 ;; No group ids are currently skipped! Delete this line if any are and replace it with said ids... @@ -121,6 +121,8 @@ 3157 3158 5368 5369 1834 5368 5369 11 + ;; Snow Special + 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 207 5532 @@ -133,6 +135,17 @@ 4029 4030 4031 4032 4033 4034 4035 0 5528 5529 0 0 + + ;; Ice Floor special + + 7422 7423 7424 7425 + 7426 7427 7428 7429 + 7430 7431 7432 0 + 7433 7434 0 0 + 7435 7436 7437 7438 + 7439 7440 7441 7442 + 7443 7444 7445 7446 + 7447 7448 7449 7450 ;; Walljump + Unisolid + Ice Spike @@ -1212,8 +1225,8 @@ 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 - 7391 7392 7393 0 - 0 0 0 0 + 7379 7381 7393 0 + 7387 7389 7391 7392 0 0 0 0 ) ) @@ -1329,7 +1342,9 @@ 7418 7421 7407 7408 7403 7404 7409 7410 7405 7406 7411 7412 - 7413 7414 7415 0 + 7471 7413 7414 7415 + 7472 0 0 0 + 7473 0 0 0 1348 1720 1719 1718 79 80 1347 1722 @@ -1385,14 +1400,14 @@ 4581 4582 4559 4560 4592 4593 4570 4571 - 4568 4554 0 0 + 4568 4554 7451 7454 4579 4576 0 0 4562 4563 4561 0 4573 4574 4572 0 4584 4585 4583 0 - 4595 4596 0 0 - 4606 4607 0 0 + 4595 4596 7452 7453 + 4606 4607 7455 7456 4586 4587 4586 4587 4597 4598 4608 4609 @@ -1413,7 +1428,7 @@ 4499 4500 4469 4470 4514 4515 4484 4485 - 4482 4464 0 0 + 4482 4464 7457 7460 4497 4494 0 0 4543 4544 4545 4546 @@ -1422,8 +1437,8 @@ 4472 4473 4471 0 4487 4488 4486 0 4502 4503 4501 0 - 4517 4518 0 0 - 4532 4533 0 0 + 4517 4518 7458 7459 + 4532 4533 7461 7462 4508 4509 4508 4509 4523 4524 4538 4539 @@ -1479,6 +1494,8 @@ 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 + 7463 7465 7467 7469 + 7464 7466 7468 7470 ;; Misc @@ -6047,8 +6064,6 @@ (tiles (width 4)(height 1) (fps 16) - (water #t) - (hurts #t) (images "tiles/water/antarctic-1a.png" "tiles/water/antarctic-1b.png" @@ -6057,19 +6072,23 @@ 3873 3874 3875 3876 ) (attributes - 1024 1024 1024 1024 + 1536 1536 1536 1536 ) ) - (tile + (tiles + (width 1)(height 1) (fps 16) - (water #t) - (hurts #t) (images "tiles/water/antarctic-1c.png" "tiles/water/antarctic-1d.png" ) - (id 3877) + (ids + 3877 + ) + (attributes + 1536 + ) ) (tiles @@ -8341,6 +8360,79 @@ (images "tiles/signs/hanging-sign-rods.png") ) + (tiles + (width 4)(height 8) + (ids + 7422 7423 7424 7425 + 7426 7427 7428 7429 + 7430 7431 7432 0 + 7433 7434 0 0 + 7435 7436 7437 7438 + 7439 7440 7441 7442 + 7443 7444 7445 7446 + 7447 7448 7449 7450 + ) + (attributes + 1 1 1 1 + 1 1 1 1 + 1 1 1 0 + 1 1 0 0 + 0 0 0 0 + 0 0 0 0 + 0 0 0 0 + 0 0 0 0 + ) + (images + "tiles/snow/ice-floor-special.png" + ) + ) + + (tiles + (width 3)(height 4) + (ids + 7451 7452 7453 + 7454 7455 7456 + 7457 7458 7459 + 7460 7461 7462 + ) + (attributes + 1 1 1 + 1 1 1 + 1 1 1 + 1 1 1 + ) + (images + "tiles/castle/castle_special.png" + ) + ) + + (tiles + (width 2)(height 4) + (ids + 7463 7464 + 7465 7466 + 7467 7468 + 7469 7470 + ) + (images + "tiles/castle/small_chain.png" + ) + ) + + (tiles + (width 1)(height 3) + (ids + 7471 + 7472 + 7473 + ) + (images + "tiles/signs/vertical-rods.png" + ) + ) + + + ;; Additional attributes (additional (thunderstorm diff --git a/data/images/tiles/castle/castle_special.png b/data/images/tiles/castle/castle_special.png new file mode 100644 index 00000000000..3b86c4e6f75 Binary files /dev/null and b/data/images/tiles/castle/castle_special.png differ diff --git a/data/images/tiles/castle/small_chain.png b/data/images/tiles/castle/small_chain.png new file mode 100644 index 00000000000..c0a63fb8fcd Binary files /dev/null and b/data/images/tiles/castle/small_chain.png differ diff --git a/data/images/tiles/signs/vertical-rods.png b/data/images/tiles/signs/vertical-rods.png new file mode 100644 index 00000000000..5d6dcd16019 Binary files /dev/null and b/data/images/tiles/signs/vertical-rods.png differ diff --git a/data/images/tiles/snow/ice-floor-special.png b/data/images/tiles/snow/ice-floor-special.png new file mode 100644 index 00000000000..b6e20da0a00 Binary files /dev/null and b/data/images/tiles/snow/ice-floor-special.png differ diff --git a/data/levels/bonus1/af_ZA.po b/data/levels/bonus1/af_ZA.po index 33de84cfdcf..588e71beb39 100644 --- a/data/levels/bonus1/af_ZA.po +++ b/data/levels/bonus1/af_ZA.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Martin van Zijl , 2019\n" "Language-Team: Afrikaans (South Africa) (http://app.transifex.com/arctic-games/supertux/language/af_ZA/)\n" diff --git a/data/levels/bonus1/ar.po b/data/levels/bonus1/ar.po index f4a7ad8baab..e9f25fba24f 100644 --- a/data/levels/bonus1/ar.po +++ b/data/levels/bonus1/ar.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Arabic (http://app.transifex.com/arctic-games/supertux/language/ar/)\n" diff --git a/data/levels/bonus1/az.po b/data/levels/bonus1/az.po index 07e67ea2289..dbecd6899f3 100644 --- a/data/levels/bonus1/az.po +++ b/data/levels/bonus1/az.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Azerbaijani (http://app.transifex.com/arctic-games/supertux/language/az/)\n" diff --git a/data/levels/bonus1/be.po b/data/levels/bonus1/be.po index 0efbf13181c..20d1ab53582 100644 --- a/data/levels/bonus1/be.po +++ b/data/levels/bonus1/be.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: se luxxy <70luxxy@gmail.com>, 2018\n" "Language-Team: Belarusian (http://app.transifex.com/arctic-games/supertux/language/be/)\n" diff --git a/data/levels/bonus1/bg.po b/data/levels/bonus1/bg.po index 4fb5f0dec20..97478c31527 100644 --- a/data/levels/bonus1/bg.po +++ b/data/levels/bonus1/bg.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Любомир Василев, 2021\n" "Language-Team: Bulgarian (http://app.transifex.com/arctic-games/supertux/language/bg/)\n" diff --git a/data/levels/bonus1/br.po b/data/levels/bonus1/br.po index 97748794405..87114c546ea 100644 --- a/data/levels/bonus1/br.po +++ b/data/levels/bonus1/br.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Gwenn M , 2015,2019\n" "Language-Team: Breton (http://app.transifex.com/arctic-games/supertux/language/br/)\n" diff --git a/data/levels/bonus1/ca.po b/data/levels/bonus1/ca.po index cd597ce979e..3b292ff7aac 100644 --- a/data/levels/bonus1/ca.po +++ b/data/levels/bonus1/ca.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Catalan (http://app.transifex.com/arctic-games/supertux/language/ca/)\n" diff --git a/data/levels/bonus1/cmn.po b/data/levels/bonus1/cmn.po index abd38dae1cc..d84c78b10ab 100644 --- a/data/levels/bonus1/cmn.po +++ b/data/levels/bonus1/cmn.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: 趙惟倫 , 2013\n" "Language-Team: Chinese (Mandarin) (http://app.transifex.com/arctic-games/supertux/language/cmn/)\n" diff --git a/data/levels/bonus1/cs.po b/data/levels/bonus1/cs.po index f362ceed426..91a791ae224 100644 --- a/data/levels/bonus1/cs.po +++ b/data/levels/bonus1/cs.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Jiří Paleček , 2021-2023\n" "Language-Team: Czech (http://app.transifex.com/arctic-games/supertux/language/cs/)\n" diff --git a/data/levels/bonus1/da.po b/data/levels/bonus1/da.po index ff5eca06022..4d22c6e2eee 100644 --- a/data/levels/bonus1/da.po +++ b/data/levels/bonus1/da.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Lars Lyngby , 2022\n" "Language-Team: Danish (http://app.transifex.com/arctic-games/supertux/language/da/)\n" diff --git a/data/levels/bonus1/de.po b/data/levels/bonus1/de.po index fc3eab299f9..43db33d216f 100644 --- a/data/levels/bonus1/de.po +++ b/data/levels/bonus1/de.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Tobias Markus , 2018-2019,2021\n" "Language-Team: German (http://app.transifex.com/arctic-games/supertux/language/de/)\n" diff --git a/data/levels/bonus1/el.po b/data/levels/bonus1/el.po index 90147c52686..33a33bdc9ce 100644 --- a/data/levels/bonus1/el.po +++ b/data/levels/bonus1/el.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Greek (http://app.transifex.com/arctic-games/supertux/language/el/)\n" diff --git a/data/levels/bonus1/eo.po b/data/levels/bonus1/eo.po index 6eb5eb92a48..b820c985850 100644 --- a/data/levels/bonus1/eo.po +++ b/data/levels/bonus1/eo.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: vpzomtrrfrt , 2020-2021\n" "Language-Team: Esperanto (http://app.transifex.com/arctic-games/supertux/language/eo/)\n" diff --git a/data/levels/bonus1/es.po b/data/levels/bonus1/es.po index b03da44005a..3b5e610170f 100644 --- a/data/levels/bonus1/es.po +++ b/data/levels/bonus1/es.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Martin, 2022\n" "Language-Team: Spanish (http://app.transifex.com/arctic-games/supertux/language/es/)\n" diff --git a/data/levels/bonus1/es_AR.po b/data/levels/bonus1/es_AR.po index 8de9948c522..829e55c357d 100644 --- a/data/levels/bonus1/es_AR.po +++ b/data/levels/bonus1/es_AR.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Salomón Duarte , 2021\n" "Language-Team: Spanish (Argentina) (http://app.transifex.com/arctic-games/supertux/language/es_AR/)\n" diff --git a/data/levels/bonus1/et.po b/data/levels/bonus1/et.po index 853e3dd3f0f..19c3f7aefcf 100644 --- a/data/levels/bonus1/et.po +++ b/data/levels/bonus1/et.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Estonian (http://app.transifex.com/arctic-games/supertux/language/et/)\n" diff --git a/data/levels/bonus1/eu.po b/data/levels/bonus1/eu.po index 12e00218a62..10cbc7e59ef 100644 --- a/data/levels/bonus1/eu.po +++ b/data/levels/bonus1/eu.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Basque (http://app.transifex.com/arctic-games/supertux/language/eu/)\n" diff --git a/data/levels/bonus1/fi.po b/data/levels/bonus1/fi.po index 9b2e0fe3727..ae2c7f30629 100644 --- a/data/levels/bonus1/fi.po +++ b/data/levels/bonus1/fi.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Jaakoppi Horila , 2016,2018,2020-2023\n" "Language-Team: Finnish (http://app.transifex.com/arctic-games/supertux/language/fi/)\n" diff --git a/data/levels/bonus1/fr.po b/data/levels/bonus1/fr.po index e274d1f968b..aa0ef683361 100644 --- a/data/levels/bonus1/fr.po +++ b/data/levels/bonus1/fr.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Semphris , 2021\n" "Language-Team: French (http://app.transifex.com/arctic-games/supertux/language/fr/)\n" diff --git a/data/levels/bonus1/fr_CA.po b/data/levels/bonus1/fr_CA.po index 9adecdbce35..5b7436f0307 100644 --- a/data/levels/bonus1/fr_CA.po +++ b/data/levels/bonus1/fr_CA.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: French (Canada) (http://app.transifex.com/arctic-games/supertux/language/fr_CA/)\n" diff --git a/data/levels/bonus1/gd.po b/data/levels/bonus1/gd.po index a9d805f52f8..d3131a1c30c 100644 --- a/data/levels/bonus1/gd.po +++ b/data/levels/bonus1/gd.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: GunChleoc, 2016,2019\n" "Language-Team: Gaelic, Scottish (http://app.transifex.com/arctic-games/supertux/language/gd/)\n" diff --git a/data/levels/bonus1/gl.po b/data/levels/bonus1/gl.po index 93608e5b765..190cb15c6f6 100644 --- a/data/levels/bonus1/gl.po +++ b/data/levels/bonus1/gl.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Xan Vieiro , 2021\n" "Language-Team: Galician (http://app.transifex.com/arctic-games/supertux/language/gl/)\n" diff --git a/data/levels/bonus1/he.po b/data/levels/bonus1/he.po index 189546fa421..5258a580571 100644 --- a/data/levels/bonus1/he.po +++ b/data/levels/bonus1/he.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Hebrew (http://app.transifex.com/arctic-games/supertux/language/he/)\n" diff --git a/data/levels/bonus1/hr.po b/data/levels/bonus1/hr.po index b2893a8e30d..60860fb5014 100644 --- a/data/levels/bonus1/hr.po +++ b/data/levels/bonus1/hr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Croatian (http://app.transifex.com/arctic-games/supertux/language/hr/)\n" diff --git a/data/levels/bonus1/hu.po b/data/levels/bonus1/hu.po index 4c8f310c1cb..688e762e235 100644 --- a/data/levels/bonus1/hu.po +++ b/data/levels/bonus1/hu.po @@ -15,7 +15,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Guih48, 2022\n" "Language-Team: Hungarian (http://app.transifex.com/arctic-games/supertux/language/hu/)\n" diff --git a/data/levels/bonus1/hy.po b/data/levels/bonus1/hy.po index 467351e8de7..cdedd101123 100644 --- a/data/levels/bonus1/hy.po +++ b/data/levels/bonus1/hy.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Armenian (http://app.transifex.com/arctic-games/supertux/language/hy/)\n" diff --git a/data/levels/bonus1/id.po b/data/levels/bonus1/id.po index 61d63b517fe..c684de7d801 100644 --- a/data/levels/bonus1/id.po +++ b/data/levels/bonus1/id.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Chris , 2022\n" "Language-Team: Indonesian (http://app.transifex.com/arctic-games/supertux/language/id/)\n" diff --git a/data/levels/bonus1/is.po b/data/levels/bonus1/is.po index 5bca0218218..bcef43aa6d4 100644 --- a/data/levels/bonus1/is.po +++ b/data/levels/bonus1/is.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Icelandic (http://app.transifex.com/arctic-games/supertux/language/is/)\n" diff --git a/data/levels/bonus1/it.po b/data/levels/bonus1/it.po index b2d2bd62d1f..5efe4a84aee 100644 --- a/data/levels/bonus1/it.po +++ b/data/levels/bonus1/it.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: A-TNT DC, 2021\n" "Language-Team: Italian (http://app.transifex.com/arctic-games/supertux/language/it/)\n" diff --git a/data/levels/bonus1/ja.po b/data/levels/bonus1/ja.po index 305c2a8c784..d64f2d55911 100644 --- a/data/levels/bonus1/ja.po +++ b/data/levels/bonus1/ja.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Ryo Nakano, 2019,2021,2024\n" "Language-Team: Japanese (http://app.transifex.com/arctic-games/supertux/language/ja/)\n" diff --git a/data/levels/bonus1/ko.po b/data/levels/bonus1/ko.po index 4ee23ed41a0..53f1ddf8344 100644 --- a/data/levels/bonus1/ko.po +++ b/data/levels/bonus1/ko.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: 최이준, 2023\n" "Language-Team: Korean (http://app.transifex.com/arctic-games/supertux/language/ko/)\n" diff --git a/data/levels/bonus1/la.po b/data/levels/bonus1/la.po index 528259d4850..9ecd5229054 100644 --- a/data/levels/bonus1/la.po +++ b/data/levels/bonus1/la.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Alisa P , 2016,2018\n" "Language-Team: Latin (http://app.transifex.com/arctic-games/supertux/language/la/)\n" diff --git a/data/levels/bonus1/lt.po b/data/levels/bonus1/lt.po index 1e812438509..505be576c52 100644 --- a/data/levels/bonus1/lt.po +++ b/data/levels/bonus1/lt.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Tom Urisk, 2021\n" "Language-Team: Lithuanian (http://app.transifex.com/arctic-games/supertux/language/lt/)\n" diff --git a/data/levels/bonus1/ms_MY.po b/data/levels/bonus1/ms_MY.po index 70f53da0eaf..eead6d65636 100644 --- a/data/levels/bonus1/ms_MY.po +++ b/data/levels/bonus1/ms_MY.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: abuyop , 2020-2022\n" "Language-Team: Malay (Malaysia) (http://app.transifex.com/arctic-games/supertux/language/ms_MY/)\n" diff --git a/data/levels/bonus1/nb.po b/data/levels/bonus1/nb.po index 3f8d459d871..3c6c4e48e4b 100644 --- a/data/levels/bonus1/nb.po +++ b/data/levels/bonus1/nb.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Norwegian Bokmål (http://app.transifex.com/arctic-games/supertux/language/nb/)\n" diff --git a/data/levels/bonus1/nds.po b/data/levels/bonus1/nds.po index fcd9a83d72a..16346e77f86 100644 --- a/data/levels/bonus1/nds.po +++ b/data/levels/bonus1/nds.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Benedikt Straub , 2018\n" "Language-Team: Low German (http://app.transifex.com/arctic-games/supertux/language/nds/)\n" diff --git a/data/levels/bonus1/nl.po b/data/levels/bonus1/nl.po index 2eb58fbb779..e396638193a 100644 --- a/data/levels/bonus1/nl.po +++ b/data/levels/bonus1/nl.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Heimen Stoffels , 2021\n" "Language-Team: Dutch (http://app.transifex.com/arctic-games/supertux/language/nl/)\n" diff --git a/data/levels/bonus1/nn.po b/data/levels/bonus1/nn.po index 4282ac67389..85d0f0a59bf 100644 --- a/data/levels/bonus1/nn.po +++ b/data/levels/bonus1/nn.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Norwegian Nynorsk (http://app.transifex.com/arctic-games/supertux/language/nn/)\n" diff --git a/data/levels/bonus1/pl.po b/data/levels/bonus1/pl.po index 79a98576f98..478e72f1bcd 100644 --- a/data/levels/bonus1/pl.po +++ b/data/levels/bonus1/pl.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Alina Gobarov, 2021\n" "Language-Team: Polish (http://app.transifex.com/arctic-games/supertux/language/pl/)\n" diff --git a/data/levels/bonus1/pt_BR.po b/data/levels/bonus1/pt_BR.po index a6785e8a46b..1f2b9216881 100644 --- a/data/levels/bonus1/pt_BR.po +++ b/data/levels/bonus1/pt_BR.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Jesusaves , 2021\n" "Language-Team: Portuguese (Brazil) (http://app.transifex.com/arctic-games/supertux/language/pt_BR/)\n" diff --git a/data/levels/bonus1/ro.po b/data/levels/bonus1/ro.po index 2edaa520519..a79d680d9f8 100644 --- a/data/levels/bonus1/ro.po +++ b/data/levels/bonus1/ro.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Nicolae Crefelean, 2015-2016,2023\n" "Language-Team: Romanian (http://app.transifex.com/arctic-games/supertux/language/ro/)\n" diff --git a/data/levels/bonus1/sk.po b/data/levels/bonus1/sk.po index 5380e36b742..ac8d19db06d 100644 --- a/data/levels/bonus1/sk.po +++ b/data/levels/bonus1/sk.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Slovak (http://app.transifex.com/arctic-games/supertux/language/sk/)\n" diff --git a/data/levels/bonus1/sl.po b/data/levels/bonus1/sl.po index 8e194271d66..3efcf7d6361 100644 --- a/data/levels/bonus1/sl.po +++ b/data/levels/bonus1/sl.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Gorzy Gorup , 2019,2022\n" "Language-Team: Slovenian (http://app.transifex.com/arctic-games/supertux/language/sl/)\n" diff --git a/data/levels/bonus1/sq.po b/data/levels/bonus1/sq.po index 9dc718b52c5..34f05ee5a04 100644 --- a/data/levels/bonus1/sq.po +++ b/data/levels/bonus1/sq.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Albanian (http://app.transifex.com/arctic-games/supertux/language/sq/)\n" diff --git a/data/levels/bonus1/sr.po b/data/levels/bonus1/sr.po index 18b506fe152..61274b56ccf 100644 --- a/data/levels/bonus1/sr.po +++ b/data/levels/bonus1/sr.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Slobodan Simić , 2016\n" "Language-Team: Serbian (http://app.transifex.com/arctic-games/supertux/language/sr/)\n" diff --git a/data/levels/bonus1/sv.po b/data/levels/bonus1/sv.po index 59c094dbab9..8d84332c0fb 100644 --- a/data/levels/bonus1/sv.po +++ b/data/levels/bonus1/sv.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Sebastian Rasmussen , 2020-2021\n" "Language-Team: Swedish (http://app.transifex.com/arctic-games/supertux/language/sv/)\n" diff --git a/data/levels/bonus1/te.po b/data/levels/bonus1/te.po index 6a465018b6f..a1e52c1e538 100644 --- a/data/levels/bonus1/te.po +++ b/data/levels/bonus1/te.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: జయంత్ వర్మ బెల్లపుకొండ , 2022\n" "Language-Team: Telugu (http://app.transifex.com/arctic-games/supertux/language/te/)\n" diff --git a/data/levels/bonus1/tr.po b/data/levels/bonus1/tr.po index 15713eb6715..98b87f758bf 100644 --- a/data/levels/bonus1/tr.po +++ b/data/levels/bonus1/tr.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Turkish (http://app.transifex.com/arctic-games/supertux/language/tr/)\n" diff --git a/data/levels/bonus1/tt.po b/data/levels/bonus1/tt.po index 3b3fa937264..5b0f38952d5 100644 --- a/data/levels/bonus1/tt.po +++ b/data/levels/bonus1/tt.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Tatar (http://app.transifex.com/arctic-games/supertux/language/tt/)\n" diff --git a/data/levels/bonus1/uk.po b/data/levels/bonus1/uk.po index df7ed42c818..b065306d92e 100644 --- a/data/levels/bonus1/uk.po +++ b/data/levels/bonus1/uk.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: Asemif official, 2023\n" "Language-Team: Ukrainian (http://app.transifex.com/arctic-games/supertux/language/uk/)\n" diff --git a/data/levels/bonus1/uz.po b/data/levels/bonus1/uz.po index be027da7ed8..aadc1cc8e99 100644 --- a/data/levels/bonus1/uz.po +++ b/data/levels/bonus1/uz.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Uzbek (http://app.transifex.com/arctic-games/supertux/language/uz/)\n" diff --git a/data/levels/bonus1/zh_CN.po b/data/levels/bonus1/zh_CN.po index 141047f6cfc..eac7ad6786c 100644 --- a/data/levels/bonus1/zh_CN.po +++ b/data/levels/bonus1/zh_CN.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: 玉堂白鹤 , 2018\n" "Language-Team: Chinese (China) (http://app.transifex.com/arctic-games/supertux/language/zh_CN/)\n" diff --git a/data/levels/bonus1/zh_TW.po b/data/levels/bonus1/zh_TW.po index 4569032984e..d0887e91b63 100644 --- a/data/levels/bonus1/zh_TW.po +++ b/data/levels/bonus1/zh_TW.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:04+0000\n" "Last-Translator: 黃柏諺 , 2019\n" "Language-Team: Chinese (Taiwan) (http://app.transifex.com/arctic-games/supertux/language/zh_TW/)\n" diff --git a/data/levels/bonus2/af_ZA.po b/data/levels/bonus2/af_ZA.po index 4730c5aa770..2d34e677e30 100644 --- a/data/levels/bonus2/af_ZA.po +++ b/data/levels/bonus2/af_ZA.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Martin van Zijl , 2019\n" "Language-Team: Afrikaans (South Africa) (http://app.transifex.com/arctic-games/supertux/language/af_ZA/)\n" diff --git a/data/levels/bonus2/ar.po b/data/levels/bonus2/ar.po index 07837069ad3..1663a3aa133 100644 --- a/data/levels/bonus2/ar.po +++ b/data/levels/bonus2/ar.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Arabic (http://app.transifex.com/arctic-games/supertux/language/ar/)\n" diff --git a/data/levels/bonus2/az.po b/data/levels/bonus2/az.po index a39c7943163..e220f231c2a 100644 --- a/data/levels/bonus2/az.po +++ b/data/levels/bonus2/az.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Azerbaijani (http://app.transifex.com/arctic-games/supertux/language/az/)\n" diff --git a/data/levels/bonus2/be.po b/data/levels/bonus2/be.po index 7fa68158acc..b2d14ea4e21 100644 --- a/data/levels/bonus2/be.po +++ b/data/levels/bonus2/be.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: se luxxy <70luxxy@gmail.com>, 2018\n" "Language-Team: Belarusian (http://app.transifex.com/arctic-games/supertux/language/be/)\n" diff --git a/data/levels/bonus2/bg.po b/data/levels/bonus2/bg.po index f571842e2da..96ae7d68e69 100644 --- a/data/levels/bonus2/bg.po +++ b/data/levels/bonus2/bg.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Любомир Василев, 2015-2016\n" "Language-Team: Bulgarian (http://app.transifex.com/arctic-games/supertux/language/bg/)\n" diff --git a/data/levels/bonus2/br.po b/data/levels/bonus2/br.po index 9b9bcd99692..509770a3a25 100644 --- a/data/levels/bonus2/br.po +++ b/data/levels/bonus2/br.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Irriep Nala Novram , 2017-2018\n" "Language-Team: Breton (http://app.transifex.com/arctic-games/supertux/language/br/)\n" diff --git a/data/levels/bonus2/ca.po b/data/levels/bonus2/ca.po index 971d00ae166..ad38c4de067 100644 --- a/data/levels/bonus2/ca.po +++ b/data/levels/bonus2/ca.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Ariadna Pascual , 2016\n" "Language-Team: Catalan (http://app.transifex.com/arctic-games/supertux/language/ca/)\n" diff --git a/data/levels/bonus2/cmn.po b/data/levels/bonus2/cmn.po index 055adc0ff56..b886ee408b3 100644 --- a/data/levels/bonus2/cmn.po +++ b/data/levels/bonus2/cmn.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: 趙惟倫 , 2013\n" "Language-Team: Chinese (Mandarin) (http://app.transifex.com/arctic-games/supertux/language/cmn/)\n" diff --git a/data/levels/bonus2/cs.po b/data/levels/bonus2/cs.po index 79c83b4b373..83fb527d2b4 100644 --- a/data/levels/bonus2/cs.po +++ b/data/levels/bonus2/cs.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Jiří Paleček , 2021-2022\n" "Language-Team: Czech (http://app.transifex.com/arctic-games/supertux/language/cs/)\n" diff --git a/data/levels/bonus2/de.po b/data/levels/bonus2/de.po index 80b0110f564..c69a249177e 100644 --- a/data/levels/bonus2/de.po +++ b/data/levels/bonus2/de.po @@ -18,7 +18,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Tobias Markus , 2018,2021\n" "Language-Team: German (http://app.transifex.com/arctic-games/supertux/language/de/)\n" diff --git a/data/levels/bonus2/el.po b/data/levels/bonus2/el.po index e93aa68afec..6224281916d 100644 --- a/data/levels/bonus2/el.po +++ b/data/levels/bonus2/el.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Vangelis Skarmoutsos (SkarmoutsosV) , 2016\n" "Language-Team: Greek (http://app.transifex.com/arctic-games/supertux/language/el/)\n" diff --git a/data/levels/bonus2/eo.po b/data/levels/bonus2/eo.po index 05a29fd2bc3..62b548c35c9 100644 --- a/data/levels/bonus2/eo.po +++ b/data/levels/bonus2/eo.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: tellovishous , 2023\n" "Language-Team: Esperanto (http://app.transifex.com/arctic-games/supertux/language/eo/)\n" diff --git a/data/levels/bonus2/es.po b/data/levels/bonus2/es.po index 2e22b9702b2..9198ae66872 100644 --- a/data/levels/bonus2/es.po +++ b/data/levels/bonus2/es.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Swyter , 2021\n" "Language-Team: Spanish (http://app.transifex.com/arctic-games/supertux/language/es/)\n" diff --git a/data/levels/bonus2/es_AR.po b/data/levels/bonus2/es_AR.po index ed5033dcaf9..5f96e59ef4e 100644 --- a/data/levels/bonus2/es_AR.po +++ b/data/levels/bonus2/es_AR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Alejo Fernandez , 2020\n" "Language-Team: Spanish (Argentina) (http://app.transifex.com/arctic-games/supertux/language/es_AR/)\n" diff --git a/data/levels/bonus2/et.po b/data/levels/bonus2/et.po index bb823a674ed..e6a054df8d6 100644 --- a/data/levels/bonus2/et.po +++ b/data/levels/bonus2/et.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Estonian (http://app.transifex.com/arctic-games/supertux/language/et/)\n" diff --git a/data/levels/bonus2/eu.po b/data/levels/bonus2/eu.po index 43155752164..62b9e5bb2fb 100644 --- a/data/levels/bonus2/eu.po +++ b/data/levels/bonus2/eu.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Mielanjel Iraeta , 2018\n" "Language-Team: Basque (http://app.transifex.com/arctic-games/supertux/language/eu/)\n" diff --git a/data/levels/bonus2/fi.po b/data/levels/bonus2/fi.po index baf3e8e7219..3ea510d4cc7 100644 --- a/data/levels/bonus2/fi.po +++ b/data/levels/bonus2/fi.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Jaakoppi Horila , 2016,2018,2020,2022-2023\n" "Language-Team: Finnish (http://app.transifex.com/arctic-games/supertux/language/fi/)\n" diff --git a/data/levels/bonus2/fr.po b/data/levels/bonus2/fr.po index c78dbbd48b3..fbaf558ad79 100644 --- a/data/levels/bonus2/fr.po +++ b/data/levels/bonus2/fr.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Antoine , 2020\n" "Language-Team: French (http://app.transifex.com/arctic-games/supertux/language/fr/)\n" diff --git a/data/levels/bonus2/fr_CA.po b/data/levels/bonus2/fr_CA.po index 7c2ab7846ec..c858b09001c 100644 --- a/data/levels/bonus2/fr_CA.po +++ b/data/levels/bonus2/fr_CA.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: French (Canada) (http://app.transifex.com/arctic-games/supertux/language/fr_CA/)\n" diff --git a/data/levels/bonus2/gd.po b/data/levels/bonus2/gd.po index 3665d8fc7cd..d1292675dfd 100644 --- a/data/levels/bonus2/gd.po +++ b/data/levels/bonus2/gd.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: GunChleoc, 2016,2019\n" "Language-Team: Gaelic, Scottish (http://app.transifex.com/arctic-games/supertux/language/gd/)\n" diff --git a/data/levels/bonus2/gl.po b/data/levels/bonus2/gl.po index 086e1c1663e..34c4f76bab3 100644 --- a/data/levels/bonus2/gl.po +++ b/data/levels/bonus2/gl.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Xan Vieiro , 2019-2020\n" "Language-Team: Galician (http://app.transifex.com/arctic-games/supertux/language/gl/)\n" diff --git a/data/levels/bonus2/he.po b/data/levels/bonus2/he.po index 65aa28a1bc1..00cab6b580c 100644 --- a/data/levels/bonus2/he.po +++ b/data/levels/bonus2/he.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Hebrew (http://app.transifex.com/arctic-games/supertux/language/he/)\n" diff --git a/data/levels/bonus2/hr.po b/data/levels/bonus2/hr.po index adcaa17fd11..bb7678a1ba3 100644 --- a/data/levels/bonus2/hr.po +++ b/data/levels/bonus2/hr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Croatian (http://app.transifex.com/arctic-games/supertux/language/hr/)\n" diff --git a/data/levels/bonus2/hu.po b/data/levels/bonus2/hu.po index 2adb8f86c64..77a23252290 100644 --- a/data/levels/bonus2/hu.po +++ b/data/levels/bonus2/hu.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Kristóf Kófiás , 2020\n" "Language-Team: Hungarian (http://app.transifex.com/arctic-games/supertux/language/hu/)\n" diff --git a/data/levels/bonus2/hy.po b/data/levels/bonus2/hy.po index 3902437e10b..8592826e195 100644 --- a/data/levels/bonus2/hy.po +++ b/data/levels/bonus2/hy.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Armenian (http://app.transifex.com/arctic-games/supertux/language/hy/)\n" diff --git a/data/levels/bonus2/id.po b/data/levels/bonus2/id.po index c52dfd2b938..2d2b70f3e0a 100644 --- a/data/levels/bonus2/id.po +++ b/data/levels/bonus2/id.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Indonesian (http://app.transifex.com/arctic-games/supertux/language/id/)\n" diff --git a/data/levels/bonus2/is.po b/data/levels/bonus2/is.po index 4f50e901bf6..95064d40103 100644 --- a/data/levels/bonus2/is.po +++ b/data/levels/bonus2/is.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Icelandic (http://app.transifex.com/arctic-games/supertux/language/is/)\n" diff --git a/data/levels/bonus2/it.po b/data/levels/bonus2/it.po index 2344fe27f3c..bbd251f616c 100644 --- a/data/levels/bonus2/it.po +++ b/data/levels/bonus2/it.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Bananasoft , 2016\n" "Language-Team: Italian (http://app.transifex.com/arctic-games/supertux/language/it/)\n" diff --git a/data/levels/bonus2/ja.po b/data/levels/bonus2/ja.po index 993bdf8eb06..0717058b1dc 100644 --- a/data/levels/bonus2/ja.po +++ b/data/levels/bonus2/ja.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Ryo Nakano, 2019\n" "Language-Team: Japanese (http://app.transifex.com/arctic-games/supertux/language/ja/)\n" diff --git a/data/levels/bonus2/ko.po b/data/levels/bonus2/ko.po index d5f73c413cc..e6f7175b036 100644 --- a/data/levels/bonus2/ko.po +++ b/data/levels/bonus2/ko.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Junghee Lee , 2022\n" "Language-Team: Korean (http://app.transifex.com/arctic-games/supertux/language/ko/)\n" diff --git a/data/levels/bonus2/la.po b/data/levels/bonus2/la.po index d75873cc146..2a3e7b77e07 100644 --- a/data/levels/bonus2/la.po +++ b/data/levels/bonus2/la.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Alisa P , 2016,2018\n" "Language-Team: Latin (http://app.transifex.com/arctic-games/supertux/language/la/)\n" diff --git a/data/levels/bonus2/lt.po b/data/levels/bonus2/lt.po index 9540188d2bb..6a7b9fa1ae5 100644 --- a/data/levels/bonus2/lt.po +++ b/data/levels/bonus2/lt.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Tom Urisk, 2021\n" "Language-Team: Lithuanian (http://app.transifex.com/arctic-games/supertux/language/lt/)\n" diff --git a/data/levels/bonus2/ms_MY.po b/data/levels/bonus2/ms_MY.po index 6b210aa70fb..f36d7d561b1 100644 --- a/data/levels/bonus2/ms_MY.po +++ b/data/levels/bonus2/ms_MY.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: abuyop , 2021\n" "Language-Team: Malay (Malaysia) (http://app.transifex.com/arctic-games/supertux/language/ms_MY/)\n" diff --git a/data/levels/bonus2/nb.po b/data/levels/bonus2/nb.po index 72a7e35134e..c5a11ea8990 100644 --- a/data/levels/bonus2/nb.po +++ b/data/levels/bonus2/nb.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Allan Nordhøy , 2016\n" "Language-Team: Norwegian Bokmål (http://app.transifex.com/arctic-games/supertux/language/nb/)\n" diff --git a/data/levels/bonus2/nds.po b/data/levels/bonus2/nds.po index 7958d7e9757..b877eabce69 100644 --- a/data/levels/bonus2/nds.po +++ b/data/levels/bonus2/nds.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Benedikt Straub , 2018\n" "Language-Team: Low German (http://app.transifex.com/arctic-games/supertux/language/nds/)\n" diff --git a/data/levels/bonus2/ne.po b/data/levels/bonus2/ne.po index 86f56bc6040..e26feb62fff 100644 --- a/data/levels/bonus2/ne.po +++ b/data/levels/bonus2/ne.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Bansaj Pradhan , 2013\n" "Language-Team: Nepali (http://app.transifex.com/arctic-games/supertux/language/ne/)\n" diff --git a/data/levels/bonus2/nl.po b/data/levels/bonus2/nl.po index 4088d16a419..185b64e4200 100644 --- a/data/levels/bonus2/nl.po +++ b/data/levels/bonus2/nl.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Heimen Stoffels , 2015-2016,2019\n" "Language-Team: Dutch (http://app.transifex.com/arctic-games/supertux/language/nl/)\n" diff --git a/data/levels/bonus2/nn.po b/data/levels/bonus2/nn.po index 6f0982dad0e..011b9399339 100644 --- a/data/levels/bonus2/nn.po +++ b/data/levels/bonus2/nn.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Karl Ove Hufthammer , 2007,2013,2015-2016,2018-2020\n" "Language-Team: Norwegian Nynorsk (http://app.transifex.com/arctic-games/supertux/language/nn/)\n" diff --git a/data/levels/bonus2/pl.po b/data/levels/bonus2/pl.po index 4ffb6ec7b02..b91bd90ccb2 100644 --- a/data/levels/bonus2/pl.po +++ b/data/levels/bonus2/pl.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Krzysztof Szeląg, 2015-2016\n" "Language-Team: Polish (http://app.transifex.com/arctic-games/supertux/language/pl/)\n" diff --git a/data/levels/bonus2/pt.po b/data/levels/bonus2/pt.po index 9e7fddbc9ff..50ccc05360e 100644 --- a/data/levels/bonus2/pt.po +++ b/data/levels/bonus2/pt.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Rui , 2016\n" "Language-Team: Portuguese (http://app.transifex.com/arctic-games/supertux/language/pt/)\n" diff --git a/data/levels/bonus2/pt_BR.po b/data/levels/bonus2/pt_BR.po index 6be5a38ca2d..42b2f2ce935 100644 --- a/data/levels/bonus2/pt_BR.po +++ b/data/levels/bonus2/pt_BR.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Rui , 2016\n" "Language-Team: Portuguese (Brazil) (http://app.transifex.com/arctic-games/supertux/language/pt_BR/)\n" diff --git a/data/levels/bonus2/ro.po b/data/levels/bonus2/ro.po index b83de69845d..c79293444de 100644 --- a/data/levels/bonus2/ro.po +++ b/data/levels/bonus2/ro.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Nicolae Crefelean, 2015-2016\n" "Language-Team: Romanian (http://app.transifex.com/arctic-games/supertux/language/ro/)\n" diff --git a/data/levels/bonus2/ru.po b/data/levels/bonus2/ru.po index 7697f5ce8fc..e60055aa177 100644 --- a/data/levels/bonus2/ru.po +++ b/data/levels/bonus2/ru.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Andrei Stepanov, 2019,2021\n" "Language-Team: Russian (http://app.transifex.com/arctic-games/supertux/language/ru/)\n" diff --git a/data/levels/bonus2/sk.po b/data/levels/bonus2/sk.po index 8625ca8b0b7..c5df16dfbd0 100644 --- a/data/levels/bonus2/sk.po +++ b/data/levels/bonus2/sk.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Slovak (http://app.transifex.com/arctic-games/supertux/language/sk/)\n" diff --git a/data/levels/bonus2/sl.po b/data/levels/bonus2/sl.po index 6a57674fe39..6f1a8841b15 100644 --- a/data/levels/bonus2/sl.po +++ b/data/levels/bonus2/sl.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Gorzy Gorup , 2019,2022\n" "Language-Team: Slovenian (http://app.transifex.com/arctic-games/supertux/language/sl/)\n" diff --git a/data/levels/bonus2/sq.po b/data/levels/bonus2/sq.po index f0ffa470a48..ed0eb1603bd 100644 --- a/data/levels/bonus2/sq.po +++ b/data/levels/bonus2/sq.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Albanian (http://app.transifex.com/arctic-games/supertux/language/sq/)\n" diff --git a/data/levels/bonus2/sr.po b/data/levels/bonus2/sr.po index 98b68e4e8f2..dfda8e4c902 100644 --- a/data/levels/bonus2/sr.po +++ b/data/levels/bonus2/sr.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Slobodan Simić , 2016\n" "Language-Team: Serbian (http://app.transifex.com/arctic-games/supertux/language/sr/)\n" diff --git a/data/levels/bonus2/sv.po b/data/levels/bonus2/sv.po index 1a8db001e47..b8e75fb2c3a 100644 --- a/data/levels/bonus2/sv.po +++ b/data/levels/bonus2/sv.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Anders Jonsson , 2017\n" "Language-Team: Swedish (http://app.transifex.com/arctic-games/supertux/language/sv/)\n" diff --git a/data/levels/bonus2/te.po b/data/levels/bonus2/te.po index 0ecc54412cc..f0c06dcbc6b 100644 --- a/data/levels/bonus2/te.po +++ b/data/levels/bonus2/te.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Nanowarrior, 2021\n" "Language-Team: Telugu (http://app.transifex.com/arctic-games/supertux/language/te/)\n" diff --git a/data/levels/bonus2/tr.po b/data/levels/bonus2/tr.po index f37347ea56e..aba548c3798 100644 --- a/data/levels/bonus2/tr.po +++ b/data/levels/bonus2/tr.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Emre ÖZKARTAL , 2016\n" "Language-Team: Turkish (http://app.transifex.com/arctic-games/supertux/language/tr/)\n" diff --git a/data/levels/bonus2/tt.po b/data/levels/bonus2/tt.po index 90f3b59f09e..28402879564 100644 --- a/data/levels/bonus2/tt.po +++ b/data/levels/bonus2/tt.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Булат Ибраһим , 2016\n" "Language-Team: Tatar (http://app.transifex.com/arctic-games/supertux/language/tt/)\n" diff --git a/data/levels/bonus2/uk.po b/data/levels/bonus2/uk.po index 542ee25daeb..d7ef2b984fa 100644 --- a/data/levels/bonus2/uk.po +++ b/data/levels/bonus2/uk.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Asemif official, 2023\n" "Language-Team: Ukrainian (http://app.transifex.com/arctic-games/supertux/language/uk/)\n" diff --git a/data/levels/bonus2/uz.po b/data/levels/bonus2/uz.po index cef82b2f99c..fc813949990 100644 --- a/data/levels/bonus2/uz.po +++ b/data/levels/bonus2/uz.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Uzbek (http://app.transifex.com/arctic-games/supertux/language/uz/)\n" diff --git a/data/levels/bonus2/zh_CN.po b/data/levels/bonus2/zh_CN.po index 484ebfd03b0..36837972fe8 100644 --- a/data/levels/bonus2/zh_CN.po +++ b/data/levels/bonus2/zh_CN.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: Wenbin Lv , 2024\n" "Language-Team: Chinese (China) (http://app.transifex.com/arctic-games/supertux/language/zh_CN/)\n" diff --git a/data/levels/bonus2/zh_TW.po b/data/levels/bonus2/zh_TW.po index 2b0fadea705..f38867df444 100644 --- a/data/levels/bonus2/zh_TW.po +++ b/data/levels/bonus2/zh_TW.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:07+0000\n" "Last-Translator: 黃柏諺 , 2019\n" "Language-Team: Chinese (Taiwan) (http://app.transifex.com/arctic-games/supertux/language/zh_TW/)\n" diff --git a/data/levels/bonus3/af_ZA.po b/data/levels/bonus3/af_ZA.po index ea88fdafa6a..b6200bcf4cf 100644 --- a/data/levels/bonus3/af_ZA.po +++ b/data/levels/bonus3/af_ZA.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Martin van Zijl , 2019-2020\n" "Language-Team: Afrikaans (South Africa) (http://app.transifex.com/arctic-games/supertux/language/af_ZA/)\n" diff --git a/data/levels/bonus3/ar.po b/data/levels/bonus3/ar.po index 03b20c58f7a..2ba649898ac 100644 --- a/data/levels/bonus3/ar.po +++ b/data/levels/bonus3/ar.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Arabic (http://app.transifex.com/arctic-games/supertux/language/ar/)\n" diff --git a/data/levels/bonus3/az.po b/data/levels/bonus3/az.po index 64f8aaf3662..63ede507a56 100644 --- a/data/levels/bonus3/az.po +++ b/data/levels/bonus3/az.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Azerbaijani (http://app.transifex.com/arctic-games/supertux/language/az/)\n" diff --git a/data/levels/bonus3/be.po b/data/levels/bonus3/be.po index 88e8736b770..2b2431608a6 100644 --- a/data/levels/bonus3/be.po +++ b/data/levels/bonus3/be.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: se luxxy <70luxxy@gmail.com>, 2018\n" "Language-Team: Belarusian (http://app.transifex.com/arctic-games/supertux/language/be/)\n" diff --git a/data/levels/bonus3/bg.po b/data/levels/bonus3/bg.po index a7a01c1e8ca..255237fde8b 100644 --- a/data/levels/bonus3/bg.po +++ b/data/levels/bonus3/bg.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Любомир Василев, 2021\n" "Language-Team: Bulgarian (http://app.transifex.com/arctic-games/supertux/language/bg/)\n" diff --git a/data/levels/bonus3/br.po b/data/levels/bonus3/br.po index e38ba1e8183..5eda3e7f205 100644 --- a/data/levels/bonus3/br.po +++ b/data/levels/bonus3/br.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Irriep Nala Novram , 2017-2018,2020\n" "Language-Team: Breton (http://app.transifex.com/arctic-games/supertux/language/br/)\n" diff --git a/data/levels/bonus3/ca.po b/data/levels/bonus3/ca.po index ca606592728..f5ae80cbff1 100644 --- a/data/levels/bonus3/ca.po +++ b/data/levels/bonus3/ca.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Catalan (http://app.transifex.com/arctic-games/supertux/language/ca/)\n" diff --git a/data/levels/bonus3/cs.po b/data/levels/bonus3/cs.po index 1e97fcdcd5b..dfe81313c69 100644 --- a/data/levels/bonus3/cs.po +++ b/data/levels/bonus3/cs.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Jiří Paleček , 2021-2022\n" "Language-Team: Czech (http://app.transifex.com/arctic-games/supertux/language/cs/)\n" diff --git a/data/levels/bonus3/da.po b/data/levels/bonus3/da.po index 56bff6d984d..005298bf2c3 100644 --- a/data/levels/bonus3/da.po +++ b/data/levels/bonus3/da.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Lars Lyngby , 2022\n" "Language-Team: Danish (http://app.transifex.com/arctic-games/supertux/language/da/)\n" diff --git a/data/levels/bonus3/de.po b/data/levels/bonus3/de.po index babc80e6675..3ce54dbe265 100644 --- a/data/levels/bonus3/de.po +++ b/data/levels/bonus3/de.po @@ -18,7 +18,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Tobias Markus , 2018-2019,2021\n" "Language-Team: German (http://app.transifex.com/arctic-games/supertux/language/de/)\n" diff --git a/data/levels/bonus3/el.po b/data/levels/bonus3/el.po index b535d417424..f6f68558d81 100644 --- a/data/levels/bonus3/el.po +++ b/data/levels/bonus3/el.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Greek (http://app.transifex.com/arctic-games/supertux/language/el/)\n" diff --git a/data/levels/bonus3/eo.po b/data/levels/bonus3/eo.po index 9ca2f364485..44c2a1a05b1 100644 --- a/data/levels/bonus3/eo.po +++ b/data/levels/bonus3/eo.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Jorge , 2023\n" "Language-Team: Esperanto (http://app.transifex.com/arctic-games/supertux/language/eo/)\n" diff --git a/data/levels/bonus3/es.po b/data/levels/bonus3/es.po index 1dfd580f9c5..933c4335b97 100644 --- a/data/levels/bonus3/es.po +++ b/data/levels/bonus3/es.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Swyter , 2018,2021\n" "Language-Team: Spanish (http://app.transifex.com/arctic-games/supertux/language/es/)\n" diff --git a/data/levels/bonus3/es_AR.po b/data/levels/bonus3/es_AR.po index 4daddcb2d68..3fad902be77 100644 --- a/data/levels/bonus3/es_AR.po +++ b/data/levels/bonus3/es_AR.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Salomón Duarte , 2021\n" "Language-Team: Spanish (Argentina) (http://app.transifex.com/arctic-games/supertux/language/es_AR/)\n" diff --git a/data/levels/bonus3/et.po b/data/levels/bonus3/et.po index d7396c68b8e..7d98633ae07 100644 --- a/data/levels/bonus3/et.po +++ b/data/levels/bonus3/et.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Estonian (http://app.transifex.com/arctic-games/supertux/language/et/)\n" diff --git a/data/levels/bonus3/eu.po b/data/levels/bonus3/eu.po index bf6a5edb1ba..a861946b75f 100644 --- a/data/levels/bonus3/eu.po +++ b/data/levels/bonus3/eu.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Basque (http://app.transifex.com/arctic-games/supertux/language/eu/)\n" diff --git a/data/levels/bonus3/fi.po b/data/levels/bonus3/fi.po index e36c05e6391..41a688771df 100644 --- a/data/levels/bonus3/fi.po +++ b/data/levels/bonus3/fi.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Jaakoppi Horila , 2016,2018,2020-2023\n" "Language-Team: Finnish (http://app.transifex.com/arctic-games/supertux/language/fi/)\n" diff --git a/data/levels/bonus3/fr.po b/data/levels/bonus3/fr.po index 60c784f3baa..126e9a44c2a 100644 --- a/data/levels/bonus3/fr.po +++ b/data/levels/bonus3/fr.po @@ -15,7 +15,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Semphris , 2021\n" "Language-Team: French (http://app.transifex.com/arctic-games/supertux/language/fr/)\n" diff --git a/data/levels/bonus3/fr_CA.po b/data/levels/bonus3/fr_CA.po index 4840c8a5226..971b239c903 100644 --- a/data/levels/bonus3/fr_CA.po +++ b/data/levels/bonus3/fr_CA.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022-2023\n" "Language-Team: French (Canada) (http://app.transifex.com/arctic-games/supertux/language/fr_CA/)\n" diff --git a/data/levels/bonus3/gd.po b/data/levels/bonus3/gd.po index 9972906ec1c..9b656304b48 100644 --- a/data/levels/bonus3/gd.po +++ b/data/levels/bonus3/gd.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: GunChleoc, 2016,2019\n" "Language-Team: Gaelic, Scottish (http://app.transifex.com/arctic-games/supertux/language/gd/)\n" diff --git a/data/levels/bonus3/gl.po b/data/levels/bonus3/gl.po index 482bfbbf914..b6e12553e42 100644 --- a/data/levels/bonus3/gl.po +++ b/data/levels/bonus3/gl.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Xan Vieiro , 2019-2021\n" "Language-Team: Galician (http://app.transifex.com/arctic-games/supertux/language/gl/)\n" diff --git a/data/levels/bonus3/he.po b/data/levels/bonus3/he.po index 7918b087120..5cabf476bb5 100644 --- a/data/levels/bonus3/he.po +++ b/data/levels/bonus3/he.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Hebrew (http://app.transifex.com/arctic-games/supertux/language/he/)\n" diff --git a/data/levels/bonus3/hr.po b/data/levels/bonus3/hr.po index 8fe43a9e027..50c12a1601c 100644 --- a/data/levels/bonus3/hr.po +++ b/data/levels/bonus3/hr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Croatian (http://app.transifex.com/arctic-games/supertux/language/hr/)\n" diff --git a/data/levels/bonus3/hu.po b/data/levels/bonus3/hu.po index 093d76d4cda..13ffa75c439 100644 --- a/data/levels/bonus3/hu.po +++ b/data/levels/bonus3/hu.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Guih48, 2022\n" "Language-Team: Hungarian (http://app.transifex.com/arctic-games/supertux/language/hu/)\n" diff --git a/data/levels/bonus3/hy.po b/data/levels/bonus3/hy.po index 0dd01a34cea..540c7ca84a6 100644 --- a/data/levels/bonus3/hy.po +++ b/data/levels/bonus3/hy.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Armenian (http://app.transifex.com/arctic-games/supertux/language/hy/)\n" diff --git a/data/levels/bonus3/id.po b/data/levels/bonus3/id.po index a94d50f6734..03c08097fb5 100644 --- a/data/levels/bonus3/id.po +++ b/data/levels/bonus3/id.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Indonesian (http://app.transifex.com/arctic-games/supertux/language/id/)\n" diff --git a/data/levels/bonus3/is.po b/data/levels/bonus3/is.po index 856a627cf45..2a63ff22edc 100644 --- a/data/levels/bonus3/is.po +++ b/data/levels/bonus3/is.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Icelandic (http://app.transifex.com/arctic-games/supertux/language/is/)\n" diff --git a/data/levels/bonus3/it.po b/data/levels/bonus3/it.po index 031cc2802f5..e500b4f0720 100644 --- a/data/levels/bonus3/it.po +++ b/data/levels/bonus3/it.po @@ -16,7 +16,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: A-TNT DC, 2021\n" "Language-Team: Italian (http://app.transifex.com/arctic-games/supertux/language/it/)\n" diff --git a/data/levels/bonus3/ja.po b/data/levels/bonus3/ja.po index ff451ef1d60..00f38acac24 100644 --- a/data/levels/bonus3/ja.po +++ b/data/levels/bonus3/ja.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Ryo Nakano, 2019,2021,2024\n" "Language-Team: Japanese (http://app.transifex.com/arctic-games/supertux/language/ja/)\n" diff --git a/data/levels/bonus3/ko.po b/data/levels/bonus3/ko.po index 90cb8dcb6a3..e20370ad73f 100644 --- a/data/levels/bonus3/ko.po +++ b/data/levels/bonus3/ko.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Junghee Lee , 2022\n" "Language-Team: Korean (http://app.transifex.com/arctic-games/supertux/language/ko/)\n" diff --git a/data/levels/bonus3/la.po b/data/levels/bonus3/la.po index 744be88efb7..24df089300d 100644 --- a/data/levels/bonus3/la.po +++ b/data/levels/bonus3/la.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Alisa P , 2016,2018\n" "Language-Team: Latin (http://app.transifex.com/arctic-games/supertux/language/la/)\n" diff --git a/data/levels/bonus3/lt.po b/data/levels/bonus3/lt.po index 1d795f5fb09..8f906e9cc59 100644 --- a/data/levels/bonus3/lt.po +++ b/data/levels/bonus3/lt.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Tom Urisk, 2021\n" "Language-Team: Lithuanian (http://app.transifex.com/arctic-games/supertux/language/lt/)\n" diff --git a/data/levels/bonus3/ml.po b/data/levels/bonus3/ml.po index b9e8ba0332f..65715961023 100644 --- a/data/levels/bonus3/ml.po +++ b/data/levels/bonus3/ml.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Adharsh P S , 2019\n" "Language-Team: Malayalam (http://app.transifex.com/arctic-games/supertux/language/ml/)\n" diff --git a/data/levels/bonus3/ms_MY.po b/data/levels/bonus3/ms_MY.po index 5357b78027e..acaab33d354 100644 --- a/data/levels/bonus3/ms_MY.po +++ b/data/levels/bonus3/ms_MY.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: abuyop , 2018,2020-2022\n" "Language-Team: Malay (Malaysia) (http://app.transifex.com/arctic-games/supertux/language/ms_MY/)\n" diff --git a/data/levels/bonus3/nb.po b/data/levels/bonus3/nb.po index 9aba4f0339e..9e29672e897 100644 --- a/data/levels/bonus3/nb.po +++ b/data/levels/bonus3/nb.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Norwegian Bokmål (http://app.transifex.com/arctic-games/supertux/language/nb/)\n" diff --git a/data/levels/bonus3/nds.po b/data/levels/bonus3/nds.po index 1d27034567b..406af9d35e4 100644 --- a/data/levels/bonus3/nds.po +++ b/data/levels/bonus3/nds.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Benedikt Straub , 2019\n" "Language-Team: Low German (http://app.transifex.com/arctic-games/supertux/language/nds/)\n" diff --git a/data/levels/bonus3/nl.po b/data/levels/bonus3/nl.po index 43f825c5060..125e236be7e 100644 --- a/data/levels/bonus3/nl.po +++ b/data/levels/bonus3/nl.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Heimen Stoffels , 2021\n" "Language-Team: Dutch (http://app.transifex.com/arctic-games/supertux/language/nl/)\n" diff --git a/data/levels/bonus3/nn.po b/data/levels/bonus3/nn.po index d6a5585b701..91112056ad5 100644 --- a/data/levels/bonus3/nn.po +++ b/data/levels/bonus3/nn.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Norwegian Nynorsk (http://app.transifex.com/arctic-games/supertux/language/nn/)\n" diff --git a/data/levels/bonus3/pl.po b/data/levels/bonus3/pl.po index 588d92cbd4f..b664bd2bfc1 100644 --- a/data/levels/bonus3/pl.po +++ b/data/levels/bonus3/pl.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Alina Gobarov, 2021\n" "Language-Team: Polish (http://app.transifex.com/arctic-games/supertux/language/pl/)\n" diff --git a/data/levels/bonus3/pt.po b/data/levels/bonus3/pt.po index a23a354abf9..c20e6e6460e 100644 --- a/data/levels/bonus3/pt.po +++ b/data/levels/bonus3/pt.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: lecalam, 2024\n" "Language-Team: Portuguese (http://app.transifex.com/arctic-games/supertux/language/pt/)\n" diff --git a/data/levels/bonus3/pt_BR.po b/data/levels/bonus3/pt_BR.po index f00fc295bdf..c0c7a7cf176 100644 --- a/data/levels/bonus3/pt_BR.po +++ b/data/levels/bonus3/pt_BR.po @@ -16,7 +16,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Jesusaves , 2021\n" "Language-Team: Portuguese (Brazil) (http://app.transifex.com/arctic-games/supertux/language/pt_BR/)\n" diff --git a/data/levels/bonus3/ro.po b/data/levels/bonus3/ro.po index 6b4e21bfa49..a8372cc4e29 100644 --- a/data/levels/bonus3/ro.po +++ b/data/levels/bonus3/ro.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Romanian (http://app.transifex.com/arctic-games/supertux/language/ro/)\n" diff --git a/data/levels/bonus3/ru.po b/data/levels/bonus3/ru.po index f0b573cd199..1c19d6abe68 100644 --- a/data/levels/bonus3/ru.po +++ b/data/levels/bonus3/ru.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Andrei Stepanov, 2018-2019,2021,2024\n" "Language-Team: Russian (http://app.transifex.com/arctic-games/supertux/language/ru/)\n" diff --git a/data/levels/bonus3/sk.po b/data/levels/bonus3/sk.po index 22eabf9c1fb..2c63b1849d6 100644 --- a/data/levels/bonus3/sk.po +++ b/data/levels/bonus3/sk.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Slovak (http://app.transifex.com/arctic-games/supertux/language/sk/)\n" diff --git a/data/levels/bonus3/sl.po b/data/levels/bonus3/sl.po index 0ce9c1762d9..98e9757e836 100644 --- a/data/levels/bonus3/sl.po +++ b/data/levels/bonus3/sl.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Gorzy Gorup , 2018-2019,2022\n" "Language-Team: Slovenian (http://app.transifex.com/arctic-games/supertux/language/sl/)\n" diff --git a/data/levels/bonus3/sq.po b/data/levels/bonus3/sq.po index acc75fb2742..0cbc373b76c 100644 --- a/data/levels/bonus3/sq.po +++ b/data/levels/bonus3/sq.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Albanian (http://app.transifex.com/arctic-games/supertux/language/sq/)\n" diff --git a/data/levels/bonus3/sr.po b/data/levels/bonus3/sr.po index d02a95f52fb..4f4f9b257b3 100644 --- a/data/levels/bonus3/sr.po +++ b/data/levels/bonus3/sr.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Slobodan Simić , 2016,2018,2020\n" "Language-Team: Serbian (http://app.transifex.com/arctic-games/supertux/language/sr/)\n" diff --git a/data/levels/bonus3/sv.po b/data/levels/bonus3/sv.po index 40fb65f05b0..92d77bf16d1 100644 --- a/data/levels/bonus3/sv.po +++ b/data/levels/bonus3/sv.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Sebastian Rasmussen , 2019,2021\n" "Language-Team: Swedish (http://app.transifex.com/arctic-games/supertux/language/sv/)\n" diff --git a/data/levels/bonus3/te.po b/data/levels/bonus3/te.po index c541cb562c6..6d6889e207b 100644 --- a/data/levels/bonus3/te.po +++ b/data/levels/bonus3/te.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: Nanowarrior, 2021-2022\n" "Language-Team: Telugu (http://app.transifex.com/arctic-games/supertux/language/te/)\n" diff --git a/data/levels/bonus3/tr.po b/data/levels/bonus3/tr.po index 16f504d4ff4..10164fb33d3 100644 --- a/data/levels/bonus3/tr.po +++ b/data/levels/bonus3/tr.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Turkish (http://app.transifex.com/arctic-games/supertux/language/tr/)\n" diff --git a/data/levels/bonus3/tt.po b/data/levels/bonus3/tt.po index 526ed0ed2fc..9a6850b374e 100644 --- a/data/levels/bonus3/tt.po +++ b/data/levels/bonus3/tt.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Tatar (http://app.transifex.com/arctic-games/supertux/language/tt/)\n" diff --git a/data/levels/bonus3/uk.po b/data/levels/bonus3/uk.po index d2c4c6fd2e4..222ac546cab 100644 --- a/data/levels/bonus3/uk.po +++ b/data/levels/bonus3/uk.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Ukrainian (http://app.transifex.com/arctic-games/supertux/language/uk/)\n" diff --git a/data/levels/bonus3/uz.po b/data/levels/bonus3/uz.po index 7a7f6c1198b..206abf3cf81 100644 --- a/data/levels/bonus3/uz.po +++ b/data/levels/bonus3/uz.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Uzbek (http://app.transifex.com/arctic-games/supertux/language/uz/)\n" diff --git a/data/levels/bonus3/zh_CN.po b/data/levels/bonus3/zh_CN.po index ac798d250b9..41489161291 100644 --- a/data/levels/bonus3/zh_CN.po +++ b/data/levels/bonus3/zh_CN.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: 玉堂白鹤 , 2018\n" "Language-Team: Chinese (China) (http://app.transifex.com/arctic-games/supertux/language/zh_CN/)\n" diff --git a/data/levels/bonus3/zh_TW.po b/data/levels/bonus3/zh_TW.po index cd5760a28ef..df8a5006860 100644 --- a/data/levels/bonus3/zh_TW.po +++ b/data/levels/bonus3/zh_TW.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:08+0000\n" "Last-Translator: 黃柏諺 , 2019\n" "Language-Team: Chinese (Taiwan) (http://app.transifex.com/arctic-games/supertux/language/zh_TW/)\n" diff --git a/data/levels/halloween2014/ar.po b/data/levels/halloween2014/ar.po index c8b15055ecc..68bad58ac1a 100644 --- a/data/levels/halloween2014/ar.po +++ b/data/levels/halloween2014/ar.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Arabic (http://app.transifex.com/arctic-games/supertux/language/ar/)\n" diff --git a/data/levels/halloween2014/az.po b/data/levels/halloween2014/az.po index 9ba5919de1a..8e99ea4bac8 100644 --- a/data/levels/halloween2014/az.po +++ b/data/levels/halloween2014/az.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Azerbaijani (http://app.transifex.com/arctic-games/supertux/language/az/)\n" diff --git a/data/levels/halloween2014/bg.po b/data/levels/halloween2014/bg.po index da9fb54b077..05a0aa1adc1 100644 --- a/data/levels/halloween2014/bg.po +++ b/data/levels/halloween2014/bg.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Любомир Василев, 2015\n" "Language-Team: Bulgarian (http://app.transifex.com/arctic-games/supertux/language/bg/)\n" diff --git a/data/levels/halloween2014/br.po b/data/levels/halloween2014/br.po index 13ad8973973..a832274869c 100644 --- a/data/levels/halloween2014/br.po +++ b/data/levels/halloween2014/br.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Irriep Nala Novram , 2017-2018\n" "Language-Team: Breton (http://app.transifex.com/arctic-games/supertux/language/br/)\n" diff --git a/data/levels/halloween2014/ca.po b/data/levels/halloween2014/ca.po index 496f6878e88..bcf28ab2dad 100644 --- a/data/levels/halloween2014/ca.po +++ b/data/levels/halloween2014/ca.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Ariadna Pascual , 2016\n" "Language-Team: Catalan (http://app.transifex.com/arctic-games/supertux/language/ca/)\n" diff --git a/data/levels/halloween2014/cs.po b/data/levels/halloween2014/cs.po index ebbda6f89d1..824aa8041c2 100644 --- a/data/levels/halloween2014/cs.po +++ b/data/levels/halloween2014/cs.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Jiří Paleček , 2021\n" "Language-Team: Czech (http://app.transifex.com/arctic-games/supertux/language/cs/)\n" diff --git a/data/levels/halloween2014/da.po b/data/levels/halloween2014/da.po index 8b4f5cfe0c9..72fa8988e02 100644 --- a/data/levels/halloween2014/da.po +++ b/data/levels/halloween2014/da.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Joe Hansen , 2015\n" "Language-Team: Danish (http://app.transifex.com/arctic-games/supertux/language/da/)\n" diff --git a/data/levels/halloween2014/de.po b/data/levels/halloween2014/de.po index 948817e72fc..4af93ab94ea 100644 --- a/data/levels/halloween2014/de.po +++ b/data/levels/halloween2014/de.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Ettore Atalan , 2015\n" "Language-Team: German (http://app.transifex.com/arctic-games/supertux/language/de/)\n" diff --git a/data/levels/halloween2014/el.po b/data/levels/halloween2014/el.po index 2e23cc9fb67..da986bfa4f8 100644 --- a/data/levels/halloween2014/el.po +++ b/data/levels/halloween2014/el.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Vangelis Skarmoutsos (SkarmoutsosV) , 2016\n" "Language-Team: Greek (http://app.transifex.com/arctic-games/supertux/language/el/)\n" diff --git a/data/levels/halloween2014/eo.po b/data/levels/halloween2014/eo.po index 3497f75e8f1..571fcd93905 100644 --- a/data/levels/halloween2014/eo.po +++ b/data/levels/halloween2014/eo.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Esperanto (http://app.transifex.com/arctic-games/supertux/language/eo/)\n" diff --git a/data/levels/halloween2014/es.po b/data/levels/halloween2014/es.po index 23345e3afc5..f08f39968ac 100644 --- a/data/levels/halloween2014/es.po +++ b/data/levels/halloween2014/es.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Swyter , 2021\n" "Language-Team: Spanish (http://app.transifex.com/arctic-games/supertux/language/es/)\n" diff --git a/data/levels/halloween2014/es_AR.po b/data/levels/halloween2014/es_AR.po index 0042b08ef95..1b2fc357536 100644 --- a/data/levels/halloween2014/es_AR.po +++ b/data/levels/halloween2014/es_AR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Alejo Fernandez , 2020\n" "Language-Team: Spanish (Argentina) (http://app.transifex.com/arctic-games/supertux/language/es_AR/)\n" diff --git a/data/levels/halloween2014/et.po b/data/levels/halloween2014/et.po index 5ac278d2cbb..26ca9bde3fe 100644 --- a/data/levels/halloween2014/et.po +++ b/data/levels/halloween2014/et.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Estonian (http://app.transifex.com/arctic-games/supertux/language/et/)\n" diff --git a/data/levels/halloween2014/eu.po b/data/levels/halloween2014/eu.po index c81f1b84fff..e625e1dd46d 100644 --- a/data/levels/halloween2014/eu.po +++ b/data/levels/halloween2014/eu.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Mielanjel Iraeta , 2018\n" "Language-Team: Basque (http://app.transifex.com/arctic-games/supertux/language/eu/)\n" diff --git a/data/levels/halloween2014/fi.po b/data/levels/halloween2014/fi.po index f9ac661df01..4733caf09a7 100644 --- a/data/levels/halloween2014/fi.po +++ b/data/levels/halloween2014/fi.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Jaakoppi Horila , 2016,2022\n" "Language-Team: Finnish (http://app.transifex.com/arctic-games/supertux/language/fi/)\n" diff --git a/data/levels/halloween2014/fr.po b/data/levels/halloween2014/fr.po index 3c639495ab5..f723abe2dd7 100644 --- a/data/levels/halloween2014/fr.po +++ b/data/levels/halloween2014/fr.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Sébastien Aperghis-Tramoni, 2015\n" "Language-Team: French (http://app.transifex.com/arctic-games/supertux/language/fr/)\n" diff --git a/data/levels/halloween2014/fr_CA.po b/data/levels/halloween2014/fr_CA.po index d57f3b0e9c3..d6938e70e44 100644 --- a/data/levels/halloween2014/fr_CA.po +++ b/data/levels/halloween2014/fr_CA.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: French (Canada) (http://app.transifex.com/arctic-games/supertux/language/fr_CA/)\n" diff --git a/data/levels/halloween2014/gd.po b/data/levels/halloween2014/gd.po index d7f2545d042..591b5953913 100644 --- a/data/levels/halloween2014/gd.po +++ b/data/levels/halloween2014/gd.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: GunChleoc, 2019\n" "Language-Team: Gaelic, Scottish (http://app.transifex.com/arctic-games/supertux/language/gd/)\n" diff --git a/data/levels/halloween2014/gl.po b/data/levels/halloween2014/gl.po index 5825ef2ab16..ca4fae1ec45 100644 --- a/data/levels/halloween2014/gl.po +++ b/data/levels/halloween2014/gl.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Pablo Rodriguez , 2019\n" "Language-Team: Galician (http://app.transifex.com/arctic-games/supertux/language/gl/)\n" diff --git a/data/levels/halloween2014/he.po b/data/levels/halloween2014/he.po index dcabe020b0e..bfe9228ecee 100644 --- a/data/levels/halloween2014/he.po +++ b/data/levels/halloween2014/he.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Hebrew (http://app.transifex.com/arctic-games/supertux/language/he/)\n" diff --git a/data/levels/halloween2014/hr.po b/data/levels/halloween2014/hr.po index bda1ec9a930..f89d2597d40 100644 --- a/data/levels/halloween2014/hr.po +++ b/data/levels/halloween2014/hr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Croatian (http://app.transifex.com/arctic-games/supertux/language/hr/)\n" diff --git a/data/levels/halloween2014/hu.po b/data/levels/halloween2014/hu.po index 490311efefe..b411857aa5f 100644 --- a/data/levels/halloween2014/hu.po +++ b/data/levels/halloween2014/hu.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Kristóf Kófiás , 2020\n" "Language-Team: Hungarian (http://app.transifex.com/arctic-games/supertux/language/hu/)\n" diff --git a/data/levels/halloween2014/hy.po b/data/levels/halloween2014/hy.po index d77063fded9..b5f2715c2c3 100644 --- a/data/levels/halloween2014/hy.po +++ b/data/levels/halloween2014/hy.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Armenian (http://app.transifex.com/arctic-games/supertux/language/hy/)\n" diff --git a/data/levels/halloween2014/id.po b/data/levels/halloween2014/id.po index afe5772d990..d027dc330aa 100644 --- a/data/levels/halloween2014/id.po +++ b/data/levels/halloween2014/id.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Indonesian (http://app.transifex.com/arctic-games/supertux/language/id/)\n" diff --git a/data/levels/halloween2014/is.po b/data/levels/halloween2014/is.po index 198942650ad..99b0ba41192 100644 --- a/data/levels/halloween2014/is.po +++ b/data/levels/halloween2014/is.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Icelandic (http://app.transifex.com/arctic-games/supertux/language/is/)\n" diff --git a/data/levels/halloween2014/it.po b/data/levels/halloween2014/it.po index 08064c9edbe..db3091acef4 100644 --- a/data/levels/halloween2014/it.po +++ b/data/levels/halloween2014/it.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Gianfranco Del Borrello , 2016\n" "Language-Team: Italian (http://app.transifex.com/arctic-games/supertux/language/it/)\n" diff --git a/data/levels/halloween2014/ja.po b/data/levels/halloween2014/ja.po index 7e4621a181d..5202b28f195 100644 --- a/data/levels/halloween2014/ja.po +++ b/data/levels/halloween2014/ja.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Ryo Nakano, 2019\n" "Language-Team: Japanese (http://app.transifex.com/arctic-games/supertux/language/ja/)\n" diff --git a/data/levels/halloween2014/ko.po b/data/levels/halloween2014/ko.po index efd6d8dacac..43fa1da9374 100644 --- a/data/levels/halloween2014/ko.po +++ b/data/levels/halloween2014/ko.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Myeongjin , 2016\n" "Language-Team: Korean (http://app.transifex.com/arctic-games/supertux/language/ko/)\n" diff --git a/data/levels/halloween2014/la.po b/data/levels/halloween2014/la.po index d9619fcee5c..cac5d804f32 100644 --- a/data/levels/halloween2014/la.po +++ b/data/levels/halloween2014/la.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Latin (http://app.transifex.com/arctic-games/supertux/language/la/)\n" diff --git a/data/levels/halloween2014/lt.po b/data/levels/halloween2014/lt.po index a79759177e1..d87d8e7504e 100644 --- a/data/levels/halloween2014/lt.po +++ b/data/levels/halloween2014/lt.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Tom Urisk, 2021\n" "Language-Team: Lithuanian (http://app.transifex.com/arctic-games/supertux/language/lt/)\n" diff --git a/data/levels/halloween2014/ml.po b/data/levels/halloween2014/ml.po index f2c048b313a..da0e8b48cda 100644 --- a/data/levels/halloween2014/ml.po +++ b/data/levels/halloween2014/ml.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Adharsh P S , 2019\n" "Language-Team: Malayalam (http://app.transifex.com/arctic-games/supertux/language/ml/)\n" diff --git a/data/levels/halloween2014/ms_MY.po b/data/levels/halloween2014/ms_MY.po index 6fcd01c3e1e..f8edf09117e 100644 --- a/data/levels/halloween2014/ms_MY.po +++ b/data/levels/halloween2014/ms_MY.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: abuyop , 2018,2021\n" "Language-Team: Malay (Malaysia) (http://app.transifex.com/arctic-games/supertux/language/ms_MY/)\n" diff --git a/data/levels/halloween2014/nb.po b/data/levels/halloween2014/nb.po index 16e69fb3ad4..7e5bc5940aa 100644 --- a/data/levels/halloween2014/nb.po +++ b/data/levels/halloween2014/nb.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Karl Ove Hufthammer , 2015\n" "Language-Team: Norwegian Bokmål (http://app.transifex.com/arctic-games/supertux/language/nb/)\n" diff --git a/data/levels/halloween2014/nds.po b/data/levels/halloween2014/nds.po index be39f8e56f7..e9aee6429bd 100644 --- a/data/levels/halloween2014/nds.po +++ b/data/levels/halloween2014/nds.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Benedikt Straub , 2018\n" "Language-Team: Low German (http://app.transifex.com/arctic-games/supertux/language/nds/)\n" diff --git a/data/levels/halloween2014/nl.po b/data/levels/halloween2014/nl.po index 2a75111a171..524225cf47a 100644 --- a/data/levels/halloween2014/nl.po +++ b/data/levels/halloween2014/nl.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Heimen Stoffels , 2015,2019\n" "Language-Team: Dutch (http://app.transifex.com/arctic-games/supertux/language/nl/)\n" diff --git a/data/levels/halloween2014/nn.po b/data/levels/halloween2014/nn.po index e46c3eafc8e..89c1393fb94 100644 --- a/data/levels/halloween2014/nn.po +++ b/data/levels/halloween2014/nn.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Karl Ove Hufthammer , 2015\n" "Language-Team: Norwegian Nynorsk (http://app.transifex.com/arctic-games/supertux/language/nn/)\n" diff --git a/data/levels/halloween2014/pl.po b/data/levels/halloween2014/pl.po index f1efddaab90..6e8c5dc5d43 100644 --- a/data/levels/halloween2014/pl.po +++ b/data/levels/halloween2014/pl.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Krzysztof Szeląg, 2015\n" "Language-Team: Polish (http://app.transifex.com/arctic-games/supertux/language/pl/)\n" diff --git a/data/levels/halloween2014/pt.po b/data/levels/halloween2014/pt.po index 41af271fff7..7a4d1ff75ad 100644 --- a/data/levels/halloween2014/pt.po +++ b/data/levels/halloween2014/pt.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Rui , 2016\n" "Language-Team: Portuguese (http://app.transifex.com/arctic-games/supertux/language/pt/)\n" diff --git a/data/levels/halloween2014/pt_BR.po b/data/levels/halloween2014/pt_BR.po index 4179e4dc84b..a7150b6c707 100644 --- a/data/levels/halloween2014/pt_BR.po +++ b/data/levels/halloween2014/pt_BR.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Rui , 2016\n" "Language-Team: Portuguese (Brazil) (http://app.transifex.com/arctic-games/supertux/language/pt_BR/)\n" diff --git a/data/levels/halloween2014/ro.po b/data/levels/halloween2014/ro.po index c8d5b416472..97d42f8492f 100644 --- a/data/levels/halloween2014/ro.po +++ b/data/levels/halloween2014/ro.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Romanian (http://app.transifex.com/arctic-games/supertux/language/ro/)\n" diff --git a/data/levels/halloween2014/ru.po b/data/levels/halloween2014/ru.po index 823ba0b6281..4f38f41b03b 100644 --- a/data/levels/halloween2014/ru.po +++ b/data/levels/halloween2014/ru.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Dmitry Anikonov , 2015\n" "Language-Team: Russian (http://app.transifex.com/arctic-games/supertux/language/ru/)\n" diff --git a/data/levels/halloween2014/sk.po b/data/levels/halloween2014/sk.po index ff8b7e23fe7..1020bd76c74 100644 --- a/data/levels/halloween2014/sk.po +++ b/data/levels/halloween2014/sk.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: MiroslavR , 2015\n" "Language-Team: Slovak (http://app.transifex.com/arctic-games/supertux/language/sk/)\n" diff --git a/data/levels/halloween2014/sl.po b/data/levels/halloween2014/sl.po index 15f7670e106..0913ffa364e 100644 --- a/data/levels/halloween2014/sl.po +++ b/data/levels/halloween2014/sl.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Gorzy Gorup , 2022\n" "Language-Team: Slovenian (http://app.transifex.com/arctic-games/supertux/language/sl/)\n" diff --git a/data/levels/halloween2014/sq.po b/data/levels/halloween2014/sq.po index da57e192cd6..bad5e1dda1f 100644 --- a/data/levels/halloween2014/sq.po +++ b/data/levels/halloween2014/sq.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Albanian (http://app.transifex.com/arctic-games/supertux/language/sq/)\n" diff --git a/data/levels/halloween2014/sv.po b/data/levels/halloween2014/sv.po index 4cca9a5b252..1585efd29d1 100644 --- a/data/levels/halloween2014/sv.po +++ b/data/levels/halloween2014/sv.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Sebastian Rasmussen , 2015\n" "Language-Team: Swedish (http://app.transifex.com/arctic-games/supertux/language/sv/)\n" diff --git a/data/levels/halloween2014/te.po b/data/levels/halloween2014/te.po index 13ab9eb9022..f2f5671fbfc 100644 --- a/data/levels/halloween2014/te.po +++ b/data/levels/halloween2014/te.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Nanowarrior, 2022\n" "Language-Team: Telugu (http://app.transifex.com/arctic-games/supertux/language/te/)\n" diff --git a/data/levels/halloween2014/tr.po b/data/levels/halloween2014/tr.po index c366e26b832..393a254e943 100644 --- a/data/levels/halloween2014/tr.po +++ b/data/levels/halloween2014/tr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: mahmut özcan , 2015\n" "Language-Team: Turkish (http://app.transifex.com/arctic-games/supertux/language/tr/)\n" diff --git a/data/levels/halloween2014/tt.po b/data/levels/halloween2014/tt.po index d2ecb6c3073..844443a382d 100644 --- a/data/levels/halloween2014/tt.po +++ b/data/levels/halloween2014/tt.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Булат Ибраһим , 2016\n" "Language-Team: Tatar (http://app.transifex.com/arctic-games/supertux/language/tt/)\n" diff --git a/data/levels/halloween2014/uk.po b/data/levels/halloween2014/uk.po index 36d258054fb..bc040c2cd6f 100644 --- a/data/levels/halloween2014/uk.po +++ b/data/levels/halloween2014/uk.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: Max Lyashuk , 2015\n" "Language-Team: Ukrainian (http://app.transifex.com/arctic-games/supertux/language/uk/)\n" diff --git a/data/levels/halloween2014/uz.po b/data/levels/halloween2014/uz.po index 94c6ad494b2..cd32df46866 100644 --- a/data/levels/halloween2014/uz.po +++ b/data/levels/halloween2014/uz.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Uzbek (http://app.transifex.com/arctic-games/supertux/language/uz/)\n" diff --git a/data/levels/halloween2014/zh_CN.po b/data/levels/halloween2014/zh_CN.po index b2cdb54198d..9e040ff2128 100644 --- a/data/levels/halloween2014/zh_CN.po +++ b/data/levels/halloween2014/zh_CN.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-03-03 03:26+0100\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2015-10-19 18:02+0000\n" "Last-Translator: CodingJellyfish , 2018\n" "Language-Team: Chinese (China) (http://app.transifex.com/arctic-games/supertux/language/zh_CN/)\n" diff --git a/data/levels/world2/ar.po b/data/levels/world2/ar.po index bad2011da65..24102164073 100644 --- a/data/levels/world2/ar.po +++ b/data/levels/world2/ar.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022-2023\n" "Language-Team: Arabic (http://app.transifex.com/arctic-games/supertux/language/ar/)\n" diff --git a/data/levels/world2/az.po b/data/levels/world2/az.po index d93fab148f6..64381be4427 100644 --- a/data/levels/world2/az.po +++ b/data/levels/world2/az.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Azerbaijani (http://app.transifex.com/arctic-games/supertux/language/az/)\n" diff --git a/data/levels/world2/bg.po b/data/levels/world2/bg.po index 49010e782ef..7852e4c23cd 100644 --- a/data/levels/world2/bg.po +++ b/data/levels/world2/bg.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Любомир Василев, 2020-2021,2024\n" "Language-Team: Bulgarian (http://app.transifex.com/arctic-games/supertux/language/bg/)\n" diff --git a/data/levels/world2/ca.po b/data/levels/world2/ca.po index 654d6b5ba22..a2720e3b2b3 100644 --- a/data/levels/world2/ca.po +++ b/data/levels/world2/ca.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Catalan (http://app.transifex.com/arctic-games/supertux/language/ca/)\n" diff --git a/data/levels/world2/cs.po b/data/levels/world2/cs.po index 1b281dcc582..6628b06f941 100644 --- a/data/levels/world2/cs.po +++ b/data/levels/world2/cs.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Jiří Paleček , 2021\n" "Language-Team: Czech (http://app.transifex.com/arctic-games/supertux/language/cs/)\n" diff --git a/data/levels/world2/da.po b/data/levels/world2/da.po index 09a0b705d14..4bc97adb16e 100644 --- a/data/levels/world2/da.po +++ b/data/levels/world2/da.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Lars Lyngby , 2022\n" "Language-Team: Danish (http://app.transifex.com/arctic-games/supertux/language/da/)\n" diff --git a/data/levels/world2/de.po b/data/levels/world2/de.po index dfe64d5d1c5..6ecae9cbd37 100644 --- a/data/levels/world2/de.po +++ b/data/levels/world2/de.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Wuzzy , 2015\n" "Language-Team: German (http://app.transifex.com/arctic-games/supertux/language/de/)\n" diff --git a/data/levels/world2/el.po b/data/levels/world2/el.po index c411ca9efe6..5e6f837bf64 100644 --- a/data/levels/world2/el.po +++ b/data/levels/world2/el.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Greek (http://app.transifex.com/arctic-games/supertux/language/el/)\n" diff --git a/data/levels/world2/eo.po b/data/levels/world2/eo.po index 8cd9c5cdf83..816c87e2aaf 100644 --- a/data/levels/world2/eo.po +++ b/data/levels/world2/eo.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: tellovishous , 2020-2021,2023\n" "Language-Team: Esperanto (http://app.transifex.com/arctic-games/supertux/language/eo/)\n" diff --git a/data/levels/world2/es.po b/data/levels/world2/es.po index 9606db703d1..a2de997b158 100644 --- a/data/levels/world2/es.po +++ b/data/levels/world2/es.po @@ -15,7 +15,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Swyter , 2018,2021\n" "Language-Team: Spanish (http://app.transifex.com/arctic-games/supertux/language/es/)\n" diff --git a/data/levels/world2/es_AR.po b/data/levels/world2/es_AR.po index d21d5051c29..96a8a8c6189 100644 --- a/data/levels/world2/es_AR.po +++ b/data/levels/world2/es_AR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Salomón Duarte , 2021\n" "Language-Team: Spanish (Argentina) (http://app.transifex.com/arctic-games/supertux/language/es_AR/)\n" diff --git a/data/levels/world2/et.po b/data/levels/world2/et.po index 2f95175ec24..7c9eb13e25a 100644 --- a/data/levels/world2/et.po +++ b/data/levels/world2/et.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Estonian (http://app.transifex.com/arctic-games/supertux/language/et/)\n" diff --git a/data/levels/world2/eu.po b/data/levels/world2/eu.po index de1a8e9dd38..d046eb7dce8 100644 --- a/data/levels/world2/eu.po +++ b/data/levels/world2/eu.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Basque (http://app.transifex.com/arctic-games/supertux/language/eu/)\n" diff --git a/data/levels/world2/fi.po b/data/levels/world2/fi.po index 9d9fbf30dd5..9367a1c758d 100644 --- a/data/levels/world2/fi.po +++ b/data/levels/world2/fi.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Jaakoppi Horila , 2016,2018-2023\n" "Language-Team: Finnish (http://app.transifex.com/arctic-games/supertux/language/fi/)\n" diff --git a/data/levels/world2/fr.po b/data/levels/world2/fr.po index 1a8819fe2c2..9605ad2aa76 100644 --- a/data/levels/world2/fr.po +++ b/data/levels/world2/fr.po @@ -17,7 +17,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Semphris , 2021\n" "Language-Team: French (http://app.transifex.com/arctic-games/supertux/language/fr/)\n" diff --git a/data/levels/world2/fr_CA.po b/data/levels/world2/fr_CA.po index 7c3cbbe99cf..e697e9fbd65 100644 --- a/data/levels/world2/fr_CA.po +++ b/data/levels/world2/fr_CA.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: French (Canada) (http://app.transifex.com/arctic-games/supertux/language/fr_CA/)\n" diff --git a/data/levels/world2/gd.po b/data/levels/world2/gd.po index a44d6ebed8c..7214cfe75cf 100644 --- a/data/levels/world2/gd.po +++ b/data/levels/world2/gd.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: GunChleoc, 2016,2019\n" "Language-Team: Gaelic, Scottish (http://app.transifex.com/arctic-games/supertux/language/gd/)\n" diff --git a/data/levels/world2/gl.po b/data/levels/world2/gl.po index cf37ad751ad..982c71a906e 100644 --- a/data/levels/world2/gl.po +++ b/data/levels/world2/gl.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Xan Vieiro , 2021\n" "Language-Team: Galician (http://app.transifex.com/arctic-games/supertux/language/gl/)\n" diff --git a/data/levels/world2/he.po b/data/levels/world2/he.po index fde00e6c384..dc13a4ecd73 100644 --- a/data/levels/world2/he.po +++ b/data/levels/world2/he.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Hebrew (http://app.transifex.com/arctic-games/supertux/language/he/)\n" diff --git a/data/levels/world2/hr.po b/data/levels/world2/hr.po index c3766344a96..62e954cd8d4 100644 --- a/data/levels/world2/hr.po +++ b/data/levels/world2/hr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Croatian (http://app.transifex.com/arctic-games/supertux/language/hr/)\n" diff --git a/data/levels/world2/hu.po b/data/levels/world2/hu.po index f6fb8e99864..5156a34ccff 100644 --- a/data/levels/world2/hu.po +++ b/data/levels/world2/hu.po @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Hungarian (http://app.transifex.com/arctic-games/supertux/language/hu/)\n" diff --git a/data/levels/world2/hy.po b/data/levels/world2/hy.po index 8e9221c6428..bb5ff8c85a4 100644 --- a/data/levels/world2/hy.po +++ b/data/levels/world2/hy.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Armenian (http://app.transifex.com/arctic-games/supertux/language/hy/)\n" diff --git a/data/levels/world2/id.po b/data/levels/world2/id.po index 2ae99b0240c..26559a6fc21 100644 --- a/data/levels/world2/id.po +++ b/data/levels/world2/id.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Triyan W. Nugroho , 2022\n" "Language-Team: Indonesian (http://app.transifex.com/arctic-games/supertux/language/id/)\n" diff --git a/data/levels/world2/is.po b/data/levels/world2/is.po index 24aba1d9016..5aa4ad9ba56 100644 --- a/data/levels/world2/is.po +++ b/data/levels/world2/is.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Icelandic (http://app.transifex.com/arctic-games/supertux/language/is/)\n" diff --git a/data/levels/world2/it.po b/data/levels/world2/it.po index 9251adbf8c8..f7a7f6907ab 100644 --- a/data/levels/world2/it.po +++ b/data/levels/world2/it.po @@ -16,7 +16,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: A-TNT DC, 2021\n" "Language-Team: Italian (http://app.transifex.com/arctic-games/supertux/language/it/)\n" diff --git a/data/levels/world2/ja.po b/data/levels/world2/ja.po index da3acb4a372..f5e18a31ab0 100644 --- a/data/levels/world2/ja.po +++ b/data/levels/world2/ja.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Japanese (http://app.transifex.com/arctic-games/supertux/language/ja/)\n" diff --git a/data/levels/world2/ko.po b/data/levels/world2/ko.po index 66f4b46d2f1..9ddbdaa452c 100644 --- a/data/levels/world2/ko.po +++ b/data/levels/world2/ko.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Korean (http://app.transifex.com/arctic-games/supertux/language/ko/)\n" diff --git a/data/levels/world2/ml.po b/data/levels/world2/ml.po index 334c917df61..65696abc7bd 100644 --- a/data/levels/world2/ml.po +++ b/data/levels/world2/ml.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Adithyan S S , 2020\n" "Language-Team: Malayalam (http://app.transifex.com/arctic-games/supertux/language/ml/)\n" diff --git a/data/levels/world2/ms_MY.po b/data/levels/world2/ms_MY.po index 0ba37e3cb94..9fafc1eac16 100644 --- a/data/levels/world2/ms_MY.po +++ b/data/levels/world2/ms_MY.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: abuyop , 2021-2022\n" "Language-Team: Malay (Malaysia) (http://app.transifex.com/arctic-games/supertux/language/ms_MY/)\n" diff --git a/data/levels/world2/nb.po b/data/levels/world2/nb.po index b9f55309f69..5bf23e8ebea 100644 --- a/data/levels/world2/nb.po +++ b/data/levels/world2/nb.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Norwegian Bokmål (http://app.transifex.com/arctic-games/supertux/language/nb/)\n" diff --git a/data/levels/world2/nl.po b/data/levels/world2/nl.po index ff9fe9706f3..6325105bc62 100644 --- a/data/levels/world2/nl.po +++ b/data/levels/world2/nl.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Heimen Stoffels , 2021\n" "Language-Team: Dutch (http://app.transifex.com/arctic-games/supertux/language/nl/)\n" diff --git a/data/levels/world2/nn.po b/data/levels/world2/nn.po index 4093b8ff581..0667598daa0 100644 --- a/data/levels/world2/nn.po +++ b/data/levels/world2/nn.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Norwegian Nynorsk (http://app.transifex.com/arctic-games/supertux/language/nn/)\n" diff --git a/data/levels/world2/pl.po b/data/levels/world2/pl.po index aa0d5308972..d4bd4a49388 100644 --- a/data/levels/world2/pl.po +++ b/data/levels/world2/pl.po @@ -23,7 +23,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Ziemowit Zabawa, 2022\n" "Language-Team: Polish (http://app.transifex.com/arctic-games/supertux/language/pl/)\n" diff --git a/data/levels/world2/pt.po b/data/levels/world2/pt.po index 48820985a39..406db594fee 100644 --- a/data/levels/world2/pt.po +++ b/data/levels/world2/pt.po @@ -16,7 +16,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: lecalam, 2024\n" "Language-Team: Portuguese (http://app.transifex.com/arctic-games/supertux/language/pt/)\n" diff --git a/data/levels/world2/pt_BR.po b/data/levels/world2/pt_BR.po index 059ce84a6b4..cc3d44d3c45 100644 --- a/data/levels/world2/pt_BR.po +++ b/data/levels/world2/pt_BR.po @@ -18,7 +18,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Jesusaves , 2021\n" "Language-Team: Portuguese (Brazil) (http://app.transifex.com/arctic-games/supertux/language/pt_BR/)\n" diff --git a/data/levels/world2/ro.po b/data/levels/world2/ro.po index acb70a7a719..81ea747ca76 100644 --- a/data/levels/world2/ro.po +++ b/data/levels/world2/ro.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Romanian (http://app.transifex.com/arctic-games/supertux/language/ro/)\n" diff --git a/data/levels/world2/ru.po b/data/levels/world2/ru.po index 5282560758e..5bc353c2416 100644 --- a/data/levels/world2/ru.po +++ b/data/levels/world2/ru.po @@ -15,7 +15,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Темак, 2022\n" "Language-Team: Russian (http://app.transifex.com/arctic-games/supertux/language/ru/)\n" diff --git a/data/levels/world2/sk.po b/data/levels/world2/sk.po index 2cafc889425..21b3cd6ed73 100644 --- a/data/levels/world2/sk.po +++ b/data/levels/world2/sk.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Slovak (http://app.transifex.com/arctic-games/supertux/language/sk/)\n" diff --git a/data/levels/world2/sl.po b/data/levels/world2/sl.po index 87763cea0b2..a9bc8f83731 100644 --- a/data/levels/world2/sl.po +++ b/data/levels/world2/sl.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Gorzy Gorup , 2016,2018-2020,2022\n" "Language-Team: Slovenian (http://app.transifex.com/arctic-games/supertux/language/sl/)\n" diff --git a/data/levels/world2/sq.po b/data/levels/world2/sq.po index 5078cfe1282..60d78f8b2d5 100644 --- a/data/levels/world2/sq.po +++ b/data/levels/world2/sq.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Albanian (http://app.transifex.com/arctic-games/supertux/language/sq/)\n" diff --git a/data/levels/world2/sv.po b/data/levels/world2/sv.po index e1104b81f22..c16d09e6216 100644 --- a/data/levels/world2/sv.po +++ b/data/levels/world2/sv.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Sebastian Rasmussen , 2019-2021\n" "Language-Team: Swedish (http://app.transifex.com/arctic-games/supertux/language/sv/)\n" diff --git a/data/levels/world2/te.po b/data/levels/world2/te.po index d77fdfc0a4d..ec5066c1fb2 100644 --- a/data/levels/world2/te.po +++ b/data/levels/world2/te.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Nanowarrior, 2022\n" "Language-Team: Telugu (http://app.transifex.com/arctic-games/supertux/language/te/)\n" diff --git a/data/levels/world2/tr.po b/data/levels/world2/tr.po index 5b085f3576a..7025ca6bb1f 100644 --- a/data/levels/world2/tr.po +++ b/data/levels/world2/tr.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Turkish (http://app.transifex.com/arctic-games/supertux/language/tr/)\n" diff --git a/data/levels/world2/tt.po b/data/levels/world2/tt.po index 899ff470f3d..c17140927fd 100644 --- a/data/levels/world2/tt.po +++ b/data/levels/world2/tt.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Tatar (http://app.transifex.com/arctic-games/supertux/language/tt/)\n" diff --git a/data/levels/world2/uk.po b/data/levels/world2/uk.po index 3c3a5644fd3..13c3882ecea 100644 --- a/data/levels/world2/uk.po +++ b/data/levels/world2/uk.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2022\n" "Language-Team: Ukrainian (http://app.transifex.com/arctic-games/supertux/language/uk/)\n" diff --git a/data/levels/world2/uz.po b/data/levels/world2/uz.po index 6d93d888f4e..e99bb5acad6 100644 --- a/data/levels/world2/uz.po +++ b/data/levels/world2/uz.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: IAN RODRÍGUEZ Lorenzo, 2023\n" "Language-Team: Uzbek (http://app.transifex.com/arctic-games/supertux/language/uz/)\n" diff --git a/data/levels/world2/zh_CN.po b/data/levels/world2/zh_CN.po index 38097c1f349..8bd50e79665 100644 --- a/data/levels/world2/zh_CN.po +++ b/data/levels/world2/zh_CN.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: SuperTux\n" "Report-Msgid-Bugs-To: https://github.com/SuperTux/supertux/issues\n" -"POT-Creation-Date: 2024-10-15 23:31+0000\n" +"POT-Creation-Date: 2024-10-20 09:04+0000\n" "PO-Revision-Date: 2013-08-10 23:00+0000\n" "Last-Translator: Wenbin Lv , 2024\n" "Language-Team: Chinese (China) (http://app.transifex.com/arctic-games/supertux/language/zh_CN/)\n" diff --git a/data/locale/gl.po b/data/locale/gl.po index f96d2f232ea..f7464e3f71a 100644 --- a/data/locale/gl.po +++ b/data/locale/gl.po @@ -201,15 +201,15 @@ msgstr "Pechar" #: src/supertux/statistics.cpp:70 msgid "Enable Coins Statistic" -msgstr "" +msgstr "Activar estatísticas de moedas" #: src/supertux/statistics.cpp:71 msgid "Enable Badguys Statistic" -msgstr "" +msgstr "Activar estatísticas dos inimigos" #: src/supertux/statistics.cpp:72 msgid "Enable Secrets Statistic" -msgstr "" +msgstr "Activar estatísticas dos segredos" #: src/supertux/statistics.cpp:93 msgid "Max coins collected:" @@ -616,7 +616,7 @@ msgid "" "Ctrl+D = Duplicate line\n" "Ctrl+Z = Undo\n" "Ctrl+Y = Redo" -msgstr "" +msgstr "Atallos de teclado:\n---------------------\nEsc = Abrir menú\nCtrl+S = Gardar\nCtrl+T = Probar\nCtrl+Z = Desfacer\nCtrl+Y = Refacer\nF5 = Activar/desactivar autotile\nF6 = Renderizar luz\nF7 = Axustar á cuadrícula\nF8 = Amosar cuadrícula\nCtrl++ ou Ctrl+Despr. arriba = Achegar\nCtrl+- ou Ctrl+Despr. abaixo = Alonxar\nCtrl+D = Restablecer o zoom\n\nAtallos de script:\n ------------- \nInicio = Ir ao comezo da liña\nFin = Ir ao final da liña\nFlecha esquerda = Retroceder no texto\nFlecha dereita = Avanzar no texto\nRetroceso = Eliminar diante do cursor de texto\nSuprimir = Eliminar detrás do cursor de texto\nCtrl+X = Cortar toda a liña\nCtrl+C = Copiar toda a liña\nCtrl+V = Pegar\nCtrl+D = Duplicar liña\nCtrl+Z = Desfacer\nCtrl+Y = Refacer" #: src/supertux/menu/editor_menu.cpp:232 msgid "Deprecated tiles are still present in the level." @@ -624,7 +624,7 @@ msgstr "Os bloques obsoletos aínda están presentes no nivel." #: src/supertux/menu/editor_menu.cpp:239 msgid "Do you want to show all deprecated tiles on active tilemaps?" -msgstr "Queres mostrar todos os bloques obsoletos nos mapas de bloques ativos?" +msgstr "Queres mostrar todos os bloques obsoletos nos mapas de bloques activos?" #: src/supertux/menu/editor_menu.cpp:246 msgid "There are no more deprecated tiles in the level!" @@ -672,7 +672,7 @@ msgstr "Utilizar Fontes Bitmap" #: src/supertux/menu/debug_menu.cpp:74 msgid "Show Tile IDs in Editor Toolbox" -msgstr "" +msgstr "Amosar IDs das celas na caixa de ferramentas do editor" #: src/supertux/menu/debug_menu.cpp:75 msgid "Dump Texture Cache" @@ -732,7 +732,7 @@ msgstr "Nota do Nivel" #: src/supertux/menu/editor_level_menu.cpp:38 msgid "Tileset" -msgstr "Conxunto de Teselas" +msgstr "Conxunto de Bloques" #: src/supertux/menu/editor_level_menu.cpp:42 msgid "Target Time" @@ -753,7 +753,7 @@ msgstr "Introduce unha licenza para este nivel." #: src/supertux/menu/editor_tilegroup_menu.cpp:26 src/object/tilemap.cpp:297 #: src/editor/toolbox_widget.cpp:74 msgid "Tiles" -msgstr "Tesela" +msgstr "Bloques" #: src/supertux/menu/editor_levelset_menu.cpp:50 #: src/supertux/menu/editor_level_select_menu.cpp:97 @@ -957,15 +957,15 @@ msgstr "Non hai Complementos instalados" #: src/supertux/menu/addon_menu.cpp:125 msgid "{} *UPDATE*" -msgstr "" +msgstr "{} *ACTUALIZACIÓN*" #: src/supertux/menu/addon_menu.cpp:127 msgid "{} [DISABLED] *UPDATE*" -msgstr "" +msgstr "\"{} [DESACTIVADO] *ACTUALIZACIÓN*" #: src/supertux/menu/addon_menu.cpp:136 msgid "{} [DISABLED]" -msgstr "" +msgstr "{} [DESACTIVADO]" #: src/supertux/menu/addon_menu.cpp:146 msgid "No updates available." @@ -1502,24 +1502,24 @@ msgstr "Axustar a resolución ó tamaño do navegador" #: src/supertux/menu/options_menu.cpp:113 msgid "Frame prediction" -msgstr "" +msgstr "Predición de fotogramas" #: src/supertux/menu/options_menu.cpp:114 msgid "" "Smooth camera motion, generating intermediate frames. This has a noticeable " "effect on monitors at >> 60Hz. Moving objects may be blurry." -msgstr "" +msgstr "Movemento suave da cámara, xerando fotogramas intermedios. Isto ten un efecto notable en monitores a máis de 60 Hz. Os obxectos en movemento poden verse borrosos." #: src/supertux/menu/options_menu.cpp:122 msgid "Camera Peek Multiplier" -msgstr "" +msgstr "Multiplicador de vista da cámara" #: src/supertux/menu/options_menu.cpp:123 msgid "" "The fractional distance towards the camera peek position to move each frame.\n" "\n" "0 = No Peek, 1 = Instant Peek" -msgstr "" +msgstr "A distancia fraccionaria cara á posición de vista da cámara que se move en cada fotograma.\n\n0 = Sen vista, 1 = Vista instantánea." #: src/supertux/menu/options_menu.cpp:125 msgid "Change Video System" @@ -1751,11 +1751,11 @@ msgstr "Axustar o volume da música" #: src/supertux/menu/options_menu.cpp:548 msgid "Flash Intensity" -msgstr "" +msgstr "Intensidade do flash" #: src/supertux/menu/options_menu.cpp:549 msgid "Adjust the intensity of the flash produced by the thunderstorm" -msgstr "" +msgstr "Axustar a intensidade do flash producido pola tormenta eléctrica" #: src/supertux/menu/options_menu.cpp:562 msgid "On-screen controls scale" @@ -2452,7 +2452,7 @@ msgstr "Tesela Inestable" #: src/object/rock.hpp:40 src/object/bonus_block.cpp:269 msgid "Rock" -msgstr "Pedra" +msgstr "Rocha" #: src/object/snow_particle_system.cpp:114 msgid "Epsilon" @@ -2625,7 +2625,7 @@ msgstr "Fondo" #: src/object/bigsnowball.hpp:39 msgid "Big Snowball" -msgstr "" +msgstr "Gran bola de neve" #: src/object/shard.hpp:35 msgid "Shard" @@ -2727,7 +2727,7 @@ msgstr "Partículas Extravagantes" #: src/object/wind.cpp:88 msgid "Particles Enabled" -msgstr "" +msgstr "Partículas activadas" #: src/object/ambient_light.hpp:37 msgid "Ambient Light" @@ -3234,11 +3234,11 @@ msgstr "Script de golpe" #: src/object/bigsnowball.cpp:83 msgid "Break on impact?" -msgstr "" +msgstr "Romper ao impactar?" #: src/object/bigsnowball.cpp:84 msgid "Bounce?" -msgstr "" +msgstr "Rebotar?" #: src/object/fallblock.hpp:41 msgid "Falling Platform" @@ -3246,7 +3246,7 @@ msgstr "Plataforma que cae" #: src/object/ambient_sound.cpp:87 msgid "Radius (in tiles)" -msgstr "Radio (en mosaicos)" +msgstr "Radio (en bloques)" #: src/object/cloud_particle_system.hpp:50 msgid "Cloud Particles" @@ -3286,7 +3286,7 @@ msgstr "Tronada" #: src/object/sticky_object.cpp:72 src/object/sticky_object.cpp:132 msgid "Sticky" -msgstr "" +msgstr "Adherente" #: src/object/level_time.hpp:75 msgid "Time Limit" @@ -3789,7 +3789,7 @@ msgstr "Sector: {}" #: src/editor/layers_widget.cpp:464 msgid "Add Layer" -msgstr "" +msgstr "Engadir capa" #: src/editor/particle_editor.cpp:114 msgid "Change texture... ->" @@ -4399,7 +4399,7 @@ msgstr "Bala de folla" #: src/badguy/mole_rock.hpp:44 msgid "Mole's rock" -msgstr "Pedras da toupeira" +msgstr "Rochas da toupeira" #: src/badguy/dispenser.hpp:68 msgid "Dispenser" @@ -4532,7 +4532,7 @@ msgstr "Vidas" #. mode is activated. #: src/badguy/boss.cpp:94 msgid "Lives to Pinch Mode" -msgstr "" +msgstr "Vidas para o modo de pinzar" #. l10n: Pinch Mode refers to a particular boss mode that gets #. activated once the boss has lost the specified amounts of lives. @@ -4540,7 +4540,7 @@ msgstr "" #. mode. #: src/badguy/boss.cpp:99 msgid "Pinch Mode Activation Script" -msgstr "" +msgstr "Script de activación do modo de pinzar" #: src/badguy/smartball.cpp:35 msgid "Pumpkin" @@ -4564,11 +4564,11 @@ msgstr "Dardo" #: src/badguy/granito.cpp:259 msgid "Detect script" -msgstr "" +msgstr "Script de detección" #: src/badguy/granito.cpp:260 msgid "Carried script" -msgstr "" +msgstr "Script de transporte" #: src/badguy/granito.cpp:277 src/badguy/granito_big.cpp:73 msgid "Default" @@ -4584,7 +4584,7 @@ msgstr "Camiñando" #: src/badguy/granito.cpp:280 src/badguy/granito_big.cpp:76 msgid "Scriptable" -msgstr "" +msgstr "Scriptable" #: src/badguy/granito.cpp:283 msgid "Sitting" @@ -4628,7 +4628,7 @@ msgstr "Peixe inofensivo" #: src/badguy/granito_big.cpp:64 msgid "Carrying Script" -msgstr "" +msgstr "Script de transporte" #: src/badguy/fish_swimming.hpp:40 msgid "Swimming Fish" @@ -5122,7 +5122,7 @@ msgstr "Cova de Xeo & Cristal" #: data/images/ice_world.strf:169 msgid "Snow Embellishments" -msgstr "" +msgstr "Adornos de neve" #: data/images/ice_world.strf:339 msgid "Underground Forest" @@ -5130,7 +5130,7 @@ msgstr "Bosque Subterráneo" #: data/images/ice_world.strf:417 msgid "Trees & Rocks" -msgstr "" +msgstr "Árbores e Rochas" #: data/images/ice_world.strf:494 msgid "Seasonal" @@ -5170,7 +5170,7 @@ msgstr "Fondo corrompido" #: data/images/tiles.strf:1181 msgid "Jagged Rocks" -msgstr "" +msgstr "Rochas irregulares" #: data/images/tiles.strf:1225 msgid "Block + Bonus" @@ -5238,10 +5238,10 @@ msgstr "Para niveis creados en versións anteriores á -0.6.3, que usan bloques #: data/images/converters/data.stcd:13 msgid "Jagged Rock Tiles from Addon" -msgstr "" +msgstr "Bloques de rocha irregular do complemento" #: data/images/converters/data.stcd:15 msgid "" "For levels, created with the rock tiles addon, converts their IDs to vanilla" " rock tile IDs" -msgstr "" +msgstr "Para os niveis creados co complemento de bloques de rocha, converte os seus IDs aos IDs de bloques de rocha por defecto" diff --git a/data/locale/zh_CN.po b/data/locale/zh_CN.po index a56a17f5409..09095b4e09e 100644 --- a/data/locale/zh_CN.po +++ b/data/locale/zh_CN.po @@ -5174,7 +5174,7 @@ msgstr "腐烂背景" #: data/images/tiles.strf:1181 msgid "Jagged Rocks" -msgstr "" +msgstr "锯齿状岩石" #: data/images/tiles.strf:1225 msgid "Block + Bonus" @@ -5242,10 +5242,10 @@ msgstr "用于在 0.6.3 之前的版本创建的关卡,这些关卡使用水 #: data/images/converters/data.stcd:13 msgid "Jagged Rock Tiles from Addon" -msgstr "" +msgstr "来自扩展的锯齿状岩石图块" #: data/images/converters/data.stcd:15 msgid "" "For levels, created with the rock tiles addon, converts their IDs to vanilla" " rock tile IDs" -msgstr "" +msgstr "用于使用岩石图块扩展创建的关卡,将它们的 ID 转换为原始的岩石图块 ID。" diff --git a/data/music/misc/calm_ocean.music b/data/music/misc/calm_ocean.music new file mode 100644 index 00000000000..a9772145bad --- /dev/null +++ b/data/music/misc/calm_ocean.music @@ -0,0 +1,5 @@ +(supertux-music + (file "calm_ocean.ogg") + (loop-begin 16) + (loop-at -1) +) \ No newline at end of file diff --git a/data/music/misc/calm_ocean.ogg b/data/music/misc/calm_ocean.ogg new file mode 100644 index 00000000000..261a740046b Binary files /dev/null and b/data/music/misc/calm_ocean.ogg differ diff --git a/src/addon/addon_manager.cpp b/src/addon/addon_manager.cpp index 67f4f1c6365..54be09eca1a 100644 --- a/src/addon/addon_manager.cpp +++ b/src/addon/addon_manager.cpp @@ -276,7 +276,10 @@ AddonManager::request_check_online() { empty_cache_directory(); - TransferStatusPtr status = m_downloader.request_download(m_repository_url, ADDON_INFO_PATH); + // Since then() may be called immediately if networking is disabled, + // hold the status in a separate variable so that `m_transfer_status = {}` + // below doesn't cause this function to return nullptr. + auto status = m_downloader.request_download(m_repository_url, ADDON_INFO_PATH); status->then( [this](bool success) { diff --git a/src/addon/downloader.cpp b/src/addon/downloader.cpp index 56d82b08214..1c36364ea32 100644 --- a/src/addon/downloader.cpp +++ b/src/addon/downloader.cpp @@ -33,6 +33,7 @@ #endif #include "physfs/util.hpp" +#include "supertux/gameconfig.hpp" #include "supertux/globals.hpp" #include "util/file_system.hpp" #include "util/log.hpp" @@ -137,6 +138,7 @@ TransferStatusList::update() void TransferStatusList::push(TransferStatusPtr status) { + assert(!status->parent_list); status->parent_list = this; m_transfer_statuses.push_back(status); @@ -421,6 +423,9 @@ Downloader::download(const std::string& url, size_t (*write_func)(void* ptr, size_t size, size_t nmemb, void* userdata), void* userdata) { + if (g_config->disable_network) + throw std::runtime_error("Networking is disabled"); + log_info << "Downloading " << url << std::endl; #ifndef EMSCRIPTEN @@ -456,6 +461,9 @@ Downloader::download(const std::string& url, std::string Downloader::download(const std::string& url) { + if (g_config->disable_network) + throw std::runtime_error("Networking is disabled"); + std::string result; download(url, my_curl_string_append, &result); return result; @@ -464,6 +472,9 @@ Downloader::download(const std::string& url) void Downloader::download(const std::string& url, const std::string& filename) { + if (g_config->disable_network) + throw std::runtime_error("Networking is disabled"); + #ifndef EMSCRIPTEN log_info << "download: " << url << " to " << filename << std::endl; std::unique_ptr fout(PHYSFS_openWrite(filename.c_str()), @@ -512,6 +523,31 @@ Downloader::abort(TransferId id) void Downloader::update() { + if (g_config->disable_network) + { + // Remove any on-going transfers + for (const auto& transfer_data : m_transfers) + { + TransferStatusPtr status = transfer_data.second->get_status(); + status->error_msg = "Networking is disabled"; + for (const auto& callback : status->callbacks) + { + try + { + callback(false); + } + catch(const std::exception& err) + { + log_warning << "Illegal exception in Downloader: " << err.what() << std::endl; + } + } + if (status->parent_list) + status->parent_list->on_transfer_complete(status, false); + } + m_transfers.clear(); + return; + } + #ifndef EMSCRIPTEN // Prevent updating a Downloader multiple times in the same frame. if (m_last_update_time == g_real_time) return; diff --git a/src/editor/editor.cpp b/src/editor/editor.cpp index 5b399e4d641..37ac7f9de3a 100644 --- a/src/editor/editor.cpp +++ b/src/editor/editor.cpp @@ -410,6 +410,12 @@ Editor::get_tileselect_move_mode() const return m_toolbox_widget->get_tileselect_move_mode(); } +void +Editor::update_autotileset() +{ + m_overlay_widget->update_autotileset(); +} + void Editor::scroll(const Vector& velocity) { diff --git a/src/editor/editor.hpp b/src/editor/editor.hpp index d31a5b80cae..5eec578fd42 100644 --- a/src/editor/editor.hpp +++ b/src/editor/editor.hpp @@ -124,6 +124,8 @@ class Editor final : public Screen, void check_deprecated_tiles(bool focus = false); bool has_deprecated_tiles() const { return m_has_deprecated_tiles; } + void update_autotileset(); + /** Checks whether the level can be saved and does not contain obvious issues (currently: check if main sector and a spawn point named "main" is present) */ diff --git a/src/editor/layers_widget.cpp b/src/editor/layers_widget.cpp index 61d9bf78f1d..98a330e863a 100644 --- a/src/editor/layers_widget.cpp +++ b/src/editor/layers_widget.cpp @@ -148,17 +148,7 @@ EditorLayersWidget::draw(DrawingContext& context) void EditorLayersWidget::update(float dt_sec) { - auto it = m_layer_icons.begin(); - while (it != m_layer_icons.end()) - { - auto layer_icon = (*it).get(); - if (!layer_icon->is_valid()) - { - it = m_layer_icons.erase(it); - continue; - } - ++it; - } + remove_invalid_layers(); TileMap* selected_tilemap = get_selected_tilemap(); if (selected_tilemap) @@ -460,6 +450,8 @@ EditorLayersWidget::add_layer(GameObject* layer, bool initial) void EditorLayersWidget::update_tip() { + remove_invalid_layers(); + if (m_hovered_layer == m_layer_icons.size()) m_object_tip->set_info(_("Add Layer")); else if (m_hovered_layer > m_layer_icons.size()) @@ -477,6 +469,22 @@ EditorLayersWidget::update_current_tip() update_tip(); } +void +EditorLayersWidget::remove_invalid_layers() +{ + auto it = m_layer_icons.begin(); + while (it != m_layer_icons.end()) + { + auto layer_icon = (*it).get(); + if (!layer_icon->is_valid()) + { + it = m_layer_icons.erase(it); + continue; + } + ++it; + } +} + TileMap* EditorLayersWidget::get_selected_tilemap() const { diff --git a/src/editor/layers_widget.hpp b/src/editor/layers_widget.hpp index e974fa91e26..3efc7355c42 100644 --- a/src/editor/layers_widget.hpp +++ b/src/editor/layers_widget.hpp @@ -78,7 +78,9 @@ class EditorLayersWidget final : public Widget private: Vector get_layer_coords(const int pos) const; int get_layer_pos(const Vector& coords) const; + void update_tip(); + void remove_invalid_layers(); private: Editor& m_editor; diff --git a/src/editor/object_option.cpp b/src/editor/object_option.cpp index 06f70b2bfa7..13afd13bee3 100644 --- a/src/editor/object_option.cpp +++ b/src/editor/object_option.cpp @@ -29,8 +29,12 @@ #include "gui/menu_object_select.hpp" #include "object/tilemap.hpp" #include "supertux/direction.hpp" +#include "supertux/game_object_factory.hpp" #include "supertux/moving_object.hpp" #include "util/gettext.hpp" +#include "util/log.hpp" +#include "util/reader_iterator.hpp" +#include "util/reader_mapping.hpp" #include "util/writer.hpp" #include "video/color.hpp" @@ -46,11 +50,62 @@ std::string fmt_to_string(const T& v) } // namespace +bool BaseObjectOption::s_allow_saving_defaults = false; + BaseObjectOption::BaseObjectOption(const std::string& text, const std::string& key, unsigned int flags) : m_text(text), m_key(key), - m_flags(flags) + m_flags(flags), + m_last_state() +{ +} + +std::string +BaseObjectOption::save() const { + std::ostringstream stream; + Writer writer(stream); + save(writer); + + return stream.str(); +} + +void +BaseObjectOption::save_state() +{ + s_allow_saving_defaults = true; + m_last_state = save(); + s_allow_saving_defaults = false; +} + +bool +BaseObjectOption::has_state_changed() const +{ + s_allow_saving_defaults = true; + const bool result = m_last_state != save(); + s_allow_saving_defaults = false; + + return result; +} + +void +BaseObjectOption::parse_state(const ReaderMapping& reader) +{ + parse(reader); +} + +void +BaseObjectOption::save_old_state(std::ostream& out) const +{ + out << m_last_state; +} + +void +BaseObjectOption::save_new_state(Writer& writer) const +{ + s_allow_saving_defaults = true; + save(writer); + s_allow_saving_defaults = false; } template @@ -74,11 +129,17 @@ BoolObjectOption::add_to_menu(Menu& menu) const menu.add_toggle(-1, get_text(), m_value_pointer); } +void +BoolObjectOption::parse(const ReaderMapping& reader) +{ + reader.get(get_key().c_str(), *m_value_pointer); +} + void BoolObjectOption::save(Writer& writer) const { if (!get_key().empty()) { - if (m_default_value && *m_default_value == *m_value_pointer) { + if (!s_allow_saving_defaults && m_default_value && *m_default_value == *m_value_pointer) { // skip } else { writer.write(get_key(), *m_value_pointer); @@ -100,11 +161,17 @@ IntObjectOption::IntObjectOption(const std::string& text, int* pointer, const st { } +void +IntObjectOption::parse(const ReaderMapping& reader) +{ + reader.get(get_key().c_str(), *m_value_pointer); +} + void IntObjectOption::save(Writer& writer) const { if (!get_key().empty()) { - if (m_default_value && *m_default_value == *m_value_pointer) { + if (!s_allow_saving_defaults && m_default_value && *m_default_value == *m_value_pointer) { // skip } else { writer.write(get_key(), *m_value_pointer); @@ -130,11 +197,6 @@ LabelObjectOption::LabelObjectOption(const std::string& text, { } -void -LabelObjectOption::save(Writer& writer) const -{ -} - std::string LabelObjectOption::to_string() const { @@ -155,6 +217,13 @@ RectfObjectOption::RectfObjectOption(const std::string& text, Rectf* pointer, co { } +void +RectfObjectOption::parse(const ReaderMapping& reader) +{ + reader.get("width", m_width); + reader.get("height", m_height); +} + void RectfObjectOption::save(Writer& write) const { @@ -187,11 +256,17 @@ FloatObjectOption::FloatObjectOption(const std::string& text, float* pointer, co { } +void +FloatObjectOption::parse(const ReaderMapping& reader) +{ + reader.get(get_key().c_str(), *m_value_pointer); +} + void FloatObjectOption::save(Writer& writer) const { if (!get_key().empty()) { - if (m_default_value && *m_default_value == *m_value_pointer) { + if (!s_allow_saving_defaults && m_default_value && *m_default_value == *m_value_pointer) { // skip } else { writer.write(get_key(), *m_value_pointer); @@ -219,11 +294,19 @@ StringObjectOption::StringObjectOption(const std::string& text, std::string* poi { } +void +StringObjectOption::parse(const ReaderMapping& reader) +{ + reader.get(get_key().c_str(), *m_value_pointer); +} + void StringObjectOption::save(Writer& writer) const { if (!get_key().empty()) { - if ((m_default_value && *m_default_value == *m_value_pointer) || m_value_pointer->empty()) { + if (!s_allow_saving_defaults && + ((m_default_value && *m_default_value == *m_value_pointer) || + m_value_pointer->empty())) { // skip } else { writer.write(get_key(), *m_value_pointer, (get_flags() & OPTION_TRANSLATABLE)); @@ -251,11 +334,19 @@ StringMultilineObjectOption::StringMultilineObjectOption(const std::string& text { } +void +StringMultilineObjectOption::parse(const ReaderMapping& reader) +{ + reader.get(get_key().c_str(), *m_value_pointer); +} + void StringMultilineObjectOption::save(Writer& writer) const { if (!get_key().empty()) { - if ((m_default_value && *m_default_value == *m_value_pointer) || m_value_pointer->empty()) { + if (!s_allow_saving_defaults && + ((m_default_value && *m_default_value == *m_value_pointer) || + m_value_pointer->empty())) { // skip } else { writer.write(get_key(), *m_value_pointer, (get_flags() & OPTION_TRANSLATABLE)); @@ -288,11 +379,17 @@ StringSelectObjectOption::StringSelectObjectOption(const std::string& text, int* { } +void +StringSelectObjectOption::parse(const ReaderMapping& reader) +{ + reader.get(get_key().c_str(), *m_value_pointer); +} + void StringSelectObjectOption::save(Writer& writer) const { if (!get_key().empty()) { - if (m_default_value && *m_default_value == *m_value_pointer) { + if (!s_allow_saving_defaults && m_default_value && *m_default_value == *m_value_pointer) { // skip } else { writer.write(get_key(), *m_value_pointer); @@ -333,13 +430,28 @@ EnumObjectOption::EnumObjectOption(const std::string& text, int* pointer, { } +void +EnumObjectOption::parse(const ReaderMapping& reader) +{ + std::string symbol; + if (reader.get(get_key().c_str(), symbol)) + { + int i = 0; + while (i < static_cast(m_symbols.size()) && m_symbols[i] != symbol) + i++; + + if (0 <= i && i < static_cast(m_symbols.size())) + *m_value_pointer = i; + } +} + void EnumObjectOption::save(Writer& writer) const { - if (0 <= *m_value_pointer && *m_value_pointer < int(m_symbols.size()) && + if (0 <= *m_value_pointer && *m_value_pointer < static_cast(m_symbols.size()) && !get_key().empty()) { - if (m_default_value && *m_default_value == *m_value_pointer) { + if (!s_allow_saving_defaults && m_default_value && *m_default_value == *m_value_pointer) { // skip } else { writer.write(get_key(), m_symbols[*m_value_pointer]); @@ -350,7 +462,7 @@ EnumObjectOption::save(Writer& writer) const std::string EnumObjectOption::to_string() const { - if (0 <= *m_value_pointer && *m_value_pointer < int(m_labels.size())) { + if (0 <= *m_value_pointer && *m_value_pointer < static_cast(m_labels.size())) { return m_labels[*m_value_pointer]; } else { return _("invalid"); @@ -373,11 +485,17 @@ ScriptObjectOption::ScriptObjectOption(const std::string& text, std::string* poi { } +void +ScriptObjectOption::parse(const ReaderMapping& reader) +{ + reader.get(get_key().c_str(), *m_value_pointer); +} + void ScriptObjectOption::save(Writer& writer) const { auto& value = *m_value_pointer; - if (!value.empty()) + if (s_allow_saving_defaults || !value.empty()) { if (!get_key().empty()) { writer.write(get_key(), value); @@ -415,10 +533,16 @@ FileObjectOption::FileObjectOption(const std::string& text, std::string* pointer { } +void +FileObjectOption::parse(const ReaderMapping& reader) +{ + reader.get(get_key().c_str(), *m_value_pointer); +} + void FileObjectOption::save(Writer& writer) const { - if (m_default_value && *m_default_value == *m_value_pointer) { + if (!s_allow_saving_defaults && m_default_value && *m_default_value == *m_value_pointer) { // skip } else { auto& value = *m_value_pointer; @@ -452,11 +576,19 @@ ColorObjectOption::ColorObjectOption(const std::string& text, Color* pointer, co { } +void +ColorObjectOption::parse(const ReaderMapping& reader) +{ + std::vector v_color; + if (reader.get(get_key().c_str(), v_color)) + *m_value_pointer = Color(v_color, m_use_alpha); +} + void ColorObjectOption::save(Writer& writer) const { if (!get_key().empty()) { - if (m_default_value && *m_default_value == *m_value_pointer) { + if (!s_allow_saving_defaults && m_default_value && *m_default_value == *m_value_pointer) { // skip } else { auto vec = m_value_pointer->toVector(); @@ -489,6 +621,34 @@ ObjectSelectObjectOption::ObjectSelectObjectOption(const std::string& text, std: { } +void +ObjectSelectObjectOption::parse(const ReaderMapping& reader) +{ + std::optional objects_mapping; + if (reader.get(get_key().c_str(), objects_mapping)) + { + m_value_pointer->clear(); + + auto iter = objects_mapping->get_iter(); + while (iter.next()) + { + try + { + auto obj = GameObjectFactory::instance().create(iter.get_key(), iter.as_mapping()); + if (m_add_object_function) + m_add_object_function(std::move(obj)); + else + m_value_pointer->push_back(std::move(obj)); + } + catch (const std::exception& err) + { + log_warning << "Error adding object select option object '" << iter.get_key() + << "': " << err.what() << std::endl; + } + } + } +} + void ObjectSelectObjectOption::save(Writer& writer) const { @@ -530,19 +690,32 @@ ObjectSelectObjectOption::add_to_menu(Menu& menu) const }); } +TilesObjectOption::TilesState::TilesState() : + width(), + height(), + tiles() +{ +} + TilesObjectOption::TilesObjectOption(const std::string& text, TileMap* tilemap, const std::string& key, unsigned int flags) : - ObjectOption(text, key, flags), - m_tilemap(tilemap) + ObjectOption(text, key, flags, tilemap), + m_last_tiles_state() +{ +} + +void +TilesObjectOption::parse(const ReaderMapping& reader) { + m_value_pointer->parse_tiles(reader); } void TilesObjectOption::save(Writer& write) const { - write.write("width", m_tilemap->get_width()); - write.write("height", m_tilemap->get_height()); - write.write("tiles", m_tilemap->get_tiles(), m_tilemap->get_width()); + write.write("width", m_value_pointer->get_width()); + write.write("height", m_value_pointer->get_height()); + write.write("tiles", m_value_pointer->get_tiles(), m_value_pointer->get_width()); } std::string @@ -556,12 +729,86 @@ TilesObjectOption::add_to_menu(Menu& menu) const { } +void +TilesObjectOption::save_state() +{ + BaseObjectOption::save_state(); + + m_last_tiles_state.width = m_value_pointer->get_width(); + m_last_tiles_state.height = m_value_pointer->get_height(); + m_last_tiles_state.tiles = m_value_pointer->get_tiles(); +} + +void +TilesObjectOption::parse_state(const ReaderMapping& reader) +{ + parse(reader); + + std::vector tile_changes; // Array of pairs (index, old/new tile ID). + if (!reader.get("tile-changes", tile_changes)) + return; + + if (tile_changes.size() % 2 != 0) + throw std::runtime_error("'tile-changes' does not contain number pairs."); + + for (size_t i = 0; i < tile_changes.size(); i += 2) + m_value_pointer->change(static_cast(tile_changes[i]), tile_changes[i + 1]); +} + +void +TilesObjectOption::save_old_state(std::ostream& out) const +{ + Writer writer(out); + save_tile_changes(writer, false); +} + +void +TilesObjectOption::save_new_state(Writer& writer) const +{ + save_tile_changes(writer, true); +} + +void +TilesObjectOption::save_tile_changes(Writer& writer, bool new_tiles) const +{ + writer.write("width", new_tiles ? m_value_pointer->get_width() : m_last_tiles_state.width); + writer.write("height", new_tiles ? m_value_pointer->get_height() : m_last_tiles_state.height); + + assert(!m_last_tiles_state.tiles.empty()); + const auto& tiles = m_value_pointer->get_tiles(); + + // Tiles have been resized. Save all tiles. + if (m_last_tiles_state.tiles.size() != tiles.size()) + { + writer.write("tiles", new_tiles ? tiles : m_last_tiles_state.tiles); + return; + } + + // Get and write old/new states of changed tiles in the array. + std::vector tile_changes; // Array of pairs (index, old/new tile ID). + for (uint32_t i = 0; i < static_cast(m_last_tiles_state.tiles.size()); i++) + { + if (m_last_tiles_state.tiles[i] != tiles[i]) + { + tile_changes.push_back(i); + tile_changes.push_back(new_tiles ? tiles[i] : m_last_tiles_state.tiles[i]); + } + } + writer.write("tile-changes", tile_changes); +} + PathObjectOption::PathObjectOption(const std::string& text, Path* path, const std::string& key, unsigned int flags) : ObjectOption(text, key, flags, path) { } +void +PathObjectOption::parse(const ReaderMapping& reader) +{ + m_value_pointer->read(reader); +} + void PathObjectOption::save(Writer& write) const { @@ -586,6 +833,12 @@ PathRefObjectOption::PathRefObjectOption(const std::string& text, PathObject& ta { } +void +PathRefObjectOption::parse(const ReaderMapping& reader) +{ + reader.get(get_key().c_str(), m_path_ref); +} + void PathRefObjectOption::save(Writer& writer) const { @@ -612,6 +865,12 @@ SExpObjectOption::SExpObjectOption(const std::string& text, const std::string& k { } +void +SExpObjectOption::parse(const ReaderMapping& reader) +{ + reader.get(get_key().c_str(), *m_value_pointer); +} + void SExpObjectOption::save(Writer& writer) const { @@ -638,6 +897,19 @@ PathHandleOption::PathHandleOption(const std::string& text, PathWalker::Handle& { } +void +PathHandleOption::parse(const ReaderMapping& reader) +{ + std::optional handle_mapping; + if (reader.get(get_key().c_str(), handle_mapping)) + { + handle_mapping->get("scale_x", m_target.m_scalar_pos.x); + handle_mapping->get("scale_y", m_target.m_scalar_pos.y); + handle_mapping->get("offset_x", m_target.m_pixel_offset.x); + handle_mapping->get("offset_y", m_target.m_pixel_offset.y); + } +} + void PathHandleOption::save(Writer& writer) const { @@ -742,6 +1014,12 @@ StringArrayOption::StringArrayOption(const std::string& text, const std::string& m_items(items) {} +void +StringArrayOption::parse(const ReaderMapping& reader) +{ + reader.get("strings", m_items); +} + void StringArrayOption::save(Writer& write) const { @@ -759,6 +1037,12 @@ ListOption::ListOption(const std::string& text, const std::string& key, const st m_items(items) {} +void +ListOption::parse(const ReaderMapping& reader) +{ + reader.get(get_key().c_str(), *m_value_pointer); +} + void ListOption::save(Writer& writer) const { @@ -782,6 +1066,14 @@ DirectionOption::DirectionOption(const std::string& text, Direction* value_ptr, Direction::RIGHT, Direction::UP, Direction::DOWN }; } +void +DirectionOption::parse(const ReaderMapping& reader) +{ + std::string dir_string; + if (reader.get(get_key().c_str(), dir_string)) + *m_value_pointer = string_to_dir(dir_string); +} + void DirectionOption::save(Writer& writer) const { diff --git a/src/editor/object_option.hpp b/src/editor/object_option.hpp index ede074fc842..2385921be40 100644 --- a/src/editor/object_option.hpp +++ b/src/editor/object_option.hpp @@ -45,20 +45,34 @@ class GameObject; class Menu; class Path; class PathObject; +class ReaderMapping; class Rectf; class TileMap; class Writer; class BaseObjectOption { +protected: + /** If set, options with their default value set will be saved. */ + static bool s_allow_saving_defaults; + public: BaseObjectOption(const std::string& text, const std::string& key, unsigned int flags); virtual ~BaseObjectOption() = default; - virtual void save(Writer& write) const = 0; + virtual void parse(const ReaderMapping& reader) = 0; + virtual void save(Writer& writer) const = 0; virtual std::string to_string() const = 0; virtual void add_to_menu(Menu& menu) const = 0; + std::string save() const; + + virtual void save_state(); + bool has_state_changed() const; + virtual void parse_state(const ReaderMapping& reader); + virtual void save_old_state(std::ostream& out) const; + virtual void save_new_state(Writer& writer) const; + const std::string& get_key() const { return m_key; } const std::string& get_text() const { return m_text; } unsigned int get_flags() const { return m_flags; } @@ -68,6 +82,8 @@ class BaseObjectOption const std::string m_key; const unsigned int m_flags; + std::string m_last_state; + private: BaseObjectOption(const BaseObjectOption&) = delete; BaseObjectOption& operator=(const BaseObjectOption&) = delete; @@ -97,7 +113,8 @@ class BoolObjectOption final : public ObjectOption std::optional default_value, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -116,7 +133,8 @@ class IntObjectOption final : public ObjectOption std::optional default_value, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -134,7 +152,8 @@ class LabelObjectOption final : public ObjectOption<> LabelObjectOption(const std::string& text, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override {} + virtual void save(Writer& writer) const override {} virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -149,7 +168,8 @@ class RectfObjectOption final : public ObjectOption RectfObjectOption(const std::string& text, Rectf* pointer, const std::string& key, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -169,7 +189,8 @@ class FloatObjectOption final : public ObjectOption std::optional default_value, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -188,7 +209,8 @@ class StringObjectOption final : public ObjectOption std::optional default_value, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -207,7 +229,8 @@ class StringMultilineObjectOption final : public ObjectOption std::optional default_value, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -226,7 +249,8 @@ class StringSelectObjectOption final : public ObjectOption std::optional default_value, const std::string& key, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -248,7 +272,8 @@ class EnumObjectOption final : public ObjectOption std::optional default_value, const std::string& key, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -268,7 +293,8 @@ class ScriptObjectOption final : public ObjectOption ScriptObjectOption(const std::string& text, std::string* pointer, const std::string& key, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -288,7 +314,8 @@ class FileObjectOption final : public ObjectOption bool path_relative_to_basedir, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -310,7 +337,8 @@ class ColorObjectOption final : public ObjectOption std::optional default_value, bool use_alpha, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -330,7 +358,8 @@ class ObjectSelectObjectOption final : public ObjectOption)>& add_object_func, const std::string& key, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -349,12 +378,29 @@ class TilesObjectOption final : public ObjectOption TilesObjectOption(const std::string& text, TileMap* tilemap, const std::string& key, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; + virtual void save_state() override; + virtual void parse_state(const ReaderMapping& reader) override; + virtual void save_old_state(std::ostream& out) const override; + virtual void save_new_state(Writer& writer) const override; + +private: + void save_tile_changes(Writer& writer, bool new_tiles) const; + private: - TileMap* m_tilemap; + struct TilesState final + { + TilesState(); + + int width; + int height; + std::vector tiles; + }; + TilesState m_last_tiles_state; private: TilesObjectOption(const TilesObjectOption&) = delete; @@ -367,7 +413,8 @@ class PathObjectOption final : public ObjectOption PathObjectOption(const std::string& text, Path* path, const std::string& key, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -382,7 +429,8 @@ class PathRefObjectOption final : public ObjectOption PathRefObjectOption(const std::string& text, PathObject& target, const std::string& path_ref, const std::string& key, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -399,7 +447,8 @@ class SExpObjectOption final : public ObjectOption public: SExpObjectOption(const std::string& text, const std::string& key, sexp::Value& value, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -414,7 +463,8 @@ class PathHandleOption final : public ObjectOption PathHandleOption(const std::string& text, PathWalker::Handle& handle, const std::string& key, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -431,7 +481,8 @@ class RemoveObjectOption final : public ObjectOption<> public: RemoveObjectOption(); - virtual void save(Writer& write) const override {} + virtual void parse(const ReaderMapping& reader) override {} + virtual void save(Writer& writer) const override {} virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -445,7 +496,8 @@ class TestFromHereOption final : public ObjectOption<> public: TestFromHereOption(); - virtual void save(Writer& write) const override {} + virtual void parse(const ReaderMapping& reader) override {} + virtual void save(Writer& writer) const override {} virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -459,7 +511,8 @@ class ParticleEditorOption final : public ObjectOption<> public: ParticleEditorOption(); - virtual void save(Writer& write) const override {} + virtual void parse(const ReaderMapping& reader) override {} + virtual void save(Writer& writer) const override {} virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -473,7 +526,8 @@ class ButtonOption final : public ObjectOption<> public: ButtonOption(const std::string& text, std::function callback); - virtual void save(Writer& write) const override {} + virtual void parse(const ReaderMapping& reader) override {} + virtual void save(Writer& writer) const override {} virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; @@ -490,7 +544,8 @@ class StringArrayOption final : public ObjectOption<> public: StringArrayOption(const std::string& text, const std::string& key, std::vector& items); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override { return "text-area"; } virtual void add_to_menu(Menu& menu) const override; @@ -507,7 +562,8 @@ class ListOption final : public ObjectOption public: ListOption(const std::string& text, const std::string& key, const std::vector& items, std::string* value_ptr); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override { return *m_value_pointer; } virtual void add_to_menu(Menu& menu) const override; @@ -526,7 +582,8 @@ class DirectionOption final : public ObjectOption std::vector possible_directions, const std::string& key, unsigned int flags); - virtual void save(Writer& write) const override; + virtual void parse(const ReaderMapping& reader) override; + virtual void save(Writer& writer) const override; virtual std::string to_string() const override; virtual void add_to_menu(Menu& menu) const override; diff --git a/src/editor/object_settings.cpp b/src/editor/object_settings.cpp index 45ee96e4ca2..964850e3971 100644 --- a/src/editor/object_settings.cpp +++ b/src/editor/object_settings.cpp @@ -20,6 +20,7 @@ #include #include "util/gettext.hpp" +#include "util/log.hpp" #include "video/color.hpp" ObjectSettings::ObjectSettings(const std::string& name) : @@ -28,9 +29,25 @@ ObjectSettings::ObjectSettings(const std::string& name) : { } +ObjectSettings::ObjectSettings(ObjectSettings&& other) : + m_name(other.m_name), + m_options(std::move(other.m_options)) +{ +} + void ObjectSettings::add_option(std::unique_ptr option) { + if (!option->get_key().empty()) + { + // Make sure no option with the same key exists + assert(std::none_of(m_options.begin(), m_options.end(), + [key = option->get_key()](const auto& opt) + { + return key == opt->get_key(); + })); + } + m_options.push_back(std::move(option)); } @@ -392,4 +409,71 @@ ObjectSettings::remove(const std::string& key) m_options.end()); } +void +ObjectSettings::parse(const ReaderMapping& reader) +{ + for (const auto& option : m_options) + { + try + { + option->parse(reader); + } + catch (const std::exception& err) + { + log_warning << "Error processing data for option '" << option->get_key() + << "': " << err.what() << std::endl; + } + } +} + +void +ObjectSettings::save_state() +{ + for (const auto& option : m_options) + option->save_state(); +} + +bool +ObjectSettings::has_state_changed() const +{ + for (const auto& option : m_options) + if (option->has_state_changed()) + return true; + + return false; +} + +void +ObjectSettings::parse_state(const ReaderMapping& reader) +{ + for (const auto& option : m_options) + { + try + { + option->parse_state(reader); + } + catch (const std::exception& err) + { + log_warning << "Error processing state data for option '" << option->get_key() + << "': " << err.what() << std::endl; + } + } +} + +void +ObjectSettings::save_old_state(std::ostream& out) const +{ + for (const auto& option : m_options) + if (option->has_state_changed()) + option->save_old_state(out); +} + +void +ObjectSettings::save_new_state(Writer& writer) const +{ + for (const auto& option : m_options) + if (option->has_state_changed()) + option->save_new_state(writer); +} + /* EOF */ diff --git a/src/editor/object_settings.hpp b/src/editor/object_settings.hpp index b9ba078d970..df523d17113 100644 --- a/src/editor/object_settings.hpp +++ b/src/editor/object_settings.hpp @@ -28,10 +28,14 @@ class Color; enum class Direction; class GameObject; class PathObject; +class ReaderMapping; enum class WalkMode; +class Writer; + namespace worldmap { enum class Direction; } // namespace worldmap + namespace sexp { class Value; } // namespace sexp @@ -40,7 +44,9 @@ class ObjectSettings final { public: ObjectSettings(const std::string& name); - ObjectSettings(ObjectSettings&&) = default; + ObjectSettings(ObjectSettings&& other); + + ObjectSettings& operator=(ObjectSettings&&) = default; const std::string& get_name() const { return m_name; } @@ -167,6 +173,22 @@ class ObjectSettings final /** Remove an option from the list, this is a hack */ void remove(const std::string& key); + /** Parse option properties. */ + void parse(const ReaderMapping& reader); + + /** Save the current states of all options. */ + void save_state(); + + /** Check all options for any with a changed state. */ + bool has_state_changed() const; + + /** Parse option properties from an alternative state. */ + void parse_state(const ReaderMapping& reader); + + /** Write the old/new states of all modified options. */ + void save_old_state(std::ostream& out) const; + void save_new_state(Writer& writer) const; + private: void add_option(std::unique_ptr option); diff --git a/src/editor/overlay_widget.cpp b/src/editor/overlay_widget.cpp index 6bf19cdd0fd..c00caf6128c 100644 --- a/src/editor/overlay_widget.cpp +++ b/src/editor/overlay_widget.cpp @@ -16,6 +16,8 @@ #include "editor/overlay_widget.hpp" +#include + #include "editor/editor.hpp" #include "editor/node_marker.hpp" #include "editor/object_menu.hpp" @@ -53,6 +55,7 @@ EditorOverlayWidget::EditorOverlayWidget(Editor& editor) : m_editor(editor), m_hovered_tile(0, 0), m_hovered_tile_prev(0, 0), + m_last_hovered_tile(0, 0), m_sector_pos(0, 0), m_mouse_pos(0, 0), m_previous_mouse_pos(0, 0), @@ -66,6 +69,8 @@ EditorOverlayWidget::EditorOverlayWidget(Editor& editor) : m_selected_object(nullptr), m_edited_path(nullptr), m_last_node_marker(nullptr), + m_available_autotilesets(), + m_current_autotileset(0), m_object_tip(new Tip()), m_obj_mouse_desync(0, 0), m_rectangle_preview(new TileSelection()), @@ -170,7 +175,7 @@ EditorOverlayWidget::autotile(const Vector& pos, uint32_t tile) if (!tilemap || !is_position_inside_tilemap(tilemap, pos)) return; tilemap->save_state(); - tilemap->autotile(static_cast(pos.x), static_cast(pos.y), tile); + tilemap->autotile(static_cast(pos.x), static_cast(pos.y), tile, get_current_autotileset()); } void @@ -196,7 +201,7 @@ EditorOverlayWidget::autotile_corner(const Vector& pos, uint32_t tile, if (!tilemap || !is_position_inside_tilemap(tilemap, pos)) return; tilemap->save_state(); - tilemap->autotile_corner(static_cast(pos.x), static_cast(pos.y), tile, op); + tilemap->autotile_corner(static_cast(pos.x), static_cast(pos.y), tile, get_current_autotileset(), op); } void @@ -220,36 +225,37 @@ EditorOverlayWidget::input_autotile_corner(const Vector& corner, uint32_t tile, } void -EditorOverlayWidget::put_tile(const Vector& target_tile) +EditorOverlayWidget::put_tiles(const Vector& target_tile, TileSelection* tiles) { m_editor.get_selected_tilemap()->save_state(); - Vector hovered_corner = target_tile + Vector(0.5f, 0.5f); - auto tiles = m_editor.get_tiles(); + const Vector hovered_corner = target_tile + Vector(0.5f, 0.5f); Vector add_tile(0.0f, 0.0f); for (add_tile.x = static_cast(tiles->m_width) - 1.0f; add_tile.x >= 0.0f; add_tile.x--) { for (add_tile.y = static_cast(tiles->m_height) - 1.0f; add_tile.y >= 0; add_tile.y--) { + const uint32_t tile = tiles->pos(static_cast(add_tile.x), static_cast(add_tile.y)); - uint32_t tile = tiles->pos(static_cast(add_tile.x), static_cast(add_tile.y)); - auto tilemap = m_editor.get_selected_tilemap(); - - if (g_config->editor_autotile_mode && ((tilemap && tilemap->get_autotileset(tile)) || tile == 0)) + if (g_config->editor_autotile_mode) { - if (tile == 0) - { - tilemap->autotile_erase(target_tile + add_tile, hovered_corner + add_tile); - } - else if (tilemap->get_autotileset(tile)->is_corner()) + AutotileSet* autotileset = get_current_autotileset(); + if (autotileset) { - input_autotile_corner(hovered_corner + add_tile, - tile, - target_tile + add_tile); - } - else - { - input_autotile(target_tile + add_tile, tile); + if (tile == 0) + { + m_editor.get_selected_tilemap()->autotile_erase(target_tile + add_tile, hovered_corner + add_tile, autotileset); + } + else if (autotileset->is_corner()) + { + input_autotile_corner(hovered_corner + add_tile, + tile, + target_tile + add_tile); + } + else + { + input_autotile(target_tile + add_tile, tile); + } } } else @@ -350,7 +356,7 @@ EditorOverlayWidget::put_next_tiles() { // Avoid drawing lines when the user has hold the left mouse button for some // time while not putting a tile - put_tile(m_hovered_tile); + put_tiles(m_hovered_tile, m_editor.get_tiles()); m_hovered_tile_prev = m_hovered_tile; return; } @@ -359,7 +365,7 @@ EditorOverlayWidget::put_next_tiles() for (const Vector &pos : rasterize_line_segment(m_hovered_tile_prev * 2.0f, m_hovered_tile * 2.0f)) { - put_tile(pos * 0.5f); + put_tiles(pos * 0.5f, m_editor.get_tiles()); } m_hovered_tile_prev = m_hovered_tile; } @@ -387,30 +393,6 @@ EditorOverlayWidget::preview_rectangle() } } - -void -EditorOverlayWidget::draw_rectangle() -{ - Rectf dr = drag_rect(); - dr.set_p1(glm::floor(sp_to_tp(dr.p1()))); - dr.set_p2(glm::floor(sp_to_tp(dr.p2()))); - bool sgn_x = m_drag_start.x < m_sector_pos.x; - bool sgn_y = m_drag_start.y < m_sector_pos.y; - - int x_ = sgn_x ? 0 : static_cast(-dr.get_width()); - for (int x = static_cast(dr.get_left()); x <= static_cast(dr.get_right()); x++, x_++) - { - int y_ = sgn_y ? 0 : static_cast(-dr.get_height()); - for (int y = static_cast(dr.get_top()); y <= static_cast(dr.get_bottom()); y++, y_++) - { - if (g_config->editor_autotile_mode) - input_autotile(Vector(static_cast(x), static_cast(y)), m_editor.get_tiles()->pos(x_, y_)); - else - input_tile(Vector(static_cast(x), static_cast(y)), m_editor.get_tiles()->pos(x_, y_)); - } - } -} - bool EditorOverlayWidget::check_tiles_for_fill(uint32_t replace_tile, uint32_t target_tile, @@ -418,10 +400,8 @@ EditorOverlayWidget::check_tiles_for_fill(uint32_t replace_tile, { if (g_config->editor_autotile_mode) { - return m_editor.get_tileset()->get_autotileset_from_tile(replace_tile) - == m_editor.get_tileset()->get_autotileset_from_tile(target_tile) - && m_editor.get_tileset()->get_autotileset_from_tile(replace_tile) - != m_editor.get_tileset()->get_autotileset_from_tile(third_tile); + return m_editor.get_tileset()->has_mutual_autotileset(replace_tile, target_tile) && + !m_editor.get_tileset()->has_mutual_autotileset(replace_tile, third_tile); } else { @@ -437,7 +417,7 @@ EditorOverlayWidget::fill() if (!tilemap) return; // The tile that is going to be replaced: - uint32_t replace_tile = tilemap->get_tile_id(static_cast(m_hovered_tile.x), static_cast(m_hovered_tile.y)); + uint32_t replace_tile = tilemap->get_tile_id(m_hovered_tile); if (replace_tile == tiles->pos(0, 0)) { @@ -479,7 +459,7 @@ EditorOverlayWidget::fill() if (pos_.x >= 0) { if (check_tiles_for_fill(replace_tile, - tilemap->get_tile_id(static_cast(pos_.x), static_cast(pos_.y)), + tilemap->get_tile_id(pos_), tiles->pos(static_cast(tpos.x - 1), static_cast(tpos.y)))) { pos_stack.push_back( pos_ ); @@ -492,7 +472,7 @@ EditorOverlayWidget::fill() if (pos_.x < static_cast(tilemap->get_width())) { if (check_tiles_for_fill(replace_tile, - tilemap->get_tile_id(static_cast(pos_.x), static_cast(pos_.y)), + tilemap->get_tile_id(pos_), tiles->pos(static_cast(tpos.x + 1), static_cast(tpos.y)))) { pos_stack.push_back( pos_ ); @@ -505,7 +485,7 @@ EditorOverlayWidget::fill() if (pos_.y >= 0) { if (check_tiles_for_fill(replace_tile, - tilemap->get_tile_id(static_cast(pos_.x), static_cast(pos_.y)), + tilemap->get_tile_id(pos_), tiles->pos(static_cast(tpos.x), static_cast(tpos.y - 1)))) { pos_stack.push_back( pos_ ); @@ -518,7 +498,7 @@ EditorOverlayWidget::fill() if (pos_.y < static_cast(tilemap->get_height())) { if (check_tiles_for_fill(replace_tile, - tilemap->get_tile_id(static_cast(pos_.x), static_cast(pos_.y)), + tilemap->get_tile_id(pos_), tiles->pos(static_cast(tpos.x), static_cast(tpos.y + 1)))) { pos_stack.push_back( pos_ ); @@ -539,7 +519,7 @@ void EditorOverlayWidget::replace() { auto tilemap = m_editor.get_selected_tilemap(); - uint32_t replace_tile = tilemap->get_tile_id(static_cast(m_hovered_tile.x), static_cast(m_hovered_tile.y)); + uint32_t replace_tile = tilemap->get_tile_id(m_hovered_tile); // Don't do anything if the old and new tiles are the same tile. if (m_editor.get_tiles()->m_width == 1 && m_editor.get_tiles()->m_height == 1 && replace_tile == m_editor.get_tiles()->pos(0, 0)) return; @@ -920,7 +900,7 @@ EditorOverlayWidget::process_left_click() switch (m_editor.get_tileselect_select_mode()) { case 0: - put_tile(m_hovered_tile); + put_tiles(m_hovered_tile, m_editor.get_tiles()); m_hovered_tile_prev = m_hovered_tile; m_time_prev_put_tile = std::chrono::steady_clock::now(); break; @@ -1072,6 +1052,8 @@ EditorOverlayWidget::update_tile_selection() } } } + + update_autotileset(); } bool @@ -1083,7 +1065,7 @@ EditorOverlayWidget::on_mouse_button_up(const SDL_MouseButtonEvent& button) { if (m_dragging && m_editor.get_tileselect_select_mode() == 1) { - draw_rectangle(); + put_tiles(sp_to_tp(drag_rect().p1()), m_rectangle_preview.get()); m_rectangle_preview->m_tiles.clear(); } @@ -1197,10 +1179,11 @@ bool EditorOverlayWidget::on_key_up(const SDL_KeyboardEvent& key) { auto sym = key.keysym.sym; - if (sym == SDLK_LSHIFT) { + if (sym == SDLK_LSHIFT) + { g_config->editor_snap_to_grid = !g_config->editor_snap_to_grid; } - if (sym == SDLK_LCTRL || sym == SDLK_RCTRL) + else if (sym == SDLK_LCTRL || sym == SDLK_RCTRL) { if (action_pressed) { @@ -1210,7 +1193,8 @@ EditorOverlayWidget::on_key_up(const SDL_KeyboardEvent& key) // Hovered objects depend on which keys are pressed hover_object(); } - if (sym == SDLK_LALT || sym == SDLK_RALT) { + else if (sym == SDLK_LALT || sym == SDLK_RALT) + { alt_pressed = false; } return true; @@ -1220,22 +1204,34 @@ bool EditorOverlayWidget::on_key_down(const SDL_KeyboardEvent& key) { auto sym = key.keysym.sym; - if (sym == SDLK_F8) { + + if (sym == SDLK_F8) + { g_config->editor_render_grid = !g_config->editor_render_grid; } - if (sym == SDLK_F7 || sym == SDLK_LSHIFT) { + else if (sym == SDLK_F7 || sym == SDLK_LSHIFT) + { g_config->editor_snap_to_grid = !g_config->editor_snap_to_grid; } - if (sym == SDLK_F5 || ((sym == SDLK_LCTRL || sym == SDLK_RCTRL) && !action_pressed)) + else if (sym == SDLK_F5 || ((sym == SDLK_LCTRL || sym == SDLK_RCTRL) && !action_pressed)) { g_config->editor_autotile_mode = !g_config->editor_autotile_mode; action_pressed = true; // Hovered objects depend on which keys are pressed hover_object(); } - if (sym == SDLK_LALT || sym == SDLK_RALT) { + else if (sym == SDLK_LALT || sym == SDLK_RALT) + { alt_pressed = true; } + else if (sym == SDLK_0) + { + m_current_autotileset = 0; + } + else if (sym > SDLK_0 && sym <= SDLK_9) + { + m_current_autotileset = static_cast(sym - SDLK_0); + } return true; } @@ -1254,10 +1250,68 @@ EditorOverlayWidget::update_pos() m_editor.get_sector()->get_camera().get_translation(); m_hovered_tile = sp_to_tp(m_sector_pos); + if (m_last_hovered_tile != m_hovered_tile) + { + const uint32_t hovered_id = m_editor.get_selected_tilemap()->get_tile_id(m_hovered_tile); + if ((!m_dragging || hovered_id != 0) && + m_editor.get_tiles()->pos(0, 0) == 0 && // Erasing + m_editor.get_selected_tilemap()->get_tile_id(m_last_hovered_tile) != hovered_id) + { + update_autotileset(); + } + + m_last_hovered_tile = m_hovered_tile; + } + // update tip hover_object(); } +void +EditorOverlayWidget::update_autotileset() +{ + AutotileSet* old_autotileset = get_current_autotileset(); + + if (m_editor.get_tiles()->pos(0, 0) == 0) // Erasing + { + const uint32_t current_tile = m_editor.get_selected_tilemap()->get_tile_id(m_hovered_tile); + m_available_autotilesets = m_editor.get_tileset()->get_autotilesets_from_tile(current_tile); + } + else + { + m_available_autotilesets = m_editor.get_tileset()->get_autotilesets_from_tile(m_editor.get_tiles()->pos(0, 0)); + } + + if (!old_autotileset) + { + m_current_autotileset = 0; + return; + } + auto it_autotileset = std::find(m_available_autotilesets.begin(), m_available_autotilesets.end(), old_autotileset); + m_current_autotileset = it_autotileset != m_available_autotilesets.end() ? static_cast(it_autotileset - m_available_autotilesets.begin()) : 0; +} + +AutotileSet* +EditorOverlayWidget::get_current_autotileset() const +{ + if (m_available_autotilesets.empty()) + return nullptr; + + if (m_current_autotileset < 0 || m_current_autotileset > static_cast(m_available_autotilesets.size() - 1)) + return m_available_autotilesets.front(); + + return m_available_autotilesets[m_current_autotileset]; +} + +std::string +EditorOverlayWidget::get_autotileset_key_range() const +{ + if (m_available_autotilesets.size() < 2) + return ""; + + return "(0-" + std::to_string(std::min(static_cast(m_available_autotilesets.size() - 1), 9)) + ")"; +} + void EditorOverlayWidget::draw_tile_tip(DrawingContext& context) { @@ -1507,7 +1561,7 @@ EditorOverlayWidget::draw(DrawingContext& context) { // Deprecated tiles in active tilemaps should have indication, when hovered auto sel_tilemap = m_editor.get_selected_tilemap(); - if (m_editor.get_tileset()->get(sel_tilemap->get_tile_id(static_cast(m_hovered_tile.x), static_cast(m_hovered_tile.y))).is_deprecated()) + if (m_editor.get_tileset()->get(sel_tilemap->get_tile_id(m_hovered_tile)).is_deprecated()) context.color().draw_text(Resources::normal_font, "!", tp_to_sp(Vector(static_cast(m_hovered_tile.x), static_cast(m_hovered_tile.y))) + Vector(16, 8), ALIGN_CENTER, LAYER_GUI - 10, Color::RED); @@ -1563,22 +1617,23 @@ EditorOverlayWidget::draw(DrawingContext& context) if (g_config->editor_autotile_help) { - if (m_editor.get_tileset()->get_autotileset_from_tile(m_editor.get_tiles()->pos(0, 0)) != nullptr) + if (g_config->editor_autotile_mode) { - if (g_config->editor_autotile_mode) - { - context.color().draw_text(Resources::normal_font, _("Autotile mode is on"), Vector(144, 16), ALIGN_LEFT, LAYER_OBJECTS+1, EditorOverlayWidget::text_autotile_active_color); - } - else + AutotileSet* autotileset = get_current_autotileset(); + if (m_editor.get_tiles()->pos(0, 0) == 0) { - context.color().draw_text(Resources::normal_font, _("Hold Ctrl to enable autotile"), Vector(144, 16), ALIGN_LEFT, LAYER_OBJECTS+1, EditorOverlayWidget::text_autotile_available_color); + if (autotileset) + { + context.color().draw_text(Resources::normal_font, fmt::format(fmt::runtime(_("Autotile erasing mode is on (\"{}\")")), autotileset->get_name()) + " " + get_autotileset_key_range(), Vector(144, 16), ALIGN_LEFT, LAYER_OBJECTS+1, EditorOverlayWidget::text_autotile_active_color); + } + else + { + context.color().draw_text(Resources::normal_font, _("Autotile erasing cannot be performed here"), Vector(144, 16), ALIGN_LEFT, LAYER_OBJECTS+1, EditorOverlayWidget::text_autotile_error_color); + } } - } - else if (g_config->editor_autotile_mode) - { - if (m_editor.get_tiles()->pos(0, 0) == 0) + else if (autotileset) { - context.color().draw_text(Resources::normal_font, _("Autotile erasing mode is on"), Vector(144, 16), ALIGN_LEFT, LAYER_OBJECTS+1, EditorOverlayWidget::text_autotile_active_color); + context.color().draw_text(Resources::normal_font, fmt::format(fmt::runtime(_("Autotile mode is on (\"{}\")")), autotileset->get_name()) + " " + get_autotileset_key_range(), Vector(144, 16), ALIGN_LEFT, LAYER_OBJECTS+1, EditorOverlayWidget::text_autotile_active_color); } else { @@ -1587,7 +1642,11 @@ EditorOverlayWidget::draw(DrawingContext& context) } else if (m_editor.get_tiles()->pos(0, 0) == 0) { - context.color().draw_text(Resources::normal_font, _("Hold Ctrl to enable autotile erasing"), Vector(144, 16), ALIGN_LEFT, LAYER_OBJECTS+1, EditorOverlayWidget::text_autotile_available_color); + context.color().draw_text(Resources::normal_font, _("Hold Ctrl to enable autotile erasing") + " " + get_autotileset_key_range(), Vector(144, 16), ALIGN_LEFT, LAYER_OBJECTS+1, EditorOverlayWidget::text_autotile_available_color); + } + else + { + context.color().draw_text(Resources::normal_font, _("Hold Ctrl to enable autotile") + " " + get_autotileset_key_range(), Vector(144, 16), ALIGN_LEFT, LAYER_OBJECTS+1, EditorOverlayWidget::text_autotile_available_color); } } } diff --git a/src/editor/overlay_widget.hpp b/src/editor/overlay_widget.hpp index 89b6b9388f6..9fea628e558 100644 --- a/src/editor/overlay_widget.hpp +++ b/src/editor/overlay_widget.hpp @@ -28,6 +28,7 @@ #include "supertux/timer.hpp" #include "util/typed_uid.hpp" +class AutotileSet; class Color; class DrawingContext; class Editor; @@ -64,6 +65,7 @@ class EditorOverlayWidget final : public Widget virtual void on_window_resize() override; void update_pos(); + void update_autotileset(); void delete_markers(); void update_node_iterators(); void on_level_change(); @@ -81,7 +83,7 @@ class EditorOverlayWidget final : public Widget void input_autotile(const Vector& pos, uint32_t tile); void autotile_corner(const Vector& pos, uint32_t tile, TileMap::AutotileCornerOperation op); void input_autotile_corner(const Vector& corner, uint32_t tile, const Vector& override_pos = Vector(-1.f, -1.f)); - void put_tile(const Vector& target_tile); + void put_tiles(const Vector& target_tile, TileSelection* tiles); void put_next_tiles(); void draw_rectangle(); void preview_rectangle(); @@ -101,6 +103,9 @@ class EditorOverlayWidget final : public Widget void select_object(); void add_path_node(); + AutotileSet* get_current_autotileset() const; + std::string get_autotileset_key_range() const; + void draw_tile_tip(DrawingContext&); void draw_tile_grid(DrawingContext&, int tile_size, bool draw_shadow) const; void draw_tilemap_border(DrawingContext&); @@ -130,6 +135,7 @@ class EditorOverlayWidget final : public Widget Editor& m_editor; Vector m_hovered_tile; Vector m_hovered_tile_prev; + Vector m_last_hovered_tile; Vector m_sector_pos; Vector m_mouse_pos; Vector m_previous_mouse_pos; @@ -147,6 +153,9 @@ class EditorOverlayWidget final : public Widget TypedUID m_edited_path; TypedUID m_last_node_marker; + std::vector m_available_autotilesets; + int m_current_autotileset; + std::unique_ptr m_object_tip; Vector m_obj_mouse_desync; diff --git a/src/editor/toolbox_widget.cpp b/src/editor/toolbox_widget.cpp index 00fc2b1f3d4..4db15151ce2 100644 --- a/src/editor/toolbox_widget.cpp +++ b/src/editor/toolbox_widget.cpp @@ -108,6 +108,7 @@ EditorToolboxWidget::on_mouse_button_down(const SDL_MouseButtonEvent& button) { if (m_tilebox->on_mouse_button_down(button)) { + m_editor.update_autotileset(); update_mouse_icon(); return true; } @@ -150,6 +151,7 @@ EditorToolboxWidget::on_mouse_button_down(const SDL_MouseButtonEvent& button) case 0: m_tilebox->get_tiles()->set_tile(0); m_tilebox->set_object(""); + m_editor.update_autotileset(); update_mouse_icon(); break; diff --git a/src/gui/item_color_picker_2d.cpp b/src/gui/item_color_picker_2d.cpp new file mode 100644 index 00000000000..198a9959fa5 --- /dev/null +++ b/src/gui/item_color_picker_2d.cpp @@ -0,0 +1,143 @@ +// SuperTux +// Copyright (C) 2024 HybridDog +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "gui/item_color_picker_2d.hpp" + +#include + +#include "math/util.hpp" +#include "video/drawing_context.hpp" +#include "video/video_system.hpp" +#include "video/surface.hpp" +#include "video/sdl_surface.hpp" + + +namespace { + +/** Get the color of a pixel from an 8-bit RGB image + * + * @param surface SDL2 surface containing the image + * @param pos Floating-point pixel coordinates in [0,1]^2 + * + * @return Color of the pixel at the integer position which corresponds to pos + */ +Color +get_pixel(const SDLSurfacePtr& surface, const Vector& pos) +{ + assert(surface->format->BytesPerPixel == 3); + int x = math::clamp( + static_cast(pos.x * static_cast(surface->w - 1) + 0.5f), + 0, + surface->w - 1 + ); + int y = math::clamp( + static_cast(pos.y * static_cast(surface->h - 1) + 0.5f), + 0, + surface->h - 1 + ); + uint8_t *pixel = static_cast(surface->pixels) + + y * surface->pitch + x * 3; + if constexpr (SDL_BYTEORDER == SDL_BIG_ENDIAN) + return Color::from_rgb888(pixel[2], pixel[1], pixel[0]); + return Color::from_rgb888(pixel[0], pixel[1], pixel[2]); +} + +} // namespace + + +ItemColorPicker2D::ItemColorPicker2D(Color& col) : + MenuItem(""), + m_image(Surface::from_file("images/engine/editor/color_picker_2d.png")), + m_image_with_pixels(SDLSurface::from_file( + "images/engine/editor/color_picker_2d.png")), + m_original_color(col), + m_color(col) +{ +} + +void +ItemColorPicker2D::draw_marker(Canvas& canvas, Color col, float radius) const +{ + ColorOKLCh col_oklab = col; + Vector pos_rel( + fmodf(col_oklab.h * 0.5f / math::PI + 1.0f, 1.0f), + 1.0f - col_oklab.get_modified_lightness() + ); + Vector pos( + m_image_rect.get_left() + pos_rel.x * (m_image_rect.get_right() + - m_image_rect.get_left()), + m_image_rect.get_top() + pos_rel.y * (m_image_rect.get_bottom() + - m_image_rect.get_top()) + ); + col.alpha = 1.0f; + canvas.draw_hexagon(pos, radius, Color::BLACK, LAYER_GUI+1); + canvas.draw_hexagon(pos, 0.86f * radius, Color::WHITE, LAYER_GUI+1); + canvas.draw_hexagon(pos, 0.7f * radius, col, LAYER_GUI+2); +} + +void +ItemColorPicker2D::draw(DrawingContext& context, const Vector& pos, + int menu_width, bool active) +{ + m_image_rect = Rectf( + pos + Vector(16, -get_height() / 2 + 8), + pos + Vector(menu_width - 16, get_height() / 2 - 8) + ); + context.color().draw_surface_scaled(m_image, m_image_rect, LAYER_GUI); + draw_marker(context.color(), m_original_color, 4.7f); + draw_marker(context.color(), m_color, 5.5f); +} + +void +ItemColorPicker2D::event(const SDL_Event& ev) +{ + bool is_mouseclick = ev.type == SDL_MOUSEBUTTONDOWN + && ev.button.button == SDL_BUTTON_LEFT; + bool is_hold_mousemove = ev.type == SDL_MOUSEMOTION + && (ev.motion.state & SDL_BUTTON_LMASK); + if (is_mouseclick) { + m_mousedown = true; + } else if (!is_hold_mousemove || !m_mousedown) { + m_mousedown = false; + return; + } + + Vector mouse_pos = VideoSystem::current()->get_viewport().to_logical( + ev.motion.x, ev.motion.y); + Vector pos( + (mouse_pos.x - m_image_rect.get_left()) + / (m_image_rect.get_right() - m_image_rect.get_left()), + (mouse_pos.y - m_image_rect.get_top()) + / (m_image_rect.get_bottom() - m_image_rect.get_top()) + ); + if (is_mouseclick + && (pos.x < 0.0f || pos.x > 1.0f || pos.y < 0.0f || pos.y > 1.0f)) { + m_mousedown = false; + return; + } + + // The hue is periodic -> go back to the start after the mouse leaves the + // corner + pos.x = fmodf(pos.x + 3.0f, 1.0f); + // The lightness is not periodic -> clamp + pos.y = math::clamp(pos.y, 0.0f, 1.0f); + float alpha = m_color.alpha; + m_color = get_pixel(m_image_with_pixels, pos); + m_color.alpha = alpha; +} + + +/* EOF */ diff --git a/src/gui/item_color_picker_2d.hpp b/src/gui/item_color_picker_2d.hpp new file mode 100644 index 00000000000..70159673411 --- /dev/null +++ b/src/gui/item_color_picker_2d.hpp @@ -0,0 +1,91 @@ +// SuperTux +// Copyright (C) 2024 HybridDog +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef HEADER_SUPERTUX_GUI_ITEM_COLOR_PICKER_2D_HPP +#define HEADER_SUPERTUX_GUI_ITEM_COLOR_PICKER_2D_HPP + +#include "gui/menu_item.hpp" + +#include "util/colorspace_oklab.hpp" +#include "video/color.hpp" +#include "video/sdl_surface_ptr.hpp" + +/** A two-dimensional color picker + * + * The color picker displays an image and enables picking a color from it by + * clicking. + * The image contains all fully-saturated sRGB colors, + * with the OKLab hue on the horizontal axis and modified OKLab lightness, Lr, + * on the vertical axis. + * Since the user can select the hue and lightness, and the chroma is fixed to + * the highest value, the color picker is only two-dimensional. + */ +class ItemColorPicker2D final : public MenuItem +{ +public: + ItemColorPicker2D(Color& col); + + /** Show an image with all fully-saturated sRGB colors, a marker for the + * currently selected color and a smaller marker for the initial color */ + virtual void draw(DrawingContext&, const Vector& pos, int menu_width, + bool active) override; + /// Determine the minimum width of the menu item + virtual int get_width() const override { return 280; } + virtual int get_height() const override { return get_width(); } + /** Handle mouse input */ + virtual void event(const SDL_Event& ev) override; + virtual bool changes_width() const override { return true; } + +private: + /** Draw a marker for a given color + * + * The position of the marker is calculated from col's OKLab Lr and hue + * values, and is unaffected by chroma. + * The inside of the marker shows col. + * The drawing uses the layers LAYER_GUI+1 and LAYER_GUI+2. + * + * @param canvas Target canvas where the marker is drawn onto + * @param col Color for which the marker is drawn + * @param radius Marker size + */ + void draw_marker(Canvas& canvas, Color col, float radius) const; + +private: + /// Image for drawing + SurfacePtr m_image; + /** The same image to sample pixels from it + * + * Since we cannot get pixel data from a Surface, we need this in addition to + * m_image. + */ + SDLSurfacePtr m_image_with_pixels; + /// Color during the initialisation of the menu item + Color m_original_color; + /// Color which the user dynamically modifies + Color& m_color; + /// Determines if the user is still holding down the left mouse button + bool m_mousedown = false; + /// Coordinates where m_image is currently drawn + Rectf m_image_rect{0, 0, 1, 1}; + +private: + ItemColorPicker2D(const ItemColorPicker2D&) = delete; + ItemColorPicker2D& operator=(const ItemColorPicker2D&) = delete; +}; + +#endif + +/* EOF */ diff --git a/src/gui/item_colorchannel_oklab.cpp b/src/gui/item_colorchannel_oklab.cpp deleted file mode 100644 index f9780eee62f..00000000000 --- a/src/gui/item_colorchannel_oklab.cpp +++ /dev/null @@ -1,227 +0,0 @@ -// SuperTux -// Copyright (C) 2021 -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "gui/item_colorchannel.hpp" - -#include - -#include "math/util.hpp" -#include "video/drawing_context.hpp" -#include "video/video_system.hpp" -#include "video/viewport.hpp" - - -// This value affects the gamut clipping in the hue selection. -// A bigger value means more preserving of chroma instead of lightness. -constexpr float HUE_COLORFULNESS = 0.5f; - -ItemColorChannelOKLab::ItemColorChannelOKLab(Color* col, int channel, - Menu* menu) : - MenuItem(""), - m_color(col), - m_col_prev(0, 0, 0), - m_channel(ChannelType::CHANNEL_L), - m_menu(menu), - m_mousedown(false) -{ - if (channel == 1) - m_channel = ChannelType::CHANNEL_L; - else if (channel == 2) - m_channel = ChannelType::CHANNEL_C; - else - m_channel = ChannelType::CHANNEL_H; -} - -void -ItemColorChannelOKLab::draw(DrawingContext& context, const Vector& pos, - int menu_width, bool active) -{ - const float lw = static_cast(menu_width - 32); - ColorOKLCh col_oklch(0, 0, 0); - if (active) { - col_oklch = m_col_prev; - } else { - col_oklch = ColorOKLCh(*m_color); - } - - // Draw all possible colour values for the given component - float chroma_max_any_l = 1.0f; - if (m_channel == ChannelType::CHANNEL_C) - chroma_max_any_l = col_oklch.get_maximum_chroma_any_l(); - constexpr int NUM_RECTS = 128; - std::vector colors(NUM_RECTS+1); - for (int i = 0; i < NUM_RECTS+1; ++i) { - ColorOKLCh col_oklch_current = col_oklch; - float x = static_cast(i) / NUM_RECTS; - if (m_channel == ChannelType::CHANNEL_L) { - col_oklch_current.L = x; - } else if (m_channel == ChannelType::CHANNEL_C) { - col_oklch_current.C = x * chroma_max_any_l; - col_oklch_current.clip_lightness(); - } else { - col_oklch_current.h = (2.0f * x - 1.0f) * math::PI; - col_oklch_current.clip_adaptive_L0_L_cusp(HUE_COLORFULNESS); - } - colors[i] = col_oklch_current.to_srgb(); - } - for (int i = 0; i < NUM_RECTS; ++i) { - float x1 = 16 + static_cast(i) * lw / NUM_RECTS; - float x2 = x1 + lw / NUM_RECTS; - context.color().draw_gradient(colors[i], colors[i+1], LAYER_GUI-1, - GradientDirection::HORIZONTAL, - Rectf(pos + Vector(x1, -10), pos + Vector(x2, 10))); - } - - // Draw a marker for the current colour - float x_marker; - if (m_channel == ChannelType::CHANNEL_L) { - x_marker = col_oklch.L; - } else if (m_channel == ChannelType::CHANNEL_C) { - x_marker = chroma_max_any_l > 0.0f ? col_oklch.C / chroma_max_any_l : 0.0f; - } else { - x_marker = 0.5f * col_oklch.h / math::PI + 0.5f; - } - x_marker = pos.x + 16 + x_marker * lw; - context.color().draw_triangle(Vector(x_marker - 3, pos.y - 11), - Vector(x_marker + 3, pos.y - 11), Vector(x_marker, pos.y - 4), - Color::WHITE, LAYER_GUI-1); - context.color().draw_triangle(Vector(x_marker, pos.y + 4), - Vector(x_marker - 3, pos.y + 11), Vector(x_marker + 3, pos.y + 11), - Color::BLACK, LAYER_GUI-1); - - if (m_channel == ChannelType::CHANNEL_C && chroma_max_any_l > 0.0f) { - // Draw a marker where the lightness clipping starts - x_marker = col_oklch.get_maximum_chroma() / chroma_max_any_l; - x_marker = pos.x + 16 + x_marker * lw; - context.color().draw_triangle(Vector(x_marker - 2, pos.y - 11), - Vector(x_marker + 2, pos.y - 11), Vector(x_marker, pos.y), - Color(0.73f, 0.73f, 0.73f), LAYER_GUI-1); - } -} - -void -ItemColorChannelOKLab::process_action(const MenuAction& action) -{ - if (action == MenuAction::SELECT) { - m_col_prev = ColorOKLCh(*m_color); - return; - } - float increment; - if (action == MenuAction::LEFT) - increment = -0.1f; - else if (action == MenuAction::RIGHT) - increment = 0.1f; - else - return; - - ColorOKLCh col_oklch = m_col_prev; - ColorOKLCh col_oklch_clipped(0, 0, 0); - if (m_channel == ChannelType::CHANNEL_L) { - col_oklch.L = math::clamp(col_oklch.L + increment, 0.0f, 1.0f); - col_oklch_clipped = col_oklch; - } else if (m_channel == ChannelType::CHANNEL_C) { - float chroma_max = col_oklch.get_maximum_chroma_any_l(); - increment *= chroma_max; - col_oklch.C = math::clamp(col_oklch.C + increment, 0.0f, chroma_max); - col_oklch_clipped = col_oklch; - col_oklch_clipped.clip_lightness(); - } else { - increment *= 3.0f; - col_oklch.h = fmodf(col_oklch.h + increment + 3.0f * math::PI, - 2.0f * math::PI) - math::PI; - col_oklch_clipped = col_oklch; - col_oklch_clipped.clip_adaptive_L0_L_cusp(HUE_COLORFULNESS); - } - set_color(col_oklch_clipped, col_oklch); -} - -void -ItemColorChannelOKLab::event(const SDL_Event& ev) -{ - // Determine the new colour with the mouse position if either the mouse - // is clicked once or clicked and held down - bool is_mouseclick = ev.type == SDL_MOUSEBUTTONDOWN - && ev.button.button == SDL_BUTTON_LEFT; - bool is_hold_mousemove = ev.type == SDL_MOUSEMOTION - && (ev.motion.state & SDL_BUTTON_LMASK); - if (is_mouseclick) { - m_mousedown = true; - } else if (!is_hold_mousemove || !m_mousedown) { - m_mousedown = false; - return; - } - - Vector mouse_pos = VideoSystem::current()->get_viewport().to_logical( - ev.motion.x, ev.motion.y); - - // Calculate the menu item positions as passed in the draw method - Vector menu_centre = m_menu->get_center_pos(); - const float menu_width = m_menu->get_width(); - const float menu_height = m_menu->get_height(); - Vector pos( - menu_centre.x - menu_width / 2.0f, - menu_centre.y - + 24.0f * static_cast(m_menu->get_active_item_id()) - - menu_height / 2.0f + 12.0f - ); - - // Calculate the relative horizontal position - float x1 = pos.x + 16.0f; - float x2 = pos.x + menu_width - 16.0f; - float x = (mouse_pos.x - x1) / (x2 - x1); - if (m_channel != ChannelType::CHANNEL_H) { - x = math::clamp(x, 0.0f, 1.0f); - } else { - // The hue is periodic - x = fmodf(x + 3.0f, 1.0f); - } - - // Ignore distant mouse presses - if (x < -0.5f || x > 1.5f || mouse_pos.y > pos.y + menu_height / 2.0f - || mouse_pos.y < pos.y - menu_height / 2.0f) - return; - - ColorOKLCh col_oklch = m_col_prev; - ColorOKLCh col_oklch_clipped(0, 0, 0); - if (m_channel == ChannelType::CHANNEL_L) { - col_oklch.L = x; - col_oklch_clipped = col_oklch; - } else if (m_channel == ChannelType::CHANNEL_C) { - float chroma_max_any_l = col_oklch.get_maximum_chroma_any_l(); - col_oklch.C = x * chroma_max_any_l; - col_oklch_clipped = col_oklch; - col_oklch_clipped.clip_lightness(); - } else { - col_oklch.h = (2.0f * x - 1.0f) * math::PI; - col_oklch_clipped = col_oklch; - col_oklch_clipped.clip_adaptive_L0_L_cusp(HUE_COLORFULNESS); - } - set_color(col_oklch_clipped, col_oklch); -} - -void -ItemColorChannelOKLab::set_color(ColorOKLCh& col_oklch_clipped, - ColorOKLCh& col_oklch_store) -{ - // Save the current unclipped colour - m_col_prev = col_oklch_store; - // Convert the colour back to sRGB and clip if needed; preserve transparency - float alpha = m_color->alpha; - *m_color = col_oklch_clipped.to_srgb(); - m_color->alpha = alpha; -} - -/* EOF */ diff --git a/src/gui/item_colorchannel_rgba.cpp b/src/gui/item_colorchannel_rgba.cpp index 2448522e348..fae55b8639a 100644 --- a/src/gui/item_colorchannel_rgba.cpp +++ b/src/gui/item_colorchannel_rgba.cpp @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include "gui/item_colorchannel.hpp" +#include "gui/item_colorchannel_rgba.hpp" #include diff --git a/src/gui/item_colorchannel.hpp b/src/gui/item_colorchannel_rgba.hpp similarity index 65% rename from src/gui/item_colorchannel.hpp rename to src/gui/item_colorchannel_rgba.hpp index 4e234a1f913..c7264a0175d 100644 --- a/src/gui/item_colorchannel.hpp +++ b/src/gui/item_colorchannel_rgba.hpp @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#ifndef HEADER_SUPERTUX_GUI_ITEM_COLORCHANNEL_HPP -#define HEADER_SUPERTUX_GUI_ITEM_COLORCHANNEL_HPP +#ifndef HEADER_SUPERTUX_GUI_ITEM_COLORCHANNEL_RGBA_HPP +#define HEADER_SUPERTUX_GUI_ITEM_COLORCHANNEL_RGBA_HPP #include "gui/menu_item.hpp" @@ -65,37 +65,6 @@ class ItemColorChannelRGBA final : public MenuItem ItemColorChannelRGBA& operator=(const ItemColorChannelRGBA&) = delete; }; - -class ItemColorChannelOKLab final : public MenuItem -{ -public: - enum class ChannelType { CHANNEL_L, CHANNEL_C, CHANNEL_H }; - -public: - ItemColorChannelOKLab(Color* col, int channel, Menu* menu); - virtual void draw(DrawingContext&, const Vector& pos, int menu_width, - bool active) override; - /** Returns the minimum width of the menu item. */ - virtual int get_width() const override { return 64; } - virtual void process_action(const MenuAction& action) override; - virtual void event(const SDL_Event& ev) override; - virtual bool changes_width() const override { return true; } - -private: - void set_color(ColorOKLCh& col_oklch_clipped, ColorOKLCh& col_oklch_store); - -private: - Color* m_color; - ColorOKLCh m_col_prev; - ChannelType m_channel; - Menu* m_menu; - bool m_mousedown; - -private: - ItemColorChannelOKLab(const ItemColorChannelOKLab&) = delete; - ItemColorChannelOKLab& operator=(const ItemColorChannelOKLab&) = delete; -}; - #endif /* EOF */ diff --git a/src/gui/menu.cpp b/src/gui/menu.cpp index 8c235b05dcf..fc4486925ac 100644 --- a/src/gui/menu.cpp +++ b/src/gui/menu.cpp @@ -20,8 +20,9 @@ #include "gui/item_action.hpp" #include "gui/item_back.hpp" #include "gui/item_color.hpp" -#include "gui/item_colorchannel.hpp" +#include "gui/item_colorchannel_rgba.hpp" #include "gui/item_colordisplay.hpp" +#include "gui/item_color_picker_2d.hpp" #include "gui/item_controlfield.hpp" #include "gui/item_floatfield.hpp" #include "gui/item_goto.hpp" @@ -267,10 +268,9 @@ Menu::add_color_channel_rgba(float* input, Color channel, int id, bool is_linear return add_item(input, channel, id, is_linear); } -ItemColorChannelOKLab& -Menu::add_color_channel_oklab(Color* color, int channel) -{ - return add_item(color, channel, this); +ItemColorPicker2D& +Menu::add_color_picker_2d(Color& color) { + return add_item(color); } ItemPaths& @@ -308,7 +308,7 @@ Menu::add_images(const std::vector& image_paths, int max_image_widt { return add_item(image_paths, max_image_width, max_image_height, id); } - + ItemList& Menu::add_list(const std::string& text, const std::vector& items, std::string* value_ptr, int id) { diff --git a/src/gui/menu.hpp b/src/gui/menu.hpp index 0e0a1d05053..59362245315 100644 --- a/src/gui/menu.hpp +++ b/src/gui/menu.hpp @@ -30,7 +30,7 @@ class ItemAction; class ItemBack; class ItemColor; class ItemColorChannelRGBA; -class ItemColorChannelOKLab; +class ItemColorPicker2D; class ItemColorDisplay; class ItemControlField; class ItemFloatField; @@ -102,7 +102,7 @@ class Menu ItemColorDisplay& add_color_display(Color* color, int id = -1); ItemColorChannelRGBA& add_color_channel_rgba(float* input, Color channel, int id = -1, bool is_linear = false); - ItemColorChannelOKLab& add_color_channel_oklab(Color* color, int channel); + ItemColorPicker2D& add_color_picker_2d(Color& color); ItemPaths& add_path_settings(const std::string& text, PathObject& target, const std::string& path_ref); ItemStringArray& add_string_array(const std::string& text, std::vector& items, int id = -1); ItemImages& add_images(const std::string& image_path, int max_image_width = 0, int max_image_height = 0, int id = -1); diff --git a/src/gui/menu_color.cpp b/src/gui/menu_color.cpp index a071989b932..af068748b14 100644 --- a/src/gui/menu_color.cpp +++ b/src/gui/menu_color.cpp @@ -24,9 +24,7 @@ ColorMenu::ColorMenu(Color* color_) : add_label(_("Mix the colour")); add_hl(); - add_color_channel_oklab(color, 1); - add_color_channel_oklab(color, 2); - add_color_channel_oklab(color, 3); + add_color_picker_2d(*color); add_color_channel_rgba(&(color->red), Color::RED); add_color_channel_rgba(&(color->green), Color::GREEN); add_color_channel_rgba(&(color->blue), Color::BLUE); diff --git a/src/gui/menu_manager.cpp b/src/gui/menu_manager.cpp index b85cb0cd982..d568333edf4 100644 --- a/src/gui/menu_manager.cpp +++ b/src/gui/menu_manager.cpp @@ -131,7 +131,8 @@ MenuManager::draw(DrawingContext& context) { if (m_dialog.has_next) // Has next dialog { - if (m_dialog.next) m_dialog.next->update(); + // Removed to fix a crash with changing dialog in initial next dialog update + //if (m_dialog.next) m_dialog.next->update(); if (m_dialog.current && m_dialog.next) { diff --git a/src/object/block.cpp b/src/object/block.cpp index 318335f9ec0..a51e65f4906 100644 --- a/src/object/block.cpp +++ b/src/object/block.cpp @@ -193,7 +193,7 @@ Block::break_me() Sector::get().add(m_sprite->clone(), action, pos, ANCHOR_MIDDLE, velocity, Vector(0, gravity), - LAYER_OBJECTS + 3); + m_layer); } remove_me(); diff --git a/src/object/moving_sprite.cpp b/src/object/moving_sprite.cpp index 7f419594b94..e71205bb0c9 100644 --- a/src/object/moving_sprite.cpp +++ b/src/object/moving_sprite.cpp @@ -209,7 +209,7 @@ MovingSprite::change_sprite(const std::string& new_sprite_name) m_sprite_name = new_sprite_name; update_hitbox(); - return SpriteManager::current()->last_load_successful(); + return m_sprite->load_successful(); } ObjectSettings diff --git a/src/object/player.cpp b/src/object/player.cpp index 98c7eb27e48..132f359050d 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -1909,28 +1909,25 @@ Player::get_coins() const } BonusType -Player::string_to_bonus(const std::string& bonus) const { - BonusType type = BONUS_NONE; - +Player::string_to_bonus(const std::string& bonus) const +{ if (bonus == "grow") { - type = BONUS_GROWUP; + return BONUS_GROWUP; } else if (bonus == "fireflower") { - type = BONUS_FIRE; + return BONUS_FIRE; } else if (bonus == "iceflower") { - type = BONUS_ICE; + return BONUS_ICE; } else if (bonus == "airflower") { - type = BONUS_AIR; + return BONUS_AIR; } else if (bonus == "earthflower") { - type = BONUS_EARTH; + return BONUS_EARTH; } else if (bonus == "none") { - type = BONUS_NONE; + return BONUS_NONE; } else { std::ostringstream msg; msg << "Unknown bonus type " << bonus; throw std::runtime_error(msg.str()); } - - return type; } std::string diff --git a/src/object/tilemap.cpp b/src/object/tilemap.cpp index a464917ab22..ba9cacc13c7 100644 --- a/src/object/tilemap.cpp +++ b/src/object/tilemap.cpp @@ -156,9 +156,16 @@ TileMap::TileMap(const TileSet *tileset_, const ReaderMapping& reader) : m_effective_solid = m_real_solid; update_effective_solid(false); + parse_tiles(reader); +} + +void +TileMap::parse_tiles(const ReaderMapping& reader) +{ reader.get("width", m_width); reader.get("height", m_height); - if (m_width < 0 || m_height < 0) { + if (m_width < 0 || m_height < 0) + { //throw std::runtime_error("Invalid/No width/height specified in tilemap."); m_width = 0; m_height = 0; @@ -166,13 +173,15 @@ TileMap::TileMap(const TileSet *tileset_, const ReaderMapping& reader) : resize(static_cast(Sector::get().get_width() / 32.0f), static_cast(Sector::get().get_height() / 32.0f)); m_editor_active = false; - } else { - if (!reader.get("tiles", m_tiles)) + } + else + { + reader.get("tiles", m_tiles); + if (m_tiles.empty()) throw std::runtime_error("No tiles in tilemap."); - if (int(m_tiles.size()) != m_width * m_height) { + if (static_cast(m_tiles.size()) != m_width * m_height) throw std::runtime_error("wrong number of tiles in tilemap."); - } } bool empty = true; @@ -190,6 +199,11 @@ TileMap::TileMap(const TileSet *tileset_, const ReaderMapping& reader) : { log_info << "Tilemap '" << get_name() << "', z-pos '" << m_z_pos << "' is empty." << std::endl; } + + m_new_size_x = m_width; + m_new_size_y = m_height; + m_new_offset_x = 0; + m_new_offset_y = 0; } void @@ -654,6 +668,12 @@ TileMap::get_tile_id(int x, int y) const return m_tiles[y*m_width + x]; } +uint32_t +TileMap::get_tile_id(const Vector& pos) const +{ + return get_tile_id(static_cast(pos.x), static_cast(pos.y)); +} + bool TileMap::is_outside_bounds(const Vector& pos) const { @@ -699,6 +719,12 @@ TileMap::change(int x, int y, uint32_t newtile) m_tiles[y*m_width + x] = newtile; } +void +TileMap::change(int idx, uint32_t newtile) +{ + m_tiles[idx] = newtile; +} + void TileMap::change_at(const Vector& pos, uint32_t newtile) { @@ -726,80 +752,43 @@ TileMap::change_all(uint32_t oldtile, uint32_t newtile) } void -TileMap::autotile(int x, int y, uint32_t tile) +TileMap::autotile(int x, int y, uint32_t tile, AutotileSet* autotileset) { if (x < 0 || x >= m_width || y < 0 || y >= m_height) return; - uint32_t current_tile = m_tiles[y*m_width + x]; - AutotileSet* curr_set; - if (current_tile == 0) - { - // Special case 1 : If the tile is empty, check if we can use a non-solid - // tile from the currently selected tile's autotile set (if any). - curr_set = m_tileset->get_autotileset_from_tile(tile); - } - else if (m_tileset->get_autotileset_from_tile(tile) != nullptr && - m_tileset->get_autotileset_from_tile(tile)->is_member(current_tile)) - { - // Special case 2 : If the tile is in multiple autotilesets, check if it - // is in the same tileset as the selected tile. (Example : tile 47) - curr_set = m_tileset->get_autotileset_from_tile(tile); - } - else - { - curr_set = m_tileset->get_autotileset_from_tile(current_tile); - } - - // If tile is not autotileable, abort - // If tile is from a corner autotileset, abort as well - if (curr_set == nullptr) - { + if (!autotileset || !autotileset->is_member(tile)) return; - } - uint32_t realtile = curr_set->get_autotile(current_tile, - curr_set->is_solid(get_tile_id(x-1, y-1)), - curr_set->is_solid(get_tile_id(x , y-1)), - curr_set->is_solid(get_tile_id(x+1, y-1)), - curr_set->is_solid(get_tile_id(x-1, y )), - curr_set->is_solid(get_tile_id(x , y )), - curr_set->is_solid(get_tile_id(x+1, y )), - curr_set->is_solid(get_tile_id(x-1, y+1)), - curr_set->is_solid(get_tile_id(x , y+1)), - curr_set->is_solid(get_tile_id(x+1, y+1)), + m_tiles[y*m_width + x] = autotileset->get_autotile(m_tiles[y*m_width + x], + autotileset->is_solid(get_tile_id(x-1, y-1)), + autotileset->is_solid(get_tile_id(x , y-1)), + autotileset->is_solid(get_tile_id(x+1, y-1)), + autotileset->is_solid(get_tile_id(x-1, y )), + autotileset->is_solid(get_tile_id(x , y )), + autotileset->is_solid(get_tile_id(x+1, y )), + autotileset->is_solid(get_tile_id(x-1, y+1)), + autotileset->is_solid(get_tile_id(x , y+1)), + autotileset->is_solid(get_tile_id(x+1, y+1)), x, y); - - m_tiles[y*m_width + x] = realtile; } void -TileMap::autotile_corner(int x, int y, uint32_t tile, AutotileCornerOperation op) +TileMap::autotile_corner(int x, int y, uint32_t tile, AutotileSet* autotileset, AutotileCornerOperation op) { if (x < 0 || x >= m_width || y < 0 || y >= m_height) return; - if (!m_tileset->get_autotileset_from_tile(tile)->is_corner()) + if (!autotileset || !autotileset->is_corner() || !autotileset->is_member(tile)) return; - AutotileSet* curr_set = m_tileset->get_autotileset_from_tile(tile); - - // If tile is not autotileable, abort - if (curr_set == nullptr) - { - return; - } - // If tile is not empty or already of the appropriate tileset, abort uint32_t current_tile = m_tiles[y*m_width + x]; - if (current_tile != 0 && (m_tileset->get_autotileset_from_tile(tile) != nullptr - && !m_tileset->get_autotileset_from_tile(tile)->is_member(current_tile))) - { + if (current_tile != 0 && !autotileset->is_member(current_tile)) return; - } // If the current tile is 0, it will automatically return 0 - uint8_t mask = curr_set->get_mask_from_tile(current_tile); + uint8_t mask = autotileset->get_mask_from_tile(current_tile); if (op == AutotileCornerOperation::REMOVE_TOP_LEFT) mask = static_cast(mask & 0x07); if (op == AutotileCornerOperation::REMOVE_TOP_RIGHT) mask = static_cast(mask & 0x0B); if (op == AutotileCornerOperation::REMOVE_BOTTOM_LEFT) mask = static_cast(mask & 0x0D); @@ -809,7 +798,7 @@ TileMap::autotile_corner(int x, int y, uint32_t tile, AutotileCornerOperation op if (op == AutotileCornerOperation::ADD_BOTTOM_LEFT) mask = static_cast(mask | 0x02); if (op == AutotileCornerOperation::ADD_BOTTOM_RIGHT) mask = static_cast(mask | 0x01); - uint32_t realtile = (!mask) ? 0 : curr_set->get_autotile(current_tile, + uint32_t realtile = (!mask) ? 0 : autotileset->get_autotile(current_tile, (mask & 0x08) != 0, false, (mask & 0x04) != 0, @@ -827,12 +816,16 @@ TileMap::autotile_corner(int x, int y, uint32_t tile, AutotileCornerOperation op bool TileMap::is_corner(uint32_t tile) const { - auto* ats = m_tileset->get_autotileset_from_tile(tile); - return ats && ats->is_corner(); + for (const AutotileSet* autotileset : get_autotilesets(tile)) + { + if (autotileset->is_corner()) + return true; + } + return false; } void -TileMap::autotile_erase(const Vector& pos, const Vector& corner_pos) +TileMap::autotile_erase(const Vector& pos, const Vector& corner_pos, AutotileSet* autotileset) { if (pos.x < 0.f || pos.x >= static_cast(m_width) || pos.y < 0.f || pos.y >= static_cast(m_height)) @@ -844,15 +837,16 @@ TileMap::autotile_erase(const Vector& pos, const Vector& corner_pos) uint32_t current_tile = m_tiles[static_cast(pos.y)*m_width + static_cast(pos.x)]; + if (!autotileset || (current_tile != 0 && !autotileset->is_member(current_tile))) + return; - AutotileSet* curr_set = m_tileset->get_autotileset_from_tile(current_tile); - - if (curr_set && curr_set->is_corner()) { + if (current_tile != 0 && autotileset->is_corner()) + { int x = static_cast(corner_pos.x), y = static_cast(corner_pos.y); - autotile_corner(x, y, current_tile, AutotileCornerOperation::REMOVE_TOP_LEFT); - autotile_corner(x-1, y, current_tile, AutotileCornerOperation::REMOVE_TOP_RIGHT); - autotile_corner(x, y-1, current_tile, AutotileCornerOperation::REMOVE_BOTTOM_LEFT); - autotile_corner(x-1, y-1, current_tile, AutotileCornerOperation::REMOVE_BOTTOM_RIGHT); + autotile_corner(x, y, current_tile, autotileset, AutotileCornerOperation::REMOVE_TOP_LEFT); + autotile_corner(x-1, y, current_tile, autotileset, AutotileCornerOperation::REMOVE_TOP_RIGHT); + autotile_corner(x, y-1, current_tile, autotileset, AutotileCornerOperation::REMOVE_BOTTOM_LEFT); + autotile_corner(x-1, y-1, current_tile, autotileset, AutotileCornerOperation::REMOVE_BOTTOM_RIGHT); } else { @@ -861,58 +855,58 @@ TileMap::autotile_erase(const Vector& pos, const Vector& corner_pos) if (x - 1 >= 0 && y - 1 >= 0 && !is_corner(m_tiles[(y-1)*m_width + x-1])) { if (m_tiles[y*m_width + x] == 0) - autotile(x, y, m_tiles[(y-1)*m_width + x-1]); - autotile(x-1, y-1, m_tiles[(y-1)*m_width + x-1]); + autotile(x, y, m_tiles[(y-1)*m_width + x-1], autotileset); + autotile(x-1, y-1, m_tiles[(y-1)*m_width + x-1], autotileset); } if (y - 1 >= 0 && !is_corner(m_tiles[(y-1)*m_width + x])) { if (m_tiles[y*m_width + x] == 0) - autotile(x, y, m_tiles[(y-1)*m_width + x]); - autotile(x, y-1, m_tiles[(y-1)*m_width + x]); + autotile(x, y, m_tiles[(y-1)*m_width + x], autotileset); + autotile(x, y-1, m_tiles[(y-1)*m_width + x], autotileset); } if (y - 1 >= 0 && x + 1 < m_width && !is_corner(m_tiles[(y-1)*m_width + x+1])) { if (m_tiles[y*m_width + x] == 0) - autotile(x, y, m_tiles[(y-1)*m_width + x+1]); - autotile(x+1, y-1, m_tiles[(y-1)*m_width + x+1]); + autotile(x, y, m_tiles[(y-1)*m_width + x+1], autotileset); + autotile(x+1, y-1, m_tiles[(y-1)*m_width + x+1], autotileset); } if (x - 1 >= 0 && !is_corner(m_tiles[y*m_width + x-1])) { if (m_tiles[y*m_width + x] == 0) - autotile(x, y, m_tiles[y*m_width + x-1]); - autotile(x-1, y, m_tiles[y*m_width + x-1]); + autotile(x, y, m_tiles[y*m_width + x-1], autotileset); + autotile(x-1, y, m_tiles[y*m_width + x-1], autotileset); } if (x + 1 < m_width && !is_corner(m_tiles[y*m_width + x+1])) { if (m_tiles[y*m_width + x] == 0) - autotile(x, y, m_tiles[y*m_width + x+1]); - autotile(x+1, y, m_tiles[y*m_width + x+1]); + autotile(x, y, m_tiles[y*m_width + x+1], autotileset); + autotile(x+1, y, m_tiles[y*m_width + x+1], autotileset); } if (x - 1 >= 0 && y + 1 < m_height && !is_corner(m_tiles[(y+1)*m_width + x-1])) { if (m_tiles[y*m_width + x] == 0) - autotile(x, y, m_tiles[(y+1)*m_width + x-1]); - autotile(x-1, y+1, m_tiles[(y+1)*m_width + x-1]); + autotile(x, y, m_tiles[(y+1)*m_width + x-1], autotileset); + autotile(x-1, y+1, m_tiles[(y+1)*m_width + x-1], autotileset); } if (y + 1 < m_height && !is_corner(m_tiles[(y+1)*m_width + x])) { if (m_tiles[y*m_width + x] == 0) - autotile(x, y, m_tiles[(y+1)*m_width + x]); - autotile(x, y+1, m_tiles[(y+1)*m_width + x]); + autotile(x, y, m_tiles[(y+1)*m_width + x], autotileset); + autotile(x, y+1, m_tiles[(y+1)*m_width + x], autotileset); } if (y + 1 < m_height && x + 1 < m_width && !is_corner(m_tiles[(y+1)*m_width + x+1])) { if (m_tiles[y*m_width + x] == 0) - autotile(x, y, m_tiles[(y+1)*m_width + x+1]); - autotile(x+1, y+1, m_tiles[(y+1)*m_width + x+1]); + autotile(x, y, m_tiles[(y+1)*m_width + x+1], autotileset); + autotile(x+1, y+1, m_tiles[(y+1)*m_width + x+1], autotileset); } } } -AutotileSet* -TileMap::get_autotileset(uint32_t tile) const +std::vector +TileMap::get_autotilesets(uint32_t tile) const { - return m_tileset->get_autotileset_from_tile(tile); + return m_tileset->get_autotilesets_from_tile(tile); } void @@ -989,9 +983,9 @@ TileMap::register_class(ssq::VM& vm) PathObject::register_members(cls); - cls.addFunc("get_tile_id", &TileMap::get_tile_id); + cls.addFunc("get_tile_id", &TileMap::get_tile_id); cls.addFunc("get_tile_id_at", &TileMap::get_tile_id_at); - cls.addFunc("change", &TileMap::change); + cls.addFunc("change", &TileMap::change); cls.addFunc("change_at", &TileMap::change_at); cls.addFunc("change_all", &TileMap::change_all); cls.addFunc("fade", &TileMap::fade); diff --git a/src/object/tilemap.hpp b/src/object/tilemap.hpp index 16a3f4a0b43..8daf470761a 100644 --- a/src/object/tilemap.hpp +++ b/src/object/tilemap.hpp @@ -31,6 +31,7 @@ #include "video/flip.hpp" #include "video/drawing_target.hpp" +class AutotileSet; class CollisionObject; class CollisionGroundMovementManager; class DrawingContext; @@ -57,6 +58,8 @@ class TileMap final : public GameObject, TileMap(const TileSet *tileset, const ReaderMapping& reader); ~TileMap() override; + void parse_tiles(const ReaderMapping& reader); + virtual void finish_construction() override; static std::string class_name() { return "tilemap"; } @@ -169,6 +172,7 @@ class TileMap final : public GameObject, * @param int $y */ uint32_t get_tile_id(int x, int y) const; + uint32_t get_tile_id(const Vector& pos) const; /** * @scripting * @description Returns the ID of the tile at the given position (in world coordinates). @@ -187,6 +191,7 @@ class TileMap final : public GameObject, * @param int $newtile */ void change(int x, int y, uint32_t newtile); + void change(int idx, uint32_t newtile); /** * @scripting * @description Changes the tile at the given position (in-world coordinates) to ""newtile"". @@ -205,7 +210,7 @@ class TileMap final : public GameObject, void change_all(uint32_t oldtile, uint32_t newtile); /** Puts the correct autotile block at the given position */ - void autotile(int x, int y, uint32_t tile); + void autotile(int x, int y, uint32_t tile, AutotileSet* autotileset); enum class AutotileCornerOperation { ADD_TOP_LEFT, @@ -219,13 +224,13 @@ class TileMap final : public GameObject, }; /** Puts the correct autotile blocks at the tiles around the given corner */ - void autotile_corner(int x, int y, uint32_t tile, AutotileCornerOperation op); + void autotile_corner(int x, int y, uint32_t tile, AutotileSet* autotileset, AutotileCornerOperation op); /** Erases in autotile mode */ - void autotile_erase(const Vector& pos, const Vector& corner_pos); + void autotile_erase(const Vector& pos, const Vector& corner_pos, AutotileSet* autotileset); - /** Returns the Autotileset associated with the given tile */ - AutotileSet* get_autotileset(uint32_t tile) const; + /** Returns the Autotilesets associated with the given tile */ + std::vector get_autotilesets(uint32_t tile) const; void set_flip(Flip flip) { m_flip = flip; } Flip get_flip() const { return m_flip; } diff --git a/src/sprite/sprite.cpp b/src/sprite/sprite.cpp index e5e239ed991..b3dc6bf58bd 100644 --- a/src/sprite/sprite.cpp +++ b/src/sprite/sprite.cpp @@ -98,7 +98,9 @@ Sprite::set_action(const std::string& name, int loops) const SpriteData::Action* newaction = m_data.get_action(name); if (!newaction) { - log_warning << "Action '" << name << "' not found." << std::endl; + // HACK: Lots of things trigger this message therefore turning it into a warning + // would make it quite annoying + log_debug << "Action '" << name << "' not found." << std::endl; return; } diff --git a/src/sprite/sprite.hpp b/src/sprite/sprite.hpp index 7c9c21b99a7..76c85c326a9 100644 --- a/src/sprite/sprite.hpp +++ b/src/sprite/sprite.hpp @@ -85,9 +85,6 @@ class Sprite final /** Get current frame progress */ float get_current_frame_progress() const { return m_frame; } - /** Get sprite's name */ - const std::string& get_name() const { return m_data.name; } - /** Get current action name */ const std::string& get_action() const { return m_action->name; } @@ -127,6 +124,8 @@ class Sprite final bool has_action (const std::string& name) const { return (m_data.get_action(name) != nullptr); } size_t get_actions_count() const { return m_data.actions.size(); } + bool load_successful() const { return m_data.m_load_successful; } + private: void update(); diff --git a/src/sprite/sprite_data.cpp b/src/sprite/sprite_data.cpp index bd8d2c8d5f5..3a70d16130d 100644 --- a/src/sprite/sprite_data.cpp +++ b/src/sprite/sprite_data.cpp @@ -1,5 +1,6 @@ // SuperTux // Copyright (C) 2006 Matthias Braun +// 2023-2024 Vankata453 // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -29,6 +30,7 @@ #include "util/reader_document.hpp" #include "util/reader_mapping.hpp" #include "util/reader_object.hpp" +#include "util/string_util.hpp" #include "video/surface.hpp" #include "video/texture_manager.hpp" @@ -48,70 +50,141 @@ SpriteData::Action::Action() : { } -SpriteData::SpriteData(const ReaderMapping& mapping) : - actions(), - name() +void +SpriteData::Action::reset(SurfacePtr surface) { - auto iter = mapping.get_iter(); - while (iter.next()) - { - if (iter.get_key() == "name") { - iter.get(name); - } else if (iter.get_key() == "action") { - parse_action(iter.as_mapping()); - } else { - log_warning << "Unknown sprite field: " << iter.get_key() << std::endl; - } - } - if (actions.empty()) - throw std::runtime_error("Error: Sprite without actions."); + x_offset = 0; + y_offset = 0; + hitbox_w = static_cast(surface->get_width()); + hitbox_h = static_cast(surface->get_height()); + hitbox_unisolid = false; + fps = 10; + loops = -1; + loop_frame = 1; + has_custom_loops = false; + family_name.clear(); + surfaces = { surface }; } -SpriteData::SpriteData(const std::string& image) : - actions(), - name() -{ - auto surface = Surface::from_file(image); - if (!TextureManager::current()->last_load_successful()) - throw std::runtime_error("Cannot load image."); - auto action = create_action_from_surface(surface); - action->name = "default"; - actions[action->name] = std::move(action); +SpriteData::SpriteData(const std::string& filename) : + m_filename(filename), + m_load_successful(false), + actions() +{ + load(); } -SpriteData::SpriteData() : - actions(), - name() +void +SpriteData::load() { - auto surface = Surface::from_texture(TextureManager::current()->create_dummy_texture()); - auto action = create_action_from_surface(surface); - action->name = "default"; - actions[action->name] = std::move(action); + // Reset all existing actions to a dummy texture + if (!actions.empty()) + { + auto surface = Surface::from_texture(TextureManager::current()->create_dummy_texture()); + for (const auto& action : actions) + action.second->reset(surface); + } + + if (StringUtil::has_suffix(m_filename, ".sprite")) + { + try + { + auto doc = ReaderDocument::from_file(m_filename); + auto root = doc.get_root(); + + if (root.get_name() != "supertux-sprite") + { + std::ostringstream msg; + msg << "'" << m_filename << "' is not a 'supertux-sprite' file!"; + throw std::runtime_error(msg.str()); + } + else + { + // Load ".sprite" file + parse(root.get_mapping()); + } + } + catch (const std::exception& err) + { + log_warning << "Parse error when trying to load sprite '" << m_filename + << "': " << err.what() << std::endl; + + // Load initial dummy texture + if (actions.empty()) + { + auto surface = Surface::from_texture(TextureManager::current()->create_dummy_texture()); + auto action = std::make_unique(); + action->name = "default"; + action->reset(surface); + actions[action->name] = std::move(action); + } + + m_load_successful = false; + return; + } + } + else + { + // Load single image + auto surface = Surface::from_file(m_filename); + if (!TextureManager::current()->last_load_successful()) + throw std::runtime_error("Cannot load image."); + + // Create action, if it doesn't exist + { + auto i = actions.find("default"); + if (i == actions.end()) + { + auto action = std::make_unique(); + action->name = "default"; + actions["default"] = std::move(action); + } + } + actions["default"]->reset(surface); + } + + m_load_successful = true; } -std::unique_ptr -SpriteData::create_action_from_surface(SurfacePtr surface) +void +SpriteData::parse(const ReaderMapping& mapping) { - auto action = std::make_unique(); - - action->hitbox_w = static_cast(surface->get_width()); - action->hitbox_h = static_cast(surface->get_height()); - action->surfaces.push_back(surface); + auto iter = mapping.get_iter(); + while (iter.next()) + { + if (iter.get_key() == "action") + parse_action(iter.as_mapping()); + else + log_warning << "Unknown sprite field: " << iter.get_key() << std::endl; + } - return action; + if (actions.empty()) + throw std::runtime_error("Error: Sprite without actions."); } void SpriteData::parse_action(const ReaderMapping& mapping) { - auto action = std::make_unique(); + std::string name; + mapping.get("name", name); - if (!mapping.get("name", action->name)) + // Create action, if it doesn't exist { - if (!actions.empty()) - throw std::runtime_error("If there are more than one action, they need names!"); + auto i = actions.find(name); + if (i == actions.end()) + { + auto action = std::make_unique(); + action->name = name; + actions[name] = std::move(action); + } } + Action* action = actions[name].get(); + + // Reset action + action->hitbox_w = 0; + action->hitbox_h = 0; + action->surfaces.clear(); std::vector hitbox; if (mapping.get("hitbox", hitbox)) @@ -128,7 +201,7 @@ SpriteData::parse_action(const ReaderMapping& mapping) break; default: - throw std::runtime_error("hitbox should specify 2/4 coordinates"); + throw std::runtime_error("Hitbox should specify 2/4 coordinates!"); } } mapping.get("unisolid", action->hitbox_unisolid); @@ -141,7 +214,7 @@ SpriteData::parse_action(const ReaderMapping& mapping) { if (action->loop_frame < 1) { - log_warning << "'loop-frame' of action '" << action->name << "' in sprite '" << name << "' set to a value below 1." << std::endl; + log_warning << "'loop-frame' of action '" << action->name << "' in sprite '" << m_filename << "' set to a value below 1." << std::endl; action->loop_frame = 1; } } @@ -343,7 +416,7 @@ SpriteData::parse_action(const ReaderMapping& mapping) else { std::stringstream msg; - msg << "Sprite '" << name << "' unknown tag in 'surfaces' << " << i.get_name(); + msg << "Sprite '" << m_filename << "' unknown tag in 'surfaces' << " << i.get_name(); throw std::runtime_error(msg.str()); } } @@ -362,7 +435,7 @@ SpriteData::parse_action(const ReaderMapping& mapping) else { std::stringstream msg; - msg << "Sprite '" << name << "' contains no images in action '" + msg << "Sprite '" << m_filename << "' contains no images in action '" << action->name << "'."; throw std::runtime_error(msg.str()); } @@ -372,11 +445,9 @@ SpriteData::parse_action(const ReaderMapping& mapping) const int frames = static_cast(action->surfaces.size()); if (action->loop_frame > frames && frames > 0) { - log_warning << "'loop-frame' of action '" << action->name << "' in sprite '" << name << "' not-in-range of total frames." << std::endl; + log_warning << "'loop-frame' of action '" << action->name << "' in sprite '" << m_filename << "' not-in-range of total frames." << std::endl; action->loop_frame = 1; } - - actions[action->name] = std::move(action); } const SpriteData::Action* diff --git a/src/sprite/sprite_data.hpp b/src/sprite/sprite_data.hpp index 555c2edf3a0..5137f5b50f8 100644 --- a/src/sprite/sprite_data.hpp +++ b/src/sprite/sprite_data.hpp @@ -1,5 +1,6 @@ // SuperTux // Copyright (C) 2006 Matthias Braun +// 2023-2024 Vankata453 // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -17,8 +18,8 @@ #ifndef HEADER_SUPERTUX_SPRITE_SPRITE_DATA_HPP #define HEADER_SUPERTUX_SPRITE_SPRITE_DATA_HPP -#include #include +#include #include #include "video/surface_ptr.hpp" @@ -30,26 +31,17 @@ class SpriteData final friend class Sprite; public: - /** - * Sprite from data. - * `mapping` has to be a pointer to data in the form of "((hitbox 5 10 0 0) ...)". - */ - SpriteData(const ReaderMapping& mapping); - /** Single-image sprite */ - SpriteData(const std::string& image); - /** Dummy texture sprite */ - SpriteData(); - - const std::string& get_name() const - { - return name; - } + SpriteData(const std::string& filename); + + void load(); private: - struct Action + struct Action final { Action(); + void reset(SurfacePtr surface); + std::string name; /** Position correction */ @@ -87,17 +79,22 @@ class SpriteData final std::vector surfaces; }; - typedef std::map > Actions; - - static std::unique_ptr create_action_from_surface(SurfacePtr surface); - +private: + void parse(const ReaderMapping& mapping); void parse_action(const ReaderMapping& mapping); - /** Get an action */ + const Action* get_action(const std::string& act) const; private: + const std::string m_filename; + bool m_load_successful; + + typedef std::unordered_map> Actions; Actions actions; - std::string name; + +private: + SpriteData(const SpriteData& other); + SpriteData& operator=(const SpriteData&) = delete; }; #endif diff --git a/src/sprite/sprite_manager.cpp b/src/sprite/sprite_manager.cpp index db21bd7b5f7..fc12c97ff59 100644 --- a/src/sprite/sprite_manager.cpp +++ b/src/sprite/sprite_manager.cpp @@ -1,6 +1,6 @@ // SuperTux // Copyright (C) 2006 Matthias Braun -// 2023 Vankata453 +// 2023-2024 Vankata453 // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -17,24 +17,11 @@ #include "sprite/sprite_manager.hpp" -#include -#include - #include "sprite/sprite.hpp" -#include "util/file_system.hpp" -#include "util/log.hpp" -#include "util/reader_document.hpp" -#include "util/reader_mapping.hpp" -#include "util/string_util.hpp" - -std::unique_ptr SpriteManager::s_dummy_sprite_data = nullptr; SpriteManager::SpriteManager() : - m_sprites(), - m_load_successful(false) + m_sprites() { - if (!s_dummy_sprite_data) - s_dummy_sprite_data.reset(new SpriteData()); } SpritePtr @@ -45,65 +32,28 @@ SpriteManager::create(const std::string& name) if (i == m_sprites.end()) { // Try loading the sprite file. - try - { - data = load(name); - } - catch (const std::exception& err) - { - log_warning << "Error loading sprite '" << name << "', using dummy texture: " << err.what() << std::endl; - m_load_successful = false; - return SpritePtr(new Sprite(*s_dummy_sprite_data)); // Return a dummy sprite. - } + data = load(name); } else { data = i->second.get(); } - m_load_successful = true; return SpritePtr(new Sprite(*data)); } SpriteData* SpriteManager::load(const std::string& filename) { - std::unique_ptr sprite_data; - - if (StringUtil::has_suffix(filename, ".sprite")) - { - std::optional doc; - try - { - doc = ReaderDocument::from_file(filename); - } - catch (const std::exception& err) - { - std::ostringstream msg; - msg << "Parse error when trying to load sprite '" << filename - << "': " << err.what(); - throw std::runtime_error(msg.str()); - } - auto root = doc->get_root(); - - if (root.get_name() != "supertux-sprite") - { - std::ostringstream msg; - msg << "'" << filename << "' is not a supertux-sprite file"; - throw std::runtime_error(msg.str()); - } - else - { - sprite_data = std::make_unique(root.get_mapping()); - } - } - else - { - sprite_data = std::make_unique(filename); - } - - m_sprites[filename] = std::move(sprite_data); + m_sprites[filename] = std::make_unique(filename); return m_sprites[filename].get(); } +void +SpriteManager::reload() +{ + for (const auto& sprite_data : m_sprites) + sprite_data.second->load(); +} + /* EOF */ diff --git a/src/sprite/sprite_manager.hpp b/src/sprite/sprite_manager.hpp index 381e04f96a8..5159a23ddc2 100644 --- a/src/sprite/sprite_manager.hpp +++ b/src/sprite/sprite_manager.hpp @@ -1,6 +1,6 @@ // SuperTux // Copyright (C) 2006 Matthias Braun -// 2023 Vankata453 +// 2023-2024 Vankata453 // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -31,21 +31,18 @@ class SpriteData; class SpriteManager final : public Currenton { private: - static std::unique_ptr s_dummy_sprite_data; - -private: - typedef std::map > Sprites; + typedef std::map> Sprites; Sprites m_sprites; - bool m_load_successful; public: SpriteManager(); - bool last_load_successful() const { return m_load_successful; } - - /** loads a sprite. */ + /** Loads a sprite. */ SpritePtr create(const std::string& filename); + /** Reloads all sprites. */ + void reload(); + private: SpriteData* load(const std::string& filename); diff --git a/src/supertux/autotile.hpp b/src/supertux/autotile.hpp index e5951c7716c..1d2e8a92df1 100644 --- a/src/supertux/autotile.hpp +++ b/src/supertux/autotile.hpp @@ -100,6 +100,8 @@ class AutotileSet final /** Returns the id of the first block in the autotileset. Used for erronous configs. */ uint32_t get_default_tile() const { return m_default; } + const std::string& get_name() const { return m_name; } + /** true if the given tile is present in the autotileset */ bool is_member(uint32_t tile_id) const; diff --git a/src/supertux/constants.hpp b/src/supertux/constants.hpp index cf22817f11f..f2624c06e12 100644 --- a/src/supertux/constants.hpp +++ b/src/supertux/constants.hpp @@ -19,10 +19,9 @@ #include -// the engine will be run with a logical framerate of 64fps. -// We chose 64fps here because it is a power of 2, so 1/64 gives an "even" -// binary fraction... -static const float LOGICAL_FPS = 64.0; +// the engine will be run with a logical framerate of 66.666fps, corresponding +// to a 15 msec gap between steps. Warning: changing this may affect physics +static const float LOGICAL_FPS = 1000.0f / 15.0f; // SHIFT_DELTA is used for sliding over 1-tile gaps and collision detection static const float SHIFT_DELTA = 7.0f; diff --git a/src/supertux/game_object.cpp b/src/supertux/game_object.cpp index d52bb6d5e20..d245bcf8604 100644 --- a/src/supertux/game_object.cpp +++ b/src/supertux/game_object.cpp @@ -196,14 +196,14 @@ GameObject::save_state() if (!m_parent->undo_tracking_enabled()) { - m_last_state.clear(); + m_last_state.reset(); return; } - if (!track_state()) + if (!track_state() || m_last_state) return; - if (m_last_state.empty()) - m_last_state = save(); + m_last_state = get_settings(); + m_last_state->save_state(); } void @@ -214,21 +214,15 @@ GameObject::check_state() if (!m_parent->undo_tracking_enabled()) { - m_last_state.clear(); + m_last_state.reset(); return; } - if (!track_state()) + if (!track_state() || !m_last_state) return; - // If settings have changed, save the change. - if (!m_last_state.empty()) - { - if (m_last_state != save()) - { - m_parent->save_object_change(*this, m_last_state); - } - m_last_state.clear(); - } + // Save any option changes. + m_parent->save_object_change(*this, *m_last_state); + m_last_state.reset(); } void diff --git a/src/supertux/game_object.hpp b/src/supertux/game_object.hpp index e576d653c2d..7b4ce294ba5 100644 --- a/src/supertux/game_object.hpp +++ b/src/supertux/game_object.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "editor/object_settings.hpp" @@ -309,9 +310,9 @@ class GameObject : public ExposableClass /** this flag indicates if the object should be removed at the end of the frame */ bool m_scheduled_for_removal; - /** The object's data at the time of the last state save. + /** The object's settings at the time of the last state save. Used to check for changes that may have occured. */ - std::string m_last_state; + std::optional m_last_state; std::vector > m_components; diff --git a/src/supertux/game_object_change.cpp b/src/supertux/game_object_change.cpp new file mode 100644 index 00000000000..db0a3b184dc --- /dev/null +++ b/src/supertux/game_object_change.cpp @@ -0,0 +1,92 @@ +// SuperTux +// Copyright (C) 2024 Vankata453 +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "supertux/game_object_change.hpp" + +#include "util/log.hpp" +#include "util/reader_iterator.hpp" +#include "util/reader_mapping.hpp" +#include "util/writer.hpp" + +GameObjectChange::GameObjectChange(const std::string& name_, const UID& uid_, + const std::string& data_, const std::string& new_data_, + Action action_) : + name(name_), + uid(uid_), + data(data_), + new_data(new_data_), + action(action_) +{ +} + +GameObjectChange::GameObjectChange(const ReaderMapping& reader) : + name(), + uid(), + data(), + new_data(), + action() +{ + reader.get("name", name); + reader.get("uid", uid); + reader.get("data", data); + reader.get("action", reinterpret_cast(action)); +} + +void +GameObjectChange::save(Writer& writer) const +{ + writer.write("name", name); + writer.write("uid", uid); + writer.write("data", data); + writer.write("action", reinterpret_cast(action)); +} + + +GameObjectChangeSet::GameObjectChangeSet(const UID& uid_, std::vector changes_) : + uid(uid_), + changes(std::move(changes_)) +{ +} + +GameObjectChangeSet::GameObjectChangeSet(const ReaderMapping& reader) : + uid(), + changes() +{ + auto iter = reader.get_iter(); + while (iter.next()) + { + if (iter.get_key() != "object-change") + { + log_warning << "Unknown key '" << iter.get_key() << "' in GameObjectChanges data. Ignoring." << std::endl; + continue; + } + + changes.push_back(GameObjectChange(iter.as_mapping())); + } +} + +void +GameObjectChangeSet::save(Writer& writer) const +{ + for (const auto& change : changes) + { + writer.start_list("object-change"); + change.save(writer); + writer.end_list("object-change"); + } +} + +/* EOF */ diff --git a/src/supertux/game_object_change.hpp b/src/supertux/game_object_change.hpp new file mode 100644 index 00000000000..96624adf460 --- /dev/null +++ b/src/supertux/game_object_change.hpp @@ -0,0 +1,71 @@ +// SuperTux +// Copyright (C) 2024 Vankata453 +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef HEADER_SUPERTUX_SUPERTUX_GAME_OBJECT_CHANGE_HPP +#define HEADER_SUPERTUX_SUPERTUX_GAME_OBJECT_CHANGE_HPP + +#include +#include + +#include "util/uid.hpp" + +class ReaderMapping; +class Writer; + +/** Stores a change in a GameObject's state. */ +class GameObjectChange final +{ +public: + enum Action + { + ACTION_CREATE, + ACTION_DELETE, + ACTION_MODIFY + }; + +public: + GameObjectChange(const std::string& name, const UID& uid, + const std::string& data, const std::string& new_data, + Action action); + GameObjectChange(const ReaderMapping& reader); + + void save(Writer& writer) const; + +public: + std::string name; + UID uid; + std::string data; // Stores old data of changed object options + std::string new_data; // Stores new data of changed object options + Action action; // The action which triggered a state change +}; + +/** Stores multiple GameObjectChange-s. */ +class GameObjectChangeSet final +{ +public: + GameObjectChangeSet(const UID& uid, std::vector changes); + GameObjectChangeSet(const ReaderMapping& reader); + + void save(Writer& writer) const; + +public: + UID uid; + std::vector changes; +}; + +#endif + +/* EOF */ diff --git a/src/supertux/game_object_manager.cpp b/src/supertux/game_object_manager.cpp index 52d33a26af7..eecf558bd68 100644 --- a/src/supertux/game_object_manager.cpp +++ b/src/supertux/game_object_manager.cpp @@ -29,6 +29,9 @@ #include "object/tilemap.hpp" #include "supertux/game_object_factory.hpp" #include "supertux/moving_object.hpp" +#include "util/reader_document.hpp" +#include "util/reader_mapping.hpp" +#include "util/writer.hpp" bool GameObjectManager::s_draw_solids_only = false; @@ -283,7 +286,7 @@ GameObjectManager::flush_game_objects() // If object changes have been performed since last flush, push them to the undo stack. if (m_undo_tracking && !m_pending_change_stack.empty()) { - m_undo_stack.push_back({ m_change_uid_generator.next(), std::move(m_pending_change_stack) }); + m_undo_stack.emplace_back(m_change_uid_generator.next(), std::move(m_pending_change_stack)); m_redo_stack.clear(); undo_stack_cleanup(); } @@ -376,16 +379,93 @@ GameObjectManager::on_editor_save() m_last_saved_change = (m_undo_stack.empty() ? UID() : m_undo_stack.back().uid); } +void +GameObjectManager::apply_object_change(const GameObjectChange& change, bool track_undo) +{ + GameObject* object = get_object_by_uid(change.uid); + switch (change.action) + { + case GameObjectChange::ACTION_CREATE: + { + create_object_from_change(change, track_undo); + } + break; + + case GameObjectChange::ACTION_DELETE: + { + if (!object) + throw std::runtime_error("Object '" + change.name + "' does not exist."); + + object->m_track_undo = track_undo; + object->remove_me(); + } + break; + + case GameObjectChange::ACTION_MODIFY: + { + if (!object) + throw std::runtime_error("Object '" + change.name + "' does not exist."); + + auto settings = object->get_settings(); + if (track_undo) + settings.save_state(); + + parse_object_settings(settings, change.data); // Parse settings + object->after_editor_set(); + + if (track_undo) + save_object_change(*object, settings); + } + break; + + default: + break; + } +} + +void +GameObjectManager::apply_object_changes(const GameObjectChangeSet& change_set, bool track_undo) +{ + for (const auto& change : change_set.changes) + { + try + { + apply_object_change(change, track_undo); + } + catch (const std::exception& err) + { + log_warning << "Cannot process object state change for object with UID " + << change.uid << ": " << err.what() << std::endl; + } + } +} + void GameObjectManager::undo() { if (m_undo_stack.empty()) return; - ObjectChanges& changes = m_undo_stack.back(); + GameObjectChangeSet& change_set = m_undo_stack.back(); - for (auto& obj_change : changes.objects) - process_object_change(obj_change); + auto it = change_set.changes.begin(); + while (it != change_set.changes.end()) + { + try + { + process_object_change(*it); + it++; + } + catch (const std::exception& err) + { + log_warning << "Cannot process object change: " << err.what() << std::endl; + it = change_set.changes.erase(it); // Drop invalid changes + } + } - m_redo_stack.push_back(std::move(changes)); + if (!change_set.changes.empty()) + { + // Changes have been reversed for redo + m_redo_stack.push_back(std::move(change_set)); + } m_undo_stack.pop_back(); } @@ -393,62 +473,139 @@ void GameObjectManager::redo() { if (m_redo_stack.empty()) return; - ObjectChanges& changes = m_redo_stack.back(); + GameObjectChangeSet& change_set = m_redo_stack.back(); - for (auto& obj_change : changes.objects) - process_object_change(obj_change); + auto it = change_set.changes.begin(); + while (it != change_set.changes.end()) + { + try + { + process_object_change(*it); + it++; + } + catch (const std::exception& err) + { + log_warning << "Cannot process object change: " << err.what() << std::endl; + it = change_set.changes.erase(it); // Drop invalid changes + } + } - m_undo_stack.push_back(std::move(changes)); + if (!change_set.changes.empty()) + { + // Changes have been reversed for undo + m_undo_stack.push_back(std::move(change_set)); + } m_redo_stack.pop_back(); } void -GameObjectManager::create_object_from_change(const ObjectChange& change) +GameObjectManager::create_object_from_change(const GameObjectChange& change, bool track_undo) { auto object = GameObjectFactory::instance().create(change.name, change.data); - object->m_track_undo = false; + object->m_track_undo = track_undo; object->set_uid(change.uid); object->after_editor_set(); add_object(std::move(object)); } void -GameObjectManager::process_object_change(ObjectChange& change) +GameObjectManager::parse_object_settings(ObjectSettings& settings, const std::string& data) +{ + std::istringstream stream(data); + auto doc = ReaderDocument::from_stream(stream); + auto root = doc.get_root(); + if (root.get_name() != "supertux-game-object") + throw std::runtime_error("Data is not 'supertux-game-object'."); + + settings.parse_state(root.get_mapping()); +} + +std::string +GameObjectManager::save_object_settings_state(const ObjectSettings& settings, bool new_state) +{ + std::ostringstream stream; + Writer writer(stream); + + writer.start_list("supertux-game-object"); + if (new_state) + settings.save_new_state(writer); + else + settings.save_old_state(stream); + writer.end_list("supertux-game-object"); + + return stream.str(); +} + +void +GameObjectManager::process_object_change(GameObjectChange& change) { GameObject* object = get_object_by_uid(change.uid); - if (object) // Object exists, remove it. + switch (change.action) { - object->m_track_undo = false; - object->remove_me(); + case GameObjectChange::ACTION_CREATE: /** Object was added, remove it. */ + { + if (!object) + throw std::runtime_error("Object '" + change.name + "' no longer exists."); - const std::string data = object->save(); + object->m_track_undo = false; + object->remove_me(); - // If settings have changed, re-create object with old settings. - if (!change.creation && change.data != data) - create_object_from_change(change); + // Prepare for redo + change.data = object->save(); + change.action = GameObjectChange::ACTION_DELETE; + } + break; - change.data = std::move(data); - } - else // Object doesn't exist, create it. - { - create_object_from_change(change); + case GameObjectChange::ACTION_DELETE: /** Object was deleted, create it. */ + { + create_object_from_change(change, false); + + // Prepare for redo + change.action = GameObjectChange::ACTION_CREATE; + } + break; + + case GameObjectChange::ACTION_MODIFY: /** Object was modified, revert settings. */ + { + if (!object) + throw std::runtime_error("Object '" + change.name + "' no longer exists."); + + auto settings = object->get_settings(); + settings.save_state(); + + parse_object_settings(settings, change.data); // Parse old settings + object->after_editor_set(); + + // Prepare for redo + change.data = save_object_settings_state(settings, false); + change.new_data = save_object_settings_state(settings, true); + } + break; + + default: + break; } } void -GameObjectManager::save_object_change(GameObject& object, bool creation) +GameObjectManager::save_object_state(GameObject& object, GameObjectChange::Action action) { - if (m_undo_tracking && object.track_state() && object.m_track_undo) - m_pending_change_stack.push_back({ object.get_class_name(), object.get_uid(), object.save(), creation }); + if (object.track_state() && object.m_track_undo) + m_pending_change_stack.push_back({ object.get_class_name(), object.get_uid(), + object.save(), "", action }); object.m_track_undo = true; } void -GameObjectManager::save_object_change(GameObject& object, const std::string& data) +GameObjectManager::save_object_change(const GameObject& object, const ObjectSettings& settings) { - if (m_undo_tracking) - m_pending_change_stack.push_back({ object.get_class_name(), object.get_uid(), data, false }); + if (!settings.has_state_changed()) return; + + m_pending_change_stack.push_back({ object.get_class_name(), object.get_uid(), + save_object_settings_state(settings, false), + save_object_settings_state(settings, true), + GameObjectChange::ACTION_MODIFY }); } void @@ -489,13 +646,13 @@ GameObjectManager::this_before_object_add(GameObject& object) } } - save_object_change(object, true); + save_object_state(object, GameObjectChange::ACTION_CREATE); } void GameObjectManager::this_before_object_remove(GameObject& object) { - save_object_change(object); + save_object_state(object, GameObjectChange::ACTION_DELETE); { // By name: const std::string& name = object.get_name(); diff --git a/src/supertux/game_object_manager.hpp b/src/supertux/game_object_manager.hpp index 07a79f77dba..e6da628f6aa 100644 --- a/src/supertux/game_object_manager.hpp +++ b/src/supertux/game_object_manager.hpp @@ -28,6 +28,7 @@ #include #include "supertux/game_object.hpp" +#include "supertux/game_object_change.hpp" #include "util/uid_generator.hpp" class DrawingContext; @@ -273,14 +274,19 @@ class GameObjectManager : public ExposableClass void undo(); void redo(); - /** Save object change in the undo stack with given data. + /** Apply saved object changes. */ + void apply_object_change(const GameObjectChange& change, bool track_undo); + void apply_object_changes(const GameObjectChangeSet& changes, bool track_undo); + + /** Save object settings changes in the undo stack. Used to save an object's previous state before a change had occurred. */ - void save_object_change(GameObject& object, const std::string& data); + void save_object_change(const GameObject& object, const ObjectSettings& settings); /** Clear undo/redo stacks. */ void clear_undo_stack(); - /** Indicate if there are any object changes in the undo stack. */ + /** Indicate if there are any unsaved object changes in the undo stack. + @see m_last_saved_change */ bool has_object_changes() const; /** Called on editor level save. */ @@ -311,27 +317,20 @@ class GameObjectManager : public ExposableClass } private: - struct ObjectChange - { - std::string name; - UID uid; - std::string data; - bool creation; // If the change represents an object creation. - }; - struct ObjectChanges - { - UID uid; - std::vector objects; - }; - /** Create object from object change. */ - void create_object_from_change(const ObjectChange& change); + void create_object_from_change(const GameObjectChange& change, bool track_undo); + + /** Parse object settings ("supertux-game-object") from a string. */ + static void parse_object_settings(ObjectSettings& settings, const std::string& data); + + /** Save old or new state of object settings. */ + static std::string save_object_settings_state(const ObjectSettings& settings, bool new_state); - /** Process object change on undo/redo. */ - void process_object_change(ObjectChange& change); + /** Undo/redo object change. */ + void process_object_change(GameObjectChange& change); - /** Save object change in the undo stack. */ - void save_object_change(GameObject& object, bool creation = false); + /** Save object state in the undo stack. */ + void save_object_state(GameObject& object, GameObjectChange::Action action); void this_before_object_add(GameObject& object); void this_before_object_remove(GameObject& object); @@ -347,9 +346,9 @@ class GameObjectManager : public ExposableClass UIDGenerator m_change_uid_generator; bool m_undo_tracking; int m_undo_stack_size; - std::vector m_undo_stack; - std::vector m_redo_stack; - std::vector m_pending_change_stack; // Before a flush, any changes go here + std::vector m_undo_stack; + std::vector m_redo_stack; + std::vector m_pending_change_stack; // Before a flush, any changes go here UID m_last_saved_change; std::vector> m_gameobjects; diff --git a/src/supertux/gameconfig.cpp b/src/supertux/gameconfig.cpp index 810b8ef025f..67a443eb1c2 100644 --- a/src/supertux/gameconfig.cpp +++ b/src/supertux/gameconfig.cpp @@ -35,6 +35,7 @@ #endif Config::Config() : + m_initial(true), profile(1), fullscreen_size(0, 0), fullscreen_refresh_rate(0), @@ -78,11 +79,8 @@ Config::Config() : confirmation_dialog(false), pause_on_focusloss(true), custom_mouse_cursor(true), -#ifdef __EMSCRIPTEN__ do_release_check(false), -#else - do_release_check(true), -#endif + disable_network(true), custom_title_levels(true), #ifdef ENABLE_DISCORD enable_discord(false), @@ -155,6 +153,7 @@ Config::load() config_mapping.get("pause_on_focusloss", pause_on_focusloss); config_mapping.get("custom_mouse_cursor", custom_mouse_cursor); config_mapping.get("do_release_check", do_release_check); + config_mapping.get("disable_network", disable_network); config_mapping.get("custom_title_levels", custom_title_levels); std::optional config_integrations_mapping; @@ -351,6 +350,7 @@ Config::load() } check_values(); + m_initial = false; } void @@ -374,6 +374,7 @@ Config::save() writer.write("pause_on_focusloss", pause_on_focusloss); writer.write("custom_mouse_cursor", custom_mouse_cursor); writer.write("do_release_check", do_release_check); + writer.write("disable_network", disable_network); writer.write("custom_title_levels", custom_title_levels); writer.start_list("integrations"); diff --git a/src/supertux/gameconfig.hpp b/src/supertux/gameconfig.hpp index 97cde1e6491..a726247e484 100644 --- a/src/supertux/gameconfig.hpp +++ b/src/supertux/gameconfig.hpp @@ -36,6 +36,11 @@ class Config final void check_values(); + bool is_initial() const { return m_initial; } + +private: + bool m_initial; + public: int profile; @@ -108,6 +113,7 @@ class Config final bool pause_on_focusloss; bool custom_mouse_cursor; bool do_release_check; + bool disable_network; bool custom_title_levels; #ifdef ENABLE_DISCORD diff --git a/src/supertux/main.cpp b/src/supertux/main.cpp index d89cf671757..6c814866696 100644 --- a/src/supertux/main.cpp +++ b/src/supertux/main.cpp @@ -771,6 +771,9 @@ Main::run(int argc, char** argv) void Main::release_check() { + if (g_config->disable_network) + return; + // Detect a potential new release of SuperTux. If a release, other than // the current one is indicated on the given web file, show a notification on the main menu screen. const std::string target_file = "ver_info.nfo"; diff --git a/src/supertux/menu/addon_menu.cpp b/src/supertux/menu/addon_menu.cpp index da4a532262a..565df572eba 100644 --- a/src/supertux/menu/addon_menu.cpp +++ b/src/supertux/menu/addon_menu.cpp @@ -23,6 +23,8 @@ #include "gui/dialog.hpp" #include "gui/menu_item.hpp" #include "gui/menu_manager.hpp" +#include "supertux/gameconfig.hpp" +#include "supertux/globals.hpp" #include "supertux/menu/addon_browse_menu.hpp" #include "supertux/menu/addon_file_install_menu.hpp" #include "supertux/menu/addon_preview_menu.hpp" @@ -169,7 +171,10 @@ AddonMenu::menu_action(MenuItem& item) } else if (index == MNID_BROWSE) { - MenuManager::instance().push_menu(std::make_unique(m_langpacks_only, false)); + if (g_config->disable_network) + Dialog::show_message(_("To browse through the add-on catalog, you must enable networking.")); + else + MenuManager::instance().push_menu(std::make_unique(m_langpacks_only, false)); } else if (index == MNID_INSTALL_FROM_FILE) { @@ -202,17 +207,23 @@ AddonMenu::menu_action(MenuItem& item) void AddonMenu::check_for_updates() { + if (g_config->disable_network) + { + Dialog::show_message(_("To check for add-on updates, you must enable networking.")); + return; + } + try { TransferStatusPtr status = m_addon_manager.request_check_online(); + auto dialog = std::make_unique(status, false); + dialog->set_title(_("Checking for updates...")); + MenuManager::instance().set_dialog(std::move(dialog)); status->then([this](bool success) { if (success) refresh(); set_active_item(MNID_CHECK_ONLINE); }); - auto dialog = std::make_unique(status, false); - dialog->set_title(_("Checking for updates...")); - MenuManager::instance().set_dialog(std::move(dialog)); } catch (std::exception& e) { diff --git a/src/supertux/menu/addon_preview_menu.cpp b/src/supertux/menu/addon_preview_menu.cpp index 80aefba86bc..ac5fae61ae3 100644 --- a/src/supertux/menu/addon_preview_menu.cpp +++ b/src/supertux/menu/addon_preview_menu.cpp @@ -22,6 +22,8 @@ #include "addon/addon_manager.hpp" #include "gui/menu_item.hpp" #include "gui/menu_manager.hpp" +#include "supertux/gameconfig.hpp" +#include "supertux/globals.hpp" #include "supertux/menu/download_dialog.hpp" #include "supertux/resources.hpp" #include "util/log.hpp" @@ -147,6 +149,10 @@ AddonPreviewMenu::rebuild_menu() add_inactive(_("Failed to load all available screenshot previews.")); } } + else if (g_config->disable_network) + { + add_inactive(_("To fetch add-on screenshots, you must enable networking.")); + } else { const std::string show_screenshots_text = _("Show screenshots"); diff --git a/src/supertux/menu/debug_menu.cpp b/src/supertux/menu/debug_menu.cpp index 1461c19bb13..86447ec09ff 100644 --- a/src/supertux/menu/debug_menu.cpp +++ b/src/supertux/menu/debug_menu.cpp @@ -20,10 +20,14 @@ #include #include "editor/editor.hpp" +#include "gui/item_action.hpp" #include "gui/item_stringselect.hpp" +#include "sprite/sprite_manager.hpp" #include "supertux/debug.hpp" #include "supertux/gameconfig.hpp" #include "supertux/globals.hpp" +#include "supertux/resources.hpp" +#include "supertux/tile_manager.hpp" #include "util/gettext.hpp" #include "util/log.hpp" #include "video/texture_manager.hpp" @@ -72,6 +76,16 @@ DebugMenu::DebugMenu() : []{ return g_debug.get_use_bitmap_fonts(); }, [](bool value){ g_debug.set_use_bitmap_fonts(value); }); add_toggle(-1, _("Show Tile IDs in Editor Toolbox"), &g_debug.show_toolbox_tile_ids); + + add_entry(_("Reload Resources"), []{ + TextureManager::current()->reload(); + + Resources::load(true); + SpriteManager::current()->reload(); + TileManager::current()->reload(); + }) + .set_help(_("Reloads all fonts, textures, sprites and tilesets.")); + add_entry(_("Dump Texture Cache"), []{ TextureManager::current()->debug_print(get_logging_instance()); }); add_hl(); diff --git a/src/supertux/menu/main_menu.cpp b/src/supertux/menu/main_menu.cpp index 7c08e21e057..e011d2a88c8 100644 --- a/src/supertux/menu/main_menu.cpp +++ b/src/supertux/menu/main_menu.cpp @@ -22,6 +22,7 @@ #include "gui/menu_item.hpp" #include "gui/menu_manager.hpp" #include "supertux/fadetoblack.hpp" +#include "supertux/gameconfig.hpp" #include "supertux/globals.hpp" #include "supertux/level.hpp" #include "supertux/level_parser.hpp" @@ -68,6 +69,24 @@ MainMenu::MainMenu() #endif on_window_resize(); + +#ifndef __EMSCRIPTEN__ + // Show network-related confirmation dialogs on first startup + if (g_config->is_initial()) + { + Dialog::show_confirmation(_("Would you allow SuperTux to connect to the Internet?\n\nThis enables additional features, such as the in-game add-on catalog."), + []() + { + g_config->disable_network = false; + + Dialog::show_confirmation(_("Would you allow SuperTux to check for new releases on startup?\n\nYou will be notified if any are found."), + []() + { + g_config->do_release_check = true; + }); + }, true); + } +#endif } void diff --git a/src/supertux/menu/options_menu.cpp b/src/supertux/menu/options_menu.cpp index 9d120d7bc57..f8e3e3d8f9e 100644 --- a/src/supertux/menu/options_menu.cpp +++ b/src/supertux/menu/options_menu.cpp @@ -56,6 +56,8 @@ OptionsMenu::less_than_volume(const std::string& lhs, const std::string& rhs) } OptionsMenu::OptionsMenu(Type type, bool complete) : + m_type(type), + m_complete(complete), m_magnifications(), m_aspect_ratios(), m_window_resolutions(), @@ -66,13 +68,21 @@ OptionsMenu::OptionsMenu(Type type, bool complete) : m_flash_intensity_values(), m_mobile_control_scales() { - switch (type) // Insert label and menu items, appropriate for the chosen OptionsMenu type + refresh(); +} + +void +OptionsMenu::refresh() +{ + clear(); + + switch (m_type) // Insert label and menu items, appropriate for the chosen OptionsMenu type { case LOCALE: /** LOCALE */ { insert_label(_("Locale")); - if (complete) + if (m_complete) { add_submenu(_("Select Language"), MenuStorage::LANGUAGE_MENU) .set_help(_("Select a different language to display text in")); @@ -174,7 +184,7 @@ OptionsMenu::OptionsMenu(Type type, bool complete) : { insert_label(_("Extras")); - if (complete) + if (m_complete) add_submenu(_("Select Profile"), MenuStorage::PROFILE_MENU) .set_help(_("Select a profile to play with")); @@ -219,8 +229,12 @@ OptionsMenu::OptionsMenu(Type type, bool complete) : add_toggle(MNID_CUSTOM_CURSOR, _("Use custom mouse cursor"), &g_config->custom_mouse_cursor).set_help(_("Whether the game renders its own cursor or uses the system's cursor")); #ifndef __EMSCRIPTEN__ - add_toggle(MNID_RELEASE_CHECK, _("Check for new releases"), &g_config->do_release_check) - .set_help(_("Allows the game to perform checks for new SuperTux releases on startup and notify if any found.")); + if (!g_config->disable_network) + add_toggle(MNID_RELEASE_CHECK, _("Check for new releases"), &g_config->do_release_check) + .set_help(_("Allows the game to perform checks for new SuperTux releases on startup and notify if any found.")); + + add_toggle(MNID_DISABLE_NETWORK, _("Disable network"), &g_config->disable_network) + .set_help(_("Prevents the game from connecting online")); #endif break; @@ -767,6 +781,11 @@ OptionsMenu::menu_action(MenuItem& item) g_config->m_mobile_controls_scale /= 100.0f; break; + case MNID_DISABLE_NETWORK: + refresh(); + set_active_item(MNID_DISABLE_NETWORK); + break; + default: break; } diff --git a/src/supertux/menu/options_menu.hpp b/src/supertux/menu/options_menu.hpp index 703f7120236..d1c07baccb4 100644 --- a/src/supertux/menu/options_menu.hpp +++ b/src/supertux/menu/options_menu.hpp @@ -39,6 +39,7 @@ class OptionsMenu final : public Menu OptionsMenu(Type type, bool complete); ~OptionsMenu() override; + void refresh() override; void on_window_resize() override; void menu_action(MenuItem& item) override; @@ -81,6 +82,7 @@ class OptionsMenu final : public Menu MNID_PAUSE_ON_FOCUSLOSS, MNID_CUSTOM_CURSOR, MNID_RELEASE_CHECK, + MNID_DISABLE_NETWORK, MNID_MOBILE_CONTROLS, MNID_MOBILE_CONTROLS_SCALE }; @@ -92,6 +94,9 @@ class OptionsMenu final : public Menu }; private: + const Type m_type; + const bool m_complete; + StringOption m_magnifications; StringOption m_aspect_ratios; StringOption m_window_resolutions; diff --git a/src/supertux/resources.cpp b/src/supertux/resources.cpp index 18f779888ed..ce05b971234 100644 --- a/src/supertux/resources.cpp +++ b/src/supertux/resources.cpp @@ -27,6 +27,7 @@ #include "video/font.hpp" #include "video/surface.hpp" #include "video/ttf_font.hpp" +#include "video/ttf_surface_manager.hpp" std::unique_ptr Resources::mouse_cursor; @@ -48,7 +49,7 @@ SurfacePtr Resources::no_tile; std::string Resources::current_font; void -Resources::load() +Resources::load(bool reload) { // Load the mouse-cursor mouse_cursor.reset(new MouseCursor(SpriteManager::current()->create("images/engine/menu/mousecursor.sprite"))); @@ -69,7 +70,7 @@ Resources::load() console_font.reset(new TTFFont("fonts/SourceCodePro-Medium.ttf", 12, 1.25f, 0, 1)); auto font = get_font_for_locale(g_dictionary_manager->get_language()); - if(font != current_font) + if(reload || font != current_font) { current_font = font; fixed_font.reset(new TTFFont(font, 18, 1.25f, 2, 1)); @@ -79,6 +80,7 @@ Resources::load() control_font.reset(new TTFFont("fonts/Roboto-Regular.ttf", 15, 1.25f, 0, 0)); } } + TTFSurfaceManager::current()->clear_cache(); /* Load menu images */ checkbox = Surface::from_file("images/engine/menu/checkbox-unchecked.png"); diff --git a/src/supertux/resources.hpp b/src/supertux/resources.hpp index 509717493dc..27e38e6fae8 100644 --- a/src/supertux/resources.hpp +++ b/src/supertux/resources.hpp @@ -62,7 +62,7 @@ class Resources final static SurfacePtr no_tile; public: - static void load(); + static void load(bool reload = false); static void unload(); static bool needs_custom_font(const tinygettext::Language& locale); static std::string get_font_for_locale(const tinygettext::Language& locale); diff --git a/src/supertux/screen_manager.cpp b/src/supertux/screen_manager.cpp index 1343af44ace..e53cfcbfdc8 100644 --- a/src/supertux/screen_manager.cpp +++ b/src/supertux/screen_manager.cpp @@ -137,10 +137,9 @@ ScreenManager::ScreenManager(VideoSystem& video_system, InputManager& input_mana m_menu_manager(new MenuManager()), m_controller_hud(new ControllerHUD), m_mobile_controller(), - last_ticks(0), - elapsed_ticks(0), - ms_per_step(static_cast(1000.0f / LOGICAL_FPS)), - seconds_per_step(static_cast(ms_per_step) / 1000.0f), + last_time(std::chrono::steady_clock::now()), + elapsed_time(0.0f), + seconds_per_step(1.0f / LOGICAL_FPS), m_fps_statistics(new FPS_Stats()), m_speed(1.0), m_actions(), @@ -563,23 +562,25 @@ ScreenManager::handle_screen_switch() void ScreenManager::loop_iter() { - Uint32 ticks = SDL_GetTicks(); - elapsed_ticks += ticks - last_ticks; - last_ticks = ticks; + auto now = std::chrono::steady_clock::now(); + auto nsecs = std::chrono::duration_cast(now - last_time).count(); + elapsed_time += 1e-9f * static_cast(nsecs); + g_real_time += 1e-9f * static_cast(nsecs); + last_time = now; - if (elapsed_ticks > ms_per_step * 8) { + if (elapsed_time > seconds_per_step * 8) { // when the game loads up or levels are switched the // elapsed_ticks grows extremely large, so we just ignore those // large time jumps - elapsed_ticks = 0; + elapsed_time = 0; } bool always_draw = g_debug.draw_redundant_frames || g_config->frame_prediction; - if (elapsed_ticks < ms_per_step && !always_draw) { + if (elapsed_time < seconds_per_step && !always_draw) { // Sleep a bit because not enough time has passed since the previous // logical game step - SDL_Delay(ms_per_step - elapsed_ticks); + SDL_Delay(static_cast(1000.0f * (seconds_per_step - elapsed_time))); return; } @@ -587,10 +588,8 @@ void ScreenManager::loop_iter() Integration::update_status_all(m_screen_stack.back()->get_status()); Integration::update_all(); - g_real_time = static_cast(ticks) / 1000.0f; - float speed_multiplier = g_debug.get_game_speed_multiplier(); - int steps = elapsed_ticks / ms_per_step; + int steps = static_cast(std::floor(elapsed_time / seconds_per_step)); // Do not calculate more than a few steps at once // The maximum number of steps executed before drawing a frame is @@ -624,14 +623,13 @@ void ScreenManager::loop_iter() g_game_time += dtime; process_events(); update_gamelogic(dtime); - elapsed_ticks -= ms_per_step; + elapsed_time -= seconds_per_step; } // When the game is laggy, real time may be >1 step after the game time // To avoid predicting positions too far ahead, when using frame prediction, // limit the draw time offset to at most one step. - Uint32 tick_offset = std::min(elapsed_ticks, ms_per_step); - float time_offset = m_speed * speed_multiplier * static_cast(tick_offset) / 1000.0f; + float time_offset = m_speed * speed_multiplier * std::min(elapsed_time, seconds_per_step); if ((steps > 0 && !m_screen_stack.empty()) || always_draw) { diff --git a/src/supertux/screen_manager.hpp b/src/supertux/screen_manager.hpp index b2e7ab46fad..1b1de08c359 100644 --- a/src/supertux/screen_manager.hpp +++ b/src/supertux/screen_manager.hpp @@ -18,6 +18,7 @@ #ifndef HEADER_SUPERTUX_SUPERTUX_SCREEN_MANAGER_HPP #define HEADER_SUPERTUX_SUPERTUX_SCREEN_MANAGER_HPP +#include #include #include @@ -80,9 +81,8 @@ class ScreenManager final : public Currenton std::unique_ptr m_controller_hud; MobileController m_mobile_controller; - Uint32 last_ticks; - Uint32 elapsed_ticks; - const Uint32 ms_per_step; + std::chrono::steady_clock::time_point last_time; + float elapsed_time; const float seconds_per_step; std::unique_ptr m_fps_statistics; diff --git a/src/supertux/tile_manager.cpp b/src/supertux/tile_manager.cpp index 0b9bd685015..8d710da28b7 100644 --- a/src/supertux/tile_manager.cpp +++ b/src/supertux/tile_manager.cpp @@ -42,4 +42,11 @@ TileManager::get_tileset(const std::string &filename) } } +void +TileManager::reload() +{ + for (const auto& tileset : m_tilesets) + tileset.second->reload(); +} + /* EOF */ diff --git a/src/supertux/tile_manager.hpp b/src/supertux/tile_manager.hpp index 0b6cc54de5d..b93bc5d75bd 100644 --- a/src/supertux/tile_manager.hpp +++ b/src/supertux/tile_manager.hpp @@ -28,12 +28,18 @@ class TileSet; class TileManager final : public Currenton { private: - std::map > m_tilesets; + std::map> m_tilesets; public: TileManager(); TileSet* get_tileset(const std::string &filename); + + void reload(); + +private: + TileManager(const TileManager&) = delete; + TileManager& operator=(const TileManager&) = delete; }; #endif diff --git a/src/supertux/tile_set.cpp b/src/supertux/tile_set.cpp index 7d2b8b16e67..bc02481bcc2 100644 --- a/src/supertux/tile_set.cpp +++ b/src/supertux/tile_set.cpp @@ -36,17 +36,18 @@ Tilegroup::Tilegroup() : std::unique_ptr TileSet::from_file(const std::string& filename) { - auto tileset = std::make_unique(); + auto tileset = std::make_unique(filename); TileSetParser parser(*tileset, filename); parser.parse(); - tileset->print_debug_info(filename); + tileset->print_debug_info(); return tileset; } -TileSet::TileSet() : +TileSet::TileSet(const std::string& filename) : + m_filename(filename), m_autotilesets(), m_thunderstorm_tiles(), m_tiles(1), @@ -55,6 +56,18 @@ TileSet::TileSet() : m_tiles[0] = std::make_unique(); } +void +TileSet::reload() +{ + m_autotilesets.clear(); + m_thunderstorm_tiles.clear(); + m_tiles.resize(1); // Preserve only the initial tile with an ID of 0 + m_tilegroups.clear(); + + TileSetParser parser(*this, m_filename); + parser.parse(); +} + void TileSet::add_tile(int id, std::unique_ptr tile) { @@ -87,22 +100,35 @@ TileSet::get(const uint32_t id) const } } -AutotileSet* -TileSet::get_autotileset_from_tile(uint32_t tile_id) const +std::vector +TileSet::get_autotilesets_from_tile(uint32_t tile_id) const { if (tile_id == 0) { - return nullptr; + return {}; } + std::vector autotilesets; for (auto& ats : m_autotilesets) { if (ats->is_member(tile_id)) - { - return ats.get(); - } + autotilesets.push_back(ats.get()); + } + return autotilesets; +} + +bool +TileSet::has_mutual_autotileset(uint32_t lhs, uint32_t rhs) const +{ + if (lhs == rhs) + return true; + + for (const auto& autotileset : m_autotilesets) + { + if (autotileset->is_member(lhs) && autotileset->is_member(rhs)) + return true; } - return nullptr; + return false; } void @@ -168,7 +194,7 @@ TileSet::add_tilegroup(const Tilegroup& tilegroup) } void -TileSet::print_debug_info(const std::string& filename) +TileSet::print_debug_info() { if (false) { // enable this if you want to see a list of free tiles diff --git a/src/supertux/tile_set.hpp b/src/supertux/tile_set.hpp index 8335e098db3..9a1bbc78456 100644 --- a/src/supertux/tile_set.hpp +++ b/src/supertux/tile_set.hpp @@ -47,9 +47,11 @@ class TileSet final static std::unique_ptr from_file(const std::string& filename); public: - TileSet(); + TileSet(const std::string& filename); ~TileSet() = default; + void reload(); + void add_tile(int id, std::unique_ptr tile); /** Adds a group of tiles that haven't @@ -63,7 +65,8 @@ class TileSet final const Tile& get(const uint32_t id) const; - AutotileSet* get_autotileset_from_tile(uint32_t tile_id) const; + std::vector get_autotilesets_from_tile(uint32_t tile_id) const; + bool has_mutual_autotileset(uint32_t lhs, uint32_t rhs) const; uint32_t get_max_tileid() const { return static_cast(m_tiles.size()); @@ -73,8 +76,11 @@ class TileSet final return m_tilegroups; } - void print_debug_info(const std::string& filename); + void print_debug_info(); +private: + const std::string m_filename; + public: // Must be public because of tile_set_parser.cpp std::vector> m_autotilesets; diff --git a/src/trigger/door.cpp b/src/trigger/door.cpp index 5b8e956d0dd..c35136be8f6 100644 --- a/src/trigger/door.cpp +++ b/src/trigger/door.cpp @@ -169,7 +169,7 @@ Door::draw(DrawingContext& context) Vector shake_delta = Vector(static_cast(graphicsRandom.rand(-8, 8)), static_cast(graphicsRandom.rand(-8, 8))); float shake_strength = m_lock_warn_timer.started() ? m_lock_warn_timer.get_timeleft() : 0.f; m_lock_sprite->draw(context.color(), get_bbox().get_middle() - - (Vector(m_lock_sprite->get_width() / 2, m_lock_sprite->get_height() / 2) + (shake_delta*shake_strength)), LAYER_BACKGROUNDTILES + 1, m_flip); + (Vector(m_lock_sprite->get_width() / 2, m_lock_sprite->get_height() / 2) + (shake_delta*shake_strength)), m_layer, m_flip); } } diff --git a/src/util/colorspace_oklab.cpp b/src/util/colorspace_oklab.cpp index ffc17375a89..e7e35af8b24 100644 --- a/src/util/colorspace_oklab.cpp +++ b/src/util/colorspace_oklab.cpp @@ -40,16 +40,8 @@ namespace { struct ColorRGB { float r, g, b; - bool is_valid() const; }; -bool -ColorRGB::is_valid() const -{ - return r >= 0.0f && r <= 1.0f && g >= 0.0f && g <= 1.0f - && b >= 0.0f && b <= 1.0f; -} - struct ColorOKLab { float L, a, b; }; @@ -65,24 +57,6 @@ ColorRGB srgb_to_linear_srgb(const Color& c) return {to_linear(c.red), to_linear(c.green), to_linear(c.blue)}; } -Color linear_srgb_to_srgb(const ColorRGB& c) -{ - auto make_nonlinear = [&](float channel) -> float { - if (channel <= 0.0031308f) - return 12.92f * channel; - else - return (1.0f + 0.055f) * powf(channel, 1.0f / 2.4f) - 0.055f; - }; - float r = make_nonlinear(c.r); - float g = make_nonlinear(c.g); - float b = make_nonlinear(c.b); - // The clamping here is only for safety against numerical precision errors. - // r, g and b should already be in [0,1] (at least approximately) - // since they were clipped in the OKLab colourspace. - return Color(math::clamp(r, 0.0f, 1.0f), math::clamp(g, 0.0f, 1.0f), - math::clamp(b, 0.0f, 1.0f)); -} - ColorOKLab linear_srgb_to_oklab(const ColorRGB& c) { float l = 0.4122214708f * c.r + 0.5363325363f * c.g + 0.0514459929f * c.b; @@ -100,215 +74,15 @@ ColorOKLab linear_srgb_to_oklab(const ColorRGB& c) }; } -ColorRGB oklab_to_linear_srgb(const ColorOKLab& c) -{ - float l_ = c.L + 0.3963377774f * c.a + 0.2158037573f * c.b; - float m_ = c.L - 0.1055613458f * c.a - 0.0638541728f * c.b; - float s_ = c.L - 0.0894841775f * c.a - 1.2914855480f * c.b; - - float l = l_*l_*l_; - float m = m_*m_*m_; - float s = s_*s_*s_; - - return { - +4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s, - -1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s, - -0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s, - }; -} - ColorOKLCh lab_to_lch(const ColorOKLab& c) { return ColorOKLCh{c.L, sqrtf(c.a * c.a + c.b * c.b), atan2f(c.b, c.a)}; } -ColorOKLab lch_to_lab(const ColorOKLCh& c) -{ - return {c.L, c.C * cosf(c.h), c.C * sinf(c.h)}; -} - -// Finds the maximum saturation possible for a given hue that fits in sRGB -// Saturation here is defined as S = C/L -// a and b must be normalized so a^2 + b^2 == 1. -float compute_max_saturation(float a, float b) -{ - // Max saturation will be when one of r, g or b goes below zero. - // Select different coefficients depending on which component goes below zero first. - float k0, k1, k2, k3, k4, wl, wm, ws; - - if (-1.88170328f * a - 0.80936493f * b > 1) - { - // Red component. - k0 = +1.19086277f; k1 = +1.76576728f; k2 = +0.59662641f; k3 = +0.75515197f; k4 = +0.56771245f; - wl = +4.0767416621f; wm = -3.3077115913f; ws = +0.2309699292f; - } - else if (1.81444104f * a - 1.19445276f * b > 1) - { - // Green component. - k0 = +0.73956515f; k1 = -0.45954404f; k2 = +0.08285427f; k3 = +0.12541070f; k4 = +0.14503204f; - wl = -1.2681437731f; wm = +2.6097574011f; ws = -0.3413193965f; - } - else - { - // Blue component. - k0 = +1.35733652f; k1 = -0.00915799f; k2 = -1.15130210f; k3 = -0.50559606f; k4 = +0.00692167f; - wl = -0.0041960863f; wm = -0.7034186147f; ws = +1.7076147010f; - } - - // Approximate max saturation using a polynomial: - float S = k0 + k1 * a + k2 * b + k3 * a * a + k4 * a * b; - - // Do one step Halley's method to get closer - // this gives an error less than 10e6, except for some blue hues where the dS/dh is close to infinite - // this should be sufficient for most applications, otherwise do two/three steps. - - float k_l = +0.3963377774f * a + 0.2158037573f * b; - float k_m = -0.1055613458f * a - 0.0638541728f * b; - float k_s = -0.0894841775f * a - 1.2914855480f * b; - - { - float l_ = 1.f + S * k_l; - float m_ = 1.f + S * k_m; - float s_ = 1.f + S * k_s; - - float l = l_ * l_ * l_; - float m = m_ * m_ * m_; - float s = s_ * s_ * s_; - - float l_dS = 3.f * k_l * l_ * l_; - float m_dS = 3.f * k_m * m_ * m_; - float s_dS = 3.f * k_s * s_ * s_; - - float l_dS2 = 6.f * k_l * k_l * l_; - float m_dS2 = 6.f * k_m * k_m * m_; - float s_dS2 = 6.f * k_s * k_s * s_; - - float f = wl * l + wm * m + ws * s; - float f1 = wl * l_dS + wm * m_dS + ws * s_dS; - float f2 = wl * l_dS2 + wm * m_dS2 + ws * s_dS2; - - S = S - f * f1 / (f1*f1 - 0.5f * f * f2); - } - - return S; -} - -// Finds L_cusp and C_cusp for a given hue -// a and b must be normalized so a^2 + b^2 == 1. -struct OKLabCusp { - float L, C; -}; -OKLabCusp find_cusp(float a, float b) -{ - // First, find the maximum saturation (saturation S = C/L). - float S_cusp = compute_max_saturation(a, b); - - // Convert to linear sRGB to find the first point where at least one of r,g or b >= 1: - ColorOKLab c = {1, S_cusp * a, S_cusp * b}; - ColorRGB rgb_at_max = oklab_to_linear_srgb(c); - float L_cusp = cbrtf(1.f / std::max(std::max(rgb_at_max.r, rgb_at_max.g), - rgb_at_max.b)); - float C_cusp = L_cusp * S_cusp; - - return {L_cusp , C_cusp}; -} - -// Finds intersection of the line defined by -// L = L0 * (1 - t) + t * L1; -// C = t * C1; -// a and b must be normalized so a^2 + b^2 == 1. -float find_gamut_intersection(float a, float b, float L1, float C1, float L0) -{ - // Find the cusp of the gamut triangle. - OKLabCusp cusp = find_cusp(a, b); - - // Find the intersection for upper and lower half seprately. - float t; - if (((L1 - L0) * cusp.C - (cusp.L - L0) * C1) <= 0.f) - { - // Lower half. - - t = cusp.C * L0 / (C1 * cusp.L + cusp.C * (L0 - L1)); - } - else - { - // Upper half. - - // First intersect with triangle. - t = cusp.C * (L0 - 1.f) / (C1 * (cusp.L - 1.f) + cusp.C * (L0 - L1)); - - // Then one step Halley's method. - { - float dL = L1 - L0; - float dC = C1; - - float k_l = +0.3963377774f * a + 0.2158037573f * b; - float k_m = -0.1055613458f * a - 0.0638541728f * b; - float k_s = -0.0894841775f * a - 1.2914855480f * b; - - float l_dt = dL + dC * k_l; - float m_dt = dL + dC * k_m; - float s_dt = dL + dC * k_s; - - - // If higher accuracy is required, 2 or 3 iterations of the following block can be used: - { - float L = L0 * (1.f - t) + t * L1; - float C = t * C1; - - float l_ = L + C * k_l; - float m_ = L + C * k_m; - float s_ = L + C * k_s; - - float l = l_ * l_ * l_; - float m = m_ * m_ * m_; - float s = s_ * s_ * s_; - - float ldt = 3 * l_dt * l_ * l_; - float mdt = 3 * m_dt * m_ * m_; - float sdt = 3 * s_dt * s_ * s_; - - float ldt2 = 6 * l_dt * l_dt * l_; - float mdt2 = 6 * m_dt * m_dt * m_; - float sdt2 = 6 * s_dt * s_dt * s_; - - float r = 4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s - 1; - float r1 = 4.0767416621f * ldt - 3.3077115913f * mdt + 0.2309699292f * sdt; - float r2 = 4.0767416621f * ldt2 - 3.3077115913f * mdt2 + 0.2309699292f * sdt2; - - float u_r = r1 / (r1 * r1 - 0.5f * r * r2); - float t_r = -r * u_r; - - float g = -1.2681437731f * l + 2.6097574011f * m - 0.3413193965f * s - 1; - float g1 = -1.2681437731f * ldt + 2.6097574011f * mdt - 0.3413193965f * sdt; - float g2 = -1.2681437731f * ldt2 + 2.6097574011f * mdt2 - 0.3413193965f * sdt2; - - float u_g = g1 / (g1 * g1 - 0.5f * g * g2); - float t_g = -g * u_g; - - b = -0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s - 1; - float b1 = -0.0041960863f * ldt - 0.7034186147f * mdt + 1.7076147010f * sdt; - float b2 = -0.0041960863f * ldt2 - 0.7034186147f * mdt2 + 1.7076147010f * sdt2; - - float u_b = b1 / (b1 * b1 - 0.5f * b * b2); - float t_b = -b * u_b; - - t_r = u_r >= 0.f ? t_r : FLT_MAX; - t_g = u_g >= 0.f ? t_g : FLT_MAX; - t_b = u_b >= 0.f ? t_b : FLT_MAX; - - t += std::min(t_r, std::min(t_g, t_b)); - } - } - } - - return t; -} - } // namespace -ColorOKLCh::ColorOKLCh(Color& c) : +ColorOKLCh::ColorOKLCh(const Color& c) : L(0.0f), C(0.0f), h(0.0f) @@ -317,119 +91,20 @@ ColorOKLCh::ColorOKLCh(Color& c) : ColorOKLab lab = linear_srgb_to_oklab(rgb); *this = lab_to_lch(lab); if (C < 0.00001f) - // Deterministic behaviour when increasing chroma of greyscale colours. + // Deterministic behaviour for greyscale colors h = 0.0f; } -Color -ColorOKLCh::to_srgb() const -{ - ColorOKLCh c = *this; - ColorOKLab lab = lch_to_lab(c); - ColorRGB rgb = oklab_to_linear_srgb(lab); - if (!rgb.is_valid()) { - c.clip_chroma(); - // Gamut clipping; reduce chroma when needed. - lab = lch_to_lab(c); - rgb = oklab_to_linear_srgb(lab); - } - if (!(rgb.r > -0.001f && rgb.r < 1.001f && rgb.g > -0.001f && rgb.g < 1.001f - && rgb.b > -0.001f && rgb.b < 1.001f)) { - log_warning << "Colour out of bounds (after clipping): (" << rgb.r << - ", " << rgb.g << ", " << rgb.b << ")" << std::endl; - } - return linear_srgb_to_srgb(rgb); -} - float -ColorOKLCh::get_maximum_chroma() const -{ - if (C <= 0.0f || L <= 0.0f || L >= 1.0f) - return 0.0f; - return find_gamut_intersection(cosf(h), sinf(h), L, 1.0f, L); -} - -float -ColorOKLCh::get_maximum_chroma_any_l() const -{ - OKLabCusp cusp = find_cusp(cosf(h), sinf(h)); - return cusp.C; -} - -void -ColorOKLCh::clip_chroma() -{ - // Avoid numerical problems for certain hues of blue. - if (-1.67462f < h && h < -1.67460f) - h = -1.67462f; - - L = math::clamp(L, 0.0f, 1.0f); - C = math::clamp(C, 0.0f, get_maximum_chroma()); -} - -void -ColorOKLCh::clip_lightness() -{ - // Avoid numerical problems for certain hues of blue. - if (-1.67462f < h && h < -1.67460f) - h = -1.67462f; - - L = math::clamp(L, 0.0f, 1.0f); - ColorOKLab lab = lch_to_lab(*this); - ColorRGB rgb = oklab_to_linear_srgb(lab); - if (rgb.is_valid()) - return; - - OKLabCusp cusp = find_cusp(lab.a / C, lab.b / C); - if (C >= cusp.C) { - // The cusp is the most colourful point for the given hue. - C = cusp.C; - L = cusp.L; - return; - } - // Select a point inside the triangle defined by (L,C) in {(0,0), (1,0), cusp} - // and then move it further if it's not in the sRGB gamut. - if (L > cusp.L) { - // Reduce L so that it's on the triangle. - L = std::min(L, 1.0f + C * (cusp.L - 1.0f) / cusp.C); - // Reduce L so that it's in the sRGB gamut. - float L0 = -100.0f; - float t = find_gamut_intersection(lab.a / C, lab.b / C, L, C, L0); - L = (1.0f - t) * L0 + t * L; - C *= t; - } else { - // Here the triangle is accurate. - L = std::max(L, C * cusp.L / cusp.C); - } -} - -void -ColorOKLCh::clip_adaptive_L0_L_cusp(float alpha) -{ - // Avoid numerical problems for certain hues of blue. - if (-1.67462f < h && h < -1.67460f) - h = -1.67462f; - - ColorOKLab lab = lch_to_lab(*this); - ColorRGB rgb = oklab_to_linear_srgb(lab); - if (rgb.is_valid()) - return; - - float a_ = lab.a / C; - float b_ = lab.b / C; - OKLabCusp cusp = find_cusp(a_, b_); - - float Ld = L - cusp.L; - float k = 2.f * (Ld > 0 ? 1.f - cusp.L : cusp.L); - - float e1 = 0.5f * k + fabsf(Ld) + alpha * C / k; - float sgn = Ld < 0.0f ? -1.0f : 1.0f; - float L0 = cusp.L + 0.5f * (sgn * (e1 - sqrtf( - std::max(e1 * e1 - 2.f * k * fabsf(Ld), 0.0f)))); - - float t = find_gamut_intersection(a_, b_, L, C, L0); - L = (1.0f - t) * L0 + t * L; - C *= t; +ColorOKLCh::get_modified_lightness() const +{ + // The formula is from + // https://bottosson.github.io/posts/colorpicker/#intermission---a-new-lightness-estimate-for-oklab + constexpr float k_1 = 0.206f; + constexpr float k_2 = 0.03f; + constexpr float k_3 = (1.f + k_1) / (1.f + k_2); + return 0.5f * (k_3 * L - k_1 + sqrtf((k_3 * L - k_1) * (k_3 * L - k_1) + + 4 * k_2 * k_3 * L)); } /* EOF */ diff --git a/src/util/colorspace_oklab.hpp b/src/util/colorspace_oklab.hpp index 5c1d215f10d..0d65be50997 100644 --- a/src/util/colorspace_oklab.hpp +++ b/src/util/colorspace_oklab.hpp @@ -18,6 +18,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +#ifndef HEADER_UTIL_COLORSPACE_OKLAB_HPP +#define HEADER_UTIL_COLORSPACE_OKLAB_HPP class Color; @@ -25,32 +27,14 @@ struct ColorOKLCh final { ColorOKLCh(float pL, float pC, float ph) : L(pL), C(pC), h(ph) {} // Convert an non-linear sRGB colour to OKLab's LCh - ColorOKLCh(Color& c); + ColorOKLCh(const Color& c); - // Convert to non-linear sRGB; clip_chroma is applied if required. - Color to_srgb() const; - - // Find the maximum chroma which is still representable in sRGB while the - // lightness and hue are preserved - float get_maximum_chroma() const; - - // Find the maximum chroma which is still representable in sRGB while the - // hue is preserved - float get_maximum_chroma_any_l() const; - - // Reduce the chroma so that the colour can be represented in sRGB. - // Also clamp the lightness if needed. - void clip_chroma(); - - // Change the lightness so that the colour can be represented in sRGB. - void clip_lightness(); - - // Changes both the lightness and chroma so that the colour can be represented - // in sRGB. The resulting colour should have less visual distance to the true - // colour than colour produced by clipping only chroma or lightness. - void clip_adaptive_L0_L_cusp(float alpha=0.05f); + // Calculate a different lightness estimate which has less dark values + float get_modified_lightness() const; float L, C, h; }; +#endif + /* EOF */ diff --git a/src/util/reader_mapping.cpp b/src/util/reader_mapping.cpp index 2534d14f0c7..a7bcef0200e 100644 --- a/src/util/reader_mapping.cpp +++ b/src/util/reader_mapping.cpp @@ -45,6 +45,9 @@ ReaderMapping::get_iter() const const sexp::Value* ReaderMapping::get_item(const char* key) const { + if (!key || !key[0]) // Check whether key is valid and non-empty + return nullptr; + for (size_t i = 1; i < m_arr.size(); ++i) { auto const& pair = m_arr[i]; @@ -95,6 +98,12 @@ ReaderMapping::get(const char* key, uint32_t& value, const std::optional& default_value) const +{ + GET_VALUE_MACRO("uint32_t", is_integer, as_int) +} + bool ReaderMapping::get(const char* key, float& value, const std::optional& default_value) const { @@ -146,6 +155,7 @@ ReaderMapping::get(const char* key, std::string& value, const std::optionalas_array(); \ for (size_t i = 1; i < item.size(); ++i) \ { \ @@ -159,7 +169,6 @@ bool ReaderMapping::get(const char* key, std::vector& value, const std::optional>& default_value) const { - value.clear(); GET_VALUES_MACRO("bool", is_boolean, as_bool) } @@ -167,7 +176,6 @@ bool ReaderMapping::get(const char* key, std::vector& value, const std::optional>& default_value) const { - value.clear(); GET_VALUES_MACRO("int", is_integer, as_int) } @@ -176,7 +184,6 @@ bool ReaderMapping::get(const char* key, std::vector& value, const std::optional>& default_value) const { - value.clear(); GET_VALUES_MACRO("float", is_real, as_float) } @@ -184,7 +191,6 @@ bool ReaderMapping::get(const char* key, std::vector& value, const std::optional>& default_value) const { - value.clear(); GET_VALUES_MACRO("string", is_string, as_string) } @@ -192,7 +198,6 @@ bool ReaderMapping::get(const char* key, std::vector& value, const std::optional>& default_value) const { - value.clear(); GET_VALUES_MACRO("unsigned int", is_integer, as_int) } diff --git a/src/util/reader_mapping.hpp b/src/util/reader_mapping.hpp index 186f544bb50..02a4af3d9aa 100644 --- a/src/util/reader_mapping.hpp +++ b/src/util/reader_mapping.hpp @@ -21,6 +21,7 @@ #include #include "util/reader_iterator.hpp" +#include "util/uid.hpp" namespace sexp { class Value; @@ -43,6 +44,7 @@ class ReaderMapping final bool get(const char* key, bool& value, const std::optional& default_value = std::nullopt) const; bool get(const char* key, int& value, const std::optional& default_value = std::nullopt) const; bool get(const char* key, uint32_t& value, const std::optional& default_value = std::nullopt) const; + bool get(const char* key, UID& value, const std::optional& default_value = std::nullopt) const; bool get(const char* key, float& value, const std::optional& default_value = std::nullopt) const; bool get(const char* key, std::string& value, const std::optional& default_value = std::nullopt) const; diff --git a/src/util/uid.hpp b/src/util/uid.hpp index c7c58d7a1bd..d043a8f590b 100644 --- a/src/util/uid.hpp +++ b/src/util/uid.hpp @@ -55,6 +55,11 @@ class UID UID(const UID& other) = default; UID& operator=(const UID& other) = default; + inline UID& operator=(uint32_t value) { + m_value = value; + return *this; + } + inline operator bool() const { return m_value != 0; } diff --git a/src/util/writer.cpp b/src/util/writer.cpp index b8dd33dad24..725afc9771e 100644 --- a/src/util/writer.cpp +++ b/src/util/writer.cpp @@ -104,6 +104,13 @@ Writer::write(const std::string& name, float value) *out << '(' << name << ' ' << value << ")\n"; } +void +Writer::write(const std::string& name, const UID& uid) +{ + indent(); + *out << '(' << name << ' ' << uid << ")\n"; +} + /** This function is needed to properly resolve the overloaded write() function, without it the call write("foo", "bar") would call write(name, bool), not write(name, string, bool) */ diff --git a/src/util/writer.hpp b/src/util/writer.hpp index e374b62b2c8..273bbd40aaa 100644 --- a/src/util/writer.hpp +++ b/src/util/writer.hpp @@ -20,6 +20,8 @@ #include #include +#include "util/uid.hpp" + namespace sexp { class Value; } // namespace sexp @@ -38,6 +40,7 @@ class Writer final void write(const std::string& name, bool value); void write(const std::string& name, int value); void write(const std::string& name, float value); + void write(const std::string& name, const UID& uid); void write(const std::string& name, const char* value); void write(const std::string& name, const std::string& value, bool translatable = false); void write(const std::string& name, const std::vector& value); diff --git a/src/video/canvas.cpp b/src/video/canvas.cpp index 1fe2bf91a49..e627a6ed886 100644 --- a/src/video/canvas.cpp +++ b/src/video/canvas.cpp @@ -17,6 +17,7 @@ #include "video/canvas.hpp" #include +#include #include "supertux/globals.hpp" #include "util/log.hpp" @@ -331,6 +332,26 @@ Canvas::draw_triangle(const Vector& pos1, const Vector& pos2, const Vector& pos3 m_requests.push_back(request); } +void +Canvas::draw_hexagon(const Vector& pos, float radius, const Color& color, + int layer) +{ + float radius2 = radius * sqrtf(0.8f); + float x_off_small = radius * sqrtf(0.2f); + std::array offsets{ + Vector(-x_off_small, -radius2), + Vector(x_off_small, -radius2), + Vector(-radius, 0), + Vector(radius, 0), + Vector(-x_off_small, radius2), + Vector(x_off_small, radius2), + }; + for (size_t i = 0; i < offsets.size() - 2; ++i) { + draw_triangle(pos + offsets[i], pos + offsets[i + 1], pos + offsets[i + 2], + color, layer); + } +} + void Canvas::get_pixel(const Vector& position, const std::shared_ptr& color_out) { diff --git a/src/video/canvas.hpp b/src/video/canvas.hpp index cdccdd884f7..aee91aa2489 100644 --- a/src/video/canvas.hpp +++ b/src/video/canvas.hpp @@ -82,6 +82,16 @@ class Canvas final void draw_line(const Vector& pos1, const Vector& pos2, const Color& color, int layer); void draw_triangle(const Vector& pos1, const Vector& pos2, const Vector& pos3, const Color& color, int layer); + /** Draw a flat-topped regular hexagon + * + * @param pos Centre position + * @param radius Radius of the hexagon's circle hull + * @param color Color + * @param layer Layer + */ + void draw_hexagon(const Vector& pos, float radius, const Color& color, + int layer); + /** on next update, set color to lightmap's color at position */ void get_pixel(const Vector& position, const std::shared_ptr& color_out); diff --git a/src/video/color.cpp b/src/video/color.cpp index 868e7c59d8f..244e59ece3b 100644 --- a/src/video/color.cpp +++ b/src/video/color.cpp @@ -45,7 +45,7 @@ Color::Color(float red_, float green_, float blue_, float alpha_) : assert(0 <= blue && blue <= 1.0f); } -Color::Color(const std::vector& vals) : +Color::Color(const std::vector& vals, bool use_alpha) : red(), green(), blue(), @@ -61,7 +61,7 @@ Color::Color(const std::vector& vals) : red = vals[0]; green = vals[1]; blue = vals[2]; - if (vals.size() > 3) + if (use_alpha && vals.size() > 3) alpha = vals[3]; else alpha = 1.0; diff --git a/src/video/color.hpp b/src/video/color.hpp index 87b13355f15..8490e133c95 100644 --- a/src/video/color.hpp +++ b/src/video/color.hpp @@ -95,7 +95,7 @@ class Color final Color(float red_, float green_, float blue_, float alpha_ = 1.0); - Color(const std::vector& vals); + Color(const std::vector& vals, bool use_alpha = true); bool operator==(const Color& other) const; bool operator!=(const Color& other) const; diff --git a/src/video/gl/gl_texture.cpp b/src/video/gl/gl_texture.cpp index 84789bd547a..4a825d4f67f 100644 --- a/src/video/gl/gl_texture.cpp +++ b/src/video/gl/gl_texture.cpp @@ -24,7 +24,6 @@ GLTexture::GLTexture(int width, int height, std::optional fill_color) : m_handle(), - m_sampler(), m_texture_width(), m_texture_height(), m_image_width(), @@ -68,15 +67,23 @@ GLTexture::GLTexture(int width, int height, std::optional fill_color) : } GLTexture::GLTexture(const SDL_Surface& image, const Sampler& sampler) : + Texture(sampler), m_handle(), - m_sampler(sampler), m_texture_width(), m_texture_height(), m_image_width(), m_image_height() +{ + reload(image); +} + +void +GLTexture::reload(const SDL_Surface& image) { assert_gl(); + glDeleteTextures(1, &m_handle); + if (gl_needs_power_of_two()) { m_texture_width = next_power_of_two(image.w); diff --git a/src/video/gl/gl_texture.hpp b/src/video/gl/gl_texture.hpp index a2a650b9f2e..1975236301f 100644 --- a/src/video/gl/gl_texture.hpp +++ b/src/video/gl/gl_texture.hpp @@ -24,8 +24,6 @@ #include "video/sampler.hpp" #include "video/texture.hpp" -class Sampler; - /** This class is a wrapper around a texture handle. It stores the texture width and height and provides convenience functions for uploading SDL_Surfaces into the texture. */ @@ -36,6 +34,8 @@ class GLTexture final : public Texture GLTexture(const SDL_Surface& image, const Sampler& sampler); ~GLTexture() override; + virtual void reload(const SDL_Surface& image) override; + virtual int get_texture_width() const override { return m_texture_width; } virtual int get_texture_height() const override { return m_texture_height; } @@ -55,7 +55,6 @@ class GLTexture final : public Texture private: GLuint m_handle; - Sampler m_sampler; int m_texture_width; int m_texture_height; int m_image_width; diff --git a/src/video/null/null_texture.cpp b/src/video/null/null_texture.cpp index d91d8b4fe46..35c018a9150 100644 --- a/src/video/null/null_texture.cpp +++ b/src/video/null/null_texture.cpp @@ -26,6 +26,11 @@ NullTexture::~NullTexture() { } +void +NullTexture::reload(const SDL_Surface&) +{ +} + int NullTexture::get_texture_width() const { diff --git a/src/video/null/null_texture.hpp b/src/video/null/null_texture.hpp index ea278f46d65..04043099ef3 100644 --- a/src/video/null/null_texture.hpp +++ b/src/video/null/null_texture.hpp @@ -27,8 +27,11 @@ class NullTexture : public Texture NullTexture(const Size& size); ~NullTexture() override; + virtual void reload(const SDL_Surface& image) override; + virtual int get_texture_width() const override; virtual int get_texture_height() const override; + virtual int get_image_width() const override; virtual int get_image_height() const override; diff --git a/src/video/sdl/sdl_texture.cpp b/src/video/sdl/sdl_texture.cpp index e8a3690a3e8..5a2363cdf20 100644 --- a/src/video/sdl/sdl_texture.cpp +++ b/src/video/sdl/sdl_texture.cpp @@ -23,19 +23,27 @@ #include "video/video_system.hpp" SDLTexture::SDLTexture(SDL_Texture* texture, int width, int height, const Sampler& sampler) : + Texture(sampler), m_texture(texture), m_width(width), - m_height(height), - m_sampler(sampler) + m_height(height) { } SDLTexture::SDLTexture(const SDL_Surface& image, const Sampler& sampler) : + Texture(sampler), m_texture(), m_width(), - m_height(), - m_sampler(sampler) + m_height() { + reload(image); +} + +void +SDLTexture::reload(const SDL_Surface& image) +{ + SDL_DestroyTexture(m_texture); + m_texture = SDL_CreateTextureFromSurface(static_cast(VideoSystem::current()->get_renderer()).get_sdl_renderer(), const_cast(&image)); if (!m_texture) diff --git a/src/video/sdl/sdl_texture.hpp b/src/video/sdl/sdl_texture.hpp index b28b60195f3..e36e8571a57 100644 --- a/src/video/sdl/sdl_texture.hpp +++ b/src/video/sdl/sdl_texture.hpp @@ -23,15 +23,15 @@ #include "video/sampler.hpp" -struct SDL_Texture; - class SDLTexture final : public Texture { public: SDLTexture(SDL_Texture* texture, int width, int height, const Sampler& sampler); - SDLTexture(const SDL_Surface& sdl_surface, const Sampler& sampler); + SDLTexture(const SDL_Surface& image, const Sampler& sampler); ~SDLTexture() override; + virtual void reload(const SDL_Surface& image) override; + virtual int get_texture_width() const override { return m_width; } virtual int get_texture_height() const override { return m_height; } @@ -45,7 +45,6 @@ class SDLTexture final : public Texture SDL_Texture* m_texture; int m_width; int m_height; - Sampler m_sampler; private: SDLTexture(const SDLTexture&) = delete; diff --git a/src/video/sdl_surface_ptr.hpp b/src/video/sdl_surface_ptr.hpp index 3eaf8786d10..cef48e64781 100644 --- a/src/video/sdl_surface_ptr.hpp +++ b/src/video/sdl_surface_ptr.hpp @@ -82,6 +82,13 @@ class SDLSurfacePtr final m_surface = surface; } + void reset(SDLSurfacePtr& other) + { + SDL_FreeSurface(m_surface); + m_surface = other.m_surface; + other.m_surface = nullptr; + } + SDL_Surface* get() const { return m_surface; diff --git a/src/video/texture.cpp b/src/video/texture.cpp index e7c60fd69e2..92ffef90416 100644 --- a/src/video/texture.cpp +++ b/src/video/texture.cpp @@ -19,6 +19,13 @@ #include "video/texture_manager.hpp" Texture::Texture() : + m_sampler(), + m_cache_key() +{ +} + +Texture::Texture(const Sampler& sampler) : + m_sampler(sampler), m_cache_key() { } diff --git a/src/video/texture.hpp b/src/video/texture.hpp index 16534a53995..69b14dc7c7f 100644 --- a/src/video/texture.hpp +++ b/src/video/texture.hpp @@ -23,6 +23,9 @@ #include "math/rect.hpp" #include "video/flip.hpp" +#include "video/sampler.hpp" + +struct SDL_Surface; /** This class is a wrapper around a texture handle. It stores the texture width and height and provides convenience functions for @@ -37,16 +40,24 @@ class Texture protected: Texture(); + Texture(const Sampler& sampler); public: virtual ~Texture(); + virtual void reload(const SDL_Surface& image) = 0; + virtual int get_texture_width() const = 0; virtual int get_texture_height() const = 0; virtual int get_image_width() const = 0; virtual int get_image_height() const = 0; + const Sampler& get_sampler() const { return m_sampler; } + +protected: + Sampler m_sampler; + private: std::optional m_cache_key; diff --git a/src/video/texture_manager.cpp b/src/video/texture_manager.cpp index bf5c2b24ec4..ccee7c8a23d 100644 --- a/src/video/texture_manager.cpp +++ b/src/video/texture_manager.cpp @@ -275,7 +275,8 @@ TextureManager::create_image_texture(const std::string& filename, const Rect& re m_load_successful = true; try { - return create_image_texture_raw(filename, rect, sampler); + SDLSurfacePtr surface = create_image_surface_raw(filename, rect, sampler); + return VideoSystem::current()->new_texture(*surface, sampler); } catch(const std::exception& err) { @@ -298,8 +299,8 @@ TextureManager::get_surface(const std::string& filename) return *(m_surfaces[filename] = std::move(surface)); } -TexturePtr -TextureManager::create_image_texture_raw(const std::string& filename, const Rect& rect, const Sampler& sampler) +SDLSurfacePtr +TextureManager::create_image_surface_raw(const std::string& filename, const Rect& rect, const Sampler& sampler) { assert(rect.valid()); @@ -358,7 +359,7 @@ TextureManager::create_image_texture_raw(const std::string& filename, const Rect } } - return VideoSystem::current()->new_texture(*subimage, sampler); + return subimage; } TexturePtr @@ -367,7 +368,8 @@ TextureManager::create_image_texture(const std::string& filename, const Sampler& m_load_successful = true; try { - return create_image_texture_raw(filename, sampler); + SDLSurfacePtr surface = create_image_surface(filename); + return VideoSystem::current()->new_texture(*surface, sampler); } catch (const std::exception& err) { @@ -377,42 +379,84 @@ TextureManager::create_image_texture(const std::string& filename, const Sampler& } } -TexturePtr -TextureManager::create_image_texture_raw(const std::string& filename, const Sampler& sampler) -{ - SDLSurfacePtr surface = create_image_surface(filename); - TexturePtr texture = VideoSystem::current()->new_texture(*surface, sampler); - surface.reset(nullptr); - return texture; -} - -TexturePtr -TextureManager::create_dummy_texture() +SDLSurfacePtr +TextureManager::create_dummy_surface() { // on error, try loading placeholder file try { - TexturePtr tex = create_image_texture_raw(s_dummy_texture, Sampler()); - return tex; + SDLSurfacePtr surface = create_image_surface(s_dummy_texture); + return surface; } catch (const std::exception& err) { // on error (when loading placeholder), try using empty surface, // when that fails to, just give up - SDLSurfacePtr image(SDL_CreateRGBSurface(0, 128, 128, 8, 0, 0, 0, 0)); - if (!image) + SDLSurfacePtr surface(SDL_CreateRGBSurface(0, 128, 128, 8, 0, 0, 0, 0)); + if (!surface) { throw; } else { log_warning << "Couldn't load texture '" << s_dummy_texture << "' (now using empty one): " << err.what() << std::endl; - TexturePtr texture = VideoSystem::current()->new_texture(*image); - return texture; + return surface; } } } +TexturePtr +TextureManager::create_dummy_texture() const +{ + SDLSurfacePtr surface = create_dummy_surface(); + return VideoSystem::current()->new_texture(*surface); +} + +void +TextureManager::reload() +{ + // Reload surfaces + for (auto& surface : m_surfaces) + { + SDLSurfacePtr surface_new = create_image_surface(surface.first); + surface.second.reset(surface_new); + } + + // Reload textures + for (auto& texture : m_image_textures) + { + auto texture_ptr = texture.second.lock(); + + SDLSurfacePtr surface; + if (std::get<1>(texture.first).empty()) // No specific rect for texture + { + try + { + surface = create_image_surface(std::get<0>(texture.first)); + } + catch (const std::exception& err) + { + log_warning << "Couldn't load texture '" << std::get<0>(texture.first) << "' (now using dummy texture): " << err.what() << std::endl; + surface = create_dummy_surface(); + } + } + else // Texture has a specific rect + { + try + { + surface = create_image_surface_raw(std::get<0>(texture.first), std::get<1>(texture.first), texture_ptr->get_sampler()); + } + catch (const std::exception& err) + { + log_warning << "Couldn't load texture '" << std::get<0>(texture.first) << "' (now using dummy texture): " << err.what() << std::endl; + surface = create_dummy_surface(); + } + } + + texture_ptr->reload(*surface); + } +} + void TextureManager::debug_print(std::ostream& out) const { diff --git a/src/video/texture_manager.hpp b/src/video/texture_manager.hpp index 73c80930ee9..240e37cb431 100644 --- a/src/video/texture_manager.hpp +++ b/src/video/texture_manager.hpp @@ -53,7 +53,9 @@ class TextureManager final : public Currenton TexturePtr get(const std::string& filename, const std::optional& rect, const Sampler& sampler = Sampler()); - TexturePtr create_dummy_texture(); + TexturePtr create_dummy_texture() const; + + void reload(); void debug_print(std::ostream& out) const; @@ -63,17 +65,18 @@ class TextureManager final : public Currenton const SDL_Surface& get_surface(const std::string& filename); void reap_cache_entry(const Texture::Key& key); - TexturePtr create_image_texture(const std::string& filename, const Rect& rect, const Sampler& sampler); - /** on failure a dummy texture is returned and no exception is thrown */ TexturePtr create_image_texture(const std::string& filename, const Sampler& sampler); + TexturePtr create_image_texture(const std::string& filename, const Rect& rect, const Sampler& sampler); + /** throw an exception on error */ - TexturePtr create_image_texture_raw(const std::string& filename, const Sampler& sampler); - TexturePtr create_image_texture_raw(const std::string& filename, const Rect& rect, const Sampler& sampler); + SDLSurfacePtr create_image_surface_raw(const std::string& filename, const Rect& rect, const Sampler& sampler); + + static SDLSurfacePtr create_dummy_surface(); private: - std::map > m_image_textures; + std::map> m_image_textures; std::map m_surfaces; bool m_load_successful; diff --git a/src/video/ttf_font.cpp b/src/video/ttf_font.cpp index 6b0f5526aca..5e732442308 100644 --- a/src/video/ttf_font.cpp +++ b/src/video/ttf_font.cpp @@ -103,8 +103,10 @@ TTFFont::draw_text(Canvas& canvas, const std::string& text, const Vector& pos, FontAlignment alignment, int layer, const Color& color) { + const float init_y = pos.y - (static_cast(TTF_FontHeight(m_font)) - get_height()) / 2.0f; + float min_x = pos.x; - float last_y = pos.y - (static_cast(TTF_FontHeight(m_font)) - get_height()) / 2.0f; + float last_y = init_y; float max_width = 0.f; LineIterator iter(text); @@ -138,7 +140,7 @@ TTFFont::draw_text(Canvas& canvas, const std::string& text, last_y += get_height(); } - return Rectf(min_x, pos.y, min_x + max_width, last_y); + return Rectf(min_x, init_y, min_x + max_width, last_y); } std::string diff --git a/src/video/ttf_surface_manager.cpp b/src/video/ttf_surface_manager.cpp index f6703cf3466..46e42c307aa 100644 --- a/src/video/ttf_surface_manager.cpp +++ b/src/video/ttf_surface_manager.cpp @@ -83,6 +83,13 @@ TTFSurfaceManager::get_cached_surface_width(const TTFFont& font, return entry.ttf_surface->get_width(); } +void +TTFSurfaceManager::clear_cache() +{ + m_cache.clear(); + m_cache_iter = m_cache.begin(); +} + void TTFSurfaceManager::cache_cleanup_step() { diff --git a/src/video/ttf_surface_manager.hpp b/src/video/ttf_surface_manager.hpp index 110d170757e..d6e87de982a 100644 --- a/src/video/ttf_surface_manager.hpp +++ b/src/video/ttf_surface_manager.hpp @@ -39,6 +39,8 @@ class TTFSurfaceManager final : public Currenton // Returns -1 if there is no cached text surface int get_cached_surface_width(const TTFFont& font, const std::string& text); + void clear_cache(); + void print_debug_info(std::ostream& out); private: diff --git a/tests/unit/util/colorspace_oklab.cpp b/tests/unit/util/colorspace_oklab.cpp index 005f37a3562..cfc8ac9342e 100644 --- a/tests/unit/util/colorspace_oklab.cpp +++ b/tests/unit/util/colorspace_oklab.cpp @@ -40,67 +40,4 @@ TEST(ColorOKLCh, ctor_Color) EXPECT_NEAR(color.h, -1.9393998f, 0.001f); } -TEST(ColorOKLCh, to_srgb) -{ - Color col(.1f, 1.f, 0.f); - ColorOKLCh color(col); - - col = color.to_srgb(); - - EXPECT_NEAR(col.red, .1f, 0.001f); - EXPECT_NEAR(col.green, 1.f, 0.001f); - EXPECT_NEAR(col.blue, 0.f, 0.001f); -} - -TEST(ColorOKLCh, get_maximum_chroma) -{ - ColorOKLCh color(.6f, 1.f, .3f); - - float chroma = color.get_maximum_chroma(); - - EXPECT_NEAR(chroma, .24032472f, 0.001f); -} - -TEST(ColorOKLCh, get_maximum_chroma_any_l) -{ - ColorOKLCh color(0.f, .1f, .05f); - - float chroma = color.get_maximum_chroma_any_l(); - - EXPECT_NEAR(chroma, .26009744f, 0.001f); -} - -TEST(ColorOKLCh, clip_chroma) -{ - ColorOKLCh color(.45f, .67f, .12f); - - color.clip_chroma(); - - EXPECT_NEAR(color.L, .45f, 0.001f); - EXPECT_NEAR(color.C, .1804768f, 0.001f); - EXPECT_NEAR(color.h, .12f, 0.001f); -} - -TEST(ColorOKLCh, clip_lightness) -{ - ColorOKLCh color(.45f, .67f, .12f); - - color.clip_lightness(); - - EXPECT_NEAR(color.L, .64147455f, 0.001f); - EXPECT_NEAR(color.C, .2572695f, 0.001f); - EXPECT_NEAR(color.h, .12f, 0.001f); -} - -TEST(ColorOKLCh, clip_adaptive_L0_L_cusp) -{ - ColorOKLCh color(1.f, 1.f, 1.f); - - color.clip_adaptive_L0_L_cusp(0.25f); - - EXPECT_NEAR(color.L, .83574224f, 0.001f); - EXPECT_NEAR(color.C, .10836758f, 0.001f); - EXPECT_NEAR(color.h, 1.f, 0.001f); -} - /* EOF */