]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - warp/weapon.c
1 /* Header: weapon.c,v 7.0.1.2 86/10/20 14:36:33 lwall Exp */
4 * Revision 7.0.1.2 86/10/20 14:36:33 lwall
7 * Revision 7.0.1.1 86/10/16 10:54:42 lwall
8 * Added Damage. Fixed random bugs.
10 * Revision 7.0 86/10/08 15:18:08 lwall
11 * Split into separate files. Added amoebas and pirates.
36 fire_torp(OBJECT
*from
, int ydir
, int xdir
)
40 if (from
->type
== Enemy
||
41 (from
== ent
&& etorp
> 0) ||
42 (from
== base
&& btorp
> 0)) {
43 to
= occupant
[(from
->posy
+from
->vely
+ydir
+YSIZE00
)%YSIZE
]
44 [(from
->posx
+from
->velx
+xdir
+XSIZE00
)%XSIZE
];
45 if (from
->type
!= Enemy
|| !to
|| to
->vely
|| to
->velx
) {
46 if (from
->type
!= Enemy
&&
47 (to
= isatorp
[from
==base
][ydir
+1][xdir
+1])) {
53 to
= make_object(Torp
, '+', from
->posy
,from
->posx
,
54 from
->vely
+ydir
,from
->velx
+xdir
, 0L, 1L,&root
);
56 isatorp
[0][ydir
+1][xdir
+1] = to
;
59 else if (from
== base
) {
60 to
= make_object(Torp
, '+', from
->posy
,from
->posx
,
61 from
->vely
+ydir
,from
->velx
+xdir
, 0L, 1L,&root
);
63 isatorp
[1][ydir
+1][xdir
+1] = to
;
66 else if (from
->image
== 'G') {
68 to
= make_object(Torp
, 'o', from
->posy
,from
->posx
,
69 from
->vely
+ydir
,from
->velx
+xdir
, 100L, 1L,&root
);
76 else if (rand_mod(120)+10 > smarts
)
84 to
= make_object(Torp
, 'x', from
->posy
,from
->posx
,
85 from
->vely
+ydir
,from
->velx
+xdir
, 0L, 1L,&root
);
86 if (rand_mod(160)+10 > smarts
)
91 to
->mass
= 1000+super
*20;
101 attack(OBJECT
*attackee
)
110 bool webnear
= false;
117 if (attackee
== nuke
) {
118 if (amb
[attackee
->posy
][attackee
->posx
] != '~')
123 for (dx
= -1; dx
<=1 ; dx
++) {
124 for (dy
= -1; dy
<=1; dy
++) {
126 cury
= attackee
->posy
;
127 curx
= attackee
->posx
;
128 torps
= thru_stars
= false;
129 if (massacre
|| madgorns
|| !rand_mod(53-super
) )
130 webnear
+= rand_mod(2);
133 for (prob
= scandist
;prob
;prob
--) {
134 cury
= (cury
+ dy
+ YSIZE00
) % YSIZE
;
135 curx
= (curx
+ dx
+ XSIZE00
) % XSIZE
;
136 if ((obj
= occupant
[cury
][curx
]) != NULL
) {
137 switch (obj
->image
) {
138 case 'P': case 'K': case 'R': case ' ':
140 if (attackee
== nuke
) {
141 if (rand_mod(2+scandist
-prob
) <
142 rand_mod(smarts
/40+1))
143 tract(nuke
,dy
,dx
,rand_mod(3)?1:-1);
145 if (rand_mod(51 - sm50
) <= prob
) {
146 switch (obj
->strategy
||thru_stars
?0:
149 if (-dy
+ attackee
->vely
== obj
->vely
150 && -dx
+ attackee
->velx
== obj
->velx
)
152 -dy
+ attackee
->vely
,
153 -dx
+ attackee
->velx
);
156 -dy
+ attackee
->vely
- obj
->vely
,
157 -dx
+ attackee
->velx
- obj
->velx
);
158 if (obj
->image
== ' ')
160 obj
->flags
& PIRATE
? 'P' : 'R');
164 rand_mod(prob
<5&&smarts
>70?4:3)-1;
166 obj
->vely
= -dy
* newspeed
;
167 obj
->velx
= -dx
* newspeed
;
169 !rand_mod(82-sm80
)) {
170 obj
->vely
+= attackee
->vely
;
171 obj
->velx
+= attackee
->velx
;
176 if (!torps
&& obj
->energy
> 1000) {
177 fire_phaser(obj
, -dy
, -dx
);
180 || attackee
==base
) &&
181 (massacre
|| obj
->strategy
||
184 fire_phaser(obj
, -dy
, -dx
);
185 if (obj
->image
== ' ')
187 obj
->flags
&PIRATE
? 'P':'R');
190 obj
->velx
= obj
->vely
= 0;
191 if (obj
->energy
< 1000 ||
195 else if ((attackee
==base
||
196 (cloaking
&& attackee
==ent
)
200 ent
?antibase
*2:antibase
)) )
207 if (thru_stars
&& obj
->strategy
< 7)
209 if (attackee
== nuke
) {
210 if (rand_mod(2+scandist
-prob
) <
211 rand_mod(smarts
/40+1))
212 tract(nuke
,dy
,dx
,rand_mod(3)?1:-1);
216 if (madgorns
|| !rand_mod(4)) {
217 obj
->vely
= attackee
->vely
;
218 obj
->velx
= attackee
->velx
;
220 obj
->strategy
+= (!torps
&& deados
> 10);
221 if (obj
->strategy
> 4)
223 if (!torps
&& obj
->strategy
> 5) {
225 fire_phaser(obj
, -dy
, -dx
);
226 } while (rand_mod(2));
229 else if (numgorns
>= numenemies
-1 &&
230 deados
> 15+numgorns
*5)
232 if (madgorns
|| rand_mod(51 - sm50
) <= prob
) {
233 if (-dy
+ attackee
->vely
== obj
->vely
234 && -dx
+ attackee
->velx
== obj
->velx
)
236 -dy
+ attackee
->vely
,
237 -dx
+ attackee
->velx
);
240 -dy
+ attackee
->vely
- obj
->vely
,
241 -dx
+ attackee
->velx
- obj
->velx
);
245 if (attackee
== nuke
) {
246 if (rand_mod(2+scandist
-prob
) <
247 rand_mod(smarts
/40+1))
248 tract(nuke
,dy
,dx
,rand_mod(3)?1:-1);
252 if (webnear
&& scandist
-prob
> 5) {
253 if (massacre
|| rand_mod(50) < super
) {
254 if (!torps
&& obj
->energy
> 1000) {
255 fire_phaser(obj
, -dy
, -dx
);
256 while (!rand_mod(57-sm55
))
257 fire_phaser(obj
, -dy
, -dx
);
266 case 'Q': case 'W': case 'Y': case 'U':
267 case 'I': case 'S': case 'D': case 'H': case 'J':
268 case 'L': case 'Z': case 'V': case 'M': case 'F':
269 if (attackee
== nuke
) {
270 if (rand_mod(2+scandist
-prob
) <
271 rand_mod(smarts
/40+1))
272 tract(nuke
,dy
,dx
,rand_mod(3)?1:-1);
276 if (madfriends
> 1000) {
282 if (attackee
== nuke
) {
285 (obj
->posx
+ obj
->velx
+ XSIZE00
)%XSIZE
287 (obj
->posy
+ obj
->vely
+ YSIZE00
)%YSIZE
288 == attackee
->posy
) {
289 tract(nuke
,dy
,dx
,-1);
292 while (!rand_mod(82-sm80
))
293 tract(nuke
,dy
,dx
,-1);
295 else if (smarts
> 60 ||
296 rand_mod(2+scandist
-prob
) <
297 rand_mod(smarts
/20+1))
298 tract(nuke
,dy
,dx
,rand_mod(3)?1:-1);
303 case '|': case '-': case '/': case '\\':
306 webnear
= (scandist
-prob
< 3);
310 if (attackee
== nuke
) {
311 if (rand_mod(2+scandist
-prob
) <
312 rand_mod(smarts
/20+1))
313 tract(nuke
,dy
,dx
,rand_mod(3)?1:-1);
319 case 'o': case 'O': case '0':
320 if (attackee
== nuke
) {
321 if (rand_mod(2+scandist
-prob
) <
322 rand_mod(smarts
/20+1))
323 tract(nuke
,dy
,dx
,rand_mod(3)?1:-1);
328 if (rand_mod(99+3*scandist
) < smarts
+3*prob
) {
329 obj
->vely
= -dy
+ attackee
->vely
;
330 obj
->velx
= -dx
+ attackee
->velx
;
331 if (obj
->flags
& STATIC
) {/* not a mover? */
332 obj
->flags
&= ~STATIC
;
333 obj
->prev
->next
= obj
->next
;
334 obj
->next
->prev
= obj
->prev
;
335 root
.prev
->next
= obj
;
336 obj
->prev
= root
.prev
;
341 if (obj
->image
!= '0')
345 if (attackee
== nuke
) {
346 if (rand_mod(2+scandist
-prob
) <
347 rand_mod(smarts
/20+1))
348 tract(nuke
,dy
,dx
,rand_mod(3)?1:-1);
353 if (prob
== scandist
) {
356 blast
[y
=(obj
->posy
+obj
->vely
+YSIZE00
)%YSIZE
]
357 [x
=(obj
->posx
+obj
->velx
+XSIZE00
)%XSIZE
]
358 += (obj
->image
== '0' ? 2000 : 200);
365 if (attackee
!= nuke
) {
366 if (scandist
-prob
>1 && !rand_mod(51-super
))
367 tract(obj
,-dy
,-dx
,1);
371 if (attackee
== nuke
) {
372 if (amb
[cury
][curx
] != '~') {
373 if (scandist
-prob
< nukedist
) {
374 nukedist
= scandist
-prob
;
375 nukey
= dy
; /* nearest food in */
376 nukex
= dx
; /* this direction */
378 if (smarts
> 55 && scandist
-prob
> 8) {
379 if (rand_mod(30+scandist
-prob
) <
380 rand_mod(smarts
/20+1))
384 else if (obj
->vely
|| obj
->velx
) {
385 tract(nuke
,dy
,dx
,1); /* for looks */
386 obj
->vely
= obj
->velx
= 0;
390 if (rand_mod(97-sm95
))
397 if (attackee
== nuke
) {
398 if ((!dy
&& scandist
-prob
< 8) ||
399 rand_mod(2+scandist
-prob
) <
400 rand_mod(smarts
/20+1) ) {
402 tract(nuke
,dy
,dx
,-1);
408 if (attackee
== nuke
) {
409 if (rand_mod(2+scandist
-prob
) <
410 rand_mod(smarts
/40+1))
411 tract(nuke
,dy
,dx
,rand_mod(3)?1:-1);
423 bombout
: ; /* end of loop */
427 if (attackee
== nuke
&& nukedist
< 100) {/* aim amoeba at nearest */
428 if (nukey
< 0) /* free star */
432 nuke
->strategy
= nukey
+ (nukex
<< 2);
438 fire_phaser(OBJECT
*obj
, int dy
, int dx
)
444 int decr
= 50, oldy
, oldx
;
445 static char curchar
[] = "@* ";
449 else if (obj
== base
) {
461 if (obj
->energy
>= decr
) {
465 skipping
= (obj
!= base
),
466 y
= (obj
->posy
+(obj
==base
?dy
*2:dy
)+YSIZE00
)%YSIZE
,
467 x
= (obj
->posx
+(obj
==base
?dx
*2:dx
)+XSIZE00
)%XSIZE
;
469 size
&& (!occupant
[y
][x
]||(skipping
&& occupant
[y
][x
]->type
==Star
));
471 y
= (y
+dy
+YSIZE00
) % YSIZE
,
472 x
= (x
+dx
+XSIZE00
) % XSIZE
,
473 size
= size
* 3 / 4 ) {
476 if (obj
== base
|| obj
->image
== 'T') {
490 *filler
= size
>= 500 ?
491 *curchar
: (size
>= 50 ?
497 qaddc(occupant
[y
][x
]->image
);
511 assert(occupant
[y
][x
]);
512 img
= occupant
[y
][x
]->image
;
513 if (occupant
[y
][x
]->type
== Crusher
) {
516 if (dx
==(img
== '<' ? 1 : -1) ) {
517 occupant
[y
][x
]->image
=
518 (occupant
[y
][x
]->velx
*= -1) < 0 ? '>' : '<';
522 else if (occupant
[y
][x
]->flags
& FRIENDLY
)
524 if (numamoebas
&& amb
[y
][x
] == '~' && smarts
% 3 &&
525 (smarts
> 70 || rand_mod(smarts
) > rand_mod(20)) ) {
527 modify_amoeba(y
,x
,1,'~',10);
528 else if (size
> 1000)
529 modify_amoeba(y
,x
,1,'~',7);
531 modify_amoeba(y
,x
,1,'~',5);
533 modify_amoeba(y
,x
,1,'~',2);
534 if (occupant
[y
][x
] == nuke
) {
535 nuke
->strategy
= rand_mod(30);
536 nuke
->flags
|= COUNTDOWN
;
544 *filler
= occupant
[y
][x
]->flags
& PIRATE
? 'P' : 'R';
545 occupant
[y
][x
]->image
= *filler
;
546 occupant
[y
][x
]->strategy
= 0;
550 else if (img
== 'C' || img
== 'c') {
553 occupant
[y
][x
]->image
= img
;
558 else if (img
== 'K' && size
> 50)
559 occupant
[y
][x
]->strategy
= 0;
574 y
= (occupant
[oldy
][oldx
]->posy
+ occupant
[oldy
][oldx
]->vely
+
576 x
= (occupant
[oldy
][oldx
]->posx
+ occupant
[oldy
][oldx
]->velx
+
578 if (occupant
[y
][x
] && occupant
[y
][x
]->type
== Star
) {
579 y
= occupant
[oldy
][oldx
]->posy
;
580 x
= occupant
[oldy
][oldx
]->posx
;
583 blast
[y
][x
] += size
>50 ? 15000 : (size
>15 ? 1500 : 150);
585 blast
[y
][x
] += size
*4;
586 else if (obj
->image
=='T')
587 blast
[y
][x
] += 15000;
589 blast
[y
][x
] += size
*smarts
/25;
599 tract(OBJECT
*obj
, int dy
, int dx
, int to_or_fro
)
617 y
= (obj
->posy
+dy
+YSIZE00
)%YSIZE
,
618 x
= (obj
->posx
+dx
+XSIZE00
)%XSIZE
;
619 size
&& (!occupant
[y
][x
]);
620 y
= (y
+dy
+YSIZE00
) % YSIZE
, x
= (x
+dx
+XSIZE00
) % XSIZE
, size
--) {
632 tractee
= occupant
[y
][x
];
635 if (numamoebas
&& obj
!= nuke
&& amb
[y
][x
] == '~') {
637 modify_amoeba(y
,x
,2,'~',size
);
639 modify_amoeba(y
,x
,1,' ',size
);
641 if (tractee
->type
!= Web
&&
642 (tractee
->mass
< obj
->mass
* 5 ||
643 (tractee
->type
== Crusher
&& !dx
) ) ) {
644 if (tractee
== ent
) {
645 evely
-= dy
* to_or_fro
;
646 evelx
-= dx
* to_or_fro
;
648 else if (tractee
== base
) {
649 bvely
-= dy
* to_or_fro
;
650 bvelx
-= dx
* to_or_fro
;
653 tractee
->vely
-= dy
* to_or_fro
;
654 tractee
->velx
-= dx
* to_or_fro
;
656 if (tractee
->type
== Torp
||
657 tractee
->type
== Star
) {
658 if (tractee
->flags
& STATIC
) { /* not a mover? */
659 tractee
->flags
&= ~STATIC
;
660 tractee
->prev
->next
= tractee
->next
;
661 tractee
->next
->prev
= tractee
->prev
;
662 root
.prev
->next
= tractee
;
663 tractee
->prev
= root
.prev
;
665 tractee
->next
= &root
;
669 else if (tractee
->type
== Crusher
&& !dy
&&
670 dx
==(tractee
->image
== '<' ? 1 : -1) ) {
671 setimage(tractee
, (tractee
->velx
*= -1) < 0 ? '>' : '<');
673 if (tractee
->mass
* 5 > obj
->mass
)