1 //  SuperTux - Lantern
2 //  Copyright (C) 2006 Wolfgang Becker <uafr@gmx.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/lantern.hpp"
18 
19 #include <algorithm>
20 
21 #include "audio/sound_manager.hpp"
22 #include "badguy/treewillowisp.hpp"
23 #include "badguy/willowisp.hpp"
24 #include "editor/editor.hpp"
25 #include "sprite/sprite.hpp"
26 #include "sprite/sprite_manager.hpp"
27 #include "util/reader_mapping.hpp"
28 
Lantern(const ReaderMapping & reader)29 Lantern::Lantern(const ReaderMapping& reader) :
30   Rock(reader, "images/objects/lantern/lantern.sprite"),
31   lightcolor(1.0f, 1.0f, 1.0f),
32   lightsprite(SpriteManager::current()->create("images/objects/lightmap_light/lightmap_light.sprite"))
33 {
34   std::vector<float> vColor;
35   if (reader.get("color", vColor)) {
36     lightcolor = Color(vColor);
37   } else {
38     if (!Editor::is_active()) {
39       lightcolor = Color(0, 0, 0);
40     }
41   }
42   lightsprite->set_blend(Blend::ADD);
43   updateColor();
44   SoundManager::current()->preload("sounds/willocatch.wav");
45 }
46 
Lantern(const Vector & pos)47 Lantern::Lantern(const Vector& pos) :
48   Rock(pos, "images/objects/lantern/lantern.sprite"),
49   lightcolor(0.0f, 0.0f, 0.0f),
50   lightsprite(SpriteManager::current()->create("images/objects/lightmap_light/lightmap_light.sprite"))
51 {
52   lightsprite->set_blend(Blend::ADD);
53   updateColor();
54   SoundManager::current()->preload("sounds/willocatch.wav");
55 }
56 
57 ObjectSettings
get_settings()58 Lantern::get_settings()
59 {
60   ObjectSettings result = Rock::get_settings();
61 
62   result.add_color(_("Color"), &lightcolor, "color", Color::WHITE);
63 
64   result.reorder({"color", "name", "x", "y"});
65 
66   return result;
67 }
68 
69 void
after_editor_set()70 Lantern::after_editor_set()
71 {
72   Rock::after_editor_set();
73 
74   updateColor();
75 }
76 
77 void
updateColor()78 Lantern::updateColor(){
79   lightsprite->set_color(lightcolor);
80   //Turn lantern off if light is black
81   if (lightcolor.red == 0 && lightcolor.green == 0 && lightcolor.blue == 0){
82     m_sprite->set_action("off");
83     m_sprite->set_color(Color(1.0f, 1.0f, 1.0f));
84   } else {
85     m_sprite->set_action("normal");
86     m_sprite->set_color(lightcolor);
87   }
88 }
89 
90 void
draw(DrawingContext & context)91 Lantern::draw(DrawingContext& context){
92   //Draw the Sprite.
93   MovingSprite::draw(context);
94   //Let there be light.
95   lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0);
96 }
97 
collision(GameObject & other,const CollisionHit & hit)98 HitResponse Lantern::collision(GameObject& other, const CollisionHit& hit) {
99 
100   WillOWisp* wow = dynamic_cast<WillOWisp*>(&other);
101 
102   if (wow && (is_open() || wow->get_color().greyscale() == 0.f)) {
103     // collided with WillOWisp while grabbed and unlit
104     SoundManager::current()->play("sounds/willocatch.wav");
105     lightcolor = wow->get_color();
106     updateColor();
107     wow->vanish();
108   }
109 
110   TreeWillOWisp* twow = dynamic_cast<TreeWillOWisp*>(&other);
111   if (twow && (is_open() || twow->get_color().greyscale() == 0.f)) {
112     // collided with TreeWillOWisp while grabbed and unlit
113     SoundManager::current()->play("sounds/willocatch.wav");
114     lightcolor = twow->get_color();
115     updateColor();
116     twow->vanish();
117   }
118 
119   return Rock::collision(other, hit);
120 }
121 
122 void
grab(MovingObject & object,const Vector & pos,Direction dir)123 Lantern::grab(MovingObject& object, const Vector& pos, Direction dir)
124 {
125   Rock::grab(object, pos, dir);
126 
127   // if lantern is not lit, draw it as opened
128   if (is_open()) {
129     m_sprite->set_action("off-open");
130   }
131 
132 }
133 
134 void
ungrab(MovingObject & object,Direction dir)135 Lantern::ungrab(MovingObject& object, Direction dir)
136 {
137   // if lantern is not lit, it was drawn as opened while grabbed. Now draw it as closed again
138   if (is_open()) {
139     m_sprite->set_action("off");
140   }
141 
142   Rock::ungrab(object, dir);
143 }
144 
145 bool
is_open() const146 Lantern::is_open() const
147 {
148   return (is_grabbed() && lightcolor.red == 0 && lightcolor.green == 0 && lightcolor.blue == 0);
149 }
150 
151 void
add_color(const Color & c)152 Lantern::add_color(const Color& c)
153 {
154   lightcolor.red   = std::min(1.0f, lightcolor.red   + c.red);
155   lightcolor.green = std::min(1.0f, lightcolor.green + c.green);
156   lightcolor.blue  = std::min(1.0f, lightcolor.blue  + c.blue);
157   lightcolor.alpha = std::min(1.0f, lightcolor.alpha + c.alpha);
158   updateColor();
159 }
160 
161 /* EOF */
162