1// SuperTux
2// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17#include "object/level_time.hpp"
18
19#include <algorithm>
20
21#include "editor/editor.hpp"
22#include "object/player.hpp"
23#include "supertux/resources.hpp"
24#include "supertux/sector.hpp"
25#include "util/reader_mapping.hpp"
26#include "video/drawing_context.hpp"
27#include "video/surface.hpp"
28
29/** When to alert player they're low on time! */
30static const float TIME_WARNING = 20;
31
32LevelTime::LevelTime(const ReaderMapping& reader) :
33 GameObject(reader),
34 ExposedObject<LevelTime, scripting::LevelTime>(this),
35 time_surface(Surface::from_file("images/engine/hud/time-0.png")),
36 running(!Editor::is_active()),
37 time_left()
38{
39 reader.get("time", time_left, 0.0f);
40 if (time_left <= 0 && !Editor::is_active()) {
41 log_warning << "No or invalid leveltime specified." << std::endl;
42 remove_me();
43 }
44}
45
46ObjectSettings
47LevelTime::get_settings()
48{
49 ObjectSettings result = GameObject::get_settings();
50
51 result.add_float(_("Time"), &time_left, "time");
52 result.add_remove();
53
54 return result;
55}
56
57void
58LevelTime::update(float dt_sec)
59{
60 if (!running) return;
61
62 int prev_time = static_cast<int>(floorf(time_left*5));
63 time_left -= dt_sec;
64 if (time_left <= 0) {
65 if (time_left <= -5 || !Sector::get().get_player().get_coins())
66 {
67 Sector::get().get_player().kill(true);
68 stop();
69 }
70 if (prev_time != static_cast<int>(floorf(time_left*5)))
71 {
72 Sector::get().get_player().add_coins(-1);
73 }
74 }
75}
76
77void
78LevelTime::draw(DrawingContext& context)
79{
80 context.push_transform();
81 context.set_translation(Vector(0, 0));
82
83 if ((time_left > TIME_WARNING) || (int(g_game_time * 2.5f) % 2)) {
84 std::stringstream ss;
85 ss << int(time_left);
86 std::string time_text = ss.str();
87
88 if (time_surface)
89 {
90 float all_width = static_cast<float>(time_surface->get_width()) + Resources::normal_font->get_text_width(time_text);
91 context.color().draw_surface(time_surface,
92 Vector((static_cast<float>(context.get_width()) - all_width) / 2.0f,
93 BORDER_Y + 1),
94 LAYER_FOREGROUND1);
95 context.color().draw_text(Resources::normal_font, time_text,
96 Vector((static_cast<float>(context.get_width()) - all_width) / 2.0f + static_cast<float>(time_surface->get_width()),
97 BORDER_Y),
98 ALIGN_LEFT, LAYER_FOREGROUND1, LevelTime::text_color);
99 }
100 }
101
102 context.pop_transform();
103}
104
105void
106LevelTime::start()
107{
108 running = true;
109}
110
111void
112LevelTime::stop()
113{
114 running = false;
115}
116
117float
118LevelTime::get_time() const
119{
120 return time_left;
121}
122
123void
124LevelTime::set_time(float time_left_)
125{
126 time_left = std::min(std::max(time_left_, 0.0f), 999.0f);
127}
128
129/* EOF */
130