From ff8457f8f8516212e7a1749d88416806b54dae14 Mon Sep 17 00:00:00 2001 From: LMH Date: Mon, 2 Sep 2013 17:01:16 -1000 Subject: [PATCH] Worldmap now supports an additional level sprite action that indicates completion of all level stats. A potential future improvement to this mechanism would be adding an optional "target_time" to levels which needs to be reached before the level is marked as "perfect". Note that this change will cause a one-time reset of all level stats- sorry. --- WHATSNEW.txt | 1 + data/images/worldmap/common/bonusdot.sprite | 29 +++++++++++++++++++++ data/images/worldmap/common/hiddendot.sprite | 29 +++++++++++++++++++++ data/images/worldmap/common/leveldot.sprite | 29 +++++++++++++++++++++ .../worldmap/common/leveldot_green_perfect-0.png | Bin 0 -> 1151 bytes .../worldmap/common/leveldot_green_perfect-1.png | Bin 0 -> 1158 bytes .../worldmap/common/leveldot_green_perfect-2.png | Bin 0 -> 1151 bytes .../worldmap/common/leveldot_green_perfect-3.png | Bin 0 -> 1163 bytes data/images/worldmap/common/shroom.sprite | 5 ++++ src/supertux/statistics.cpp | 8 ++++++ src/supertux/statistics.hpp | 6 +---- src/worldmap/level.cpp | 1 + src/worldmap/level.hpp | 1 + src/worldmap/tux.cpp | 2 +- src/worldmap/worldmap.cpp | 11 +++++++- 15 files changed, 115 insertions(+), 7 deletions(-) create mode 100644 data/images/worldmap/common/leveldot_green_perfect-0.png create mode 100644 data/images/worldmap/common/leveldot_green_perfect-1.png create mode 100644 data/images/worldmap/common/leveldot_green_perfect-2.png create mode 100644 data/images/worldmap/common/leveldot_green_perfect-3.png diff --git a/WHATSNEW.txt b/WHATSNEW.txt index fb01b86b4..26dee86b7 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -5,6 +5,7 @@ Tracking major changes in-situ: glow effects new badguys: iceflame, ghostflame, livefire, goldbomb, smartblock new bonuses: coinrain, coinexplode +statistics improved Supertux Release 0.3.4 (2013-07) -------------------------------- diff --git a/data/images/worldmap/common/bonusdot.sprite b/data/images/worldmap/common/bonusdot.sprite index 9183d5b11..1bb24a468 100644 --- a/data/images/worldmap/common/bonusdot.sprite +++ b/data/images/worldmap/common/bonusdot.sprite @@ -11,4 +11,33 @@ (hitbox 16 16 0 0) (images "leveldot_green.png") ) + (action + (name "perfect") + (hitbox 16 16 0 0) + (images "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green_perfect-0.png" + "leveldot_green_perfect-1.png" + "leveldot_green_perfect-2.png" + "leveldot_green_perfect-3.png" + "leveldot_green_perfect-2.png" + "leveldot_green_perfect-1.png" + "leveldot_green_perfect-0.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png") + ) ) diff --git a/data/images/worldmap/common/hiddendot.sprite b/data/images/worldmap/common/hiddendot.sprite index ee8289025..8761039c6 100644 --- a/data/images/worldmap/common/hiddendot.sprite +++ b/data/images/worldmap/common/hiddendot.sprite @@ -9,4 +9,33 @@ (hitbox 16 16 0 0) (images "leveldot_green.png") ) + (action + (name "perfect") + (hitbox 16 16 0 0) + (images "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green_perfect-0.png" + "leveldot_green_perfect-1.png" + "leveldot_green_perfect-2.png" + "leveldot_green_perfect-3.png" + "leveldot_green_perfect-2.png" + "leveldot_green_perfect-1.png" + "leveldot_green_perfect-0.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png") + ) ) diff --git a/data/images/worldmap/common/leveldot.sprite b/data/images/worldmap/common/leveldot.sprite index afa203b57..6d103cc1b 100644 --- a/data/images/worldmap/common/leveldot.sprite +++ b/data/images/worldmap/common/leveldot.sprite @@ -9,4 +9,33 @@ (hitbox 16 16 0 0) (images "leveldot_green.png") ) + (action + (name "perfect") + (hitbox 16 16 0 0) + (images "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green_perfect-0.png" + "leveldot_green_perfect-1.png" + "leveldot_green_perfect-2.png" + "leveldot_green_perfect-3.png" + "leveldot_green_perfect-2.png" + "leveldot_green_perfect-1.png" + "leveldot_green_perfect-0.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png" + "leveldot_green.png") + ) ) diff --git a/data/images/worldmap/common/leveldot_green_perfect-0.png b/data/images/worldmap/common/leveldot_green_perfect-0.png new file mode 100644 index 0000000000000000000000000000000000000000..b4a7a30a0dc17094feddbfa410de3766c93028cf GIT binary patch literal 1151 zcmV-_1c3XAP)!!4!a3(eP<3YkS1F}bX5(z#+~_V9 zU#(o(yadF+p!}990on(tz*f0Kpaw*zKRfuvf#;g@QFDfwAfQlC6a}4bn_;Zbg=Ki% zu=-2B@ca4pM?e?o1IbR67*_#Vx(`&{ifo>_c>Md9o;me&(>;I|1sOdGn~`gcj1+RX zj>(}CfpEl8*WZ8n+J&|GELLV)FW7OJjsxJ8Wp8}=_0ezNeEGd+Pu5<=r^32!v94Aa znhq%m+RGs@I8{rf7T^T}=?OQS3C^^y#^03Lt4S4b#{3ee%)WMXzIpETPhL1XKl=en z=UmHv=2o#l-)x{zXcSU7XbP0bkuJ!J1346l34G5#xUo3A1mtBOm~q)o>U_U>(trO@ z^9XgP$&K_1E9yFl?E|2#Mj&yl#afHD1wshI$j504yqaWYulH7&j5~ol?g21b1utwm z$0OYYB)9c4h0X429v_KDQP>QPL<$E77k|btbaj{9q+sM7Y7#<-oq|uQz!sm|Y^a9I?Ii>-=N_giEBL~p z;WP;49xAem5CL_$4_8%?#ziTG?rZYcV70w38_Eg6HK5{_`s24hFVjiZIOH8;pL-nF z23TteZAi`8O<-q8%_fCN5JHd*3i>NKCKIUK#5+yEq%pk1f?*hh>Z$m&H)}Yt=S3oK zmXsbt(<3KAlcG#UM{QuNCL84RZzl8>70KU*cu8H@xHbt|& z*7W^24b`+nbl13a z7So@?FnqVY*=nrjH`y58VzbvpCyHUxB_4F?bq91769&sUy~Tob&8AnsTRm-*?UXwq zpR^CA-35(fZ_j;MKkS~W@AYsai63~#iXlr1OeRQgYtl7K-c!q0&bQy0b{B{T*oO53 z&+mF8+UI}jMe>-GRHc-{SZj^8xz236*UCR{{o47V3_K{;@U5k0^* zJ&=}XK8+rD5JlvUQABK0M0%v#^`k1Han%^rh2!|cJZ??+udCuG_Qd{k`v+Rm@YeXD RaMl0-002ovPDHLkV1jAE7`y-g literal 0 HcmV?d00001 diff --git a/data/images/worldmap/common/leveldot_green_perfect-1.png b/data/images/worldmap/common/leveldot_green_perfect-1.png new file mode 100644 index 0000000000000000000000000000000000000000..825374ac38d42c77af43802de6927303e1a2ed1d GIT binary patch literal 1158 zcmV;11bO?3P)Upa*;+B4UE5J-`Pd zAS^s6NQeT!06CBr-Y@R+TaoZ?0qz%oWuSUszV__g{_y0~PBkBuy;;E1TI)P@o%Wjj zv$2$ax^RB;EYJbE#kX`p(A`c3w$fb!szB|%5BGfh$P@MB)Ab7FFeKBE=Q*voL8qh9 zxnp&~vhYiG@%vMaH-H#u1Ic!o7?lB8cmR}xNY+0%bLgwXj~(4t@gBm797_x1QZi#$ zt!YZVHFO5$8b~D$_`!qcemvbgo^-Swss%SH(oqEbBJES}e|F%DV@FErd2ufOxu zTl2H8VNAxg^k?GyBB{NOM&r;3p|Ipwk)b^BBZbKzO>7wW!Jd`H-dP|k>cEbQc3kBL z`wj=M&eiu5sXC4Rd1Adl?%Fq|jWY-&$~l~KSeGM&pi&Dc*9E1jWM;SjLJ^ENW_H{} zU@!}Qt*#D*rjA3>HCHe$9ja1^Lt|WuMk0hl;1N|6%6BM_ase*K75sK>D5Mfq-LE2C zNXgqlH(Lf_5lB2CFisJvI=-yYGcnrs!QP0;Sr9^q?ZC%nU~8VceoyyS8cPVE>g^?x z5rI%t)D%kYz?Ws52npmI=m@Nb)|#wsNIDj4+%2b}90P6u-CWieF8pzhcG6_VKSf(x+E0_r3voMLU{F2?#(oul6ra z&y=1^xU^dbF`=8nm(w^G;e?~3yQFys<1%{PjP<2HtIHW{ONLg{#6O)`eS2UU>PZLD zKiXwwvHxwURC;-Rb9t(rT_*0W5VvCTM3W{ly>85A+~wM0!u2Z|jm4a}>H0r>xq8BA zw^8hbY}`JWbQeq=d2#0_yY_lV>$`oTnj{Q;{K(Qza`IHrS~s+sj$TV&`R-KXrAc>z zxQ%W2z@tx2KR-Jcyj!ZtgGy4CQVQdov&Ln4>Kd!d*+;+sy76@Z+%4Af9c{y#reZ;4 zOB475dVnE4&@awx55-72C{*%;J?qvnUb*P8HOSH<`3zWwL+ Y7X_j8vGFssasU7T07*qoM6N<$f*Oz_p#T5? literal 0 HcmV?d00001 diff --git a/data/images/worldmap/common/leveldot_green_perfect-2.png b/data/images/worldmap/common/leveldot_green_perfect-2.png new file mode 100644 index 0000000000000000000000000000000000000000..313ec87759674e374262b4ed5cf6053a391a7387 GIT binary patch literal 1151 zcmV-_1c3XAP) z?f-7-5x*a{Pd2Sjlz;-9P3z{pwgk5W&yP)D1IR7iE8QI+vH@-YJ>X*zQDa2y0X`4` zVd+6hLX`jpD1fZ=e)(QJh=lh5aK8ks0<|ND>o4xx7oM7#agS81-ZbE8t#y`3_jb$v zvA9%xdF9I51)vKg^d`$liA>_aLme6n#ij8~Q=8yV2-f0P?a9?67D@Retc? z(ctYk-iPbP^s*~xeGM!3*1L@uz(E;7L_i9ZQf#XSY@booY7VnI{a4Fiyb-&0MhH}-pa}%3h=x=ctp73 z;;TvUcHlTw#0^p2F0_uY)R+$@c9Aq~5%>pjf$85;20MxJrZ7a{2z`@K=q@5TNs_a)(5KnVS!^0ww@mx|kGDP;=!SaSM)Z&C(rEO5 zu0)kL*H)X8dA>j|xk0DXrk`l?UYlOG%~~g+(MVZd%4sYVv|7?X^TVx^TFYuV6Y^2> zVBA?S`TA=!U+mfAotT~RsZTkCp-&W9(zGDU6nE|zS}mc|)=Q_)th_PqEKm7MSY>Rb2WVrsOVbkB4i;=&v_+$yN5?>nc? zZWP&kuUfZ8+~L0RhMj=f-z!0dD)Q@0h?kkXN{0xYtKy9ozuA&qpF6Mu^%6 z0w4yW!oz}uC;$wQ1HHnt;y&MsguexNPym*J>fwF0r}poPPHnGwhs&`)1^8NP-OF94 z*|L{ruIC?LxVUl-=m6c~Te=|VZY2Zj=`I0Pp!WVddp>;hf%@_KM1{zY&;s&2r`1@b zqcpj8T%5D~bV*%4{mtS@parY~>1LT2lmS_I2$bVc*3Z6o=!=Js9NXttb|YL4SsQ11 z7-6Wznq;+!(om~_C&hu#-*x`X_l@J7RND=;;08rHh(J)Jef*Pm4}A9IvoAkV-Safa z7}K3ar}Nls8Ei@*6_IZ#hmLAFBJu=*FZ@b5di~ccollGC^{@tr`Bpj#JlYISYeSOZ90?r_fGY>p6uS|y}DA*hxlJ0^qYi(vdA zv*RWL{aFa=W8NVn>L4YiJBPEqzn?OIk>E7W^dOK3>4EU6lsp2@;Y-Q|xExmSo3)|v zJWO%4rkQD7`MkOEs zIp54KPu5D$(7CcBlr5YbN0ujWUW||q?YiVy2WJ)CL@_g;G22wkG!2bq(>nX((wlwL zP>(u@{?RVe3)$DDQt73YrP*=SzDlxkjdr_5nrPBii*CC`tJ7urTFP8QF};}6XuIt5 z@0LzzotZRaxPY#B{aM1j)cUu$w>#F#k d-LwDP{sbMN@3a*2CaeGe002ovPDHLkV1j+>G0Fe{ literal 0 HcmV?d00001 diff --git a/data/images/worldmap/common/shroom.sprite b/data/images/worldmap/common/shroom.sprite index 5ed151bea..e432a29e0 100644 --- a/data/images/worldmap/common/shroom.sprite +++ b/data/images/worldmap/common/shroom.sprite @@ -20,6 +20,11 @@ (action (name "solved") (hitbox 16 16 0 0) + (images "level_star.png") + ) + (action + (name "perfect") + (hitbox 16 16 0 0) (images "level_star.png" "level_star1.png" "level_star1.png" diff --git a/src/supertux/statistics.cpp b/src/supertux/statistics.cpp index c749bd614..95ad4edb6 100644 --- a/src/supertux/statistics.cpp +++ b/src/supertux/statistics.cpp @@ -258,6 +258,14 @@ Statistics::operator+=(const Statistics& s2) if (s2.total_secrets != nv_secrets) total_secrets += s2.total_secrets; } +bool +Statistics::completed(const Statistics& stats) +{ + return (stats.coins == stats.total_coins && + stats.badguys == stats.total_badguys && + stats.secrets == stats.total_secrets); +} + void Statistics::declare_invalid() { diff --git a/src/supertux/statistics.hpp b/src/supertux/statistics.hpp index 5de05c836..880cd474c 100644 --- a/src/supertux/statistics.hpp +++ b/src/supertux/statistics.hpp @@ -48,11 +48,6 @@ public: Statistics(); /**< Creates new statistics, call reset() before counting */ ~Statistics(); - /// read statistics from lisp file - //void parse(const Reader& lisp); - /// write statistics to lisp file - //void write(Writer& writer); - /** * serialize statistics object as squirrel table "statistics" */ @@ -70,6 +65,7 @@ public: void reset(); /**< Set stats (but not totals) to zero */ void merge(const Statistics& stats); /**< Given another Statistics object finds the best of each one */ void operator+=(const Statistics& o); /**< Add two Statistics objects */ + bool completed(const Statistics& stats); /* Check if stats match total stats */ void declare_invalid(); /**< marks statistics as invalid for their entire lifetime (e.g. after cheating). Invalid statistics will not be merged or drawn. */ diff --git a/src/worldmap/level.cpp b/src/worldmap/level.cpp index 1f3ec1a7e..569f31f48 100644 --- a/src/worldmap/level.cpp +++ b/src/worldmap/level.cpp @@ -33,6 +33,7 @@ LevelTile::LevelTile(const std::string& basedir, const Reader& lisp) : pos(), title(), solved(false), + perfect(false), auto_play(false), sprite(), statistics(), diff --git a/src/worldmap/level.hpp b/src/worldmap/level.hpp index 54b62e63a..8730d2956 100644 --- a/src/worldmap/level.hpp +++ b/src/worldmap/level.hpp @@ -43,6 +43,7 @@ public: Vector pos; std::string title; bool solved; + bool perfect; bool auto_play; /**< true if Tux should automatically enter this level if it's unfinished */ SpritePtr sprite; diff --git a/src/worldmap/tux.cpp b/src/worldmap/tux.cpp index 41a28f083..1e6ba7b20 100644 --- a/src/worldmap/tux.cpp +++ b/src/worldmap/tux.cpp @@ -147,7 +147,7 @@ Tux::tryStartWalking() // We got a new direction, so lets start walking when possible Vector next_tile; - if ((!level || level->solved) + if ((!level || level->solved || level->perfect) && worldmap->path_ok(input_direction, tile_pos, &next_tile)) { tile_pos = next_tile; moving = true; diff --git a/src/worldmap/worldmap.cpp b/src/worldmap/worldmap.cpp index dc57331ba..3d608d532 100644 --- a/src/worldmap/worldmap.cpp +++ b/src/worldmap/worldmap.cpp @@ -461,6 +461,10 @@ WorldMap::finished_level(Level* gamelevel) // deal with statistics level->statistics.merge(gamelevel->stats); calculate_total_stats(); + if(level->statistics.completed(level->statistics)) { + level->perfect = true; + level->sprite->set_action("perfect"); + } save_state(); @@ -987,6 +991,7 @@ WorldMap::save_state() sq_newtable(vm); store_bool(vm, "solved", level->solved); + store_bool(vm, "perfect", level->perfect); level->statistics.serialize_to_squirrel(vm); sq_createslot(vm, -3); @@ -1058,7 +1063,11 @@ WorldMap::load_state() sq_pushstring(vm, level->get_name().c_str(), -1); if(SQ_SUCCEEDED(sq_get(vm, -2))) { level->solved = read_bool(vm, "solved"); - level->sprite->set_action(level->solved ? "solved" : "default"); + level->perfect = read_bool(vm, "perfect"); + if(!level->solved) + level->sprite->set_action("default"); + else + level->sprite->set_action((level->sprite->has_action("perfect") && level->perfect) ? "perfect" : "solved"); level->statistics.unserialize_from_squirrel(vm); sq_pop(vm, 1); } -- 2.11.0