ce0193acd049eba85cb3096587436c23910b0ddd
[supertux.git] / src / special.c
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
23 texture_type img_bullet;
24 texture_type img_golden_herring;
25 bitmask* bm_bullet;
26
27 void create_special_bitmasks()
28 {
29   bm_bullet = bitmask_create_SDL(img_bullet.sdl_surface);
30 }
31
32 void bullet_init(bullet_type* pbullet, float x, float y, float xm, int dir)
33 {
34   pbullet->base.width = 4;
35   pbullet->base.height = 4;
36   pbullet->base.alive = YES;
37
38   if (dir == RIGHT)
39     {
40       pbullet->base.x = x + 32;
41       pbullet->base.xm = BULLET_XM + xm;
42     }
43   else
44     {
45       pbullet->base.x = x;
46       pbullet->base.xm = -BULLET_XM + xm;
47     }
48
49   pbullet->base.y = y;
50   pbullet->base.ym = BULLET_STARTING_YM;
51 }
52
53 void bullet_action(bullet_type* pbullet)
54 {
55   if (pbullet->base.alive)
56     {
57       pbullet->base.x = pbullet->base.x + pbullet->base.xm * frame_ratio;
58       pbullet->base.y = pbullet->base.y + pbullet->base.ym * frame_ratio;
59
60       if (issolid(pbullet->base.x, pbullet->base.y))
61         {
62           if (issolid(pbullet->base.x, pbullet->base.y - pbullet->base.ym))
63             pbullet->base.alive = NO;
64           else
65             {
66               if (pbullet->base.ym >= 0)
67                 {
68                   pbullet->base.y = (int)(pbullet->base.y / 32) * 32 - 8;
69                 }
70               pbullet->base.ym = -pbullet->base.ym;
71             }
72         }
73
74       pbullet->base.ym = pbullet->base.ym + GRAVITY;
75
76       if (pbullet->base.x < scroll_x ||
77           pbullet->base.x > scroll_x + screen->w)
78         {
79           pbullet->base.alive = NO;
80         }
81     }
82
83 }
84
85 void bullet_draw(bullet_type* pbullet)
86 {
87   if (pbullet->base.alive  &&
88       pbullet->base.x >= scroll_x - pbullet->base.width &&
89       pbullet->base.x <= scroll_x + screen->w)
90     {
91       texture_draw(&img_bullet, pbullet->base.x - scroll_x, pbullet->base.y,
92                    NO_UPDATE);
93     }
94 }
95
96 void bullet_collision(bullet_type* pbullet, int c_object)
97 {
98
99   if(c_object == CO_BADGUY)
100     pbullet->base.alive = NO;
101
102 }
103
104 void upgrade_init(upgrade_type *pupgrade, float x, float y, int dir, int kind)
105 {
106   pupgrade->base.width = 32;
107   pupgrade->base.height = 0;
108   pupgrade->base.alive = YES;
109   pupgrade->kind = kind;
110   pupgrade->base.x = x;
111   pupgrade->base.y = y;
112   if(dir == LEFT)
113     pupgrade->base.xm = -2;
114   else
115     pupgrade->base.xm = 2;
116   pupgrade->base.ym = -2;
117   pupgrade->base.height = 0;
118   pupgrade->old_base = pupgrade->base;
119 }
120
121 void upgrade_action(upgrade_type *pupgrade)
122 {
123
124   if (pupgrade->base.alive)
125     {
126       if (pupgrade->base.height < 32)
127         {
128           /* Rise up! */
129
130           pupgrade->base.height = pupgrade->base.height + 0.7 * frame_ratio;
131           if(pupgrade->base.height > 32)
132             pupgrade->base.height = 32;
133         }
134       else
135         {
136           /* Move around? */
137
138           if (pupgrade->kind == UPGRADE_MINTS ||
139               pupgrade->kind == UPGRADE_HERRING)
140             {
141               pupgrade->base.x = pupgrade->base.x + pupgrade->base.xm * frame_ratio;
142               pupgrade->base.y = pupgrade->base.y + pupgrade->base.ym * frame_ratio;
143
144               collision_swept_object_map(&pupgrade->old_base,&pupgrade->base);
145
146               /* Off the screen?  Kill it! */
147
148               if (pupgrade->base.x < scroll_x - pupgrade->base.width)
149                 pupgrade->base.alive = NO;
150               if (pupgrade->base.y > screen->h)
151                 pupgrade->base.alive = NO;
152
153               if (issolid(pupgrade->base.x + 1, pupgrade->base.y + 32.) ||
154                   issolid(pupgrade->base.x + 31., pupgrade->base.y + 32.))
155                 {
156                   if (pupgrade->base.ym > 0)
157                     {
158                       if (pupgrade->kind == UPGRADE_MINTS)
159                         {
160                           pupgrade->base.ym = 0;
161                         }
162                       else if (pupgrade->kind == UPGRADE_HERRING)
163                         {
164                           pupgrade->base.ym = -8;
165                         }
166
167                       pupgrade->base.y = (int)(pupgrade->base.y / 32) * 32;
168                     }
169                 }
170               else
171                 pupgrade->base.ym = pupgrade->base.ym + GRAVITY * frame_ratio;
172
173               if (issolid(pupgrade->base.x - 1, (int) pupgrade->base.y))
174                 {
175                   if(pupgrade->base.xm < 0)
176                     pupgrade->base.xm = -pupgrade->base.xm;
177                 }
178               else if (issolid(pupgrade->base.x + pupgrade->base.width, (int) pupgrade->base.y))
179                 {
180                   if(pupgrade->base.xm > 0)
181                     pupgrade->base.xm = -pupgrade->base.xm;
182                 }
183             }
184
185         }
186     }
187 }
188
189 void upgrade_draw(upgrade_type* pupgrade)
190 {
191   SDL_Rect dest;
192   if (pupgrade->base.alive)
193     {
194       if (pupgrade->base.height < 32)
195         {
196           /* Rising up... */
197
198           dest.x = (int)(pupgrade->base.x - scroll_x);
199           dest.y = (int)(pupgrade->base.y + 32 - pupgrade->base.height);
200           dest.w = 32;
201           dest.h = (int)pupgrade->base.height;
202
203           if (pupgrade->kind == UPGRADE_MINTS)
204             texture_draw_part(&img_mints,0,0,dest.x,dest.y,dest.w,dest.h,NO_UPDATE);
205           else if (pupgrade->kind == UPGRADE_COFFEE)
206             texture_draw_part(&img_coffee,0,0,dest.x,dest.y,dest.w,dest.h,NO_UPDATE);
207           else if (pupgrade->kind == UPGRADE_HERRING)
208             texture_draw_part(&img_golden_herring,0,0,dest.x,dest.y,dest.w,dest.h,NO_UPDATE);
209         }
210       else
211         {
212           if (pupgrade->kind == UPGRADE_MINTS)
213             {
214               texture_draw(&img_mints,
215                            pupgrade->base.x - scroll_x, pupgrade->base.y,
216                            NO_UPDATE);
217             }
218           else if (pupgrade->kind == UPGRADE_COFFEE)
219             {
220               texture_draw(&img_coffee,
221                            pupgrade->base.x - scroll_x, pupgrade->base.y,
222                            NO_UPDATE);
223             }
224           else if (pupgrade->kind == UPGRADE_HERRING)
225             {
226               texture_draw(&img_golden_herring,
227                            pupgrade->base.x - scroll_x, pupgrade->base.y,
228                            NO_UPDATE);
229             }
230         }
231     }
232 }
233
234 void upgrade_collision(upgrade_type* pupgrade, void* p_c_object, int c_object)
235 {
236   player_type* pplayer = NULL;
237
238   switch (c_object)
239     {
240     case CO_PLAYER:
241       /* Remove the upgrade: */
242
243       /* p_c_object is CO_PLAYER, so assign it to pplayer */
244       pplayer = (player_type*) p_c_object;
245
246       pupgrade->base.alive = NO;
247
248       /* Affect the player: */
249
250       if (pupgrade->kind == UPGRADE_MINTS)
251         {
252           play_sound(sounds[SND_EXCELLENT], SOUND_CENTER_SPEAKER);
253           pplayer->size = BIG;
254           pplayer->base.height = 64;
255           pplayer->base.y -= 32;
256           if(collision_object_map(&pplayer->base))
257           {
258           pplayer->base.height = 32;
259           pplayer->base.y += 32;
260           pplayer->duck = YES;
261           }
262           timer_start(&super_bkgd_timer, 350);
263         }
264       else if (pupgrade->kind == UPGRADE_COFFEE)
265         {
266           play_sound(sounds[SND_COFFEE], SOUND_CENTER_SPEAKER);
267           pplayer->got_coffee = YES;
268           timer_start(&super_bkgd_timer, 250);
269         }
270       else if (pupgrade->kind == UPGRADE_HERRING)
271         {
272           play_sound(sounds[SND_HERRING], SOUND_CENTER_SPEAKER);
273           timer_start(&pplayer->invincible_timer,TUX_INVINCIBLE_TIME);
274           timer_start(&super_bkgd_timer, 250);
275           /* play the herring song ^^ */
276           if (get_current_music() != HURRYUP_MUSIC)
277             {
278               set_current_music(HERRING_MUSIC);
279               play_current_music();
280             }
281         }
282       break;
283     }
284 }
285