weapon.c revision 1.3 1 1.2 kamil /* Header: weapon.c,v 7.0.1.2 86/10/20 14:36:33 lwall Exp */
2 1.1 kamil
3 1.2 kamil /* Log: weapon.c,v
4 1.1 kamil * Revision 7.0.1.2 86/10/20 14:36:33 lwall
5 1.1 kamil * Picked some lint.
6 1.1 kamil *
7 1.1 kamil * Revision 7.0.1.1 86/10/16 10:54:42 lwall
8 1.1 kamil * Added Damage. Fixed random bugs.
9 1.1 kamil *
10 1.1 kamil * Revision 7.0 86/10/08 15:18:08 lwall
11 1.1 kamil * Split into separate files. Added amoebas and pirates.
12 1.1 kamil *
13 1.1 kamil */
14 1.1 kamil
15 1.1 kamil #include "EXTERN.h"
16 1.1 kamil #include "warp.h"
17 1.1 kamil #include "bang.h"
18 1.1 kamil #include "object.h"
19 1.1 kamil #include "move.h"
20 1.1 kamil #include "score.h"
21 1.1 kamil #include "sig.h"
22 1.1 kamil #include "term.h"
23 1.1 kamil #include "them.h"
24 1.1 kamil #include "us.h"
25 1.1 kamil #include "util.h"
26 1.1 kamil #include "INTERN.h"
27 1.1 kamil #include "weapon.h"
28 1.1 kamil
29 1.1 kamil void
30 1.3 christos weapon_init(void)
31 1.1 kamil {
32 1.1 kamil ;
33 1.1 kamil }
34 1.1 kamil
35 1.1 kamil void
36 1.3 christos fire_torp(OBJECT *from, int ydir, int xdir)
37 1.1 kamil {
38 1.3 christos OBJECT *to;
39 1.1 kamil
40 1.1 kamil if (from->type == Enemy ||
41 1.1 kamil (from == ent && etorp > 0) ||
42 1.1 kamil (from == base && btorp > 0)) {
43 1.1 kamil to = occupant[(from->posy+from->vely+ydir+YSIZE00)%YSIZE]
44 1.1 kamil [(from->posx+from->velx+xdir+XSIZE00)%XSIZE];
45 1.1 kamil if (from->type != Enemy || !to || to->vely || to->velx) {
46 1.1 kamil if (from->type != Enemy &&
47 1.1 kamil (to = isatorp[from==base][ydir+1][xdir+1])) {
48 1.1 kamil to->vely += ydir;
49 1.1 kamil to->velx += xdir;
50 1.1 kamil }
51 1.1 kamil else {
52 1.1 kamil if (from == ent) {
53 1.1 kamil to = make_object(Torp, '+', from->posy,from->posx,
54 1.1 kamil from->vely+ydir,from->velx+xdir, 0L, 1L,&root);
55 1.1 kamil aretorps++;
56 1.1 kamil isatorp[0][ydir+1][xdir+1] = to;
57 1.1 kamil etorp--;
58 1.1 kamil }
59 1.1 kamil else if (from == base) {
60 1.1 kamil to = make_object(Torp, '+', from->posy,from->posx,
61 1.1 kamil from->vely+ydir,from->velx+xdir, 0L, 1L,&root);
62 1.1 kamil aretorps++;
63 1.1 kamil isatorp[1][ydir+1][xdir+1] = to;
64 1.1 kamil btorp--;
65 1.1 kamil }
66 1.1 kamil else if (from->image == 'G') {
67 1.1 kamil numos++;
68 1.1 kamil to = make_object(Torp, 'o', from->posy,from->posx,
69 1.1 kamil from->vely+ydir,from->velx+xdir, 100L, 1L,&root);
70 1.1 kamil if (madgorns) {
71 1.1 kamil possiblescore += 35;
72 1.1 kamil to->image = '0';
73 1.1 kamil to->mass = 2000;
74 1.1 kamil to->energy = 2000;
75 1.1 kamil }
76 1.1 kamil else if (rand_mod(120)+10 > smarts)
77 1.1 kamil possiblescore += 100;
78 1.1 kamil else {
79 1.1 kamil possiblescore += 200;
80 1.1 kamil to->image = 'O';
81 1.1 kamil }
82 1.1 kamil }
83 1.1 kamil else {
84 1.1 kamil to = make_object(Torp, 'x', from->posy,from->posx,
85 1.1 kamil from->vely+ydir,from->velx+xdir, 0L, 1L,&root);
86 1.1 kamil if (rand_mod(160)+10 > smarts)
87 1.1 kamil possiblescore += 10;
88 1.1 kamil else {
89 1.1 kamil possiblescore += 100;
90 1.1 kamil to->image = 'X';
91 1.1 kamil to->mass = 1000+super*20;
92 1.1 kamil numxes++;
93 1.1 kamil }
94 1.1 kamil }
95 1.1 kamil }
96 1.1 kamil }
97 1.1 kamil }
98 1.1 kamil }
99 1.1 kamil
100 1.1 kamil void
101 1.3 christos attack(OBJECT *attackee)
102 1.1 kamil {
103 1.3 christos int dx;
104 1.3 christos int dy;
105 1.3 christos int curx;
106 1.3 christos int cury;
107 1.3 christos int prob;
108 1.3 christos OBJECT *obj;
109 1.3 christos bool torps;
110 1.3 christos bool webnear = false;
111 1.3 christos bool thru_stars;
112 1.1 kamil int nukey;
113 1.1 kamil int nukex;
114 1.1 kamil int nukedist;
115 1.1 kamil
116 1.1 kamil if (attackee) {
117 1.1 kamil if (attackee == nuke) {
118 1.1 kamil if (amb[attackee->posy][attackee->posx] != '~')
119 1.1 kamil return;
120 1.1 kamil nukey = nukex = 0;
121 1.1 kamil nukedist = 100;
122 1.1 kamil }
123 1.1 kamil for (dx= -1; dx<=1 ; dx++) {
124 1.1 kamil for (dy= -1; dy<=1; dy++) {
125 1.1 kamil if (dx||dy) {
126 1.1 kamil cury = attackee->posy;
127 1.1 kamil curx = attackee->posx;
128 1.3 christos torps = thru_stars = false;
129 1.1 kamil if (massacre || madgorns || !rand_mod(53-super) )
130 1.1 kamil webnear += rand_mod(2);
131 1.1 kamil else
132 1.3 christos webnear = false;
133 1.1 kamil for (prob = scandist;prob;prob--) {
134 1.1 kamil cury = (cury + dy + YSIZE00) % YSIZE;
135 1.1 kamil curx = (curx + dx + XSIZE00) % XSIZE;
136 1.3 christos if ((obj = occupant[cury][curx]) != NULL) {
137 1.1 kamil switch (obj->image) {
138 1.1 kamil case 'P': case 'K': case 'R': case ' ':
139 1.1 kamil pot_shot:
140 1.1 kamil if (attackee == nuke) {
141 1.1 kamil if (rand_mod(2+scandist-prob) <
142 1.1 kamil rand_mod(smarts/40+1))
143 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1);
144 1.1 kamil }
145 1.1 kamil if (rand_mod(51 - sm50) <= prob) {
146 1.1 kamil switch (obj->strategy||thru_stars?0:
147 1.1 kamil rand_mod(ent?4:2)) {
148 1.1 kamil case 1: case 2:
149 1.1 kamil if (-dy + attackee->vely == obj->vely
150 1.1 kamil && -dx + attackee->velx == obj->velx)
151 1.1 kamil fire_torp(obj,
152 1.1 kamil -dy + attackee->vely,
153 1.1 kamil -dx + attackee->velx);
154 1.1 kamil else
155 1.1 kamil fire_torp(obj,
156 1.1 kamil -dy + attackee->vely - obj->vely,
157 1.1 kamil -dx + attackee->velx - obj->velx);
158 1.1 kamil if (obj->image == ' ')
159 1.1 kamil setimage(obj,
160 1.1 kamil obj->flags & PIRATE ? 'P' : 'R');
161 1.1 kamil break;
162 1.1 kamil case 3: {
163 1.1 kamil int newspeed =
164 1.1 kamil rand_mod(prob<5&&smarts>70?4:3)-1;
165 1.1 kamil
166 1.1 kamil obj->vely = -dy * newspeed;
167 1.1 kamil obj->velx = -dx * newspeed;
168 1.1 kamil if (newspeed >= 0 &&
169 1.1 kamil !rand_mod(82-sm80)) {
170 1.1 kamil obj->vely += attackee->vely;
171 1.1 kamil obj->velx += attackee->velx;
172 1.1 kamil }
173 1.1 kamil break;
174 1.1 kamil }
175 1.1 kamil case 0:
176 1.1 kamil if (!torps && obj->energy > 1000) {
177 1.1 kamil fire_phaser(obj, -dy, -dx);
178 1.1 kamil if (smarts > 40 &&
179 1.1 kamil (scandist-prob > 5
180 1.1 kamil || attackee==base) &&
181 1.1 kamil (massacre || obj->strategy ||
182 1.1 kamil rand_mod(2)))
183 1.1 kamil while (rand_mod(2))
184 1.1 kamil fire_phaser(obj, -dy, -dx);
185 1.1 kamil if (obj->image == ' ')
186 1.1 kamil setimage(obj,
187 1.1 kamil obj->flags&PIRATE ? 'P':'R');
188 1.1 kamil }
189 1.1 kamil if (obj->strategy) {
190 1.1 kamil obj->velx = obj->vely = 0;
191 1.1 kamil if (obj->energy < 1000 ||
192 1.1 kamil bvely || bvelx)
193 1.1 kamil obj->strategy = 0;
194 1.1 kamil }
195 1.1 kamil else if ((attackee==base ||
196 1.1 kamil (cloaking && attackee==ent)
197 1.1 kamil ) &&
198 1.1 kamil scandist-prob > 5 &&
199 1.1 kamil !(rand_mod(
200 1.1 kamil ent?antibase*2:antibase)) )
201 1.1 kamil obj->strategy = 1;
202 1.1 kamil break;
203 1.1 kamil }
204 1.1 kamil }
205 1.1 kamil goto bombout;
206 1.1 kamil case 'G':
207 1.1 kamil if (thru_stars && obj->strategy < 7)
208 1.1 kamil goto bombout;
209 1.1 kamil if (attackee == nuke) {
210 1.1 kamil if (rand_mod(2+scandist-prob) <
211 1.1 kamil rand_mod(smarts/40+1))
212 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1);
213 1.1 kamil goto bombout;
214 1.1 kamil }
215 1.1 kamil if (obj->strategy) {
216 1.1 kamil if (madgorns || !rand_mod(4)) {
217 1.1 kamil obj->vely = attackee->vely;
218 1.1 kamil obj->velx = attackee->velx;
219 1.1 kamil }
220 1.1 kamil obj->strategy += (!torps && deados > 10);
221 1.1 kamil if (obj->strategy > 4)
222 1.3 christos madgorns = true;
223 1.1 kamil if (!torps && obj->strategy > 5) {
224 1.1 kamil do {
225 1.1 kamil fire_phaser(obj, -dy, -dx);
226 1.1 kamil } while (rand_mod(2));
227 1.1 kamil }
228 1.1 kamil }
229 1.1 kamil else if (numgorns >= numenemies-1 &&
230 1.1 kamil deados > 15+numgorns*5)
231 1.1 kamil obj->strategy = 1;
232 1.1 kamil if (madgorns || rand_mod(51 - sm50) <= prob) {
233 1.1 kamil if (-dy + attackee->vely == obj->vely
234 1.1 kamil && -dx + attackee->velx == obj->velx)
235 1.1 kamil fire_torp(obj,
236 1.1 kamil -dy + attackee->vely,
237 1.1 kamil -dx + attackee->velx);
238 1.1 kamil else
239 1.1 kamil fire_torp(obj,
240 1.1 kamil -dy + attackee->vely - obj->vely,
241 1.1 kamil -dx + attackee->velx - obj->velx);
242 1.1 kamil }
243 1.1 kamil goto bombout;
244 1.1 kamil case 'T':
245 1.1 kamil if (attackee == nuke) {
246 1.1 kamil if (rand_mod(2+scandist-prob) <
247 1.1 kamil rand_mod(smarts/40+1))
248 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1);
249 1.1 kamil }
250 1.1 kamil if (thru_stars)
251 1.1 kamil goto bombout;
252 1.1 kamil if (webnear && scandist-prob > 5) {
253 1.1 kamil if (massacre || rand_mod(50) < super) {
254 1.1 kamil if (!torps && obj->energy > 1000) {
255 1.1 kamil fire_phaser(obj, -dy, -dx);
256 1.1 kamil while (!rand_mod(57-sm55))
257 1.1 kamil fire_phaser(obj, -dy, -dx);
258 1.1 kamil }
259 1.1 kamil }
260 1.1 kamil }
261 1.1 kamil goto bombout;
262 1.1 kamil case 'C': case 'c':
263 1.1 kamil if (thru_stars)
264 1.1 kamil goto bombout;
265 1.1 kamil break;
266 1.1 kamil case 'Q': case 'W': case 'Y': case 'U':
267 1.1 kamil case 'I': case 'S': case 'D': case 'H': case 'J':
268 1.1 kamil case 'L': case 'Z': case 'V': case 'M': case 'F':
269 1.1 kamil if (attackee == nuke) {
270 1.1 kamil if (rand_mod(2+scandist-prob) <
271 1.1 kamil rand_mod(smarts/40+1))
272 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1);
273 1.1 kamil if (rand_mod(2))
274 1.1 kamil goto pot_shot;
275 1.1 kamil }
276 1.1 kamil if (madfriends > 1000) {
277 1.1 kamil madfriends -= 200;
278 1.1 kamil goto pot_shot;
279 1.1 kamil }
280 1.1 kamil /* FALL THROUGH */
281 1.1 kamil case '+':
282 1.1 kamil if (attackee == nuke) {
283 1.1 kamil if (smarts > 70) {
284 1.1 kamil if (
285 1.1 kamil (obj->posx + obj->velx + XSIZE00)%XSIZE
286 1.1 kamil == attackee->posx &&
287 1.1 kamil (obj->posy + obj->vely + YSIZE00)%YSIZE
288 1.1 kamil == attackee->posy ) {
289 1.3 christos tract(nuke,dy,dx,-1);
290 1.1 kamil }
291 1.1 kamil else
292 1.1 kamil while (!rand_mod(82-sm80))
293 1.3 christos tract(nuke,dy,dx,-1);
294 1.1 kamil }
295 1.1 kamil else if (smarts > 60 ||
296 1.1 kamil rand_mod(2+scandist-prob) <
297 1.1 kamil rand_mod(smarts/20+1))
298 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1);
299 1.1 kamil }
300 1.3 christos torps = false;
301 1.3 christos thru_stars = false;
302 1.1 kamil break;
303 1.1 kamil case '|': case '-': case '/': case '\\':
304 1.1 kamil if (thru_stars)
305 1.1 kamil goto bombout;
306 1.1 kamil webnear = (scandist-prob < 3);
307 1.3 christos torps = false;
308 1.1 kamil break;
309 1.1 kamil case 'x':
310 1.1 kamil if (attackee == nuke) {
311 1.1 kamil if (rand_mod(2+scandist-prob) <
312 1.1 kamil rand_mod(smarts/20+1))
313 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1);
314 1.1 kamil }
315 1.1 kamil if (thru_stars)
316 1.1 kamil goto bombout;
317 1.3 christos torps = true;
318 1.1 kamil break;
319 1.1 kamil case 'o': case 'O': case '0':
320 1.1 kamil if (attackee == nuke) {
321 1.1 kamil if (rand_mod(2+scandist-prob) <
322 1.1 kamil rand_mod(smarts/20+1))
323 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1);
324 1.1 kamil }
325 1.1 kamil if (thru_stars)
326 1.1 kamil goto bombout;
327 1.3 christos torps = true;
328 1.1 kamil if (rand_mod(99+3*scandist) < smarts+3*prob) {
329 1.1 kamil obj->vely = -dy + attackee->vely;
330 1.1 kamil obj->velx = -dx + attackee->velx;
331 1.1 kamil if (obj->flags & STATIC) {/* not a mover? */
332 1.1 kamil obj->flags &= ~STATIC;
333 1.1 kamil obj->prev->next = obj->next;
334 1.1 kamil obj->next->prev = obj->prev;
335 1.1 kamil root.prev->next = obj;
336 1.1 kamil obj->prev = root.prev;
337 1.1 kamil root.prev = obj;
338 1.1 kamil obj->next = &root;
339 1.1 kamil }
340 1.1 kamil }
341 1.1 kamil if (obj->image != '0')
342 1.1 kamil break;
343 1.3 christos /*FALLTHROUGH*/
344 1.1 kamil case 'X':
345 1.1 kamil if (attackee == nuke) {
346 1.1 kamil if (rand_mod(2+scandist-prob) <
347 1.1 kamil rand_mod(smarts/20+1))
348 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1);
349 1.1 kamil }
350 1.3 christos torps = true;
351 1.1 kamil if (thru_stars)
352 1.1 kamil goto bombout;
353 1.1 kamil if (prob == scandist) {
354 1.1 kamil int y, x;
355 1.1 kamil
356 1.1 kamil blast[y=(obj->posy+obj->vely+YSIZE00)%YSIZE]
357 1.1 kamil [x=(obj->posx+obj->velx+XSIZE00)%XSIZE]
358 1.1 kamil += (obj->image == '0' ? 2000 : 200);
359 1.1 kamil yblasted[y] |= 1;
360 1.1 kamil xblasted[x] |= 1;
361 1.3 christos blasted = true;
362 1.1 kamil }
363 1.1 kamil break;
364 1.1 kamil case 'A':
365 1.1 kamil if (attackee != nuke) {
366 1.1 kamil if (scandist-prob>1 && !rand_mod(51-super))
367 1.3 christos tract(obj,-dy,-dx,1);
368 1.1 kamil }
369 1.1 kamil /* FALL THROUGH */
370 1.1 kamil case '*': case '@':
371 1.1 kamil if (attackee == nuke) {
372 1.1 kamil if (amb[cury][curx] != '~') {
373 1.1 kamil if (scandist-prob < nukedist) {
374 1.1 kamil nukedist = scandist-prob;
375 1.1 kamil nukey = dy; /* nearest food in */
376 1.1 kamil nukex = dx; /* this direction */
377 1.1 kamil }
378 1.1 kamil if (smarts > 55 && scandist-prob > 8) {
379 1.1 kamil if (rand_mod(30+scandist-prob) <
380 1.1 kamil rand_mod(smarts/20+1))
381 1.3 christos tract(nuke,dy,dx,1);
382 1.1 kamil }
383 1.1 kamil }
384 1.1 kamil else if (obj->vely || obj->velx) {
385 1.3 christos tract(nuke,dy,dx,1); /* for looks */
386 1.1 kamil obj->vely = obj->velx = 0;
387 1.1 kamil }
388 1.1 kamil }
389 1.3 christos if (!thru_stars) {
390 1.1 kamil if (rand_mod(97-sm95))
391 1.1 kamil goto bombout;
392 1.1 kamil else
393 1.3 christos thru_stars = true;
394 1.3 christos }
395 1.1 kamil break;
396 1.1 kamil case '<': case '>':
397 1.1 kamil if (attackee == nuke) {
398 1.1 kamil if ((!dy && scandist-prob < 8) ||
399 1.1 kamil rand_mod(2+scandist-prob) <
400 1.1 kamil rand_mod(smarts/20+1) ) {
401 1.1 kamil nuke->mass += 10000;
402 1.3 christos tract(nuke,dy,dx,-1);
403 1.1 kamil nuke->mass -= 10000;
404 1.1 kamil }
405 1.1 kamil }
406 1.1 kamil goto bombout;
407 1.1 kamil case 'E': case 'B':
408 1.1 kamil if (attackee == nuke) {
409 1.1 kamil if (rand_mod(2+scandist-prob) <
410 1.1 kamil rand_mod(smarts/40+1))
411 1.3 christos tract(nuke,dy,dx,rand_mod(3)?1:-1);
412 1.1 kamil }
413 1.1 kamil goto bombout;
414 1.1 kamil default:
415 1.1 kamil goto bombout;
416 1.1 kamil }
417 1.1 kamil }
418 1.1 kamil else {
419 1.1 kamil if (thru_stars)
420 1.1 kamil goto bombout;
421 1.1 kamil }
422 1.1 kamil }
423 1.1 kamil bombout: ; /* end of loop */
424 1.1 kamil }
425 1.1 kamil }
426 1.1 kamil }
427 1.1 kamil if (attackee == nuke && nukedist < 100) {/* aim amoeba at nearest */
428 1.1 kamil if (nukey < 0) /* free star */
429 1.1 kamil nukey = 2;
430 1.1 kamil if (nukex < 0)
431 1.1 kamil nukex = 2;
432 1.1 kamil nuke->strategy = nukey + (nukex << 2);
433 1.1 kamil }
434 1.1 kamil }
435 1.1 kamil }
436 1.1 kamil
437 1.1 kamil void
438 1.3 christos fire_phaser(OBJECT *obj, int dy, int dx)
439 1.1 kamil {
440 1.3 christos int y;
441 1.3 christos int x;
442 1.3 christos int skipping;
443 1.3 christos int size=5000;
444 1.1 kamil int decr = 50, oldy, oldx;
445 1.1 kamil static char curchar[] = "@* ";
446 1.1 kamil
447 1.1 kamil if (obj == ent)
448 1.1 kamil decr = 100;
449 1.1 kamil else if (obj == base) {
450 1.1 kamil decr = 1000;
451 1.1 kamil size = 200;
452 1.1 kamil }
453 1.1 kamil if (!dy)
454 1.1 kamil curchar[2] = '-';
455 1.1 kamil else if (!dx)
456 1.1 kamil curchar[2] = '!';
457 1.1 kamil else if (dy == dx)
458 1.1 kamil curchar[2] = '\\';
459 1.1 kamil else
460 1.1 kamil curchar[2] = '/';
461 1.1 kamil if (obj->energy >= decr) {
462 1.1 kamil obj->energy -= decr;
463 1.1 kamil for (
464 1.1 kamil /* initialize */
465 1.1 kamil skipping = (obj != base),
466 1.1 kamil y = (obj->posy+(obj==base?dy*2:dy)+YSIZE00)%YSIZE,
467 1.1 kamil x = (obj->posx+(obj==base?dx*2:dx)+XSIZE00)%XSIZE;
468 1.1 kamil /* while */
469 1.1 kamil size && (!occupant[y][x]||(skipping && occupant[y][x]->type==Star));
470 1.1 kamil /* at end of loop */
471 1.1 kamil y = (y+dy+YSIZE00) % YSIZE,
472 1.1 kamil x = (x+dx+XSIZE00) % XSIZE,
473 1.1 kamil size = size * 3 / 4 ) {
474 1.1 kamil move(y+1,x*2,0);
475 1.1 kamil beg_qwrite();
476 1.1 kamil if (obj == base || obj->image == 'T') {
477 1.1 kamil *filler = '@';
478 1.1 kamil qwrite();
479 1.1 kamil *filler = '#';
480 1.1 kamil qwrite();
481 1.1 kamil *filler = '~';
482 1.1 kamil qwrite();
483 1.1 kamil *filler = '%';
484 1.1 kamil qwrite();
485 1.1 kamil *filler = ':';
486 1.1 kamil qwrite();
487 1.1 kamil *filler = '@';
488 1.1 kamil }
489 1.1 kamil else {
490 1.1 kamil *filler = size >= 500 ?
491 1.1 kamil *curchar : (size >= 50 ?
492 1.1 kamil curchar[1] :
493 1.1 kamil curchar[2]);
494 1.1 kamil }
495 1.1 kamil qwrite();
496 1.1 kamil if (occupant[y][x])
497 1.1 kamil qaddc(occupant[y][x]->image);
498 1.1 kamil else {
499 1.1 kamil if (numamoebas)
500 1.1 kamil qaddc(amb[y][x]);
501 1.1 kamil else
502 1.1 kamil qaddspace();
503 1.1 kamil if (skipping)
504 1.1 kamil skipping = 0;
505 1.1 kamil }
506 1.1 kamil end_qwrite();
507 1.1 kamil }
508 1.1 kamil if (size) {
509 1.1 kamil char img;
510 1.1 kamil
511 1.1 kamil assert(occupant[y][x]);
512 1.1 kamil img = occupant[y][x]->image;
513 1.1 kamil if (occupant[y][x]->type == Crusher) {
514 1.1 kamil if (dy)
515 1.1 kamil return;
516 1.1 kamil if (dx==(img == '<' ? 1 : -1) ) {
517 1.1 kamil occupant[y][x]->image =
518 1.1 kamil (occupant[y][x]->velx *= -1) < 0 ? '>' : '<';
519 1.1 kamil return;
520 1.1 kamil }
521 1.1 kamil }
522 1.1 kamil else if (occupant[y][x]->flags & FRIENDLY)
523 1.1 kamil madfriends += 200;
524 1.1 kamil if (numamoebas && amb[y][x] == '~' && smarts % 3 &&
525 1.1 kamil (smarts > 70 || rand_mod(smarts) > rand_mod(20)) ) {
526 1.1 kamil if (size > 10000)
527 1.1 kamil modify_amoeba(y,x,1,'~',10);
528 1.1 kamil else if (size > 1000)
529 1.1 kamil modify_amoeba(y,x,1,'~',7);
530 1.1 kamil else if (size > 50)
531 1.1 kamil modify_amoeba(y,x,1,'~',5);
532 1.1 kamil else
533 1.1 kamil modify_amoeba(y,x,1,'~',2);
534 1.1 kamil if (occupant[y][x] == nuke) {
535 1.1 kamil nuke->strategy = rand_mod(30);
536 1.1 kamil nuke->flags |= COUNTDOWN;
537 1.1 kamil }
538 1.1 kamil return;
539 1.1 kamil }
540 1.1 kamil else {
541 1.1 kamil move(y+1,x*2,0);
542 1.1 kamil beg_qwrite();
543 1.1 kamil if (img == ' ') {
544 1.1 kamil *filler = occupant[y][x]->flags & PIRATE ? 'P' : 'R';
545 1.1 kamil occupant[y][x]->image = *filler;
546 1.1 kamil occupant[y][x]->strategy = 0;
547 1.1 kamil qwrite();
548 1.1 kamil qwrite();
549 1.1 kamil }
550 1.1 kamil else if (img == 'C' || img == 'c') {
551 1.1 kamil cloaked = 0;
552 1.1 kamil img += 2;
553 1.1 kamil occupant[y][x]->image = img;
554 1.1 kamil *filler = img;
555 1.1 kamil qwrite();
556 1.1 kamil qwrite();
557 1.1 kamil }
558 1.1 kamil else if (img == 'K' && size > 50)
559 1.1 kamil occupant[y][x]->strategy = 0;
560 1.1 kamil *filler = '@';
561 1.1 kamil qwrite();
562 1.1 kamil *filler = '#';
563 1.1 kamil qwrite();
564 1.1 kamil *filler = '@';
565 1.1 kamil qwrite();
566 1.1 kamil *filler = '#';
567 1.1 kamil qwrite();
568 1.1 kamil *filler = '@';
569 1.1 kamil qwrite();
570 1.1 kamil qaddc(img);
571 1.1 kamil end_qwrite();
572 1.1 kamil oldy = y;
573 1.1 kamil oldx = x;
574 1.1 kamil y = (occupant[oldy][oldx]->posy + occupant[oldy][oldx]->vely +
575 1.1 kamil YSIZE00) % YSIZE;
576 1.1 kamil x = (occupant[oldy][oldx]->posx + occupant[oldy][oldx]->velx +
577 1.1 kamil XSIZE00) % XSIZE;
578 1.1 kamil if (occupant[y][x] && occupant[y][x]->type == Star) {
579 1.1 kamil y = occupant[oldy][oldx]->posy;
580 1.1 kamil x = occupant[oldy][oldx]->posx;
581 1.1 kamil }
582 1.1 kamil if (obj==base)
583 1.1 kamil blast[y][x] += size>50 ? 15000 : (size>15 ? 1500 : 150);
584 1.1 kamil else if (obj==ent)
585 1.1 kamil blast[y][x] += size*4;
586 1.1 kamil else if (obj->image=='T')
587 1.1 kamil blast[y][x] += 15000;
588 1.1 kamil else
589 1.1 kamil blast[y][x] += size*smarts/25;
590 1.1 kamil yblasted[y] |= 1;
591 1.1 kamil xblasted[x] |= 1;
592 1.3 christos blasted = true;
593 1.1 kamil }
594 1.1 kamil }
595 1.1 kamil }
596 1.1 kamil }
597 1.1 kamil
598 1.1 kamil int
599 1.3 christos tract(OBJECT *obj, int dy, int dx, int to_or_fro)
600 1.1 kamil {
601 1.3 christos int y;
602 1.3 christos int x;
603 1.3 christos int size=10;
604 1.1 kamil static char ch;
605 1.3 christos OBJECT *tractee;
606 1.1 kamil
607 1.1 kamil if (!dy)
608 1.1 kamil ch = '|';
609 1.1 kamil else if (!dx)
610 1.1 kamil ch = '-';
611 1.1 kamil else if (dy == dx)
612 1.1 kamil ch = '/';
613 1.1 kamil else
614 1.1 kamil ch = '\\';
615 1.1 kamil {
616 1.1 kamil for (
617 1.1 kamil y = (obj->posy+dy+YSIZE00)%YSIZE,
618 1.1 kamil x = (obj->posx+dx+XSIZE00)%XSIZE;
619 1.1 kamil size && (!occupant[y][x]);
620 1.1 kamil y = (y+dy+YSIZE00) % YSIZE, x = (x+dx+XSIZE00) % XSIZE, size--) {
621 1.1 kamil move(y+1,x*2,0);
622 1.1 kamil beg_qwrite();
623 1.1 kamil *filler = ch;
624 1.1 kamil qwrite();
625 1.1 kamil qwrite();
626 1.1 kamil if (numamoebas)
627 1.1 kamil qaddch(amb[y][x]);
628 1.1 kamil else
629 1.1 kamil qaddspace();
630 1.1 kamil end_qwrite();
631 1.1 kamil }
632 1.1 kamil tractee = occupant[y][x];
633 1.1 kamil if (size) {
634 1.1 kamil assert(tractee);
635 1.1 kamil if (numamoebas && obj != nuke && amb[y][x] == '~') {
636 1.1 kamil if (to_or_fro > 0)
637 1.1 kamil modify_amoeba(y,x,2,'~',size);
638 1.1 kamil else
639 1.1 kamil modify_amoeba(y,x,1,' ',size);
640 1.1 kamil }
641 1.1 kamil if (tractee->type != Web &&
642 1.1 kamil (tractee->mass < obj->mass * 5 ||
643 1.1 kamil (tractee->type == Crusher && !dx) ) ) {
644 1.1 kamil if (tractee == ent) {
645 1.1 kamil evely -= dy * to_or_fro;
646 1.1 kamil evelx -= dx * to_or_fro;
647 1.1 kamil }
648 1.1 kamil else if (tractee == base) {
649 1.1 kamil bvely -= dy * to_or_fro;
650 1.1 kamil bvelx -= dx * to_or_fro;
651 1.1 kamil }
652 1.1 kamil else {
653 1.1 kamil tractee->vely -= dy * to_or_fro;
654 1.1 kamil tractee->velx -= dx * to_or_fro;
655 1.1 kamil }
656 1.1 kamil if (tractee->type == Torp ||
657 1.1 kamil tractee->type == Star) {
658 1.1 kamil if (tractee->flags & STATIC) { /* not a mover? */
659 1.1 kamil tractee->flags &= ~STATIC;
660 1.1 kamil tractee->prev->next = tractee->next;
661 1.1 kamil tractee->next->prev = tractee->prev;
662 1.1 kamil root.prev->next = tractee;
663 1.1 kamil tractee->prev = root.prev;
664 1.1 kamil root.prev = tractee;
665 1.1 kamil tractee->next = &root;
666 1.1 kamil }
667 1.1 kamil }
668 1.1 kamil }
669 1.1 kamil else if (tractee->type == Crusher && !dy &&
670 1.1 kamil dx==(tractee->image == '<' ? 1 : -1) ) {
671 1.1 kamil setimage(tractee, (tractee->velx *= -1) < 0 ? '>' : '<');
672 1.1 kamil }
673 1.1 kamil if (tractee->mass * 5 > obj->mass)
674 1.1 kamil return(1);
675 1.1 kamil }
676 1.1 kamil }
677 1.1 kamil return(0);
678 1.1 kamil }
679