Fixing a few cppcheck warnings
[supertux.git] / src / supertux / player_status.cpp
1 //  SuperTux
2 //  Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
3 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
4 //
5 //  This program is free software: you can redistribute it and/or modify
6 //  it under the terms of the GNU General Public License as published by
7 //  the Free Software Foundation, either version 3 of the License, or
8 //  (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18 #include <math.h>
19 #include <sstream>
20
21 #include "audio/sound_manager.hpp"
22 #include "util/writer.hpp"
23 #include "supertux/globals.hpp"
24 #include "supertux/player_status.hpp"
25 #include "supertux/resources.hpp"
26 #include "supertux/timer.hpp"
27 #include "util/reader.hpp"
28 #include "video/drawing_context.hpp"
29
30 static const int START_COINS = 100;
31 static const int MAX_COINS = 9999;
32
33 static const int DISPLAYED_COINS_UNSET = -1;
34
35 PlayerStatus* player_status = 0;
36
37 PlayerStatus::PlayerStatus() :
38   /* Do we really want -Weffc++ to bully us into duplicating code from "reset" here? */
39   coins(START_COINS),
40   bonus(NO_BONUS),
41   max_fire_bullets(0),
42   max_ice_bullets(0),
43   max_air_time(0),
44   max_earth_time(0),
45   displayed_coins(DISPLAYED_COINS_UNSET),
46   displayed_coins_frame(0),
47   coin_surface()
48 {
49   reset();
50
51   coin_surface = Surface::create("images/engine/hud/coins-0.png");
52   SoundManager::current()->preload("sounds/coin.wav");
53   SoundManager::current()->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   displayed_coins = DISPLAYED_COINS_UNSET;
65 }
66
67 void
68 PlayerStatus::add_coins(int count, bool play_sound)
69 {
70   coins = std::min(coins + count, MAX_COINS);
71
72   if(!play_sound)
73     return;
74
75   static float sound_played_time = 0;
76   if(count >= 100)
77     SoundManager::current()->play("sounds/lifeup.wav");
78   else if (real_time > sound_played_time + 0.010) {
79     SoundManager::current()->play("sounds/coin.wav");
80     sound_played_time = real_time;
81   }
82 }
83
84 void
85 PlayerStatus::write(lisp::Writer& writer)
86 {
87   switch(bonus) {
88     case NO_BONUS:
89       writer.write("bonus", "none");
90       break;
91     case GROWUP_BONUS:
92       writer.write("bonus", "growup");
93       break;
94     case FIRE_BONUS:
95       writer.write("bonus", "fireflower");
96       break;
97     case ICE_BONUS:
98       writer.write("bonus", "iceflower");
99       break;
100     case AIR_BONUS:
101       writer.write("bonus", "airflower");
102       break;
103     case EARTH_BONUS:
104       writer.write("bonus", "earthflower");
105       break;
106     default:
107       log_warning << "Unknown bonus type." << std::endl;
108       writer.write("bonus", "none");
109   }
110   writer.write("fireflowers", max_fire_bullets);
111   writer.write("iceflowers", max_ice_bullets);
112   writer.write("airflowers", max_air_time);
113   writer.write("earthflowers", max_earth_time);
114
115   writer.write("coins", coins);
116 }
117
118 void
119 PlayerStatus::read(const Reader& lisp)
120 {
121   reset();
122
123   std::string bonusname;
124   if(lisp.get("bonus", bonusname)) {
125     if(bonusname == "none") {
126       bonus = NO_BONUS;
127     } else if(bonusname == "growup") {
128       bonus = GROWUP_BONUS;
129     } else if(bonusname == "fireflower") {
130       bonus = FIRE_BONUS;
131     } else if(bonusname == "iceflower") {
132       bonus = ICE_BONUS;
133     } else if(bonusname == "airflower") {
134       bonus = AIR_BONUS;
135     } else if(bonusname == "earthflower") {
136       bonus = EARTH_BONUS;
137     } else {
138       log_warning << "Unknown bonus '" << bonusname << "' in savefile" << std::endl;
139       bonus = NO_BONUS;
140     }
141   }
142   lisp.get("fireflowers", max_fire_bullets);
143   lisp.get("iceflowers", max_ice_bullets);
144   lisp.get("airflowers", max_air_time);
145   lisp.get("earthflowers", max_earth_time);
146
147   lisp.get("coins", coins);
148 }
149
150 void
151 PlayerStatus::draw(DrawingContext& context)
152 {
153   int player_id = 0;
154
155   if ((displayed_coins == DISPLAYED_COINS_UNSET) ||
156       (fabsf(displayed_coins - coins) > 100)) {
157     displayed_coins = coins;
158     displayed_coins_frame = 0;
159   }
160   if (++displayed_coins_frame > 2) {
161     displayed_coins_frame = 0;
162     if (displayed_coins < coins) displayed_coins++;
163     if (displayed_coins > coins) displayed_coins--;
164   }
165   displayed_coins = std::min(std::max(displayed_coins, 0), 9999);
166
167   std::stringstream ss;
168   ss << displayed_coins;
169   std::string coins_text = ss.str();
170
171   context.push_transform();
172   context.set_translation(Vector(0, 0));
173
174   if (coin_surface)
175   {
176     context.draw_surface(coin_surface,
177                          Vector(SCREEN_WIDTH - BORDER_X - coin_surface->get_width() - Resources::fixed_font->get_text_width(coins_text),
178                                 BORDER_Y + 1 + (Resources::fixed_font->get_text_height(coins_text) + 5) * player_id),
179                          LAYER_HUD);
180   }
181   context.draw_text(Resources::fixed_font,
182                     coins_text,
183                     Vector(SCREEN_WIDTH - BORDER_X - Resources::fixed_font->get_text_width(coins_text),
184                            BORDER_Y + (Resources::fixed_font->get_text_height(coins_text) + 5) * player_id),
185                     ALIGN_LEFT,
186                     LAYER_HUD,
187                     PlayerStatus::text_color);
188
189   context.pop_transform();
190 }
191
192 /* EOF */