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 "supertux/player_status.hpp"
19 
20 #include <sstream>
21 
22 #include "audio/sound_manager.hpp"
23 #include "supertux/globals.hpp"
24 #include "supertux/game_session.hpp"
25 #include "util/log.hpp"
26 #include "util/reader_mapping.hpp"
27 #include "util/writer.hpp"
28 
29 static const int START_COINS = 100;
30 static const int MAX_COINS = 9999;
31 
PlayerStatus()32 PlayerStatus::PlayerStatus() :
33   coins(START_COINS),
34   bonus(NO_BONUS),
35   max_fire_bullets(0),
36   max_ice_bullets(0),
37   max_air_time(0),
38   max_earth_time(0),
39   worldmap_sprite("images/worldmap/common/tux.sprite"),
40   last_worldmap()
41 {
42   reset();
43 
44   // FIXME: Move sound handling into PlayerStatusHUD
45   if (SoundManager::current()) {
46     SoundManager::current()->preload("sounds/coin.wav");
47     SoundManager::current()->preload("sounds/lifeup.wav");
48   }
49 }
50 
51 void
take_checkpoint_coins()52 PlayerStatus::take_checkpoint_coins()
53 {
54   int subtract_value = std::max(coins / 10, 25);
55   if (coins - subtract_value >= 0)
56     coins -= subtract_value;
57   else
58     coins = 0;
59 }
60 
reset()61 void PlayerStatus::reset()
62 {
63   coins = START_COINS;
64   bonus = NO_BONUS;
65 }
66 
67 int
get_max_coins() const68 PlayerStatus::get_max_coins() const
69 {
70   return MAX_COINS;
71 }
72 
73 bool
can_reach_checkpoint() const74 PlayerStatus::can_reach_checkpoint() const
75 {
76   return !GameSession::current()->get_reset_point_sectorname().empty();
77 }
78 
79 void
add_coins(int count,bool play_sound)80 PlayerStatus::add_coins(int count, bool play_sound)
81 {
82   coins = std::min(coins + count, MAX_COINS);
83 
84   if (!play_sound)
85     return;
86 
87   static float sound_played_time = 0;
88   if (count >= 100)
89     SoundManager::current()->play("sounds/lifeup.wav");
90   else if (g_real_time > sound_played_time + 0.010f) {
91     SoundManager::current()->play("sounds/coin.wav");
92     sound_played_time = g_real_time;
93   }
94 }
95 
96 void
write(Writer & writer)97 PlayerStatus::write(Writer& writer)
98 {
99   switch (bonus) {
100     case NO_BONUS:
101       writer.write("bonus", "none");
102       break;
103     case GROWUP_BONUS:
104       writer.write("bonus", "growup");
105       break;
106     case FIRE_BONUS:
107       writer.write("bonus", "fireflower");
108       break;
109     case ICE_BONUS:
110       writer.write("bonus", "iceflower");
111       break;
112     case AIR_BONUS:
113       writer.write("bonus", "airflower");
114       break;
115     case EARTH_BONUS:
116       writer.write("bonus", "earthflower");
117       break;
118     default:
119       log_warning << "Unknown bonus type." << std::endl;
120       writer.write("bonus", "none");
121   }
122   writer.write("fireflowers", max_fire_bullets);
123   writer.write("iceflowers", max_ice_bullets);
124   writer.write("airflowers", max_air_time);
125   writer.write("earthflowers", max_earth_time);
126 
127   writer.write("coins", coins);
128 
129   writer.write("worldmap-sprite", worldmap_sprite, false);
130   writer.write("last-worldmap", last_worldmap, false);
131 }
132 
133 void
read(const ReaderMapping & mapping)134 PlayerStatus::read(const ReaderMapping& mapping)
135 {
136   reset();
137 
138   std::string bonusname;
139   if (mapping.get("bonus", bonusname)) {
140     if (bonusname == "none") {
141       bonus = NO_BONUS;
142     } else if (bonusname == "growup") {
143       bonus = GROWUP_BONUS;
144     } else if (bonusname == "fireflower") {
145       bonus = FIRE_BONUS;
146     } else if (bonusname == "iceflower") {
147       bonus = ICE_BONUS;
148     } else if (bonusname == "airflower") {
149       bonus = AIR_BONUS;
150     } else if (bonusname == "earthflower") {
151       bonus = EARTH_BONUS;
152     } else {
153       log_warning << "Unknown bonus '" << bonusname << "' in savefile" << std::endl;
154       bonus = NO_BONUS;
155     }
156   }
157   mapping.get("fireflowers", max_fire_bullets);
158   mapping.get("iceflowers", max_ice_bullets);
159   mapping.get("airflowers", max_air_time);
160   mapping.get("earthflowers", max_earth_time);
161 
162   mapping.get("coins", coins);
163 
164   mapping.get("worldmap-sprite", worldmap_sprite);
165   mapping.get("last-worldmap", last_worldmap);
166 }
167 
get_bonus_prefix() const168 std::string PlayerStatus::get_bonus_prefix() const
169 {
170   switch (bonus) {
171   default:
172   case NO_BONUS:
173     return "small";
174   case GROWUP_BONUS:
175     return "big";
176   case FIRE_BONUS:
177     return "fire";
178   case ICE_BONUS:
179     return "ice";
180   case AIR_BONUS:
181     return "air";
182   case EARTH_BONUS:
183     return "earth";
184   }
185 }
186 
187 /* EOF */
188