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