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