Included supertux.h stuff into it.
[supertux.git] / src / special.cpp
1 //
2 // C Implementation: special
3 //
4 // Description:
5 //
6 //
7 // Author: Tobias Glaesser <tobi.web@gmx.de> & Bill Kendrick, (C) 2004
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12
13 #include "SDL.h"
14 #include "defines.h"
15 #include "special.h"
16 #include "gameloop.h"
17 #include "screen.h"
18 #include "sound.h"
19 #include "scene.h"
20 #include "globals.h"
21 #include "player.h"
22 #include "resources.h"
23
24 texture_type img_bullet;
25 texture_type img_golden_herring;
26 bitmask* bm_bullet;
27
28 void create_special_bitmasks()
29 {
30   bm_bullet = bitmask_create_SDL(img_bullet.sdl_surface);
31 }
32
33 void
34 Bullet::init(float x, float y, float xm, int dir)
35 {
36   base.width = 4;
37   base.height = 4;
38
39   if (dir == RIGHT)
40     {
41       base.x = x + 32;
42       base.xm = BULLET_XM + xm;
43     }
44   else
45     {
46       base.x = x;
47       base.xm = -BULLET_XM + xm;
48     }
49
50   base.y = y;
51   base.ym = BULLET_STARTING_YM;
52   old_base = base;
53 }
54
55 void
56 Bullet::action(double frame_ratio)
57 {
58   base.x = base.x + base.xm * frame_ratio;
59   base.y = base.y + base.ym * frame_ratio;
60
61   collision_swept_object_map(&old_base,&base);
62       
63   if (issolid(base.x, base.y + 4) || issolid(base.x, base.y))
64     {
65       base.ym = -base.ym;
66       base.y = (int)(base.y / 32) * 32;
67     }
68
69   base.ym = base.ym + GRAVITY;
70
71   if (base.x < scroll_x ||
72       base.x > scroll_x + screen->w ||
73       base.y < 0 ||
74       base.y > screen->h ||
75       issolid(base.x + 4, base.y + 2) ||
76       issolid(base.x, base.y + 2))
77     {
78       World::current()->bullets.erase(static_cast<std::vector<Bullet>::iterator>(this));
79     }
80
81 }
82
83 void 
84 Bullet::draw()
85 {
86   if (base.x >= scroll_x - base.width &&
87       base.x <= scroll_x + screen->w)
88     {
89       texture_draw(&img_bullet, base.x - scroll_x, base.y, 255,
90                    NO_UPDATE);
91     }
92 }
93
94 void
95 Bullet::collision(int c_object)
96 {
97   if(c_object == CO_BADGUY) {
98     std::vector<Bullet>::iterator i;
99     
100     for(i = World::current()->bullets.begin(); i != World::current()->bullets.end(); ++i) 
101       {
102         if(&(*i) == this) 
103           {
104             World::current()->bullets.erase(i);
105             return;
106           }
107       }
108   }
109 }
110
111 void
112 Upgrade::init(float x_, float y_, int dir_, int kind_)
113 {
114   base.width = 32;
115   base.height = 0;
116   kind = kind_;
117   base.x = x_;
118   base.y = y_;
119
120   if(dir_ == LEFT)
121     base.xm = -2;
122   else
123     base.xm = 2;
124
125   base.ym = -2;
126   base.height = 0;
127   old_base = base;
128 }
129
130 void
131 Upgrade::action(double frame_ratio)
132 {
133   if (base.height < 32)
134     {
135       /* Rise up! */
136
137       base.height = base.height + 0.7 * frame_ratio;
138       if(base.height > 32)
139         base.height = 32;
140     }
141   else
142     {
143       /* Move around? */
144
145       if (kind == UPGRADE_MINTS ||
146           kind == UPGRADE_HERRING)
147         {
148           base.x = base.x + base.xm * frame_ratio;
149           base.y = base.y + base.ym * frame_ratio;
150
151           collision_swept_object_map(&old_base,&base);
152
153           /* Off the screen?  Kill it! */
154
155           if (base.x < scroll_x - base.width)
156             World::current()->upgrades.erase(static_cast<std::vector<Upgrade>::iterator>(this));
157           if (base.y > screen->h)
158             World::current()->upgrades.erase(static_cast<std::vector<Upgrade>::iterator>(this));
159
160           if (issolid(base.x + 1, base.y + 32.) ||
161               issolid(base.x + 31., base.y + 32.))
162             {
163               if (base.ym > 0)
164                 {
165                   if (kind == UPGRADE_MINTS)
166                     {
167                       base.ym = 0;
168                     }
169                   else if (kind == UPGRADE_HERRING)
170                     {
171                       base.ym = -8;
172                     }
173
174                   base.y = (int)(base.y / 32) * 32;
175                 }
176             }
177           else
178             base.ym = base.ym + GRAVITY * frame_ratio;
179
180           if (issolid(base.x - 1, (int) base.y))
181             {
182               if(base.xm < 0)
183                 base.xm = -base.xm;
184             }
185           else if (issolid(base.x + base.width, (int) base.y))
186             {
187               if(base.xm > 0)
188                 base.xm = -base.xm;
189             }
190         }
191
192     }
193 }
194
195 void
196 Upgrade::draw()
197 {
198   SDL_Rect dest;
199   if (base.height < 32)
200     {
201       /* Rising up... */
202
203       dest.x = (int)(base.x - scroll_x);
204       dest.y = (int)(base.y + 32 - base.height);
205       dest.w = 32;
206       dest.h = (int)base.height;
207
208       if (kind == UPGRADE_MINTS)
209         texture_draw_part(&img_mints,0,0,dest.x,dest.y,dest.w,dest.h);
210       else if (kind == UPGRADE_COFFEE)
211         texture_draw_part(&img_coffee,0,0,dest.x,dest.y,dest.w,dest.h);
212       else if (kind == UPGRADE_HERRING)
213         texture_draw_part(&img_golden_herring,0,0,dest.x,dest.y,dest.w,dest.h);
214     }
215   else
216     {
217       if (kind == UPGRADE_MINTS)
218         {
219           texture_draw(&img_mints,
220                        base.x - scroll_x, base.y);
221         }
222       else if (kind == UPGRADE_COFFEE)
223         {
224           texture_draw(&img_coffee,
225                        base.x - scroll_x, base.y);
226         }
227       else if (kind == UPGRADE_HERRING)
228         {
229           texture_draw(&img_golden_herring,
230                        base.x - scroll_x, base.y);
231         }
232     }
233 }
234
235 void
236 Upgrade::collision(void* p_c_object, int c_object)
237 {
238   Player* pplayer = NULL;
239
240   switch (c_object)
241     {
242     case CO_PLAYER:
243       /* Remove the upgrade: */
244
245       /* p_c_object is CO_PLAYER, so assign it to pplayer */
246       pplayer = (Player*) p_c_object;
247
248       World::current()->upgrades.erase(static_cast<std::vector<Upgrade>::iterator>(this));
249
250       /* Affect the player: */
251
252       if (kind == UPGRADE_MINTS)
253         {
254           play_sound(sounds[SND_EXCELLENT], SOUND_CENTER_SPEAKER);
255           pplayer->size = BIG;
256           pplayer->base.height = 64;
257           pplayer->base.y -= 32;
258           if(collision_object_map(&pplayer->base))
259             {
260               pplayer->base.height = 32;
261               pplayer->base.y += 32;
262               pplayer->duck = true;
263             }
264         }
265       else if (kind == UPGRADE_COFFEE)
266         {
267           play_sound(sounds[SND_COFFEE], SOUND_CENTER_SPEAKER);
268           pplayer->got_coffee = true;
269         }
270       else if (kind == UPGRADE_HERRING)
271         {
272           play_sound(sounds[SND_HERRING], SOUND_CENTER_SPEAKER);
273           pplayer->invincible_timer.start(TUX_INVINCIBLE_TIME);
274           /* play the herring song ^^ */
275           if (get_current_music() != HURRYUP_MUSIC)
276             {
277               set_current_music(HERRING_MUSIC);
278               play_current_music();
279             }
280         }
281       break;
282     }
283 }
284