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