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 "math/random_generator.hpp"
21 #include "object/bullet.hpp"
22 #include "object/explosion.hpp"
23 #include "supertux/object_factory.hpp"
24 #include "supertux/sector.hpp"
25 #include "sprite/sprite.hpp"
26 #include "sprite/sprite_manager.hpp"
27 #include "util/reader.hpp"
31 WeakBlock::WeakBlock(const Reader& lisp)
32 : MovingSprite(lisp, "images/objects/weak_block/strawbox.sprite", LAYER_TILES, COLGROUP_STATIC), state(STATE_NORMAL),
34 light(0.0f,0.0f,0.0f),
35 lightsprite(sprite_manager->create("images/objects/lightmap_light/lightmap_light-small.sprite"))
37 sprite->set_action("normal");
38 //Check if this weakblock destroys adjacent weakblocks
39 if(lisp.get("linked", linked)){
41 sprite_name = "images/objects/weak_block/meltbox.sprite";
42 sprite = sprite_manager->create(sprite_name);
43 sprite->set_action("normal");
46 lightsprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
47 lightsprite->set_color(Color(0.3f, 0.2f, 0.1f));
51 WeakBlock::collision_bullet(Bullet& bullet, const CollisionHit& hit)
56 //Ensure only fire destroys weakblock
57 if(bullet.get_type() == FIRE_BONUS) {
61 //Other bullets ricochet
63 bullet.ricochet(*this, hit);
68 case STATE_DISINTEGRATING:
72 log_debug << "unhandled state" << std::endl;
80 WeakBlock::collision(GameObject& other, const CollisionHit& hit)
85 if (Bullet* bullet = dynamic_cast<Bullet*> (&other)) {
86 return collision_bullet(*bullet, hit);
88 //Explosions destroy weakblocks as well
89 if (dynamic_cast<Explosion*> (&other)) {
95 case STATE_DISINTEGRATING:
99 log_debug << "unhandled state" << std::endl;
107 WeakBlock::update(float )
115 // cause burn light to flicker randomly
117 if(gameRandom.rand(10) >= 7) {
118 lightsprite->set_color(Color(0.2f + gameRandom.rand(20)/100.0f, 0.1f + gameRandom.rand(20)/100.0f, 0.1f));
120 lightsprite->set_color(Color(0.3f, 0.2f, 0.1f));
123 if (sprite->animation_done()) {
124 state = STATE_DISINTEGRATING;
125 sprite->set_action("disintegrating", 1);
127 set_group(COLGROUP_DISABLED);
128 lightsprite = sprite_manager->create("images/objects/lightmap_light/lightmap_light-tiny.sprite");
129 lightsprite->set_blend(Blend(GL_SRC_ALPHA, GL_ONE));
130 lightsprite->set_color(Color(0.3f, 0.2f, 0.1f));
134 case STATE_DISINTEGRATING:
135 if (sprite->animation_done()) {
145 WeakBlock::draw(DrawingContext& context)
147 //Draw the Sprite just in front of other objects
148 sprite->draw(context, get_pos(), LAYER_OBJECTS + 10);
149 //Draw the light if burning and dark
150 if(linked && (state != STATE_NORMAL)){
151 context.get_light( get_bbox().get_middle(), &light );
152 if (light.red + light.green + light.blue < 3.0){
153 context.push_target();
154 context.set_target(DrawingContext::LIGHTMAP);
155 sprite->draw(context, get_pos(), LAYER_OBJECTS + 10);
156 lightsprite->draw(context, get_bbox().get_middle(), 0);
157 context.pop_target();
163 WeakBlock::startBurning()
165 if (state != STATE_NORMAL) return;
166 state = STATE_BURNING;
167 sprite->set_action("burning", 1);
171 WeakBlock::spreadHit()
173 //Destroy adjacent weakblocks if applicable
175 Sector* sector = Sector::current();
177 log_debug << "no current sector" << std::endl;
180 for(Sector::GameObjects::iterator i = sector->gameobjects.begin(); i != sector->gameobjects.end(); ++i) {
181 WeakBlock* wb = dynamic_cast<WeakBlock*>(*i);
183 if (wb == this) continue;
184 if (wb->state != STATE_NORMAL) continue;
185 float dx = fabsf(wb->get_pos().x - this->get_pos().x);
186 float dy = fabsf(wb->get_pos().y - this->get_pos().y);
187 if ((dx <= 32.5) && (dy <= 32.5)) wb->startBurning();