00001 // SuperTux - Weak Block 00002 // Copyright (C) 2006 Matthias Braun <matze@braunis.de> 00003 // Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de> 00004 // 00005 // This program is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 00018 #include "object/weak_block.hpp" 00019 00020 #include "object/bullet.hpp" 00021 #include "object/explosion.hpp" 00022 #include "supertux/object_factory.hpp" 00023 #include "supertux/sector.hpp" 00024 00025 #include <math.h> 00026 00027 WeakBlock::WeakBlock(const Reader& lisp) 00028 : MovingSprite(lisp, "images/objects/strawbox/strawbox.sprite", LAYER_TILES, COLGROUP_STATIC), state(STATE_NORMAL) 00029 { 00030 sprite->set_action("normal"); 00031 } 00032 00033 HitResponse 00034 WeakBlock::collision(GameObject& other, const CollisionHit& ) 00035 { 00036 switch (state) { 00037 00038 case STATE_NORMAL: 00039 if (dynamic_cast<Bullet*>(&other)) { 00040 startBurning(); 00041 } 00042 if (dynamic_cast<Explosion*> (&other)) { 00043 startBurning(); 00044 } 00045 break; 00046 00047 case STATE_BURNING: 00048 case STATE_DISINTEGRATING: 00049 break; 00050 00051 default: 00052 log_debug << "unhandled state" << std::endl; 00053 break; 00054 } 00055 00056 return FORCE_MOVE; 00057 } 00058 00059 void 00060 WeakBlock::update(float ) 00061 { 00062 switch (state) { 00063 00064 case STATE_NORMAL: 00065 break; 00066 00067 case STATE_BURNING: 00068 if (sprite->animation_done()) { 00069 state = STATE_DISINTEGRATING; 00070 sprite->set_action("disintegrating", 1); 00071 spreadHit(); 00072 set_group(COLGROUP_DISABLED); 00073 } 00074 break; 00075 00076 case STATE_DISINTEGRATING: 00077 if (sprite->animation_done()) { 00078 remove_me(); 00079 return; 00080 } 00081 break; 00082 00083 } 00084 } 00085 00086 void 00087 WeakBlock::startBurning() 00088 { 00089 if (state != STATE_NORMAL) return; 00090 state = STATE_BURNING; 00091 sprite->set_action("burning", 1); 00092 } 00093 00094 void 00095 WeakBlock::spreadHit() 00096 { 00097 Sector* sector = Sector::current(); 00098 if (!sector) { 00099 log_debug << "no current sector" << std::endl; 00100 return; 00101 } 00102 for(Sector::GameObjects::iterator i = sector->gameobjects.begin(); i != sector->gameobjects.end(); ++i) { 00103 WeakBlock* wb = dynamic_cast<WeakBlock*>(*i); 00104 if (!wb) continue; 00105 if (wb == this) continue; 00106 if (wb->state != STATE_NORMAL) continue; 00107 float dx = fabsf(wb->get_pos().x - this->get_pos().x); 00108 float dy = fabsf(wb->get_pos().y - this->get_pos().y); 00109 if ((dx <= 32.5) && (dy <= 32.5)) wb->startBurning(); 00110 } 00111 } 00112 00113 00114 /* EOF */