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