The BIG COMMIT(tm)
[supertux.git] / src / object / bullet.cpp
1 #include <config.h>
2
3 #include <math.h>
4 #include "bullet.h"
5 #include "defines.h"
6 #include "resources.h"
7 #include "camera.h"
8 #include "sector.h"
9 #include "app/globals.h"
10 #include "special/sprite_manager.h"
11 #include "badguy/badguy.h"
12
13 static const float BULLET_XM = 300;
14 static const float BULLET_STARTING_YM = 0;
15
16 Bullet::Bullet(const Vector& pos, float xm, int dir, int kind_)
17   : kind(kind_), life_count(3), sprite(0)
18 {
19   bbox.set_pos(pos);
20   bbox.set_size(4, 4);
21
22   float speed = dir == RIGHT ? BULLET_XM : -BULLET_XM;
23   physic.set_velocity_x(speed + xm);
24   physic.set_velocity_y(-BULLET_STARTING_YM);
25
26   if (kind == ICE_BULLET) {
27     life_count = 6; //ice-bullets get "extra lives" for bumping off walls
28     sprite = sprite_manager->create("icebullet");
29   } else if(kind == FIRE_BULLET) {
30     sprite = sprite_manager->create("firebullet");
31   }
32 }
33
34 Bullet::~Bullet()
35 {
36   delete sprite;
37 }
38
39 void
40 Bullet::action(float elapsed_time)
41 {
42   if(kind == FIRE_BULLET) {
43     // @not completely framerate independant :-/
44     physic.set_velocity_y(physic.get_velocity_y() - 50 * elapsed_time);
45   }
46   if(physic.get_velocity_y() > 900)
47     physic.set_velocity_y(900);
48   else if(physic.get_velocity_y() < -900)
49     physic.set_velocity_y(-900);
50
51   float scroll_x =
52     Sector::current()->camera->get_translation().x;
53   float scroll_y =
54     Sector::current()->camera->get_translation().y;
55   if (get_pos().x < scroll_x ||
56       get_pos().x > scroll_x + screen->w ||
57 //     get_pos().y < scroll_y ||
58       get_pos().y > scroll_y + screen->h ||
59       life_count <= 0) {
60     remove_me();
61     return;
62   }
63
64   movement = physic.get_movement(elapsed_time);
65 }
66
67 void
68 Bullet::draw(DrawingContext& context)
69 {
70   sprite->draw(context, get_pos(), LAYER_OBJECTS);
71 }
72
73 HitResponse
74 Bullet::collision(GameObject& other, const CollisionHit& hit)
75 {
76   if(other.get_flags() & FLAG_SOLID) {
77     if(fabsf(hit.normal.y) > .5) { // roof or floor bump
78       physic.set_velocity_y(-physic.get_velocity_y());
79       life_count -= 1;
80     } else { // bumped left or right
81       if(kind == FIRE_BULLET)
82         remove_me();
83       else
84         physic.set_velocity_x(-physic.get_velocity_x());
85     }
86     
87     return CONTINUE;
88   }
89
90   BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
91   if(badguy) {
92     badguy->kill_fall();
93     remove_me();
94     return FORCE_MOVE;
95   }
96  
97   // TODO kill badguys
98   return FORCE_MOVE;
99 }
100
101