Candle made more versatile: flicker can be disabled and RGB light color chosen
[supertux.git] / src / object / candle.cpp
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 "math/random_generator.hpp"
18 #include "object/candle.hpp"
19 #include "object/sprite_particle.hpp"
20 #include "scripting/candle.hpp"
21 #include "scripting/squirrel_util.hpp"
22 #include "supertux/object_factory.hpp"
23 #include "supertux/sector.hpp"
24 #include "util/reader.hpp"
25
26 Candle::Candle(const Reader& lisp)
27   : MovingSprite(lisp, "images/objects/candle/candle.sprite", LAYER_BACKGROUNDTILES+1, COLGROUP_DISABLED), 
28     burning(true), 
29     flicker(true),
30     lightcolor(1.0f, 1.0f, 1.0f),
31     candle_light_1(sprite_manager->create("images/objects/candle/candle-light-1.sprite")),
32     candle_light_2(sprite_manager->create("images/objects/candle/candle-light-2.sprite"))
33 {
34   lisp.get("name", name);
35   lisp.get("burning", burning);
36   lisp.get("flicker", flicker);
37   //get color from lisp
38   std::vector<float> vColor;
39   lisp.get("color", vColor);
40   if (vColor.size() >= 3) {
41     lightcolor = Color(vColor);
42     candle_light_1->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
43     candle_light_2->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
44     candle_light_1->set_color(lightcolor);
45     candle_light_2->set_color(lightcolor);
46   }
47     
48   if (burning) {
49     sprite->set_action("on");
50   } else {
51     sprite->set_action("off");
52   }
53
54 }
55
56 void
57 Candle::draw(DrawingContext& context)
58 {
59   // draw regular sprite
60   sprite->draw(context, get_pos(), layer);
61
62   // draw on lightmap
63   if (burning) {
64     //Vector pos = get_pos() + (bbox.get_size() - candle_light_1->get_size()) / 2;
65     context.push_target();
66     context.set_target(DrawingContext::LIGHTMAP);
67     // draw approx. 1 in 10 frames darker. Makes the candle flicker
68     if (gameRandom.rand(10) != 0 || !flicker) {
69       //context.draw_surface(candle_light_1, pos, layer);
70       candle_light_1->draw(context, get_bbox().get_middle(), 0);
71     } else {
72       //context.draw_surface(candle_light_2, pos, layer);
73       candle_light_2->draw(context, get_bbox().get_middle(), 0);
74     }
75     context.pop_target();
76   }
77 }
78
79 HitResponse
80 Candle::collision(GameObject&, const CollisionHit& )
81 {
82   return FORCE_MOVE;
83 }
84
85 void
86 Candle::expose(HSQUIRRELVM vm, SQInteger table_idx)
87 {
88   if (name.empty()) return;
89   scripting::Candle* _this = new scripting::Candle(this);
90   expose_object(vm, table_idx, _this, name, true);
91 }
92
93 void
94 Candle::unexpose(HSQUIRRELVM vm, SQInteger table_idx)
95 {
96   if (name.empty()) return;
97   scripting::unexpose_object(vm, table_idx, name);
98 }
99
100 void
101 Candle::puff_smoke()
102 {
103   Vector ppos = bbox.get_middle();
104   Vector pspeed = Vector(0, -150);
105   Vector paccel = Vector(0,0);
106   Sector::current()->add_object(new SpriteParticle("images/objects/particles/smoke.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_BACKGROUNDTILES+2));
107 }
108
109 bool
110 Candle::get_burning()
111 {
112   return burning;
113 }
114
115 void
116 Candle::set_burning(bool burning)
117 {
118   if (this->burning == burning) return;
119   this->burning = burning;
120   if (burning) {
121     sprite->set_action("on");
122   } else {
123     sprite->set_action("off");
124   }
125   //puff smoke for flickering light sources only
126   if (flicker) puff_smoke();
127 }
128
129 /* EOF */