them.c revision 1.1 1 /* $Header: /tank/opengrok/rsync2/NetBSD/src/games/warp/them.c,v 1.1 2020/11/09 23:37:05 kamil Exp $ */
2
3 /* $Log: them.c,v $
4 /* Revision 1.1 2020/11/09 23:37:05 kamil
5 /* Add Warp Kit, Version 7.0 by Larry Wall
6 /*
7 /* Warp is a real-time space war game that doesn't get boring very quickly.
8 /* Read warp.doc and the manual page for more information.
9 /*
10 /* games/warp originally distributed with 4.3BSD-Reno, is back to the BSD
11 /* world via NetBSD. Its remnants were still mentioned in games/Makefile.
12 /*
13 /* Larry Wall, the original author and the copyright holder, generously
14 /* donated the game and copyright to The NetBSD Foundation, Inc.
15 /*
16 /* Import the game sources as-is from 4.3BSD-Reno, with the cession
17 /* of the copyright and license to BSD-2-clause NetBSD-style.
18 /*
19 /* Signed-off-by: Larry Wall <larry (at) wall.org>
20 /* Signed-off-by: Kamil Rytarowski <kamil (at) netbsd.org>
21 /*
22 * Revision 7.0.1.5 86/12/12 17:05:41 lwall
23 * Baseline for net release.
24 *
25 * Revision 7.0.1.4 86/10/20 12:32:38 lwall
26 * Wasn't clearing FRIENDLY flag on pirate creation.
27 *
28 * Revision 7.0.1.3 86/10/20 12:15:33 lwall
29 * Was trying to create pirates from cloaked pirates.
30 *
31 * Revision 7.0.1.2 86/10/17 10:03:44 lwall
32 * Fixed Romulan writing spaces while cloaked.
33 *
34 * Revision 7.0.1.1 86/10/16 10:53:39 lwall
35 * Added Damage. Fixed random bugs.
36 *
37 * Revision 7.0 86/10/08 15:14:15 lwall
38 * Split into separate files. Added amoebas and pirates.
39 *
40 */
41
42 #include "EXTERN.h"
43 #include "warp.h"
44 #include "bang.h"
45 #include "object.h"
46 #include "move.h"
47 #include "score.h"
48 #include "term.h"
49 #include "us.h"
50 #include "util.h"
51 #include "weapon.h"
52 #include "INTERN.h"
53 #include "them.h"
54
55 void
56 them_init()
57 {
58 ;
59 }
60
61 void
62 their_smarts()
63 {
64 Reg1 OBJECT *curkl;
65 Reg2 OBJECT *obj;
66 Reg3 int prob;
67 Reg4 int count;
68 Reg5 int y;
69 Reg6 int x;
70
71 if (numcrushes && (obj=movers)->type == Crusher) {
72 if (numamoebas) {
73 y = obj->posy;
74 x = (obj->posx+(obj->image=='<'?1:-1)+XSIZE00)%XSIZE;
75 if (amb[y][x] == '~') {
76 obj->velx = 0; /* stop and munch amoeba */
77 modify_amoeba(y,x,1,' ',(int)rand_mod(5+ambsize/10)+1);
78 if (occupant[y][x] == nuke) /* except go for nucleus */
79 obj->velx = (obj->image=='<' ? 1 : -1);
80 }
81 else if (!obj->velx) {
82 if (!rand_mod(4))
83 obj->image = rand_mod(2) ? '<' : '>';
84 obj->velx = obj->image == '<' ? 1 : -1;
85 }
86 }
87 obj->vely += (rand_mod(222) - 111) / 100;
88 if (!(rand_mod(100))) {
89 setimage(obj, (obj->velx *= -1) < 0 ? '>' : '<');
90 }
91 }
92 if (numamoebas) {
93 if (!rand_mod(3))
94 nuke->velx = nuke->vely = 0;
95 if (nuke->strategy && ambsize < 90 && !rand_mod(200-smarts))
96 modify_amoeba(0,0,0,'~',(int)rand_mod(10));
97 if (ambsize > 200 || (ambsize > 100 && !rand_mod(15)))
98 modify_amoeba(yamblast,xamblast,2,' ',(ambsize-100)/5);
99 }
100 for (curkl = enemies; curkl->type == Enemy; curkl = curkl->next) {
101 if ((curkl->flags & (CLOAKS|FRIENDLY)) == CLOAKS &&
102 (curkl->image != ' ') &&
103 (curkl->energy > 300 || massacre) ) {
104 setimage(curkl, ' ');
105 }
106 if (madgorns)
107 prob = 3;
108 else if (curkl->vely || curkl->velx)
109 prob = massacre?10:20;
110 else if ((curkl->flags & (PIRATE|FRIENDLY)) == PIRATE) {
111 /* pirates want to sit sometimes */
112 if (curkl->strategy) {
113 if ((obj = lookimg(curkl->posy, curkl->posx, '@')) ||
114 (obj = lookimg(curkl->posy, curkl->posx, 'B')) ) {
115 make_plink(obj->posy, obj->posx);
116 if (!--curkl->strategy) { /* clock ran down */
117 if (obj->image == '@') {
118 obj->image = '*';
119 numinhab--;
120 if (obj->flags & STATIC)
121 mvaddch(obj->posy+1,obj->posx*2,obj->image);
122 if (curkl->energy < 20000)
123 curkl->energy += 5000;
124 }
125 prob = 2; /* our work here is done */
126 }
127 else if (obj->image == 'B') {
128 btorp -= rand_mod(50);
129 if (btorp < 0)
130 btorp = 0;
131 obj->energy -= rand_mod(500);
132 if (obj->energy < 0)
133 obj->energy = 0;
134 prob = 10000; /* stay here */
135 }
136 else
137 prob = 10000;
138 }
139 else { /* it went away--go elsewhere */
140 prob = 4;
141 curkl->strategy = 0;
142 }
143 }
144 else if (lookimg(curkl->posy, curkl->posx, '@') ||
145 lookimg(curkl->posy, curkl->posx, 'B')) {
146 curkl->strategy = rand_mod(15)+5;
147 prob = 10000;
148 }
149 else
150 prob = 4;
151 }
152 else if (curkl->image == 'M') { /* Mudd wants to sit sometimes */
153 if ((obj = lookimg(curkl->posy, curkl->posx, 'E')) ||
154 (obj = lookimg(curkl->posy, curkl->posx, 'B')) ) {
155 if (obj->image == 'B') {
156 btorp -= rand_mod(40);
157 if (btorp < 0)
158 btorp = 0;
159 obj->energy -= rand_mod(100);
160 if (obj->energy < 0)
161 obj->energy = 0;
162 }
163 else if (!obj->vely && !obj->velx) {
164 etorp -= rand_mod(10);
165 if (etorp < 0)
166 etorp = 0;
167 obj->energy -= rand_mod(20);
168 if (obj->energy < 0)
169 obj->energy = 0;
170 }
171 prob = 10000; /* stay here */
172 }
173 else /* it went away--go elsewhere */
174 prob = 4;
175 }
176 else if (curkl->flags & FRIENDLY) {
177 if (curkl->energy < 10000 &&
178 lookimg(curkl->posy, curkl->posx, '@') ) {
179 curkl->energy += 100;
180 prob = 20; /* do some loading */
181 }
182 else
183 prob = 4;
184 }
185 else if (curkl->image == '&') {
186 if (curkl->flags & COUNTDOWN) {
187 if (curkl->strategy)
188 curkl->strategy--;
189 else
190 curkl->flags &= ~COUNTDOWN;
191 prob = 100; /* someone's feeding us, so sit still */
192 }
193 else
194 prob = 4;
195 }
196 else
197 prob = 4; /* don't sit still too long */
198 count = 11;
199 for (;;) {
200 if (--count <= 0) /* no opening, just ram something */
201 break;
202
203 #ifdef lint
204 prob = prob;
205 #endif
206 if (!(rand_mod(prob))) /* turn randomly occasionally */
207 goto accell;
208
209 y=(curkl->posy+curkl->vely+YSIZE00)%YSIZE; /* find prospective */
210 x=(curkl->posx+curkl->velx+XSIZE00)%XSIZE; /* new position */
211
212 if (numamoebas) {
213 if (curkl == nuke) {
214 if (amb[y][x] != '~')
215 goto accell; /* never move nucleus from protoplasm */
216 }
217 else {
218 if (amb[y][x] == '~' && rand_mod(2)) {
219 yamblast = y;
220 xamblast = x;
221 goto accell;
222 }
223 }
224 }
225
226 obj = occupant[y][x];
227 if (!obj) break; /* is anyone there? */
228
229 switch (obj->type) {
230 case Star:
231 if (obj->image == '@' && (curkl->flags & PIRATE)) {
232 if (curkl->image != 'P' && curkl->image != ' ') {
233 if (curkl->flags & FRIENDLY) {
234 curkl->flags &= ~FRIENDLY;
235 curkl->energy += 1000;
236 possiblescore += curkl->mass;
237 inumfriends--;
238 numfriends--;
239 inumenemies++;
240 numenemies++;
241 }
242 curkl->image = 'P';
243 }
244 break; /* go ahead and ram the star */
245 }
246 goto accell; /* try not to ram stars */
247 case Torp:
248 if (!obj->vely && !obj->velx && (rand_mod(100) <= smarts) &&
249 (obj->image == 'o' || obj->image == 'O' || obj->image == 'X'))
250 goto accell; /* try not to ram "friendly" torps */
251 break;
252 case Web:
253 if (curkl->image != 'T')
254 goto accell; /* non-Tholians shouldn't ram web */
255 if (count <= 5)
256 break; /* Tholians retrace web if desperate */
257 if (obj->image ==
258 (curkl->vely?
259 (curkl->velx?
260 (curkl->velx==curkl->vely?
261 '\\'
262 :
263 '/'
264 )
265 :
266 '|'
267 )
268 :
269 '-'
270 )
271 ) goto accell; /* Tholians try not to retrace web */
272 break; /* No problem with crossing web */
273 }
274 break; /* okay to move over object */
275
276 accell:
277 /* determine maximum velocity */
278 if (massacre && curkl->image != 'T') {
279 curkl->vely = rand_mod(7) - 3;
280 curkl->velx = rand_mod(7) - 3;
281 }
282 else if (curkl->image == '&') {
283 if (rand_mod(2)) {
284 curkl->vely = rand_mod(3) - 1;
285 curkl->velx = rand_mod(3) - 1;
286 }
287 else {
288 curkl->vely = curkl->strategy & 3;
289 if (curkl->vely & 2)
290 curkl->vely = -1;
291 curkl->velx = (curkl->strategy >> 2) & 3;
292 if (curkl->velx & 2)
293 curkl->velx = -1;
294 }
295 }
296 else if (curkl->energy >= 2500 && curkl->image != 'T') {
297 curkl->vely = rand_mod(5) - 2;
298 curkl->velx = rand_mod(5) - 2;
299 }
300 else {
301 curkl->vely = rand_mod(3) - 1;
302 curkl->velx = rand_mod(3) - 1;
303 }
304 }
305 if (count != 10) {
306 if (curkl->image == ' ') {
307 setimage(curkl, curkl->flags & PIRATE ? 'P' : 'R');
308 }
309 if (!count) {
310 curkl->vely = 0;
311 curkl->velx = 0;
312 }
313 }
314 if (curkl->image == 'G' && (base||ent) &&
315 !rand_mod((103-smarts)*10) ) {
316 int xxx,yyy;
317
318 for (xxx = -1; xxx<=1; xxx++)
319 for (yyy = -1; yyy<=1; yyy++)
320 if ((xxx||yyy) && rand_mod(2))
321 fire_torp(curkl,yyy,xxx);
322 }
323 else if (curkl->image == 'T' && (curkl->velx || curkl->vely)) {
324 Make_object(Web,
325 curkl->vely?
326 (curkl->velx?
327 (curkl->velx==curkl->vely?
328 '\\'
329 :
330 '/'
331 )
332 :
333 '|'
334 )
335 :
336 '-',
337 curkl->posy,curkl->posx,0,0,32767L,32767L,&root);
338 if (obj && obj->type == Web) {
339 unmake_object(obj);
340 occupant[y][x] = Null(OBJECT*);
341 }
342 }
343 }
344 /* klingon-style fighting */
345 if (numamoebas)
346 attack(nuke);
347 attack(base);
348 if (ent && (!cloaked || ent->image=='E' || ent->image=='e'))
349 attack(ent);
350 }
351
352 void
353 modify_amoeba(y,x,where,ch,quant)
354 Reg1 int y;
355 Reg2 int x;
356 int where;
357 Reg6 int ch;
358 Reg7 int quant;
359 {
360 Reg3 int dy;
361 Reg4 int dx;
362 Reg5 int count = 15;
363
364 if (!numamoebas)
365 return;
366 if (!where || (where==1 && rand_mod(2))) {
367 y = nuke->posy;
368 x = nuke->posx;
369 }
370 if (nuke->strategy && rand_mod(3)) {
371 dy = nuke->strategy & 3;
372 if (dy & 2)
373 dy = -1;
374 dx = (nuke->strategy >> 2) & 3;
375 if (dx & 2)
376 dx = -1;
377 if (ch == ' ') { /* take from the tail */
378 dy = -dy;
379 dx = -dx;
380 }
381 if (!rand_mod(100))
382 nuke->strategy = rand_mod(256);
383 }
384 else {
385 dy = rand_mod(3) - 1;
386 dx = rand_mod(3) - 1;
387 }
388 if (!dy && !dx)
389 return;
390 do {
391 if (--count < 0)
392 return;
393 y = (y + dy + YSIZE00) % YSIZE;
394 x = (x + dx + XSIZE00) % XSIZE;
395 } while (amb[y][x] != ' ');
396 if (ch == ' ') {
397 y = (y - dy + YSIZE00) % YSIZE;
398 x = (x - dx + XSIZE00) % XSIZE;
399 }
400 if (ambsize > 100 && quant > 2) {
401 quant >>= (ambsize/100);
402 }
403 if ((nuke->energy += quant << 6) > 32767)
404 nuke->energy = 32767;
405 count = quant << 3; /* endless loop catcher */
406 while (count-- > 0 && quant > 0) {
407 if (amb[y][x] != ch) {
408 quant--;
409 amb[y][x] = ch;
410 if (ch == '~') {
411 ambsize++;
412 yblasted[y] |= 2;
413 xblasted[x] |= 2;
414 blasted = TRUE;
415 }
416 else
417 ambsize--;
418 if (!occupant[y][x])
419 mvaddch(y+1,x*2,ch);
420 }
421 y = (y + rand_mod(3) + YSIZE99) % YSIZE;
422 x = (x + rand_mod(3) + XSIZE99) % XSIZE;
423 }
424 }
425