1 #include "main.h"
2 #include "SDL_gfxPrimitives.h"
3
4 #define MissileColor SDL_MapRGB(Screen->format,0,200,0)
5 #define MissileGreen 200
6 #define MISSILE_MAX_NUM 80
7 #define FLYER_MAX_NUM 8
8 #define MISSILE_LENGTH 200
9 #define TAIL 80
10
11 typedef struct
12 {
13 float x,y;
14 float SourceX,SourceY;
15 float xspeed,yspeed;
16 coord Pixels[MISSILE_LENGTH];
17 int CurrentPixel;
18 int Proceeded;
19 float Erase;
20 int Target;
21 int TargetX;
22 int Split;
23 } MissileType;
24
25 typedef struct
26 {
27 float x,y;
28 float xspeed;
29 float AnimPhase;
30 Sint32 Release;
31 } FlyerType;
32
33 MissileType Missile[MISSILE_MAX_NUM];
34 FlyerType Flyer[FLYER_MAX_NUM];
35 int MissileCount=0,FlyerCount=0,UpdateMissiles=1;
36
CreateMissile(int x,int y)37 void CreateMissile(int x, int y)
38 {
39 int i;
40
41 if (MissileCount<MISSILE_MAX_NUM) {
42
43 MissileType *This;
44 float Vec;
45
46 This=&Missile[MissileCount];
47 This->SourceX=This->x=x;
48 This->SourceY=This->y=y;
49 This->Target=abrand(0,8);
50 if (This->Target<3)
51 This->TargetX = 120+This->Target*100;
52 else if (This->Target<6)
53 This->TargetX = 480+(This->Target-3)*100;
54 else
55 This->TargetX = 40+(This->Target-6)*360;
56 Vec=100*hypot(This->TargetX-This->x,510-This->y);
57 This->xspeed=Wave[WaveNum].MissileSpeed*(This->TargetX-This->x)/Vec;
58 This->yspeed=Wave[WaveNum].MissileSpeed*(510-This->y)/Vec;
59 This->CurrentPixel=0;
60 This->Erase=0;
61 This->Split=0;
62 for (i=0;i<MISSILE_LENGTH;i++)
63 {This->Pixels[i].x=0;This->Pixels[i].y=0;}
64 MissileCount++;
65 }
66 else printf("Too many Missiles\n");
67 }
68
UndrawThisMissile(int i)69 void UndrawThisMissile(int i) {
70 SDL_Rect rect;
71 float f=0;
72
73 SDL_SetAlpha(BackBuffer,0,0);
74 while ( f<1 ) {
75 rect.x = Missile[i].x*f + Missile[i].SourceX*(1-f)-2;
76 rect.y = Missile[i].y*f + Missile[i].SourceY*(1-f)-2;
77 rect.w = rect.h = 5;
78 f += 4/hypot(Missile[i].x-Missile[i].SourceX,Missile[i].y-Missile[i].SourceY);
79 SDL_BlitSurface( BackBuffer, &rect, Screen, &rect);
80 }
81 }
82
RemoveMissile(int i)83 void RemoveMissile(int i)
84 {
85 Missile[i].Erase+=Speed/(float)3;
86 if (Missile[i].Erase>255) {
87 UndrawThisMissile(i);
88 Missile[i]=Missile[MissileCount-1];
89 MissileCount--;
90 }
91 }
92
DestroyTarget(int TargetNum,int TargetX)93 void DestroyTarget(int TargetNum, int TargetX)
94 {
95 SDL_Rect rect;
96
97 if (TargetNum<6) {
98 rect.x=TargetX-50;
99 rect.y=490;
100 rect.w=100;
101 rect.h=CityPic->h;
102 SDL_BlitSurface(BackPic,&rect,BackBuffer,&rect);
103 BlitToBB(rect.x,rect.y,CityHitPic);
104 BlitPart(rect.x,rect.y,BackBuffer,rect);
105 if ( ! CityDestroyed[TargetNum] ) {
106 CityDestroyed[TargetNum]=1;
107 CityNum--;
108 }
109 } else if (TargetNum<9) {
110 rect.x=TargetX-CannonHitPic->w/2;
111 rect.y=510;
112 rect.w=CannonHitPic->w;
113 rect.h=CannonHitPic->h;
114 SDL_BlitSurface(BackPic,&rect,BackBuffer,&rect);
115 BlitToBB(rect.x,rect.y,CannonHitPic);
116 SDL_SetAlpha(BackBuffer,0,0);
117 BlitPart(rect.x,rect.y,BackBuffer,rect);
118 CannonDestroyed[TargetNum-6]=1;
119 ShotNum[TargetNum-6]=-1;
120 DrawShotNum(TargetNum-6);
121 } else printf("WARNING: Target was %d!\n",TargetNum);
122 }
123
HandleMissile()124 void HandleMissile()
125 {
126 int i;
127
128 for (i=0;i<MissileCount;i++)
129 {
130 // Hit!
131 if ((Missile[i].y>=510)&&(Missile[i].Erase==0)) {
132 CreateExplosion(Missile[i].x,Missile[i].y);
133 DestroyTarget(Missile[i].Target,Missile[i].TargetX);
134 PlaySound(MissileExplosionSound);
135 }
136 // Delete Missile
137 if (
138 ((Missile[i].y>=510)
139 ||((int)Missile[i].x<0)
140 ||((int)Missile[i].x>=800))
141 ||(Missile[i].Erase>0)
142 )
143 RemoveMissile(i);
144 else {
145 // Move Missile
146 Missile[i].x+=Missile[i].xspeed*Speed;
147 Missile[i].y+=Missile[i].yspeed*Speed;
148 // Split Missile (Mirv)
149 if (Missile[i].Split) {
150 CreateMissile(Missile[i].x,Missile[i].y);
151 Missile[i].Split=0;
152 }
153 }
154 }
155 }
156
DrawMissile()157 void DrawMissile()
158 {
159 int i;
160
161 lock();
162 for (i=0;i<MissileCount;i++)
163 aalineRGBA(Screen,(int)Missile[i].x,(int)Missile[i].y,(int)Missile[i].SourceX,(int)Missile[i].SourceY,0,MissileGreen,0,255-(int)Missile[i].Erase);
164 unlock();
165 }
166
UndrawMissile()167 void UndrawMissile()
168 {
169 int i;
170
171 for (i=0;i<MissileCount;i++)
172 UndrawThisMissile(i);
173 }
174
Split(int MissileNum)175 int Split(int MissileNum)
176 {
177 if (Missile[MissileNum].y>400) return 1;
178 Missile[MissileNum].Split=1; return 0;
179 }
180
CreateFlyer()181 void CreateFlyer()
182 {
183 if (FlyerCount==FLYER_MAX_NUM) {
184 puts("Too many flyers");
185 return;
186 }
187
188 Flyer[FlyerCount].y=abrand(0,350);
189 Flyer[FlyerCount].AnimPhase=0;
190 Flyer[FlyerCount].Release=5000+abrand(0,5000);
191 // if (abrand(0,1)==0) {
192 Flyer[FlyerCount].x=-FlyerPic[0]->w+20;
193 Flyer[FlyerCount].xspeed=0.01*abrand(1,6);
194 // } else {
195 // Flyer[FlyerCount].x=800;
196 // Flyer[FlyerCount].xspeed=-0.01*abrand(1,6);
197 // }
198 FlyerCount++;
199 }
200
DrawFlyer()201 void DrawFlyer()
202 {
203 int i;
204
205 for (i=0;i<FlyerCount;i++) {
206 if ((int)Flyer[i].AnimPhase > 15) {printf("Error in DrawFlyer!\n");return;}
207 if (Flyer[i].AnimPhase < 0) {printf("Stupid (!) error in DrawFlyer!\n");return;}
208 Blit(Flyer[i].x,Flyer[i].y,FlyerPic[(int)Flyer[i].AnimPhase]);
209 }
210 }
211
UndrawFlyer()212 void UndrawFlyer()
213 {
214 int i;
215 SDL_Rect rect;
216
217 SDL_SetAlpha(BackBuffer,0,0);
218 rect.w=FlyerPic[0]->w;
219 rect.h=FlyerPic[0]->h;
220 for (i=0;i<FlyerCount;i++) {
221 rect.x=Flyer[i].x;
222 rect.y=Flyer[i].y;
223 SDL_BlitSurface(BackBuffer, &rect, Screen, &rect);
224 AddThisRect(rect);
225 }
226 }
227
RemoveFlyer(int i)228 void RemoveFlyer(int i)
229 {
230 Flyer[i]=Flyer[FlyerCount-1];
231 FlyerCount--;
232 }
233
HandleFlyer()234 void HandleFlyer()
235 {
236 int i,num;
237
238 for (i=0;i<FlyerCount;i++) {
239 Flyer[i].x+=Flyer[i].xspeed*Speed;
240 Flyer[i].AnimPhase+=0.02*Speed;
241 if ((int)Flyer[i].AnimPhase>15) Flyer[i].AnimPhase-=15;
242 if ( ((int)Flyer[i].x>=800) || (Flyer[i].x<-FlyerPic[0]->w) )
243 RemoveFlyer(i);
244 Flyer[i].Release-=Speed;
245 if (Flyer[i].Release<=0) {
246 Flyer[i].Release=4000+abrand(0,8000);
247 for (num=0;num<abrand(1,6);num++) {
248 CreateMissile(Flyer[i].x+FlyerPic[0]->w/2,Flyer[i].y+FlyerPic[0]->h/2);
249 }
250 }
251 }
252 }
253
MissileCollision(int x,int y,int rad)254 void MissileCollision(int x, int y, int rad)
255 {
256 int i,wings;
257
258 // printf("ads %d - %d - %d\n",x,y,rad);
259 for (i=0;i<MissileCount;i++)
260 {
261 if (Missile[i].Erase==0)
262 if (hypot(Missile[i].x-x,Missile[i].y-y)<rad) {
263 CreateExplosion(Missile[i].x,Missile[i].y);
264 RemoveMissile(i);
265 AddScore(20);
266 PlaySound(MissileExplosionSound);
267 }
268 }
269 for (i=0;i<FlyerCount;i++) {
270 if (Flyer[i].AnimPhase<=8)
271 wings=8-Flyer[i].AnimPhase;
272 else
273 wings=Flyer[i].AnimPhase-8;
274 // printf("%d\n",wings);
275
276 if ( ( (x+rad>Flyer[i].x) && (x-rad<Flyer[i].x+FlyerPic[0]->w)
277 && (y+rad>Flyer[i].y+FlyerPic[0]->h/2-4) && (y-rad<Flyer[i].y+FlyerPic[0]->h/2+4) )
278 ||
279 ( (x+rad>Flyer[i].x) && (x-rad<Flyer[i].x+FlyerPic[0]->w)
280 && (y+rad>Flyer[i].y+FlyerPic[0]->h/2-wings*4) && (y-rad<Flyer[i].y+FlyerPic[0]->h/2+wings*4) ) )
281 {
282 CreateExplosion(Flyer[i].x+abrand(0,FlyerPic[0]->w),Flyer[i].y+FlyerPic[0]->h/2+abrand(-wings*4,+wings*4));
283 CreateExplosion(Flyer[i].x+abrand(0,FlyerPic[0]->w),Flyer[i].y+FlyerPic[0]->h/2+abrand(-wings*4,+wings*4));
284 CreateExplosion(Flyer[i].x+abrand(0,FlyerPic[0]->w),Flyer[i].y+FlyerPic[0]->h/2+abrand(-wings*4,+wings*4));
285 RemoveFlyer(i);
286 AddScore(40);
287 PlaySound(MissileExplosionSound);
288
289 }
290 }
291 }
292