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