1 // SuperTux - Weak Block
2 // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 // Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "object/weak_block.hpp"
20 #include "audio/sound_manager.hpp"
21 #include "math/random_generator.hpp"
22 #include "object/bullet.hpp"
23 #include "object/explosion.hpp"
24 #include "supertux/object_factory.hpp"
25 #include "supertux/sector.hpp"
26 #include "sprite/sprite.hpp"
27 #include "sprite/sprite_manager.hpp"
28 #include "util/reader.hpp"
32 WeakBlock::WeakBlock(const Reader& lisp)
33 : MovingSprite(lisp, "images/objects/weak_block/strawbox.sprite", LAYER_TILES, COLGROUP_STATIC), state(STATE_NORMAL),
35 light(0.0f,0.0f,0.0f),
36 lightsprite(sprite_manager->create("images/objects/lightmap_light/lightmap_light-small.sprite"))
38 sprite->set_action("normal");
39 //Check if this weakblock destroys adjacent weakblocks
40 if(lisp.get("linked", linked)){
42 sprite_name = "images/objects/weak_block/meltbox.sprite";
43 sprite = sprite_manager->create(sprite_name);
44 sprite->set_action("normal");
47 if(sprite_name == "images/objects/weak_block/strawbox.sprite") {
48 lightsprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
49 lightsprite->set_color(Color(0.3f, 0.2f, 0.1f));
50 } else if(sprite_name == "images/objects/weak_block/meltbox.sprite")
51 sound_manager->preload("sounds/sizzle.ogg");
55 WeakBlock::collision_bullet(Bullet& bullet, const CollisionHit& hit)
60 //Ensure only fire destroys weakblock
61 if(bullet.get_type() == FIRE_BONUS) {
65 //Other bullets ricochet
67 bullet.ricochet(*this, hit);
72 case STATE_DISINTEGRATING:
76 log_debug << "unhandled state" << std::endl;
84 WeakBlock::collision(GameObject& other, const CollisionHit& hit)
89 if (Bullet* bullet = dynamic_cast<Bullet*> (&other)) {
90 return collision_bullet(*bullet, hit);
92 //Explosions destroy weakblocks as well
93 if (dynamic_cast<Explosion*> (&other)) {
99 case STATE_DISINTEGRATING:
103 log_debug << "unhandled state" << std::endl;
111 WeakBlock::update(float )
119 // cause burn light to flicker randomly
121 if(gameRandom.rand(10) >= 7) {
122 lightsprite->set_color(Color(0.2f + gameRandom.rand(20)/100.0f, 0.1f + gameRandom.rand(20)/100.0f, 0.1f));
124 lightsprite->set_color(Color(0.3f, 0.2f, 0.1f));
127 if (sprite->animation_done()) {
128 state = STATE_DISINTEGRATING;
129 sprite->set_action("disintegrating", 1);
131 set_group(COLGROUP_DISABLED);
132 lightsprite = sprite_manager->create("images/objects/lightmap_light/lightmap_light-tiny.sprite");
133 lightsprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
134 lightsprite->set_color(Color(0.3f, 0.2f, 0.1f));
138 case STATE_DISINTEGRATING:
139 if (sprite->animation_done()) {
149 WeakBlock::draw(DrawingContext& context)
151 //Draw the Sprite just in front of other objects
152 sprite->draw(context, get_pos(), LAYER_OBJECTS + 10);
153 //Draw the light if burning and dark
154 if(linked && (state != STATE_NORMAL)){
155 context.get_light( get_bbox().get_middle(), &light );
156 if (light.red + light.green + light.blue < 3.0){
157 context.push_target();
158 context.set_target(DrawingContext::LIGHTMAP);
159 sprite->draw(context, get_pos(), LAYER_OBJECTS + 10);
160 lightsprite->draw(context, get_bbox().get_middle(), 0);
161 context.pop_target();
167 WeakBlock::startBurning()
169 if (state != STATE_NORMAL) return;
170 state = STATE_BURNING;
171 sprite->set_action("burning", 1);
172 if(sprite_name == "images/objects/weak_block/meltbox.sprite")
173 sound_manager->play("sounds/sizzle.ogg");
177 WeakBlock::spreadHit()
179 //Destroy adjacent weakblocks if applicable
181 Sector* sector = Sector::current();
183 log_debug << "no current sector" << std::endl;
186 for(Sector::GameObjects::iterator i = sector->gameobjects.begin(); i != sector->gameobjects.end(); ++i) {
187 WeakBlock* wb = dynamic_cast<WeakBlock*>(*i);
189 if (wb == this) continue;
190 if (wb->state != STATE_NORMAL) continue;
191 float dx = fabsf(wb->get_pos().x - this->get_pos().x);
192 float dy = fabsf(wb->get_pos().y - this->get_pos().y);
193 if ((dx <= 32.5) && (dy <= 32.5)) wb->startBurning();