1 /* xsoldier, a shoot 'em up game with "not shooting" bonus
2 * Copyright (C) 1997 Yuusuke HASHIMOTO <s945750@educ.info.kanagawa-u.ac.jp>
3 * Copyright (C) 2002 Oohara Yuuma <oohara@libra.interq.or.jp>
4 *
5 * This is a copyleft program. See the file LICENSE for details.
6 */
7 /* $Id: enemyshot.c,v 1.7 2002/04/29 16:54:59 oohara Exp $ */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11
12 /*
13 #include <X11/Xlib.h>
14 #include <X11/xpm.h>
15 */
16
17 #include <stdlib.h>
18 #include "image.h"
19 #include "xsoldier.h"
20 #include "manage.h"
21 #include "common.h"
22 #include "enemyshot.h"
23 #include "callback.h"
24 #include "extern.h"
25 #include "sin.h"
26
27 /* enemy shot */
ShotToAngle(int x,int y,int angle,int speed)28 void ShotToAngle(int x, int y, int angle, int speed)
29 {
30 int i;
31
32 if (manage->EnemyNum >= manage->EnemyMax)
33 return;
34
35 if (speed <= 0)
36 speed = 1;
37
38 for (i=1; i<manage->EnemyMax; i++)
39 {
40 if (manage->enemy[i]->Data.used == False)
41 {
42 manage->EnemyShot.Data.X = x;
43 manage->EnemyShot.Data.Y = y;
44 manage->EnemyShot.Data.Angle = angle;
45 manage->EnemyShot.Data.Speed = speed;
46 manage->EnemyShot.Data.Cnt[0] = x << 8;
47 manage->EnemyShot.Data.Cnt[1] = y << 8;
48 manage->EnemyShot.Data.Cnt[2] = icos(angle);
49 manage->EnemyShot.Data.Cnt[3] = isin(angle);
50
51 manage->enemy[i]->Data = manage->EnemyShot.Data;
52 manage->enemy[i]->Grp = manage->EnemyShot.Grp;
53 manage->enemy[i]->Action = EnemyShotAct;
54 manage->enemy[i]->Realize = DrawImage;
55 manage->enemy[i]->Hit = NullDelHit;
56
57 manage->EnemyNum++;
58 return;
59 }
60 }
61 }
62
ShotToPoint(int x1,int y1,int x2,int y2,int speed)63 void ShotToPoint(int x1, int y1, int x2, int y2, int speed)
64 {
65 int i;
66 int diffx = x2 - x1;
67 int diffy = y2 - y1;
68 int absx = abs(diffx);
69 int absy = abs(diffy);
70
71 if (manage->EnemyNum >= manage->EnemyMax)
72 return;
73
74 if (speed <= 0)
75 speed = 1;
76
77 for (i=1; i<manage->EnemyMax; i++)
78 {
79 if (manage->enemy[i]->Data.used == False)
80 {
81 manage->EnemyShot.Data.X = x1;
82 manage->EnemyShot.Data.Y = y1;
83 manage->EnemyShot.Data.Speed = speed;
84 manage->EnemyShot.Data.Cnt[0] = x1 << 8;
85 manage->EnemyShot.Data.Cnt[1] = y1 << 8;
86 if (absx >= absy)
87 {
88 manage->EnemyShot.Data.Cnt[2] = 1 << 8;
89 manage->EnemyShot.Data.Cnt[3] = (absy/(double)absx) * 256;
90 }
91 else
92 {
93 manage->EnemyShot.Data.Cnt[2] = (absx/(double)absy) * 256;
94 manage->EnemyShot.Data.Cnt[3] = 1 << 8;
95 }
96 if (diffx < 0)
97 manage->EnemyShot.Data.Cnt[2] *= -1;
98 if (diffy < 0)
99 manage->EnemyShot.Data.Cnt[3] *= -1;
100
101 manage->enemy[i]->Data = manage->EnemyShot.Data;
102 manage->enemy[i]->Grp = manage->EnemyShot.Grp;
103 manage->enemy[i]->Action = EnemyShotAct;
104 manage->enemy[i]->Realize = DrawImage;
105 manage->enemy[i]->Hit = NullDelHit;
106
107 manage->EnemyNum++;
108 return;
109 }
110 }
111 }
112
EnemyShotAct(ObjData * my)113 DelAtt EnemyShotAct(ObjData *my)
114 {
115 /* 2^8 = 256 */
116 my->Cnt[0] += my->Cnt[2]*my->Speed;
117 my->X = my->Cnt[0] / 256;
118 my->Cnt[1] += my->Cnt[3]*my->Speed;
119 my->Y = my->Cnt[1] / 256;
120
121 my->Cnt[4]++;
122 if (my->Cnt[4] >= 3)
123 {
124 my->Cnt[4] = 0;
125 my->image++;
126 if (my->image > 3)
127 my->image = 0;
128 }
129
130 if ((my->X < 0 - my->Width/2) || (my->X > FieldW + my->Width/2))
131 return NullDel;
132 if ((my->Y < 0 - my->Height/2) || (my->Y > FieldH + my->Height/2))
133 return NullDel;
134
135 return NoneDel;
136 }
137
RingToAngle(int x,int y,int angle,int speed)138 int RingToAngle(int x, int y, int angle, int speed)
139 {
140 if (speed <= 0)
141 speed = 1;
142
143 manage->New.Data.hitAtt = MEnemy;
144 manage->New.Data.hitMask = MPlayer | MPShot;
145
146 manage->New.Data.X = x;
147 manage->New.Data.Y = y;
148 manage->New.Data.HP = 1;
149 manage->New.Data.Point = 0;
150 manage->New.Data.Angle = angle;
151 manage->New.Data.Speed = speed;
152 manage->New.Data.Cnt[0] = x << 8;
153 manage->New.Data.Cnt[1] = y << 8;
154 manage->New.Data.Cnt[2] = icos(angle);
155 manage->New.Data.Cnt[3] = isin(angle);
156 manage->New.Data.Cnt[4] = 0;
157 manage->New.Data.EnemyAtt = NullDel;
158 manage->New.Data.Width = 28;
159 manage->New.Data.Height = 28;
160
161 manage->New.Grp.image = ERingImage;
162
163 return NewObj(MEnemy,EnemyShotAct,DeleteHit,DrawImage);
164 }
165
RingToPoint(int x1,int y1,int x2,int y2,int speed)166 int RingToPoint(int x1, int y1, int x2, int y2, int speed)
167 {
168 int diffx = x2 - x1;
169 int diffy = y2 - y1;
170 int absx = abs(diffx);
171 int absy = abs(diffy);
172
173 if (speed <= 0)
174 speed = 1;
175
176 manage->New.Data.hitAtt = MEnemy;
177 manage->New.Data.hitMask = MPlayer | MPShot;
178
179 manage->New.Data.X = x1;
180 manage->New.Data.Y = y1;
181 manage->New.Data.HP = 1;
182 manage->New.Data.Point = 0;
183 manage->New.Data.Speed = speed;
184 manage->New.Data.Cnt[0] = x1 << 8;
185 manage->New.Data.Cnt[1] = y1 << 8;
186
187 if (absx >= absy)
188 {
189 manage->New.Data.Cnt[2] = 1 << 8;
190 manage->New.Data.Cnt[3] = (absy/(double)absx) * 256;
191 }
192 else
193 {
194 manage->New.Data.Cnt[2] = (absx/(double)absy) * 256;
195 manage->New.Data.Cnt[3] = 1 << 8;
196 }
197 if (diffx < 0)
198 manage->New.Data.Cnt[2] *= -1;
199 if (diffy < 0)
200 manage->New.Data.Cnt[3] *= -1;
201
202 manage->New.Data.Cnt[4] = 0;
203 manage->New.Data.EnemyAtt = NullDel;
204 manage->New.Data.Width = 28;
205 manage->New.Data.Height = 28;
206
207 manage->New.Grp.image = ERingImage;
208
209 return NewObj(MEnemy,EnemyShotAct,DeleteHit,DrawImage);
210 }
211
HomingShot(int x,int y,int ix,int iy)212 int HomingShot(int x, int y, int ix, int iy)
213 {
214 manage->New.Data.hitAtt = MEnemy;
215 manage->New.Data.hitMask = MPlayer | MPShot;
216
217 manage->New.Data.X = x;
218 manage->New.Data.Y = y;
219 manage->New.Data.HP = 1;
220 manage->New.Data.Point = 0;
221 manage->New.Data.EnemyAtt = NullDel;
222 manage->New.Data.Width = 16;
223 manage->New.Data.Height = 16;
224 manage->New.Data.inertX = ix;
225 manage->New.Data.inertY = iy;
226
227 manage->New.Grp.image = EMissileImage;
228
229 return NewObj(MEnemy,HomingAct,DeleteHit,DrawImage);
230 }
231
HomingAct(ObjData * my)232 DelAtt HomingAct(ObjData *my)
233 {
234 if (my->X < manage->player[0]->Data.X)
235 {
236 if (my->inertX < 15)
237 my->inertX += 1;
238 }
239 else
240 {
241 if (my->inertX > -15)
242 my->inertX -= 1;
243 }
244
245 if (my->Y < manage->player[0]->Data.Y)
246 my->inertY++;
247 else
248 my->inertY--;
249
250 my->X += my->inertX;
251 my->Y += my->inertY;
252
253 my->image = GetDirection(0,0,my->inertX,my->inertY);
254
255 if ((my->X < 0 - my->Width/2) || (my->X > FieldW + my->Width/2))
256 return NullDel;
257 if ((my->Y < 0 - my->Height/2) || (my->Y > FieldH + my->Height/2))
258 return NullDel;
259
260 return NoneDel;
261 }
262
LaserShot(int x,int y,int speed)263 int LaserShot(int x, int y, int speed)
264 {
265 if (speed <= 0)
266 speed = 1;
267
268 manage->New.Data.hitAtt = MEShot;
269 manage->New.Data.hitMask = MPlayer;
270
271 manage->New.Data.X = x;
272 manage->New.Data.Y = y;
273 manage->New.Data.EnemyAtt = NullDel;
274 manage->New.Data.Width = 7;
275 manage->New.Data.Height = 50;
276 manage->New.Data.Speed = speed;
277
278 manage->New.Grp.image = ELaserImage;
279
280 return NewObj(MEShot,EnemyLaserAct,NullHit,DrawImage);
281 }
282
EnemyLaserAct(ObjData * my)283 DelAtt EnemyLaserAct(ObjData *my)
284 {
285 my->Y += my->Speed;
286
287 if ((my->X < 0 - my->Width/2) || (my->X > FieldW + my->Width/2))
288 return NullDel;
289 if ((my->Y < 0 - my->Height/2) || (my->Y > FieldH + my->Height/2))
290 return NullDel;
291
292 return NoneDel;
293 }
294
BoundShot(int x,int y,int ix,int iy,int bound)295 int BoundShot(int x, int y, int ix, int iy, int bound)
296 {
297 if ((ix == 0) && (iy == 0))
298 ix = 1;
299
300 manage->New.Data.hitAtt = MEnemy;
301 manage->New.Data.hitMask = MPlayer | MPShot;
302
303 manage->New.Data.X = x;
304 manage->New.Data.Y = y;
305 manage->New.Data.EnemyAtt = NullDel;
306 manage->New.Data.Width = 28;
307 manage->New.Data.Height = 28;
308 manage->New.Data.inertX = ix;
309 manage->New.Data.inertY = iy;
310
311 manage->New.Data.Cnt[0] = 0;
312 manage->New.Data.Cnt[1] = bound;
313
314 manage->New.Grp.image = EBoundImage;
315
316 return NewObj(MEShot,BoundShotAct,NullHit,DrawImage);
317 }
318
BoundShotAct(ObjData * my)319 DelAtt BoundShotAct(ObjData *my)
320 {
321 if (my->Cnt[0] <= my->Cnt[1])
322 {
323 if ((my->X+my->inertX>FieldW) || (my->X+my->inertX<0))
324 {
325 my->inertX = my->inertX*(-1);
326 my->Cnt[0]++;
327 }
328 if ((my->Y+my->inertY>FieldH) || (my->Y+my->inertY<0))
329 {
330 my->inertY = my->inertY*(-1);
331 my->Cnt[0]++;
332 }
333 }
334
335 my->image++;
336 if (my->image >= 8)
337 my->image = 0;
338
339 my->X += my->inertX;
340 my->Y += my->inertY;
341
342 if ((my->X < 0 - my->Width/2) || (my->X > FieldW + my->Width/2))
343 return NullDel;
344 if ((my->Y < 0 - my->Height/2) || (my->Y > FieldH + my->Height/2))
345 return NullDel;
346
347 return NoneDel;
348 }
349