7 #include "special/sprite.h"
8 #include "special/sprite_manager.h"
9 #include "video/drawing_context.h"
10 #include "lisp/lisp.h"
12 #include "specialriser.h"
17 #include "player_status.h"
18 #include "badguy/badguy.h"
20 #include "object_factory.h"
22 static const float BOUNCY_BRICK_MAX_OFFSET=8;
23 static const float BOUNCY_BRICK_SPEED=90;
24 static const float EPSILON = .0001;
26 Block::Block(Sprite* newsprite)
27 : sprite(newsprite), bouncing(false), bounce_dir(0), bounce_offset(0)
29 bbox.set_size(32, 32.1);
39 Block::collision(GameObject& other, const CollisionHit& hitdata)
41 Player* player = dynamic_cast<Player*> (&other);
43 // collided from below?
44 if(hitdata.normal.x == 0 && hitdata.normal.y < 0) {
50 BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
54 Coin* coin = dynamic_cast<Coin*> (&other);
64 Block::action(float elapsed_time)
69 float offset = original_y - get_pos().y;
70 if(offset > BOUNCY_BRICK_MAX_OFFSET) {
71 bounce_dir = BOUNCY_BRICK_SPEED;
72 movement = Vector(0, bounce_dir * elapsed_time);
73 } else if(offset < BOUNCY_BRICK_SPEED * elapsed_time && bounce_dir > 0) {
74 movement = Vector(0, offset);
78 movement = Vector(0, bounce_dir * elapsed_time);
83 Block::draw(DrawingContext& context)
85 sprite->draw(context, get_pos(), LAYER_OBJECTS+1);
91 original_y = bbox.p1.y;
93 bounce_dir = -BOUNCY_BRICK_SPEED;
97 //---------------------------------------------------------------------------
99 BonusBlock::BonusBlock(const Vector& pos, int data)
100 : Block(sprite_manager->create("bonusblock"))
103 sprite->set_action("default");
105 case 1: contents = CONTENT_COIN; break;
106 case 2: contents = CONTENT_FIREGROW; break;
107 case 3: contents = CONTENT_STAR; break;
108 case 4: contents = CONTENT_1UP; break;
109 case 5: contents = CONTENT_ICEGROW; break;
111 std::cerr << "Invalid box contents!\n";
112 contents = CONTENT_COIN;
117 BonusBlock::BonusBlock(const lisp::Lisp& lisp)
118 : Block(sprite_manager->create("bonusblock"))
121 lisp.get("x", pos.x);
122 lisp.get("y", pos.y);
125 std::string contentstring;
126 contents = CONTENT_COIN;
127 if(lisp.get("contents", contentstring)) {
128 if(contentstring == "coin") {
129 contents = CONTENT_COIN;
130 } else if(contentstring == "firegrow") {
131 contents = CONTENT_FIREGROW;
132 } else if(contentstring == "icegrow") {
133 contents = CONTENT_ICEGROW;
134 } else if(contentstring == "star") {
135 contents = CONTENT_STAR;
136 } else if(contentstring == "1up") {
137 contents = CONTENT_1UP;
139 std::cerr << "Invalid box contents '" << contentstring << "'.\n";
145 BonusBlock::hit(Player& )
151 BonusBlock::try_open()
153 if(sprite->get_action_name() == "empty") {
154 SoundManager::get()->play_sound(IDToSound(SND_BRICK));
158 Sector* sector = Sector::current();
159 Player& player = *(sector->player);
162 Sector::current()->add_object(new BouncyCoin(get_pos()));
163 player.get_status().incCoins();
166 case CONTENT_FIREGROW:
167 if(player.size == SMALL) {
168 SpecialRiser* riser = new SpecialRiser(
169 new GrowUp(get_pos() + Vector(0, -32)));
170 sector->add_object(riser);
172 SpecialRiser* riser = new SpecialRiser(
173 new Flower(get_pos() + Vector(0, -32), Flower::FIREFLOWER));
174 sector->add_object(riser);
176 SoundManager::get()->play_sound(IDToSound(SND_UPGRADE));
179 case CONTENT_ICEGROW:
180 if(player.size == SMALL) {
181 SpecialRiser* riser = new SpecialRiser(
182 new GrowUp(get_pos() + Vector(0, -32)));
183 sector->add_object(riser);
185 SpecialRiser* riser = new SpecialRiser(
186 new Flower(get_pos() + Vector(0, -32), Flower::ICEFLOWER));
187 sector->add_object(riser);
189 SoundManager::get()->play_sound(IDToSound(SND_UPGRADE));
193 sector->add_object(new Star(get_pos() + Vector(0, -32)));
197 sector->add_object(new OneUp(get_pos()));
205 sprite->set_action("empty");
208 IMPLEMENT_FACTORY(BonusBlock, "bonusblock")
210 //---------------------------------------------------------------------------
212 Brick::Brick(const Vector& pos, int data)
213 : Block(sprite_manager->create("brick")), breakable(false),
226 if(sprite->get_action_name() == "empty")
233 Brick::try_break(bool playerhit)
235 if(sprite->get_action_name() == "empty")
238 SoundManager::get()->play_sound(IDToSound(SND_BRICK));
239 Sector* sector = Sector::current();
240 Player& player = *(sector->player);
241 if(coin_counter > 0) {
242 sector->add_object(new BouncyCoin(get_pos()));
244 player.get_status().incCoins();
245 if(coin_counter == 0)
246 sprite->set_action("empty");
248 } else if(breakable) {
249 if(playerhit && player.size == SMALL) {
255 new BrokenBrick(new Sprite(*sprite), get_pos(), Vector(-100, -400)));
257 new BrokenBrick(new Sprite(*sprite), get_pos() + Vector(0, 16),
258 Vector(-150, -300)));
260 new BrokenBrick(new Sprite(*sprite), get_pos() + Vector(16, 0),
263 new BrokenBrick(new Sprite(*sprite), get_pos() + Vector(16, 16),
269 //IMPLEMENT_FACTORY(Brick, "brick")