* Fixed a few own mistakes from a previous commit
[supertux.git] / src / player_status.cpp
1 //  $Id$
2 //
3 //  SuperTux -  A Jump'n Run
4 //  Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 #include <config.h>
20
21 #include "lisp/writer.hpp"
22 #include "lisp/lisp.hpp"
23 #include "player_status.hpp"
24 #include "resources.hpp"
25 #include "gettext.hpp"
26 #include "video/drawing_context.hpp"
27 #include "audio/sound_manager.hpp"
28 #include "sprite/sprite_manager.hpp"
29 #include "math/vector.hpp"
30 #include "main.hpp"
31
32 static const int START_LIVES = 4;
33 static const int MAX_LIVES = 99;
34
35 PlayerStatus* player_status = 0;
36
37 PlayerStatus::PlayerStatus()
38   : coins(0),
39     lives(START_LIVES),
40     bonus(NO_BONUS),
41     score_multiplier(1),
42     max_score_multiplier(1)
43 {
44   reset();
45   key_brass = sprite_manager->create("key-brass");
46   key_iron = sprite_manager->create("key-iron");
47   key_bronze = sprite_manager->create("key-bronze");
48   key_silver = sprite_manager->create("key-silver");
49   key_gold = sprite_manager->create("key-gold");
50   key_brass->set_action("outline");
51   key_iron->set_action("outline");
52   key_bronze->set_action("outline");
53   key_silver->set_action("outline");
54   key_gold->set_action("outline");
55 }
56
57 PlayerStatus::~PlayerStatus()
58 {
59   delete key_brass;
60   delete key_iron;
61   delete key_bronze;
62   delete key_silver;
63   delete key_gold;
64 }
65
66 void PlayerStatus::reset()
67 {
68   coins = 0;
69   keys = 0;
70   lives = START_LIVES;
71   bonus = NO_BONUS;
72   score_multiplier = 1;
73   max_score_multiplier = 1;
74 }
75
76 void
77 PlayerStatus::incLives()
78 {
79   if(lives < MAX_LIVES)
80     ++lives;
81   sound_manager->play("sounds/lifeup.wav");
82 }
83
84 void
85 PlayerStatus::incCoins()
86 {
87   coins++;
88   if(coins >= 100) {
89     incLives();
90     coins = 0;
91   }
92   sound_manager->play("sounds/coin.wav");
93 }
94
95 void
96 PlayerStatus::set_keys(int new_key)
97 {
98   keys |= new_key;
99   key_brass->set_action(keys & KEY_BRASS ? "display" : "outline");
100   key_iron->set_action(keys & KEY_IRON ? "display" : "outline");
101   key_bronze->set_action(keys & KEY_BRONZE ? "display" : "outline");
102   key_silver->set_action(keys & KEY_SILVER ? "display" : "outline");
103   key_gold->set_action(keys & KEY_GOLD ? "display" : "outline");
104 }
105
106 void
107 PlayerStatus::write(lisp::Writer& writer)
108 {
109   switch(bonus) {
110     case NO_BONUS:
111       writer.write_string("bonus", "none");
112       break;
113     case GROWUP_BONUS:
114       writer.write_string("bonus", "growup");
115       break;
116     case FIRE_BONUS:
117       writer.write_string("bonus", "fireflower");
118       break;
119     case ICE_BONUS:
120       writer.write_string("bonus", "iceflower");
121       break;
122     default:
123       std::cerr << "Unknown bonus type.\n";
124       writer.write_string("bonus", "none");
125   }
126   writer.write_bool("key-brass", keys & KEY_BRASS);
127   writer.write_bool("key-iron", keys & KEY_IRON);
128   writer.write_bool("key-bronze", keys & KEY_BRONZE);
129   writer.write_bool("key-silver", keys & KEY_SILVER);
130   writer.write_bool("key-gold", keys & KEY_GOLD);
131
132   writer.write_int("lives", lives);
133   writer.write_int("coins", coins);
134   writer.write_int("max-score-multiplier", max_score_multiplier);
135 }
136
137 void
138 PlayerStatus::read(const lisp::Lisp& lisp)
139 {
140   reset();
141   
142   std::string bonusname;
143   if(lisp.get("bonus", bonusname)) {
144     if(bonusname == "none") {
145       bonus = NO_BONUS;
146     } else if(bonusname == "growup") {
147       bonus = GROWUP_BONUS;
148     } else if(bonusname == "fireflower") {
149       bonus = FIRE_BONUS;
150     } else if(bonusname == "iceflower") {
151       bonus = ICE_BONUS;
152     } else {
153       std::cerr << "Unknown bonus '" << bonusname << "' in savefile.\n";
154       bonus = NO_BONUS;
155     }
156   }
157   bool val = false;
158   if(lisp.get("key-brass", val) && val == true)
159     set_keys(KEY_BRASS);
160   if(lisp.get("key-iron", val) && val == true)
161     set_keys(KEY_IRON);
162   if(lisp.get("key-bronze", val) && val == true)
163     set_keys(KEY_BRONZE);
164   if(lisp.get("key-silver", val) && val == true)
165     set_keys(KEY_SILVER);
166   if(lisp.get("key-gold", val) && val == true)
167     set_keys(KEY_GOLD);
168
169   lisp.get("lives", lives);
170   lisp.get("coins", coins);
171   lisp.get("max-score-multiplier", max_score_multiplier);
172 }
173
174 void
175 PlayerStatus::draw_keys(DrawingContext& context)
176 {
177   const float SPACING = 10;
178   float x,y; 
179   x = BORDER_X; y = BORDER_Y;
180   key_brass->draw(context, Vector(x, y), LAYER_FOREGROUND1);
181   x += key_brass->get_width() + SPACING;
182   key_iron->draw(context, Vector(x, y), LAYER_FOREGROUND1);
183   x += key_iron->get_width() + SPACING;
184   key_bronze->draw(context, Vector(x, y), LAYER_FOREGROUND1);
185   x += key_bronze->get_width() + SPACING;
186   key_silver->draw(context, Vector(x, y), LAYER_FOREGROUND1);
187   x += key_silver->get_width() + SPACING;
188   key_gold->draw(context, Vector(x, y), LAYER_FOREGROUND1);
189   x += key_gold->get_width() + SPACING;
190 }
191
192 void
193 PlayerStatus::draw(DrawingContext& context)
194 {
195   context.push_transform();
196   context.set_translation(Vector(0, 0));
197
198   char str[60];
199   
200   sprintf(str, " %d", player_status->coins);
201   const char* coinstext = _("COINS");
202   context.draw_text(white_text, coinstext,
203       Vector(SCREEN_WIDTH - white_text->get_text_width(coinstext) 
204               - white_text->get_text_width("   99") - BORDER_X, BORDER_Y),
205       LEFT_ALLIGN, LAYER_FOREGROUND1);
206   context.draw_text(gold_text, str,
207       Vector(SCREEN_WIDTH - gold_text->get_text_width(" 99") - BORDER_X, BORDER_Y),
208       LEFT_ALLIGN, LAYER_FOREGROUND1);
209
210   if (player_status->lives >= 5) {
211     sprintf(str, "%dx", player_status->lives);
212     float x = SCREEN_WIDTH - gold_text->get_text_width(str) - tux_life->get_width();
213     context.draw_text(gold_text, str, Vector(x - BORDER_X, BORDER_Y + 20), LEFT_ALLIGN,
214                       LAYER_FOREGROUND1);
215     context.draw_surface(tux_life, Vector(SCREEN_WIDTH - 16 - BORDER_X, BORDER_Y + 20),
216                          LAYER_FOREGROUND1);
217   } else {
218     for(int i= 0; i < player_status->lives; ++i)
219       context.draw_surface(tux_life, 
220           Vector(SCREEN_WIDTH - tux_life->get_width()*4 +(tux_life->get_width()*i) - BORDER_X,
221                  BORDER_Y + 20),
222           LAYER_FOREGROUND1);
223   }
224
225   const char* livestext = _("LIVES");
226   context.draw_text(white_text, livestext,
227       Vector(SCREEN_WIDTH - white_text->get_text_width(livestext) 
228                 - white_text->get_text_width("   99") - BORDER_X, BORDER_Y + 20),
229       LEFT_ALLIGN, LAYER_FOREGROUND1);
230   
231   draw_keys(context);  
232
233   context.pop_transform();
234 }
235
236 void
237 PlayerStatus::operator= (const PlayerStatus& other)
238 {
239   coins = other.coins;
240   lives = other.lives;
241   bonus = other.bonus;
242   score_multiplier = other.score_multiplier;
243   max_score_multiplier = other.max_score_multiplier;
244   keys = other.keys;
245 }
246