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