fixed a few bugs. (One of them thanks to a patch from Ricardo). Made more code cleanu...
[supertux.git] / src / special.c
1 //
2 // C Implementation: special
3 //
4 // Description:
5 //
6 //
7 // Author: Tobias Glaesser <tobi.web@gmx.de>, (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 void create_special_bitmasks()
24 {
25   bm_bullet = bitmask_create_SDL(img_bullet.sdl_surface);
26 }
27
28 void bullet_init(bullet_type* pbullet, float x, float y, float xm, int dir)
29 {
30   pbullet->base.width = 4;
31   pbullet->base.height = 4;
32   pbullet->base.updated = SDL_GetTicks();
33   pbullet->base.alive = YES;
34
35   if (dir == RIGHT)
36     {
37       pbullet->base.x = x + 32;
38       pbullet->base.xm = BULLET_XM + xm;
39     }
40   else
41     {
42       pbullet->base.x = x;
43       pbullet->base.xm = -BULLET_XM + xm;
44     }
45
46   pbullet->base.y = y;
47   pbullet->base.ym = BULLET_STARTING_YM;
48 }
49
50 void bullet_action(bullet_type* pbullet)
51 {
52
53   double frame_ratio = get_frame_ratio(&pbullet->base);
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 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   pupgrade->base.xm = 2;
113   pupgrade->base.ym = -2;
114   pupgrade->base.height = 0;
115   pupgrade->base.updated = SDL_GetTicks();
116 }
117
118 void upgrade_action(upgrade_type *pupgrade)
119 {
120   double frame_ratio = get_frame_ratio(&pupgrade->base);
121
122   if (pupgrade->base.alive)
123     {
124       if (pupgrade->base.height < 32)
125         {
126           /* Rise up! */
127
128           pupgrade->base.height++;
129         }
130       else
131         {
132           /* Move around? */
133
134           if (pupgrade->kind == UPGRADE_MINTS ||
135               pupgrade->kind == UPGRADE_HERRING)
136             {
137               pupgrade->base.x = pupgrade->base.x + pupgrade->base.xm * frame_ratio;
138               pupgrade->base.y = pupgrade->base.y + pupgrade->base.ym * frame_ratio;
139
140               if (issolid(pupgrade->base.x, pupgrade->base.y + 31) ||
141                   issolid(pupgrade->base.x + 31, pupgrade->base.y + 31))
142                 {
143                   if (pupgrade->base.ym > 0)
144                     {
145                       if (pupgrade->kind == UPGRADE_MINTS)
146                         {
147                           pupgrade->base.ym = 0;
148                         }
149                       else if (pupgrade->kind == UPGRADE_HERRING)
150                         {
151                           pupgrade->base.ym = -24;
152                         }
153
154                       pupgrade->base.y = (int)(pupgrade->base.y / 32) * 32;
155                     }
156                 }
157               else
158                 pupgrade->base.ym = pupgrade->base.ym + GRAVITY;
159
160               if (issolid(pupgrade->base.x, pupgrade->base.y))
161                 {
162                   pupgrade->base.xm = -pupgrade->base.xm;
163                 }
164             }
165
166
167           /* Off the screen?  Kill it! */
168
169           if (pupgrade->base.x < scroll_x - pupgrade->base.width)
170             pupgrade->base.alive = NO;
171
172         }
173     }
174 }
175
176 void upgrade_draw(upgrade_type* pupgrade)
177 {
178   if (pupgrade->base.alive)
179     {
180       if (pupgrade->base.height < 32)
181         {
182           /* Rising up... */
183
184           dest.x = pupgrade->base.x - scroll_x;
185           dest.y = pupgrade->base.y + 32 - pupgrade->base.height;
186           dest.w = 32;
187           dest.h = pupgrade->base.height;
188
189           src.x = 0;
190           src.y = 0;
191           src.w = 32;
192           src.h = pupgrade->base.height;
193
194           if (pupgrade->kind == UPGRADE_MINTS)
195             SDL_BlitSurface(img_mints.sdl_surface, &src, screen, &dest);
196           else if (pupgrade->kind == UPGRADE_COFFEE)
197             SDL_BlitSurface(img_coffee.sdl_surface, &src, screen, &dest);
198           else if (pupgrade->kind == UPGRADE_HERRING)
199             SDL_BlitSurface(img_golden_herring.sdl_surface, &src, screen, &dest);
200         }
201       else
202         {
203           if (pupgrade->kind == UPGRADE_MINTS)
204             {
205               texture_draw(&img_mints,
206                            pupgrade->base.x - scroll_x, pupgrade->base.y,
207                            NO_UPDATE);
208             }
209           else if (pupgrade->kind == UPGRADE_COFFEE)
210             {
211               texture_draw(&img_coffee,
212                            pupgrade->base.x - scroll_x, pupgrade->base.y,
213                            NO_UPDATE);
214             }
215           else if (pupgrade->kind == UPGRADE_HERRING)
216             {
217               texture_draw(&img_golden_herring,
218                            pupgrade->base.x - scroll_x, pupgrade->base.y,
219                            NO_UPDATE);
220             }
221         }
222     }
223 }
224
225 void upgrade_collision(upgrade_type* pupgrade, void* p_c_object, int c_object)
226 {
227   player_type* pplayer = NULL;
228
229   switch (c_object)
230     {
231     case CO_PLAYER:
232       /* Remove the upgrade: */
233
234       /* p_c_object is CO_PLAYER, so assign it to pplayer */
235       pplayer = p_c_object;
236
237       pupgrade->base.alive = NO;
238
239       /* Affect the player: */
240
241       if (pupgrade->kind == UPGRADE_MINTS)
242         {
243           play_sound(sounds[SND_EXCELLENT], SOUND_CENTER_SPEAKER);
244           pplayer->size = BIG;
245           timer_start(&super_bkgd_timer, 350);
246         }
247       else if (pupgrade->kind == UPGRADE_COFFEE)
248         {
249           play_sound(sounds[SND_COFFEE], SOUND_CENTER_SPEAKER);
250           pplayer->got_coffee = YES;
251           timer_start(&super_bkgd_timer, 250);
252         }
253       else if (pupgrade->kind == UPGRADE_HERRING)
254         {
255           play_sound(sounds[SND_HERRING], SOUND_CENTER_SPEAKER);
256           timer_start(&tux.invincible_timer,TUX_INVINCIBLE_TIME);
257           timer_start(&super_bkgd_timer, 250);
258           /* play the herring song ^^ */
259           if (current_music != HURRYUP_MUSIC)
260             {
261               current_music = HERRING_MUSIC;
262               if (playing_music())
263                 halt_music();
264             }
265         }
266       break;
267     }
268 }
269