qMax <qwiglydee@gmail.com>'s font patch, adds unicode support and support for drawing...
[supertux.git] / src / player_status.cpp
1 //  $Id$
2 //
3 //  SuperTux
4 //  Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
5 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
6 //
7 //  This program is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU General Public License
9 //  as published by the Free Software Foundation; either version 2
10 //  of the License, or (at your option) any later version.
11 //
12 //  This program is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //  GNU General Public License for more details.
16 //
17 //  You should have received a copy of the GNU General Public License
18 //  along with this program; if not, write to the Free Software
19 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 #include <config.h>
21
22 #include <math.h>
23 #include "lisp/writer.hpp"
24 #include "lisp/lisp.hpp"
25 #include "player_status.hpp"
26 #include "resources.hpp"
27 #include "gettext.hpp"
28 #include "video/drawing_context.hpp"
29 #include "audio/sound_manager.hpp"
30 #include "sprite/sprite_manager.hpp"
31 #include "math/vector.hpp"
32 #include "main.hpp"
33 #include "log.hpp"
34 #include "timer.hpp"
35
36 static const int START_COINS = 100;
37 static const int MAX_COINS = 99999;
38
39 PlayerStatus* player_status = 0;
40
41 PlayerStatus::PlayerStatus()
42   : coins(START_COINS),
43     bonus(NO_BONUS),
44     max_fire_bullets(0),
45     max_ice_bullets(0),
46     score_multiplier(1),
47     max_score_multiplier(1)
48 {
49   reset();
50
51   coin_surface.reset(new Surface("images/engine/hud/coins-0.png"));
52   sound_manager->preload("sounds/coin.wav");
53   sound_manager->preload("sounds/lifeup.wav");
54 }
55
56 PlayerStatus::~PlayerStatus()
57 {
58 }
59
60 void PlayerStatus::reset()
61 {
62   coins = START_COINS;
63   bonus = NO_BONUS;
64   score_multiplier = 1;
65   max_score_multiplier = 1;
66 }
67
68 void
69 PlayerStatus::add_coins(int count, bool play_sound)
70 {
71   static float sound_played_time = 0;
72   coins = std::min(coins + count, MAX_COINS);
73   if(play_sound) {
74     if(count >= 100)
75       sound_manager->play("sounds/lifeup.wav");
76     else if (real_time > sound_played_time + 0.010) {
77       sound_manager->play("sounds/coin.wav");
78       sound_played_time = real_time;
79     }
80   }
81 }
82
83 void
84 PlayerStatus::write(lisp::Writer& writer)
85 {
86   switch(bonus) {
87     case NO_BONUS:
88       writer.write_string("bonus", "none");
89       break;
90     case GROWUP_BONUS:
91       writer.write_string("bonus", "growup");
92       break;
93     case FIRE_BONUS:
94       writer.write_string("bonus", "fireflower");
95       break;
96     case ICE_BONUS:
97       writer.write_string("bonus", "iceflower");
98       break;
99     default:
100       log_warning << "Unknown bonus type." << std::endl;
101       writer.write_string("bonus", "none");
102   }
103   writer.write_int("fireflowers", max_fire_bullets);
104   writer.write_int("iceflowers", max_ice_bullets);
105
106   writer.write_int("coins", coins);
107   writer.write_int("max-score-multiplier", max_score_multiplier);
108 }
109
110 void
111 PlayerStatus::read(const lisp::Lisp& lisp)
112 {
113   reset();
114
115   std::string bonusname;
116   if(lisp.get("bonus", bonusname)) {
117     if(bonusname == "none") {
118       bonus = NO_BONUS;
119     } else if(bonusname == "growup") {
120       bonus = GROWUP_BONUS;
121     } else if(bonusname == "fireflower") {
122       bonus = FIRE_BONUS;
123     } else if(bonusname == "iceflower") {
124       bonus = ICE_BONUS;
125     } else {
126       log_warning << "Unknown bonus '" << bonusname << "' in savefile" << std::endl;
127       bonus = NO_BONUS;
128     }
129   }
130   lisp.get("fireflowers", max_fire_bullets);
131   lisp.get("iceflowers", max_ice_bullets);
132
133   lisp.get("coins", coins);
134   lisp.get("max-score-multiplier", max_score_multiplier);
135 }
136
137 void
138 PlayerStatus::draw(DrawingContext& context)
139 {
140   static int displayed_coins = -1;
141   static int next_count = 0;
142
143   if ((displayed_coins == -1) || (fabsf(displayed_coins - coins) > 100)) {
144     displayed_coins = coins;
145   }
146   if (++next_count > 2) {
147     next_count = 0;
148     if (displayed_coins < coins) displayed_coins++;
149     if (displayed_coins > coins) displayed_coins--;
150   }
151   displayed_coins = std::min(std::max(displayed_coins, 0), 9999);
152
153   std::stringstream ss;
154   ss << displayed_coins;
155   std::string coins_text = ss.str();
156
157   context.push_transform();
158   context.set_translation(Vector(0, 0));
159
160   Surface* coin_surf = coin_surface.get();
161   if (coin_surf) {
162     context.draw_surface(coin_surf, Vector(SCREEN_WIDTH - BORDER_X - coin_surf->get_width() - fixed_font->get_text_width(coins_text), BORDER_Y + 1), LAYER_HUD);
163   }
164   context.draw_text(fixed_font, coins_text, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y), ALIGN_RIGHT, LAYER_HUD, PlayerStatus::text_color);
165
166   context.pop_transform();
167 }
168
169 void
170 PlayerStatus::operator= (const PlayerStatus& other)
171 {
172   coins = other.coins;
173   bonus = other.bonus;
174   score_multiplier = other.score_multiplier;
175   max_score_multiplier = other.max_score_multiplier;
176 }