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