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