From b72c5d178e4cc95130735d8bf8716513c7cc28e1 Mon Sep 17 00:00:00 2001 From: Marek Moeckel Date: Sun, 25 Sep 2005 16:49:21 +0000 Subject: [PATCH] keys are displayed on the screen, they can be "collected" via a scripting function SVN-Revision: 2783 --- data/images/objects/keys/display_brass.png | Bin 0 -> 2080 bytes data/images/objects/keys/display_bronze.png | Bin 0 -> 2080 bytes data/images/objects/keys/display_gold.png | Bin 0 -> 2109 bytes data/images/objects/keys/display_iron.png | Bin 0 -> 2045 bytes data/images/objects/keys/display_silver.png | Bin 0 -> 2045 bytes data/images/objects/keys/key_brass.png | Bin 1710 -> 2055 bytes data/images/objects/keys/key_bronze.png | Bin 0 -> 2055 bytes data/images/objects/keys/key_iron.png | Bin 0 -> 2004 bytes data/images/objects/keys/outline_brass.png | Bin 0 -> 560 bytes data/images/objects/keys/outline_bronze.png | Bin 0 -> 560 bytes data/images/objects/keys/outline_gold.png | Bin 0 -> 662 bytes data/images/objects/keys/outline_iron.png | Bin 0 -> 436 bytes data/images/objects/keys/outline_silver.png | Bin 0 -> 436 bytes data/images/sprites.strf | 73 ++++++++++++++- data/levels/world2/level2.stl | 8 +- src/game_session.cpp | 18 ++-- src/object/player.hpp | 3 +- src/player_status.cpp | 92 ++++++++++++++++--- src/player_status.hpp | 25 +++++- src/resources.cpp | 27 +----- src/scripting/functions.cpp | 5 ++ src/scripting/functions.hpp | 11 +++ src/scripting/player.hpp | 2 + src/scripting/script_interpreter.cpp | 12 ++- src/scripting/sound.cpp | 2 +- src/scripting/wrapper.cpp | 134 ++++++++++++---------------- src/sector.cpp | 6 +- src/title.cpp | 4 +- src/worldmap.cpp | 32 +++---- 29 files changed, 304 insertions(+), 150 deletions(-) create mode 100644 data/images/objects/keys/display_brass.png create mode 100644 data/images/objects/keys/display_bronze.png create mode 100644 data/images/objects/keys/display_gold.png create mode 100644 data/images/objects/keys/display_iron.png create mode 100644 data/images/objects/keys/display_silver.png create mode 100644 data/images/objects/keys/key_bronze.png create mode 100644 data/images/objects/keys/key_iron.png create mode 100644 data/images/objects/keys/outline_brass.png create mode 100644 data/images/objects/keys/outline_bronze.png create mode 100644 data/images/objects/keys/outline_gold.png create mode 100644 data/images/objects/keys/outline_iron.png create mode 100644 data/images/objects/keys/outline_silver.png diff --git a/data/images/objects/keys/display_brass.png b/data/images/objects/keys/display_brass.png new file mode 100644 index 0000000000000000000000000000000000000000..95c1fcbf2d94df8096951ea1903d8ab0e7971995 GIT binary patch literal 2080 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 literal 0 HcmV?d00001 diff --git a/data/images/objects/keys/display_iron.png b/data/images/objects/keys/display_iron.png new file mode 100644 index 0000000000000000000000000000000000000000..46477947700e697238062bdf7de942adc5778f04 GIT binary patch literal 2045 zcmVHaq|T2Z~8V zK~zY`rIl-pRn-}WpSAYo>~o*HFvH9N29+t`4eKB_AZTs9gw{&cRx6FSsIjFrscp2O z(P(09jct^~v}#*Yt+fpUcq;|L%M|a5pj9YRU>JtEaL$=?+h?D>_geiyVOZv(Hv!`S z;%G?A>G*53;libkvlz=b4yjUTKZy(tgm6i<4=`GIk^G@;_{BGNhPBZiK$%B_DlJ_n zo}e{(Aqy7T%ldMd{8~T($fH3+Z}7J4fpxp`l^1Ai z(O~W5?z?VOzqox_QOYcdBqY+S@hdyFY31MXv1#>SLK<^gkm8u%uUrN5$CL^QZF6#=WfR`vZ~mnX{bcvxlsB&w3$^%mhyjGdiVN{@{(?o*z#- z@f<<4AW-bulciFra`LPWhDOQ^4h|BrG{eKAY~He$_h0|r_6bnaX}fny zdc#ld{%seAsYxXc+a9q6rAk1}SA?NPDX=X`GGP$01hJUO%Ukwx>krSZO=y%5R?>_L z+-k_**C`f$-DlJ0euOm8Sh%i7Hao`H@NNvl;LE*>n0NYY26q~K=c?ne?Swb6`@-(l z+TyJ(E@ruzr}`dZbe@W}47Kh!2A_xH?8zw+?SlnkAg3O#G*g0;#{vuM%GuShbCt{0+ zhLn9q%z@EEMUtsT&RsBr9Uo{~XJ{&}LWgc-0yOkZzzpiz?{V%2S#grb>TGP zQ3EF;u`Nlps>qiD3@I=SL1)Hi=1hxw?tc;$6b9=Big4mH9!wgy-DKMiep5dPn?$OG z)|O_Rh>6xdQrehy15Uh&k&!HWKHS8i{p-=e&~H99rGzkgg|vEw5xrw_S6{=NQ#zQx zpu)`Q4j?%=oae><4_N=~p9w=Z7kFbI1@6ABDk%M&V^k#8xS%|B>Op<~BRT!#b6NfT zD@Fa@&Z^E8LY*B~`qFDwX(6rikJ!p%gmk+VnHx(sMcMYjzvx@@3Zq$%mZk(JoH&!~ zzIP_Qy}k53K53rs4m@|%l=|c_#G59QtvpQM?_c8^OTLZTe*yR2`F#?J6iY9?R=>S{ z57JCb;&YTRBW-sYcH{M#$Xfq_N5}Q7?)UWzujTb)YjZl*H2-g=-EgH4)~TQ4`slzL zSpg8(Ll3$Y0VuM$5|xSoUE3ej@_(9O+GkXp423p9(h`pn1T}=vgh4r7w-cWc>S}_+ zSBr+2rcJ4sN2}2IB2WjwvIGW@OhoWJ55rDJz6jI~g)0i<5)nW&8o{mlU?ke=9X5~L zBGIO`h=3Xg>4New79wLWmQEG|te4N$hwxj+BsUImr@2Ob3W2JI^vxrwGr})GUu6P-q?E zl?KM@DxE&-o7;P4FX}R#243nDG&DmPYBDpgeCXC!``4VH1HU^O-f~VDXwVS&6-LJd$9F42t$`Xs2uy5*5F`_6AaLt? z8dMM77gP@-q;awpscdztf!Ss3Ddf!;`dR<KD3WcYyQ$gVoCoy|>YsTQE{uKn4;)Wk>VCcXwiI&B8c%>aNuk`PqO@Qv% zu`Per>Cbh#)e;x9_fYi|LG3_61*KJhj>XSQFI{pQS1*I+1`E>!KhUgx<{-B$|CXw& zv|8Hwm3`$U)8ow-uPLjp%!W-+E$-S3ss^CK5&hwIN#9ycG8rRJN$jd%7j{YVPNRVrjF>Oo?I-7L8ORB^ZpYz1^$6m bpXB@(^jUkqDk2zh00000NkvXXu0mjfKTp{$ literal 0 HcmV?d00001 diff --git a/data/images/objects/keys/display_silver.png b/data/images/objects/keys/display_silver.png new file mode 100644 index 0000000000000000000000000000000000000000..f51fec6a5d1c72e7197845e5025d32198e378860 GIT binary patch literal 2045 zcmV~o*HFvH9N29+t`4eKB_AZTs9gw{&cRx6FSsIjFrscp2O z(P(09jct^~v}#*Yt+fpUcq;|L%M|a5pj9YRU>JtEaL$=?+h?D>_geiyVOZv(Hv!`S z;%G?A>G*53;libkvlz=b4yjUTKZy(tgm6i<4=`GIk^G@;_{BGNhPBZiK$%B_DlJ_n zo}e{(Aqy7T%ldMd{8~T($fH3+Z}7J4fpxp`l^1Ai z(O~W5?z?VOzqox_QOYcdBqY+S@hdyFY31MXv1#>SLK<^gkm8u%uUrN5$CL^QZF6#=WfR`vZ~mnX{bcvxlsB&w3$^%mhyjGdiVN{@{(?o*z#- z@f<<4AW-bulciFra`LPWhDOQ^4h|BrG{eKAY~He$_h0|r_6bnaX}fny zdc#ld{%seAsYxXc+a9q6rAk1}SA?NPDX=X`GGP$01hJUO%Ukwx>krSZO=y%5R?>_L z+-k_**C`f$-DlJ0euOm8Sh%i7Hao`H@NNvl;LE*>n0NYY26q~K=c?ne?Swb6`@-(l z+TyJ(E@ruzr}`dZbe@W}47Kh!2A_xH?8zw+?SlnkAg3O#G*g0;#{vuM%GuShbCt{0+ zhLn9q%z@EEMUtsT&RsBr9Uo{~XJ{&}LWgc-0yOkZzzpiz?{V%2S#grb>TGP zQ3EF;u`Nlps>qiD3@I=SL1)Hi=1hxw?tc;$6b9=Big4mH9!wgy-DKMiep5dPn?$OG z)|O_Rh>6xdQrehy15Uh&k&!HWKHS8i{p-=e&~H99rGzkgg|vEw5xrw_S6{=NQ#zQx zpu)`Q4j?%=oae><4_N=~p9w=Z7kFbI1@6ABDk%M&V^k#8xS%|B>Op<~BRT!#b6NfT zD@Fa@&Z^E8LY*B~`qFDwX(6rikJ!p%gmk+VnHx(sMcMYjzvx@@3Zq$%mZk(JoH&!~ zzIP_Qy}k53K53rs4m@|%l=|c_#G59QtvpQM?_c8^OTLZTe*yR2`F#?J6iY9?R=>S{ z57JCb;&YTRBW-sYcH{M#$Xfq_N5}Q7?)UWzujTb)YjZl*H2-g=-EgH4)~TQ4`slzL zSpg8(Ll3$Y0VuM$5|xSoUE3ej@_(9O+GkXp423p9(h`pn1T}=vgh4r7w-cWc>S}_+ zSBr+2rcJ4sN2}2IB2WjwvIGW@OhoWJ55rDJz6jI~g)0i<5)nW&8o{mlU?ke=9X5~L zBGIO`h=3Xg>4New79wLWmQEG|te4N$hwxj+BsUImr@2Ob3W2JI^vxrwGr})GUu6P-q?E zl?KM@DxE&-o7;P4FX}R#243nDG&DmPYBDpgeCXC!``4VH1HU^O-f~VDXwVS&6-LJd$9F42t$`Xs2uy5*5F`_6AaLt? z8dMM77gP@-q;awpscdztf!Ss3Ddf!;`dR<KD3WcYyQ$gVoCoy|>YsTQE{uKn4;)Wk>VCcXwiI&B8c%>aNuk`PqO@Qv% zu`Per>Cbh#)e;x9_fYi|LG3_61*KJhj>XSQFI{pQS1*I+1`E>!KhUgx<{-B$|CXw& zv|8Hwm3`$U)8ow-uPLjp%!W-+E$-S3ss^CK5&hwIN#9ycG8rRJN$jd%7j{YVPNRVrjF>Oo?I-7L8ORB^ZpYz1^$6m bpXB@(^jUkqDk2zh00000NkvXXu0mjf#rfHz literal 0 HcmV?d00001 diff --git a/data/images/objects/keys/key_brass.png b/data/images/objects/keys/key_brass.png index 5cc296c06c9184d0e36a45b885786d02217b3ef0..4bb09f7cad1398c6881b088ff5bcaae6317ec1b5 100644 GIT binary patch delta 2030 zcmVGk&Y5%0 zf7^S1K9raSq%j26+s@AZva-JKe_MMI?tnQb06=P&pLuY~b-p^{IQKeI=2i!TfAzHf z-AWR^cQpwke1=eWx*Sz*K%isaT$udn(zG}-H^~G?V0Ah3#lK$Zf3AE}{c@!pJ#WAU z00H1no1pyAnT{96iqk5S^-0P7`D|%_Hv8=3Pfi~?c&y@iM_hRO7*k&!e+P9iO`+L- zYpZ|lu|h@6`_5fe$I4~D8SrQ7CRs`p$w|vDw!8x~-pE zv&s{gzdx_;9+RS7NtPa)DgJP-l$mI6;vO$fe*)kHfc|IIVy^g3<&j12*xa-`bD`^` z83;Gv9r5q?lJ3bDbInYFf6^b!>Ah~Ypzb>`a`ea|9nDom^z5&%zowgZ(KY*iVBX1BhN}ZvXZxs#^A^bKiaZ=}F%-I?#kAcs3_(APgO^j1i_M_EzcEBH%uB^k*Qx#smILlq!gB!e>Ip5GbD(LN=XM0 z%odR~wqs4&F**sY>3vv1QP<&>s~gTGXG*lDQ(Nm_+{CrjR=T`u1_`U4jM2S#A&#my zuK1N&BC=%#k<4ZuS}Grl>pRD?Sw-Xvv>QF0oi3^RN_QjDxae2%Ys?nVR zkTSJCzz!3G38}Vrf6#5~&eg6ytuiG12lJJYs^{FjyG-M*<77r%eYE5lpRGWDqmNf# z!`9g~`sYw5FLyg4`TbwS!UMDR=+gbBJX<9MHG_wajL77C1W|M$%P!KZeb>7$i}vYo zm*m{8V6qHOhkzll1sLMi1h56-0Z1yaxTTUw1#VvJ;ib2tf79w~rO9vXuX=kIXZ>%D z?G0+Kf?Lk8oVd%A(qoM7m#Ca2GqOeRKG*HN@bzpy+eplVevuEVOj@>%g)D^-MIX*? z1IR9f??dg$gOgPRyHkjO;gk$ayaVZG0IOlF07yXz1Lg=2&Ih|sfbcO>+d*kX&Z`5Z z;?MTo<>wwfe_oo}))BYbQJSkVO7oUL3EbHnMn}@AN?4T@41(jiuxSdd4VW2@5`dCmYXAm_B$y<0q+x9# zP_;nLmjeq~=wju>1}mJoInbi$-Ic6Qdq zI%n2i*JFi|9v!^by15dly~*$g9Y_g;!yIcZQv*)wsZ9W!i3j39I;3*cX7pDys>KN5 zRthU(e~_zTn%l5rDFz!pdfN^X(5()#gk^#N!Ic)SV*tq@Fo4qv+zztk9{r__mV>-mRxtlW>)>uX(ix^IxHW}HVC_9PGQy@%znE>Wvk zX{MboIV$hH+3lTra!>Z#l2J37Fo*=MHbwaII-i8$)m(;HC{TA`I>ovgZ*JqlayxnZ zf6UHc)gws)L<2VbM5Xf7)T}>0_eiO#MvI^{Mf83LH_rCC-WP-S!}#QtesWSJu;Gc` zRtTUDz;TH7JhM1T7j+u`R^KL%G8DCJyS6-TPCS%l0dA$c3@_*oof@aCuXleqk;C z`(!~1(dGT^(5jm9a+lLv1n&TDMB(<;W!^gZoY*BDhLA((l)2p@-Q4k#D1inN{s=)u zc%wJOJDs7GsT*WBjkr&_b4SN(f30F^Y)cv~WG-Js{bJFU9lU$0-u%tJc5rhcU@tWo zDx&cJ2?3jFbfVp|XDKKf@m`13pcGiNuVU;OIE+8+$F{)Ayg01yfU2EzjUL6)?)XTXoeL;){H094I! z9^ReJ951=fp%kLK6-8&aQ~jrFQF#7x)F1w@w?A_JTc3ZPe)2r{AF%q{E#%#Mb^rhX M07*qoM6N<$f^)Xu_W%F@ delta 1682 zcmV;D25tF=5Uvd&iBL{Q4GJ0x0000DNk~Le0000W0000L2nGNE04L4t>X9Kae+B^n z8vqdPeq#Ut20KYaK~zY`wU&E~lvf$Xf9Jc+d^0_mX=x}f)N|7 zHcMKp)u?Go)BuLoKw@I!A6l#$qqYgLUQ4iGE5=eAYl{tSq?FPE%SE6I?8RN^?#}Mc z?A*Tj?#DlX#tdB*}zHBttrj%!QeCq(mK%H#I~lK(T5^;56wt~_;@bPlbS&g;vi zeV|MJYUw;*L(IQ4lLEy5yy)NRSXVOpcxNQ_RbXaQ(&*4<3kIKinZdsve}&R>*k`xiRsW4=UTdtTBf1$Da%|t8p0Iqy`QALc$q-5Q zd~DX1MO_U%^l1Oy5H4IZ0xO{U{OI_m2bI=8tpDx&cv!FqhI%<)vb!e&rPs+tzm{Bk zD>o+;?0tP4E7}K5p>zOKe`_*40Yrc?!2hoZRDd3@vU}G-(Yx*|VSCWuPjP&hK*T~J z6wfY9qV9hcB{7blyMfiyr)>IMnAkKuq3S((r&b@=jqY6WzzJLYK9DjrRW;&C8F(`E zghXx7jkJc0_@VEQ1^&di?+uNF?%sC^9D-<8(PDusJ(MWt_D=HSe-|U872oNb47@X2 zw(4WcTZ6_G>m_C;WaE!obnAt4)ZM!P>%}+C_?jE(`EK{JmYds`Aw$BNOBg6fDG@?| zWg|3+G*qM$aOxj6j~<(ROf!X&U0pxzH=WbeW$}oq-_~rINS~H=2W^jja(AV)4v2#lo}WU&{a#X!Di=!~UYWayzy zaiNw+Z_<%o5xu<)SvkyPETnPpZ#bSLl86&jtJGXcovA=He@bW#Ap#v~<`7yLMQKQB zw>C9=B6D{$ul)32c<@-QwD~)cv^sMxB4ILTS}~cppxscG{%dJXnWo1s>5pw80b$0G z&OZ@GmV5!iz$cgYK+!Oq3ZCa7rNpX%5DrpGz(I&Ac2OasikPAYmg4su!naDo@Q6+p z^2qVSP(DvGe`-*#>dk=kQN}L6@6vt?{1X0{f^UOA;1dQRr89LG2SOj$buTTvi1*e` zMJEV6S9@cm_|~i)>MiZ7s$$-%Fq+TlRICby3B!eWI2t%T0B=<6UH4pwt!#3k|D?{m z&Jx3KdYCr_*hkJ2UF=cpOL6q?QwRa1ffuO6RY|(ee+E57AkowiyR7m0fbaHJ%Y)j^ z{Aiar-u!gOVB76Z=md3oO#k$k`-D?ad3)TqJ0r=D_BfRZQz-4n&g;Q^Db#Z#b&Nd` zp)eURb4+mhtSRS=N5r4@bLOes(B_z;X$nG}3_W{owsG47tGrAi6QD)}W;EdRkpw$O zCN>QCf3eZyNJsObXwuj7?-< z9#XtO(g%2#bszvPM1(SHR%57ZQOGW~@NJ9of8m(dYMAkCyT$c4mQX~g$pdY9AB&0zPFnNXNDR( zf5m(e$i6QROjQ+j?)P7Mp;X(xv7_OaE7Q^Vimq|>_HnH<-EO1zC_J#Y`e62i;dUnc zmDlOf%qh3>LHp%-%X)j)uN&s8T7W8YRBaKS8a8{uvOdtJH_n)Sp!&>mS=bSgBijsF z+cjMtzGIQ63(;|vh8G3qYKVmjECOZ#X!_-*dL`zb7uwDJdRN=@S;9;&Wa7^XKiHpt z_DHq(i>pjTJ}?nNPC^bS!^NMg#Z8m07*qoM6N<$g4D=IF8}}l diff --git a/data/images/objects/keys/key_bronze.png b/data/images/objects/keys/key_bronze.png new file mode 100644 index 0000000000000000000000000000000000000000..7ea1600eb2923b10595e8aa5932e654bcddb1ff4 GIT binary patch literal 2055 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 ySXX1*<0u;Scj*r)L!95_`{6yks!A+e;^@)BhS z8)jpi{8xAPo|o-GNv>MEp8Mt3bzg7y?cgsHz=H9;4jlSzXz-cq1Y*`$FAxn28~~=R zu_<6EEHIQrtRp6*-vajmd*^{Z>1#mF1~vgB(tChA56~FU1&jmT#@;FmP3blk+cK(O zMbbdY^r55Uwuf}vuHiDrk-161!$6;bcj?Oxumr@dMYq7V4`db?bQ!;lSg<^B1Uv$% zfb6&eCapw|+d;_#J2f2hO#j1nKphEF|zinc>-O-h2X5 zkryMO1KU>y*bD%!yEPCy53|6EA|0*4!VRFc(z@J$uSSJLYw%s>$2<1l1@3!Qkst5@ zxbT>}F>1ap;Q4=0>Uue}y1Zp#Uj@$nSIX}Mz5v(X0W7QYrhzT#g?fSJC0ztgRKHo^ ySXX1*<0gcHgbZnrB(b1mVzAI)+v@<uJg8R|}u-=y!#W?_9 z9O`S=;JgPY06YNr1;Aznzkpp20Hy%mjz7SAgdX%6zy!dbLx3|vm@nl`Q2|T=JWZQW9(&>bwsMF z))YmtI2T)*rQN?Y%K4Op5R1i{tJUhaQ=)eTkH_ObbX|WtPWqh3M1OV35w|ZKtJ!RR zyH-cMEGt4t>!OK-PZE)WPjfAlX+j~`@N<|RoI48x%Pe&4CXE#`BDD2ktE zv)Ln~6D|IwgmgMhgTdez zmL6M{#RL}G?Y6543x~tbR%n_=-A+y<5^)Bbrs?{a6^%xBj#iXPrFA}^|CvgqC?N!+ w(FlfNpwsD`G?pX@g+c+MDDHB(+|AYV7aA_6+lU*g_W%F@07*qoM6N<$f*Fz{j{pDw literal 0 HcmV?d00001 diff --git a/data/images/objects/keys/outline_iron.png b/data/images/objects/keys/outline_iron.png new file mode 100644 index 0000000000000000000000000000000000000000..bab8cf5df7cf18dad04336275cf4b112af5d0b03 GIT binary patch literal 436 zcmV;l0ZaagP)9B0YHU+Nbh0JbII@oy3ER#og}C zWILc>jysu;{Q0vpL+A`H0KG+A%mLH@z}phX-*DrHGmwB%fVmUDl7Y;_XX-;RR;Wyo;EFNgpbC6FHp?o($KF^70(Ncx0(Vs?X eZHDJ<8TAhRPf0v#jGNy800009B0YHU+Nbh0JbII@oy3ER#og}C zWILc>jysu;{Q0vpL+A`H0KG+A%mLH@z}phX-*DrHGmwB%fVmUDl7Y;_XX-;RR;Wyo;EFNgpbC6FHp?o($KF^70(Ncx0(Vs?X eZHDJ<8TAhRPf0v#jGNy80000get_name(), Vector(0, 160), LAYER_FOREGROUND1); - sprintf(str, "TUX x %d", player_status.lives); + sprintf(str, "TUX x %d", player_status->lives); context.draw_text(white_text, str, Vector(SCREEN_WIDTH/2, 210), CENTER_ALLIGN, LAYER_FOREGROUND1); @@ -324,10 +324,10 @@ GameSession::try_cheats() tux.set_bonus(ICE_BONUS, false); } if(main_controller->check_cheatcode("lifeup")) { - player_status.lives++; + player_status->lives++; } if(main_controller->check_cheatcode("lifedown")) { - player_status.lives--; + player_status->lives--; } if(main_controller->check_cheatcode("grease")) { tux.physic.set_velocity_x(tux.physic.get_velocity_x()*3); @@ -342,7 +342,7 @@ GameSession::try_cheats() } if(main_controller->check_cheatcode("kill")) { // kill Tux, but without losing a life - player_status.lives++; + player_status->lives++; tux.kill(tux.KILL); } #if 0 @@ -389,7 +389,7 @@ GameSession::check_end_conditions() exit_status = ES_LEVEL_FINISHED; return; } else if (!end_sequence && tux->is_dead()) { - if (player_status.lives < 0) { // No more lives!? + if (player_status->lives < 0) { // No more lives!? exit_status = ES_GAME_OVER; } else { // Still has lives, so reset Tux to the levelstart restart_level(); @@ -717,17 +717,17 @@ GameSession::start_sequence(const std::string& sequencename) void GameSession::drawstatus(DrawingContext& context) { - player_status.draw(context); + player_status->draw(context); if(config->show_fps) { char str[60]; snprintf(str, sizeof(str), "%2.1f", fps_fps); context.draw_text(white_text, "FPS", Vector(SCREEN_WIDTH - - white_text->get_text_width("FPS "), 40), + white_text->get_text_width("FPS ") - BORDER_X, BORDER_Y + 40), LEFT_ALLIGN, LAYER_FOREGROUND1); context.draw_text(gold_text, str, - Vector(SCREEN_WIDTH-4*16, 40), + Vector(SCREEN_WIDTH-4*16 - BORDER_X, BORDER_Y + 40), LEFT_ALLIGN, LAYER_FOREGROUND1); } } @@ -752,7 +752,7 @@ GameSession::drawresultscreen() sprintf(str, _("SCORE: %d"), global_stats.get_points(SCORE_STAT)); context.draw_text(gold_text, str, Vector(SCREEN_WIDTH/2, 224), CENTER_ALLIGN, LAYER_FOREGROUND1); - sprintf(str, _("COINS: %d"), player_status.coins); + sprintf(str, _("COINS: %d"), player_status->coins); context.draw_text(gold_text, str, Vector(SCREEN_WIDTH/2, 256), CENTER_ALLIGN, LAYER_FOREGROUND1); context.do_drawing(); diff --git a/src/object/player.hpp b/src/object/player.hpp index 451ed0535..ddf02b578 100644 --- a/src/object/player.hpp +++ b/src/object/player.hpp @@ -30,6 +30,7 @@ #include "physic.hpp" #include "control/controller.hpp" #include "player_status.hpp" +#include "scripting/player.hpp" class BadGuy; class Portable; @@ -78,7 +79,7 @@ extern TuxBodyParts* big_tux; extern TuxBodyParts* fire_tux; extern TuxBodyParts* ice_tux; -class Player : public MovingObject +class Player : public MovingObject, public Scripting::Player { public: enum HurtMode { KILL, SHRINK }; diff --git a/src/player_status.cpp b/src/player_status.cpp index 57acb9348..50623be8e 100644 --- a/src/player_status.cpp +++ b/src/player_status.cpp @@ -25,12 +25,14 @@ #include "gettext.hpp" #include "video/drawing_context.hpp" #include "audio/sound_manager.hpp" +#include "sprite/sprite_manager.hpp" +#include "math/vector.hpp" #include "main.hpp" static const int START_LIVES = 4; static const int MAX_LIVES = 99; -PlayerStatus player_status; +PlayerStatus* player_status = 0; PlayerStatus::PlayerStatus() : coins(0), @@ -39,11 +41,32 @@ PlayerStatus::PlayerStatus() score_multiplier(1), max_score_multiplier(1) { + reset(); + key_brass = sprite_manager->create("key-brass"); + key_iron = sprite_manager->create("key-iron"); + key_bronze = sprite_manager->create("key-bronze"); + key_silver = sprite_manager->create("key-silver"); + key_gold = sprite_manager->create("key-gold"); + key_brass->set_action("outline"); + key_iron->set_action("outline"); + key_bronze->set_action("outline"); + key_silver->set_action("outline"); + key_gold->set_action("outline"); +} + +PlayerStatus::~PlayerStatus() +{ + delete key_brass; + delete key_iron; + delete key_bronze; + delete key_silver; + delete key_gold; } void PlayerStatus::reset() { coins = 0; + keys = 0; lives = START_LIVES; bonus = NO_BONUS; score_multiplier = 1; @@ -70,6 +93,17 @@ PlayerStatus::incCoins() } void +PlayerStatus::set_keys(int new_key) +{ + keys |= new_key; + key_brass->set_action(keys & KEY_BRASS ? "display" : "outline"); + key_iron->set_action(keys & KEY_IRON ? "display" : "outline"); + key_bronze->set_action(keys & KEY_BRONZE ? "display" : "outline"); + key_silver->set_action(keys & KEY_SILVER ? "display" : "outline"); + key_gold->set_action(keys & KEY_GOLD ? "display" : "outline"); +} + +void PlayerStatus::write(lisp::Writer& writer) { switch(bonus) { @@ -89,6 +123,11 @@ PlayerStatus::write(lisp::Writer& writer) std::cerr << "Unknown bonus type.\n"; writer.write_string("bonus", "none"); } + writer.write_bool("key-brass", keys & KEY_BRASS); + writer.write_bool("key-iron", keys & KEY_IRON); + writer.write_bool("key-bronze", keys & KEY_BRONZE); + writer.write_bool("key-silver", keys & KEY_SILVER); + writer.write_bool("key-gold", keys & KEY_GOLD); writer.write_int("lives", lives); writer.write_int("coins", coins); @@ -115,6 +154,17 @@ PlayerStatus::read(const lisp::Lisp& lisp) bonus = NO_BONUS; } } + bool val; + if(lisp.get("key-brass", val) && val == true) + set_keys(KEY_BRASS); + if(lisp.get("key-iron", val) && val == true) + set_keys(KEY_IRON); + if(lisp.get("key-bronze", val) && val == true) + set_keys(KEY_BRONZE); + if(lisp.get("key-silver", val) && val == true) + set_keys(KEY_SILVER); + if(lisp.get("key-gold", val) && val == true) + set_keys(KEY_GOLD); lisp.get("lives", lives); lisp.get("coins", coins); @@ -122,6 +172,24 @@ PlayerStatus::read(const lisp::Lisp& lisp) } void +PlayerStatus::draw_keys(DrawingContext& context) +{ + const float SPACING = 10; + float x,y; + x = BORDER_X; y = BORDER_Y; + key_brass->draw(context, Vector(x, y), LAYER_FOREGROUND1); + x += key_brass->get_width() + SPACING; + key_iron->draw(context, Vector(x, y), LAYER_FOREGROUND1); + x += key_iron->get_width() + SPACING; + key_bronze->draw(context, Vector(x, y), LAYER_FOREGROUND1); + x += key_bronze->get_width() + SPACING; + key_silver->draw(context, Vector(x, y), LAYER_FOREGROUND1); + x += key_silver->get_width() + SPACING; + key_gold->draw(context, Vector(x, y), LAYER_FOREGROUND1); + x += key_gold->get_width() + SPACING; +} + +void PlayerStatus::draw(DrawingContext& context) { context.push_transform(); @@ -129,35 +197,37 @@ PlayerStatus::draw(DrawingContext& context) char str[60]; - sprintf(str, " %d", player_status.coins); + sprintf(str, " %d", player_status->coins); const char* coinstext = _("COINS"); context.draw_text(white_text, coinstext, Vector(SCREEN_WIDTH - white_text->get_text_width(coinstext) - - white_text->get_text_width(" 99"), 0), + - white_text->get_text_width(" 99") - BORDER_X, BORDER_Y), LEFT_ALLIGN, LAYER_FOREGROUND1); context.draw_text(gold_text, str, - Vector(SCREEN_WIDTH - gold_text->get_text_width(" 99"), 0), + Vector(SCREEN_WIDTH - gold_text->get_text_width(" 99") - BORDER_X, BORDER_Y), LEFT_ALLIGN, LAYER_FOREGROUND1); - if (player_status.lives >= 5) { - sprintf(str, "%dx", player_status.lives); + if (player_status->lives >= 5) { + sprintf(str, "%dx", player_status->lives); float x = SCREEN_WIDTH - gold_text->get_text_width(str) - tux_life->w; - context.draw_text(gold_text, str, Vector(x, 20), LEFT_ALLIGN, + context.draw_text(gold_text, str, Vector(x - BORDER_X, BORDER_Y + 20), LEFT_ALLIGN, LAYER_FOREGROUND1); - context.draw_surface(tux_life, Vector(SCREEN_WIDTH - 16, 20), + context.draw_surface(tux_life, Vector(SCREEN_WIDTH - 16 - BORDER_X, BORDER_Y + 20), LAYER_FOREGROUND1); } else { - for(int i= 0; i < player_status.lives; ++i) + for(int i= 0; i < player_status->lives; ++i) context.draw_surface(tux_life, - Vector(SCREEN_WIDTH - tux_life->w*4 +(tux_life->w*i), 20), + Vector(SCREEN_WIDTH - tux_life->w*4 +(tux_life->w*i) - BORDER_X, BORDER_Y + 20), LAYER_FOREGROUND1); } const char* livestext = _("LIVES"); context.draw_text(white_text, livestext, Vector(SCREEN_WIDTH - white_text->get_text_width(livestext) - - white_text->get_text_width(" 99"), 20), + - white_text->get_text_width(" 99") - BORDER_X, BORDER_Y + 20), LEFT_ALLIGN, LAYER_FOREGROUND1); + + draw_keys(context); context.pop_transform(); } diff --git a/src/player_status.hpp b/src/player_status.hpp index 4ad7a6800..06db4f1ce 100644 --- a/src/player_status.hpp +++ b/src/player_status.hpp @@ -22,6 +22,10 @@ #include "lisp/lisp.hpp" #include "timer.hpp" #include "serializable.hpp" +#include "sprite/sprite.hpp" + +static const float BORDER_X = 10; +static const float BORDER_Y = 10; enum BonusType { NO_BONUS, GROWUP_BONUS, FIRE_BONUS, ICE_BONUS @@ -36,14 +40,17 @@ class PlayerStatus : public Serializable { public: PlayerStatus(); + ~PlayerStatus(); void reset(); void incLives(); void incCoins(); + void set_keys(int new_key); void write(lisp::Writer& writer); void read(const lisp::Lisp& lisp); void draw(DrawingContext& context); + void draw_keys(DrawingContext& context); int coins; int lives; @@ -51,9 +58,25 @@ public: int score_multiplier; int max_score_multiplier; + + enum { + KEY_BRASS = 0x001, + KEY_IRON = 0x002, + KEY_BRONZE = 0x004, + KEY_SILVER = 0x008, + KEY_GOLD = 0x010, + }; + +private: + int keys; + Sprite* key_iron; + Sprite* key_brass; + Sprite* key_bronze; + Sprite* key_silver; + Sprite* key_gold; }; // global player state -extern PlayerStatus player_status; +extern PlayerStatus* player_status; #endif diff --git a/src/resources.cpp b/src/resources.cpp index 39cb26f20..92f2f41ef 100644 --- a/src/resources.cpp +++ b/src/resources.cpp @@ -116,31 +116,8 @@ void load_shared() /* Tux life: */ tux_life = new Surface("images/creatures/tux_small/tux-life.png", true); - -#if 0 - /* Sound effects: */ - sound_manager->preload_sound("jump"); - sound_manager->preload_sound("bigjump"); - sound_manager->preload_sound("skid"); - sound_manager->preload_sound("coin"); - sound_manager->preload_sound("invincible"); - sound_manager->preload_sound("brick"); - sound_manager->preload_sound("hurt"); - sound_manager->preload_sound("squish"); - sound_manager->preload_sound("fall"); - sound_manager->preload_sound("ricochet"); - sound_manager->preload_sound("bump-upgrade"); - sound_manager->preload_sound("upgrade"); - sound_manager->preload_sound("grow"); - sound_manager->preload_sound("fire-flower"); - sound_manager->preload_sound("shoot"); - sound_manager->preload_sound("lifeup"); - sound_manager->preload_sound("stomp"); - sound_manager->preload_sound("kick"); - sound_manager->preload_sound("explosion"); - sound_manager->preload_sound("warp"); - sound_manager->preload_sound("fireworks"); -#endif + + player_status = new PlayerStatus(); } /* Free shared data: */ diff --git a/src/scripting/functions.cpp b/src/scripting/functions.cpp index 2e51cad65..f62ef9227 100644 --- a/src/scripting/functions.cpp +++ b/src/scripting/functions.cpp @@ -47,5 +47,10 @@ void import(HSQUIRRELVM v, const std::string& filename) } } +void add_key(int new_key) +{ + player_status->set_keys(new_key); +} + } diff --git a/src/scripting/functions.hpp b/src/scripting/functions.hpp index 512c69ee6..ba0d36ab8 100644 --- a/src/scripting/functions.hpp +++ b/src/scripting/functions.hpp @@ -3,11 +3,19 @@ #ifndef SCRIPTING_API #define __suspend +#include "player_status.hpp" #endif namespace Scripting { +//TODO: Get this from PlayerStatus (update MiniSwig!) +static const int KEY_BRASS = 0x001; +static const int KEY_IRON = 0x002; +static const int KEY_BRONZE = 0x004; +static const int KEY_SILVER = 0x008; +static const int KEY_GOLD = 0x010; + /** displays a text file and scrolls it over the screen */ void display_text_file(const std::string& filename); /** @@ -22,6 +30,9 @@ std::string translate(const std::string& text); * This is typically used to import functions from external files. */ void import(HSQUIRRELVM v, const std::string& filename); +/** add a key to the inventory + */ +void add_key(int new_key); } diff --git a/src/scripting/player.hpp b/src/scripting/player.hpp index 9c1f009fe..58f10419f 100644 --- a/src/scripting/player.hpp +++ b/src/scripting/player.hpp @@ -12,6 +12,7 @@ public: {} #endif +#if 0 /** * Set tux bonus. * This can be "grow", "fireflow" or "iceflower" at the moment @@ -29,6 +30,7 @@ public: * Give tux more coins */ virtual void add_coins(int count) = 0; +#endif }; } diff --git a/src/scripting/script_interpreter.cpp b/src/scripting/script_interpreter.cpp index f3c8d0793..eb53a0c54 100644 --- a/src/scripting/script_interpreter.cpp +++ b/src/scripting/script_interpreter.cpp @@ -179,8 +179,18 @@ ScriptInterpreter::add_script_object(Sector* sector, const std::string& name, std::auto_ptr interpreter( new ScriptInterpreter(workdir)); interpreter->register_sector(sector); + + // load global default.nut file if it exists + //TODO: Load all .nut files from that directory + try { + std::string filename = "data/script/default.nut"; + IFileStream in(filename); + interpreter->run_script(in, filename, false); + } catch(std::exception& e) { + // nothing + } - // load default.nut file if it exists + // load world-specific default.nut file if it exists try { std::string filename = workdir + "/default.nut"; IFileStream in(filename); diff --git a/src/scripting/sound.cpp b/src/scripting/sound.cpp index bf1c1101e..6b2ac531f 100644 --- a/src/scripting/sound.cpp +++ b/src/scripting/sound.cpp @@ -21,7 +21,7 @@ namespace Scripting std::string filename = "music/"; filename += name; filename += ".ogg"; - sound_manager->play_music(name); + sound_manager->play_music(filename); } void diff --git a/src/scripting/wrapper.cpp b/src/scripting/wrapper.cpp index 0a7813d2c..8eba394b8 100644 --- a/src/scripting/wrapper.cpp +++ b/src/scripting/wrapper.cpp @@ -417,50 +417,6 @@ static int Player_release_hook(SQUserPointer ptr, int ) return 0; } -static int Player_set_bonus_wrapper(HSQUIRRELVM v) -{ - Scripting::Player* _this; - sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - const char* arg0; - sq_getstring(v, 2, &arg0); - - _this->set_bonus(arg0); - - return 0; -} - -static int Player_make_invincible_wrapper(HSQUIRRELVM v) -{ - Scripting::Player* _this; - sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - - _this->make_invincible(); - - return 0; -} - -static int Player_add_life_wrapper(HSQUIRRELVM v) -{ - Scripting::Player* _this; - sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - - _this->add_life(); - - return 0; -} - -static int Player_add_coins_wrapper(HSQUIRRELVM v) -{ - Scripting::Player* _this; - sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0); - int arg0; - sq_getinteger(v, 2, &arg0); - - _this->add_coins(arg0); - - return 0; -} - static int display_text_file_wrapper(HSQUIRRELVM v) { const char* arg0; @@ -503,6 +459,16 @@ static int import_wrapper(HSQUIRRELVM v) return 0; } +static int add_key_wrapper(HSQUIRRELVM v) +{ + int arg0; + sq_getinteger(v, 2, &arg0); + + Scripting::add_key(arg0); + + return 0; +} + } // end of namespace Wrapper void create_squirrel_instance(HSQUIRRELVM v, Scripting::DisplayEffect* object, bool setup_releasehook) @@ -692,6 +658,46 @@ void register_supertux_wrapper(HSQUIRRELVM v) using namespace Wrapper; sq_pushroottable(v); + sq_pushstring(v, "KEY_BRASS", -1); + sq_pushinteger(v, 1); + if(SQ_FAILED(sq_createslot(v, -3))) { + std::ostringstream msg; + msg << "Couldn't register constant'KEY_BRASS'"; + throw SquirrelError(v, msg.str()); + } + + sq_pushstring(v, "KEY_IRON", -1); + sq_pushinteger(v, 2); + if(SQ_FAILED(sq_createslot(v, -3))) { + std::ostringstream msg; + msg << "Couldn't register constant'KEY_IRON'"; + throw SquirrelError(v, msg.str()); + } + + sq_pushstring(v, "KEY_BRONZE", -1); + sq_pushinteger(v, 4); + if(SQ_FAILED(sq_createslot(v, -3))) { + std::ostringstream msg; + msg << "Couldn't register constant'KEY_BRONZE'"; + throw SquirrelError(v, msg.str()); + } + + sq_pushstring(v, "KEY_SILVER", -1); + sq_pushinteger(v, 8); + if(SQ_FAILED(sq_createslot(v, -3))) { + std::ostringstream msg; + msg << "Couldn't register constant'KEY_SILVER'"; + throw SquirrelError(v, msg.str()); + } + + sq_pushstring(v, "KEY_GOLD", -1); + sq_pushinteger(v, 16); + if(SQ_FAILED(sq_createslot(v, -3))) { + std::ostringstream msg; + msg << "Couldn't register constant'KEY_GOLD'"; + throw SquirrelError(v, msg.str()); + } + sq_pushstring(v, "display_text_file", -1); sq_newclosure(v, &display_text_file_wrapper, 0); if(SQ_FAILED(sq_createslot(v, -3))) { @@ -724,6 +730,14 @@ void register_supertux_wrapper(HSQUIRRELVM v) throw SquirrelError(v, msg.str()); } + sq_pushstring(v, "add_key", -1); + sq_newclosure(v, &add_key_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + std::ostringstream msg; + msg << "Couldn't register function'add_key'"; + throw SquirrelError(v, msg.str()); + } + // Register class DisplayEffect sq_pushstring(v, "DisplayEffect", -1); if(sq_newclass(v, SQFalse) < 0) { @@ -1041,38 +1055,6 @@ void register_supertux_wrapper(HSQUIRRELVM v) msg << "Couldn't create new class 'Player'"; throw SquirrelError(v, msg.str()); } - sq_pushstring(v, "set_bonus", -1); - sq_newclosure(v, &Player_set_bonus_wrapper, 0); - if(SQ_FAILED(sq_createslot(v, -3))) { - std::ostringstream msg; - msg << "Couldn't register function'set_bonus'"; - throw SquirrelError(v, msg.str()); - } - - sq_pushstring(v, "make_invincible", -1); - sq_newclosure(v, &Player_make_invincible_wrapper, 0); - if(SQ_FAILED(sq_createslot(v, -3))) { - std::ostringstream msg; - msg << "Couldn't register function'make_invincible'"; - throw SquirrelError(v, msg.str()); - } - - sq_pushstring(v, "add_life", -1); - sq_newclosure(v, &Player_add_life_wrapper, 0); - if(SQ_FAILED(sq_createslot(v, -3))) { - std::ostringstream msg; - msg << "Couldn't register function'add_life'"; - throw SquirrelError(v, msg.str()); - } - - sq_pushstring(v, "add_coins", -1); - sq_newclosure(v, &Player_add_coins_wrapper, 0); - if(SQ_FAILED(sq_createslot(v, -3))) { - std::ostringstream msg; - msg << "Couldn't register function'add_coins'"; - throw SquirrelError(v, msg.str()); - } - if(SQ_FAILED(sq_createslot(v, -3))) { std::ostringstream msg; msg << "Couldn't register class'Player'"; diff --git a/src/sector.cpp b/src/sector.cpp index 2230eca94..79d80c6f5 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -72,7 +72,7 @@ Sector::Sector() currentmusic(LEVEL_MUSIC) { song_title = "chipdisko.ogg"; - player = new Player(&player_status); + player = new Player(player_status); add_object(player); #ifdef USE_GRID @@ -750,11 +750,11 @@ Sector::add_bullet(const Vector& pos, float xm, Direction dir) static const size_t MAX_ICE_BULLETS = 1; Bullet* new_bullet = 0; - if(player_status.bonus == FIRE_BONUS) { + if(player_status->bonus == FIRE_BONUS) { if(bullets.size() > MAX_FIRE_BULLETS-1) return false; new_bullet = new Bullet(pos, xm, dir, FIRE_BULLET); - } else if(player_status.bonus == ICE_BONUS) { + } else if(player_status->bonus == ICE_BONUS) { if(bullets.size() > MAX_ICE_BULLETS-1) return false; new_bullet = new Bullet(pos, xm, dir, ICE_BULLET); diff --git a/src/title.cpp b/src/title.cpp index 537ff96e0..266b28b92 100644 --- a/src/title.cpp +++ b/src/title.cpp @@ -82,7 +82,7 @@ static int current_subset = -1; */ void resume_demo() { - player_status.reset(); + player_status->reset(); titlesession->get_current_sector()->activate("main"); titlesession->set_current(); @@ -232,7 +232,7 @@ void check_contrib_subset_menu() GameSession session( current_contrib_subset->get_level_filename(index), ST_GL_PLAY); session.run(); - player_status.reset(); + player_status->reset(); Menu::set_current(main_menu); resume_demo(); } diff --git a/src/worldmap.cpp b/src/worldmap.cpp index 0123216c8..d31d4968f 100644 --- a/src/worldmap.cpp +++ b/src/worldmap.cpp @@ -132,7 +132,7 @@ Tux::~Tux() void Tux::draw(DrawingContext& context) { - switch (player_status.bonus) { + switch (player_status->bonus) { case GROWUP_BONUS: tux_sprite->set_action("large"); break; @@ -735,7 +735,7 @@ WorldMap::update(float delta) if (level->pos == tux->get_tile_pos()) { sound_manager->stop_music(); - PlayerStatus old_player_status = player_status; + PlayerStatus old_player_status = *player_status; // do a shriking fade to the level shrink_fade(Vector((level->pos.x*32 + 16 + offset.x), @@ -787,9 +787,9 @@ WorldMap::update(float delta) level_finished = false; /* In case the player's abort the level, keep it using the old status. But the minimum lives and no bonus. */ - player_status.coins = old_player_status.coins; - player_status.lives = std::min(old_player_status.lives, player_status.lives); - player_status.bonus = NO_BONUS; + player_status->coins = old_player_status.coins; + player_status->lives = std::min(old_player_status.lives, player_status->lives); + player_status->bonus = NO_BONUS; break; case GameSession::ES_GAME_OVER: @@ -808,7 +808,7 @@ WorldMap::update(float delta) context.draw_text(blue_text, _("GAMEOVER"), Vector(SCREEN_WIDTH/2, 200), CENTER_ALLIGN, LAYER_FOREGROUND1); - sprintf(str, _("COINS: %d"), player_status.coins); + sprintf(str, _("COINS: %d"), player_status->coins); context.draw_text(gold_text, str, Vector(SCREEN_WIDTH/2, SCREEN_WIDTH - 32), CENTER_ALLIGN, LAYER_FOREGROUND1); @@ -820,7 +820,7 @@ WorldMap::update(float delta) wait_for_event(2.0, 6.0); quit = true; - player_status.reset(); + player_status->reset(); break; } case GameSession::ES_NONE: @@ -936,7 +936,7 @@ WorldMap::draw_status(DrawingContext& context) context.push_transform(); context.set_translation(Vector(0, 0)); - player_status.draw(context); + player_status->draw(context); if (!tux->is_moving()) { @@ -1078,7 +1078,7 @@ WorldMap::savegame(const std::string& filename) writer.write_float("x", tux->get_tile_pos().x); writer.write_float("y", tux->get_tile_pos().y); writer.write_string("back", direction_to_string(tux->back_direction)); - player_status.write(writer); + player_status->write(writer); writer.write_string("back", direction_to_string(tux->back_direction)); writer.end_list("tux"); @@ -1124,11 +1124,11 @@ WorldMap::loadgame(const std::string& filename) load_map(); savegame->get("intro-displayed", intro_displayed); - savegame->get("lives", player_status.lives); - savegame->get("coins", player_status.coins); - savegame->get("max-score-multiplier", player_status.max_score_multiplier); - if (player_status.lives < 0) - player_status.reset(); + savegame->get("lives", player_status->lives); + savegame->get("coins", player_status->coins); + savegame->get("max-score-multiplier", player_status->max_score_multiplier); + if (player_status->lives < 0) + player_status->reset(); const lisp::Lisp* tux_lisp = savegame->get_lisp("tux"); if(tux) @@ -1139,7 +1139,7 @@ WorldMap::loadgame(const std::string& filename) tux_lisp->get("x", p.x); tux_lisp->get("y", p.y); tux_lisp->get("back", back_str); - player_status.read(*tux_lisp); + player_status->read(*tux_lisp); tux->back_direction = string_to_direction(back_str); tux->set_tile_pos(p); @@ -1176,7 +1176,7 @@ WorldMap::loadgame(const std::string& filename) std::cerr << "Problem loading game '" << filename << "': " << e.what() << "\n"; load_map(); - player_status.reset(); + player_status->reset(); } calculate_total_stats(); -- 2.11.0