1// SuperTux
2// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.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/candle.hpp"
18
19#include "math/random.hpp"
20#include "object/sprite_particle.hpp"
21#include "sprite/sprite.hpp"
22#include "sprite/sprite_manager.hpp"
23#include "supertux/sector.hpp"
24#include "util/reader_mapping.hpp"
25
26Candle::Candle(const ReaderMapping& mapping) :
27 MovingSprite(mapping, "images/objects/candle/candle.sprite", LAYER_BACKGROUNDTILES+1, COLGROUP_DISABLED),
28 ExposedObject<Candle, scripting::Candle>(this),
29 burning(true),
30 flicker(true),
31 lightcolor(1.0f, 1.0f, 1.0f),
32 candle_light_1(SpriteManager::current()->create("images/objects/candle/candle-light-1.sprite")),
33 candle_light_2(SpriteManager::current()->create("images/objects/candle/candle-light-2.sprite"))
34{
35 mapping.get("burning", burning, true);
36 mapping.get("flicker", flicker, true);
37 std::vector<float> vColor;
38 if (!mapping.get("color", vColor)) vColor = {1.0f, 1.0f, 1.0f};
39
40 //change the light color if defined
41 if (vColor.size() >= 3) {
42 lightcolor = Color(vColor);
43 candle_light_1->set_blend(Blend::ADD);
44 candle_light_2->set_blend(Blend::ADD);
45 candle_light_1->set_color(lightcolor);
46 candle_light_2->set_color(lightcolor);
47 //the following allows the original candle appearance to be preserved
48 candle_light_1->set_action("white");
49 candle_light_2->set_action("white");
50 }
51
52 if (burning) {
53 m_sprite->set_action("on");
54 } else {
55 m_sprite->set_action("off");
56 }
57
58}
59
60void
61Candle::after_editor_set()
62{
63 candle_light_1->set_color(lightcolor);
64 candle_light_2->set_color(lightcolor);
65
66 m_sprite->set_action(burning ? "on" : "off");
67}
68
69ObjectSettings
70Candle::get_settings()
71{
72 ObjectSettings result = MovingSprite::get_settings();
73
74 result.add_bool(_("Burning"), &burning, "burning", true);
75 result.add_bool(_("Flicker"), &flicker, "flicker", true);
76 result.add_color(_("Color"), &lightcolor, "color", Color::WHITE);
77
78 result.reorder({"burning", "flicker", "name", "sprite", "color", "x", "y"});
79
80 return result;
81}
82
83void
84Candle::draw(DrawingContext& context)
85{
86 // draw regular sprite
87 m_sprite->draw(context.color(), get_pos(), m_layer);
88
89 // draw on lightmap
90 if (burning) {
91 //Vector pos = get_pos() + (bbox.get_size() - candle_light_1->get_size()) / 2;
92 // draw approx. 1 in 10 frames darker. Makes the candle flicker
93 if (gameRandom.rand(10) != 0 || !flicker) {
94 //context.color().draw_surface(candle_light_1, pos, layer);
95 candle_light_1->draw(context.light(), m_col.m_bbox.get_middle(), 0);
96 } else {
97 //context.color().draw_surface(candle_light_2, pos, layer);
98 candle_light_2->draw(context.light(), m_col.m_bbox.get_middle(), 0);
99 }
100 }
101}
102
103HitResponse
104Candle::collision(GameObject&, const CollisionHit& )
105{
106 return FORCE_MOVE;
107}
108
109void
110Candle::puff_smoke()
111{
112 Vector ppos = m_col.m_bbox.get_middle();
113 Vector pspeed = Vector(0, -150);
114 Vector paccel = Vector(0,0);
115 Sector::get().add<SpriteParticle>("images/objects/particles/smoke.sprite",
116 "default",
117 ppos, ANCHOR_MIDDLE,
118 pspeed, paccel,
119 LAYER_BACKGROUNDTILES+2);
120}
121
122bool
123Candle::get_burning() const
124{
125 return burning;
126}
127
128void
129Candle::set_burning(bool burning_)
130{
131 if (burning == burning_) return;
132 burning = burning_;
133 if (burning_) {
134 m_sprite->set_action("on");
135 } else {
136 m_sprite->set_action("off");
137 }
138 //puff smoke for flickering light sources only
139 if (flicker) puff_smoke();
140}
141
142/* EOF */
143