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