2ce2de74da0ff7ead0f0e967d9f233e8bf078550
[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   static float sound_played_time = 0;
71   coins = std::min(coins + count, MAX_COINS);
72   if(play_sound) {
73     if(count >= 100)
74       SoundManager::current()->play("sounds/lifeup.wav");
75     else if (real_time > sound_played_time + 0.010) {
76       SoundManager::current()->play("sounds/coin.wav");
77       sound_played_time = real_time;
78     }
79   }
80 }
81
82 void
83 PlayerStatus::write(lisp::Writer& writer)
84 {
85   switch(bonus) {
86     case NO_BONUS:
87       writer.write("bonus", "none");
88       break;
89     case GROWUP_BONUS:
90       writer.write("bonus", "growup");
91       break;
92     case FIRE_BONUS:
93       writer.write("bonus", "fireflower");
94       break;
95     case ICE_BONUS:
96       writer.write("bonus", "iceflower");
97       break;
98     case AIR_BONUS:
99       writer.write("bonus", "airflower");
100       break;
101     case EARTH_BONUS:
102       writer.write("bonus", "earthflower");
103       break;
104     default:
105       log_warning << "Unknown bonus type." << std::endl;
106       writer.write("bonus", "none");
107   }
108   writer.write("fireflowers", max_fire_bullets);
109   writer.write("iceflowers", max_ice_bullets);
110   writer.write("airflowers", max_air_time);
111   writer.write("earthflowers", max_earth_time);
112
113   writer.write("coins", coins);
114 }
115
116 void
117 PlayerStatus::read(const Reader& lisp)
118 {
119   reset();
120
121   std::string bonusname;
122   if(lisp.get("bonus", bonusname)) {
123     if(bonusname == "none") {
124       bonus = NO_BONUS;
125     } else if(bonusname == "growup") {
126       bonus = GROWUP_BONUS;
127     } else if(bonusname == "fireflower") {
128       bonus = FIRE_BONUS;
129     } else if(bonusname == "iceflower") {
130       bonus = ICE_BONUS;
131     } else if(bonusname == "airflower") {
132       bonus = AIR_BONUS;
133     } else if(bonusname == "earthflower") {
134       bonus = EARTH_BONUS;
135     } else {
136       log_warning << "Unknown bonus '" << bonusname << "' in savefile" << std::endl;
137       bonus = NO_BONUS;
138     }
139   }
140   lisp.get("fireflowers", max_fire_bullets);
141   lisp.get("iceflowers", max_ice_bullets);
142   lisp.get("airflowers", max_air_time);
143   lisp.get("earthflowers", max_earth_time);
144
145   lisp.get("coins", coins);
146 }
147
148 void
149 PlayerStatus::draw(DrawingContext& context)
150 {
151   int player_id = 0;
152
153   if ((displayed_coins == DISPLAYED_COINS_UNSET) ||
154       (fabsf(displayed_coins - coins) > 100)) {
155     displayed_coins = coins;
156     displayed_coins_frame = 0;
157   }
158   if (++displayed_coins_frame > 2) {
159     displayed_coins_frame = 0;
160     if (displayed_coins < coins) displayed_coins++;
161     if (displayed_coins > coins) displayed_coins--;
162   }
163   displayed_coins = std::min(std::max(displayed_coins, 0), 9999);
164
165   std::stringstream ss;
166   ss << displayed_coins;
167   std::string coins_text = ss.str();
168
169   context.push_transform();
170   context.set_translation(Vector(0, 0));
171
172   if (coin_surface)
173   {
174     context.draw_surface(coin_surface,
175                          Vector(SCREEN_WIDTH - BORDER_X - coin_surface->get_width() - Resources::fixed_font->get_text_width(coins_text),
176                                 BORDER_Y + 1 + (Resources::fixed_font->get_text_height(coins_text) + 5) * player_id),
177                          LAYER_HUD);
178   }
179   context.draw_text(Resources::fixed_font,
180                     coins_text,
181                     Vector(SCREEN_WIDTH - BORDER_X - Resources::fixed_font->get_text_width(coins_text),
182                            BORDER_Y + (Resources::fixed_font->get_text_height(coins_text) + 5) * player_id),
183                     ALIGN_LEFT,
184                     LAYER_HUD,
185                     PlayerStatus::text_color);
186
187   context.pop_transform();
188 }
189
190 /* EOF */