yeti cleanup and death animation rework, hitbox fix ups
[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 "lisp/writer.hpp"
23 #include "lisp/lisp.hpp"
24 #include "player_status.hpp"
25 #include "resources.hpp"
26 #include "gettext.hpp"
27 #include "video/drawing_context.hpp"
28 #include "audio/sound_manager.hpp"
29 #include "sprite/sprite_manager.hpp"
30 #include "math/vector.hpp"
31 #include "main.hpp"
32 #include "log.hpp"
33
34 static const int START_COINS = 100;
35 static const int MAX_COINS = 99999;
36
37 PlayerStatus* player_status = 0;
38
39 PlayerStatus::PlayerStatus()
40   : coins(START_COINS),
41     bonus(NO_BONUS),
42     score_multiplier(1),
43     max_score_multiplier(1)
44 {
45   reset();
46   key_brass.reset(sprite_manager->create("images/objects/keys/key_brass.sprite"));
47   key_iron.reset(sprite_manager->create("images/objects/keys/key_iron.sprite"));
48   key_bronze.reset(sprite_manager->create("images/objects/keys/key_bronze.sprite"));
49   key_silver.reset(sprite_manager->create("images/objects/keys/key_silver.sprite"));
50   key_gold.reset(sprite_manager->create("images/objects/keys/key_gold.sprite"));
51   key_brass->set_action("outline");
52   key_iron->set_action("outline");
53   key_bronze->set_action("outline");
54   key_silver->set_action("outline");
55   key_gold->set_action("outline");
56   
57   tux_life.reset(sprite_manager->create("images/creatures/tux_small/tux-life.sprite"));
58
59   Console::instance->registerCommand("coins", this);
60 }
61
62 PlayerStatus::~PlayerStatus()
63 {
64 }
65
66 void PlayerStatus::reset()
67 {
68   coins = START_COINS;
69   keys = 0;
70   bonus = NO_BONUS;
71   score_multiplier = 1;
72   max_score_multiplier = 1;
73 }
74
75 void
76 PlayerStatus::add_coins(int count)
77 {
78   coins = std::min(coins + count, MAX_COINS);
79   if(count > 100)
80     sound_manager->play("sounds/lifeup.wav");
81   else
82     sound_manager->play("sounds/coin.wav");
83 }
84
85 void
86 PlayerStatus::set_keys(int new_key)
87 {
88   keys |= new_key;
89   key_brass->set_action(keys & KEY_BRASS ? "display" : "outline");
90   key_iron->set_action(keys & KEY_IRON ? "display" : "outline");
91   key_bronze->set_action(keys & KEY_BRONZE ? "display" : "outline");
92   key_silver->set_action(keys & KEY_SILVER ? "display" : "outline");
93   key_gold->set_action(keys & KEY_GOLD ? "display" : "outline");
94 }
95
96 void
97 PlayerStatus::write(lisp::Writer& writer)
98 {
99   switch(bonus) {
100     case NO_BONUS:
101       writer.write_string("bonus", "none");
102       break;
103     case GROWUP_BONUS:
104       writer.write_string("bonus", "growup");
105       break;
106     case FIRE_BONUS:
107       writer.write_string("bonus", "fireflower");
108       break;
109     case ICE_BONUS:
110       writer.write_string("bonus", "iceflower");
111       break;
112     default:
113       log_warning << "Unknown bonus type." << std::endl;
114       writer.write_string("bonus", "none");
115   }
116   writer.write_bool("key-brass", keys & KEY_BRASS);
117   writer.write_bool("key-iron", keys & KEY_IRON);
118   writer.write_bool("key-bronze", keys & KEY_BRONZE);
119   writer.write_bool("key-silver", keys & KEY_SILVER);
120   writer.write_bool("key-gold", keys & KEY_GOLD);
121
122   writer.write_int("coins", coins);
123   writer.write_int("max-score-multiplier", max_score_multiplier);
124 }
125
126 void
127 PlayerStatus::read(const lisp::Lisp& lisp)
128 {
129   reset();
130   
131   std::string bonusname;
132   if(lisp.get("bonus", bonusname)) {
133     if(bonusname == "none") {
134       bonus = NO_BONUS;
135     } else if(bonusname == "growup") {
136       bonus = GROWUP_BONUS;
137     } else if(bonusname == "fireflower") {
138       bonus = FIRE_BONUS;
139     } else if(bonusname == "iceflower") {
140       bonus = ICE_BONUS;
141     } else {
142       log_warning << "Unknown bonus '" << bonusname << "' in savefile" << std::endl;
143       bonus = NO_BONUS;
144     }
145   }
146   bool val = false;
147   if(lisp.get("key-brass", val) && val == true)
148     set_keys(KEY_BRASS);
149   if(lisp.get("key-iron", val) && val == true)
150     set_keys(KEY_IRON);
151   if(lisp.get("key-bronze", val) && val == true)
152     set_keys(KEY_BRONZE);
153   if(lisp.get("key-silver", val) && val == true)
154     set_keys(KEY_SILVER);
155   if(lisp.get("key-gold", val) && val == true)
156     set_keys(KEY_GOLD);
157
158   lisp.get("coins", coins);
159   lisp.get("max-score-multiplier", max_score_multiplier);
160 }
161
162 void
163 PlayerStatus::draw_keys(DrawingContext& context)
164 {
165   const float SPACING = 10;
166   float x,y; 
167   x = BORDER_X; y = BORDER_Y;
168   key_brass->draw(context, Vector(x, y), LAYER_FOREGROUND1);
169   x += key_brass->get_width() + SPACING;
170   key_iron->draw(context, Vector(x, y), LAYER_FOREGROUND1);
171   x += key_iron->get_width() + SPACING;
172   key_bronze->draw(context, Vector(x, y), LAYER_FOREGROUND1);
173   x += key_bronze->get_width() + SPACING;
174   key_silver->draw(context, Vector(x, y), LAYER_FOREGROUND1);
175   x += key_silver->get_width() + SPACING;
176   key_gold->draw(context, Vector(x, y), LAYER_FOREGROUND1);
177   x += key_gold->get_width() + SPACING;
178 }
179
180 void
181 PlayerStatus::draw(DrawingContext& context)
182 {
183   context.push_transform();
184   context.set_translation(Vector(0, 0));
185
186   char str[60];
187  
188   int displayCoins = std::max(player_status->coins, 0);
189   sprintf(str, "%d", displayCoins);
190   const char* coinstext = _("COINS");
191   context.draw_text(white_text, coinstext, Vector(SCREEN_WIDTH - white_text->get_text_width(coinstext) - gold_text->get_text_width(" 99999") - BORDER_X, BORDER_Y), LEFT_ALLIGN, LAYER_FOREGROUND1);
192   context.draw_text(gold_text, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y), RIGHT_ALLIGN, LAYER_FOREGROUND1);
193
194   draw_keys(context);  
195
196   context.pop_transform();
197 }
198
199 void
200 PlayerStatus::operator= (const PlayerStatus& other)
201 {
202   coins = other.coins;
203   bonus = other.bonus;
204   score_multiplier = other.score_multiplier;
205   max_score_multiplier = other.max_score_multiplier;
206   keys = other.keys;
207 }
208
209 bool
210 PlayerStatus::consoleCommand(std::string command, std::vector<std::string> arguments)
211 {
212   if (command == "coins") {
213     if ((arguments.size() < 1) || (!Console::string_is<int>(arguments[0]))) {
214       log_info << "Usage: coins <number>" << std::endl;
215     } else {
216       coins = Console::string_to<int>(arguments[0]);
217     }
218     return true;
219   }
220   return false;
221 }
222