|
|
1.1 root 1: /* $Header: move.c,v 7.0.1.2 86/10/20 14:37:06 lwall Exp $ */
2:
3: /* $Log: move.c,v $
4: * Revision 7.0.1.2 86/10/20 14:37:06 lwall
5: * Picked some lint.
6: *
7: * Revision 7.0.1.1 86/10/16 10:52:09 lwall
8: * Added Damage. Fixed random bugs.
9: *
10: * Revision 7.0 86/10/08 15:12:40 lwall
11: * Split into separate files. Added amoebas and pirates.
12: *
13: */
14:
15: #include "EXTERN.h"
16: #include "warp.h"
17: #include "bang.h"
18: #include "object.h"
19: #include "move.h"
20: #include "play.h"
21: #include "score.h"
22: #include "term.h"
23: #include "them.h"
24: #include "us.h"
25: #include "util.h"
26: #include "weapon.h"
27: #include "INTERN.h"
28: #include "move.h"
29:
30: void
31: move_init()
32: {
33: ;
34: }
35:
36: void
37: bounce(obj)
38: Reg4 OBJECT *obj;
39: {
40: Reg1 int x;
41: Reg2 int y;
42: Reg3 int count=0;
43:
44: y = (obj->posy - sgn(obj->vely) + YSIZE00) % YSIZE;
45: x = (obj->posx - sgn(obj->velx) + XSIZE00) % XSIZE;
46: while (occupant[y][x]) {
47: y = (y + rand_mod(3) - 1 + YSIZE00) % YSIZE;
48: x = (x + rand_mod(3) - 1 + XSIZE00) % XSIZE;
49: if (++count > 10000) { /* if universe full, get out of it fast */
50: unmake_object(obj);
51: if (ent) unmake_object(ent);
52: if (base) unmake_object(base);
53: finish = 1;
54: return;
55: }
56: }
57: obj->posy = y;
58: obj->posx = x;
59: obj->vely = 0;
60: obj->velx = 0;
61: occupant[y][x] = obj;
62: if (numamoebas && obj->image == ' ')
63: mvaddc(y+1, x*2, amb[y][x]);
64: else
65: mvaddc(y+1, x*2, obj->image);
66: }
67:
68: void
69: move_universe()
70: {
71: Reg1 OBJECT *curobj;
72: Reg2 int x;
73: Reg3 int y;
74: Reg4 OBJECT *temp;
75: OBJECT *thenext;
76:
77: for (curobj = movers; curobj != &root; curobj = curobj->next) {
78: x = curobj->posx;
79: y = curobj->posy;
80: if (curobj == occupant[y][x]) {
81: occupant[y][x] = 0;
82: }
83: else if (curobj->type != Torp && curobj->type != Web) {
84: resetty();
85: abort();
86: }
87: }
88: for (curobj = movers; curobj != &root; curobj = thenext) {
89: thenext = curobj->next;
90: if (curobj->vely || curobj->velx) {
91: y = curobj->posy;
92: x = curobj->posx;
93: if (curobj->image != ' ' &&
94: (!(temp=occupant[y][x]) || temp->image==' ') ) {
95: move(y+1, x*2, numamoebas ? amb[y][x] : ' ');
96: }
97: y = (y + curobj->vely + YSIZE00) % YSIZE;
98: x = (x + curobj->velx + XSIZE00) % XSIZE;
99: if (!(temp=occupant[y][x]) || temp->type != Star ||
100: curobj->type != Torp || curobj->image == '+' ||
101: curobj->image == 'x') {
102: curobj->posy = y;
103: curobj->posx = x;
104: }
105: else {
106: if (curobj->image == '0') {
107: curobj->vely = rand_mod(3)-1;
108: curobj->velx = rand_mod(3)-1;
109: }
110: else
111: curobj->vely = curobj->velx = 0;
112: y = curobj->posy;
113: x = curobj->posx;
114: }
115: }
116: else { /* not moving */
117: y = curobj->posy;
118: x = curobj->posx;
119: if (curobj->type == Torp ||
120: curobj->type == Star ||
121: curobj->type == Web) {
122: curobj->flags |= STATIC;
123: curobj->next->prev = curobj->prev;
124: curobj->prev->next = curobj->next;
125: curobj->prev = movers->prev;
126: curobj->next = movers;
127: movers->prev->next = curobj;
128: movers->prev = curobj;
129: }
130: }
131: if (temp = occupant[y][x]) { /* already occupied? */
132: if (!temp->contend) {
133: if (temp->type == Torp) {
134: if (temp->image == '+')
135: blast[y][x] += 1250;
136: else if (temp->image == 'o' && (base||ent))
137: blast[y][x] += 500+super*20;
138: else if (temp->image == 'O' && (base||ent))
139: blast[y][x] += 5000+super*100;
140: }
141: }
142: yblasted[y] |= 1;
143: xblasted[x] |= 1;
144: blasted = TRUE;
145: curobj->contend = temp;
146: occupant[y][x] = curobj;
147: switch (curobj->type) {
148: case Enemy:
149: if (numamoebas && curobj == nuke && temp->image == '+')
150: blast[y][x] += 80000;
151: else if (temp->type == Enemy)
152: blast[y][x] += 10;
153: else
154: goto defblast;
155: break;
156: case Crusher:
157: if (curobj->velx)
158: blast[y][x] += 100000;
159: else
160: goto defblast;
161: break;
162: case Torp:
163: if (curobj->image == '+')
164: blast[y][x] += (temp==nuke ? 80000 : 1250);
165: else if (curobj->image == 'o')
166: blast[y][x] += 500+super*20;
167: else if (curobj->image == 'O')
168: blast[y][x] += 5000+super*100;
169: goto defblast;
170: case Star:
171: if (temp == ent)
172: goto damshield;
173: goto defblast;
174: case Enterprise:
175: if (temp->type == Star) {
176: damshield:
177: if (!rand_mod(10)) {
178: if (!damflag[NOSHIELDS])
179: damage++;
180: if (damflag[NOSHIELDS] < 100)
181: damflag[NOSHIELDS] += rand_mod(smarts)/5+2;
182: }
183: }
184: goto defblast;
185: default:
186: defblast:
187: blast[y][x] += rand_mod(751)+1;
188: break;
189: }
190: }
191: else {
192: occupant[y][x] = curobj;
193: if (curobj->image != ' ' &&
194: (curobj->velx || curobj->vely ||
195: curobj->type == Torp || curobj->type == Web) ) {
196: mvaddc(y+1, x*2, curobj->image);
197: }
198: if (curobj->type == Crusher && curobj->velx) {
199: blast[y][x] += 100000;
200: yblasted[y] |= 1;
201: xblasted[x] |= 1;
202: blasted = TRUE;
203: }
204: }
205: }
206: if (blasted) {
207: Reg7 int minxblast = -1;
208: Reg8 int maxxblast = -2;
209: Reg5 long tmpblast;
210:
211: blasted = numamoebas;
212: for (x=0; x<XSIZE; x++) {
213: if (xblasted[x]) {
214: xblasted[x] = 0;
215: maxxblast = x;
216: if (minxblast < 0)
217: minxblast = x;
218: }
219: }
220: for (y=0; y<YSIZE; y++) {
221: if (yblasted[y]) {
222: yblasted[y] = 0;
223: for (x=minxblast; x<=maxxblast; x++) {
224: tmpblast = blast[y][x];
225: if (numamoebas && amb[y][x] == '~') {
226: if (temp = occupant[y][x]) {
227: if (temp->image == '&')
228: tmpblast >>= 1;
229: else if (temp->type == Web)
230: tmpblast = 100000;
231: else
232: tmpblast += 50 + temp->energy/100;
233: if (tmpblast > 250 && !rand_mod(5+(inumstars>>4)))
234: modify_amoeba(y,x,1,'~',5);
235: }
236: xblasted[x] = 2;
237: yblasted[y] = 2;
238: }
239: if (tmpblast) {
240: Reg6 OBJECT *biggie = 0;
241:
242: blast[y][x] = 0;
243: temp = occupant[y][x];
244: if (tmpblast < 0) {
245: if (numamoebas && tmpblast < -1000000 &&
246: amb[y][x] == '~' && temp != nuke) {
247: amb[y][x] = ' ';
248: if (!temp)
249: make_plink(y,x);
250: ambsize--;
251: }
252: tmpblast = 0;
253: }
254: if (temp) {
255: if ((!numamoebas || amb[y][x]==' ') &&
256: tmpblast < 100000)
257: make_plink(y,x);
258: for ( ;temp;
259: temp = curobj->contend,curobj->contend = 0){
260: curobj = temp;
261: switch (curobj->type) {
262: case Enterprise: {
263: long tmp = curobj->energy;
264:
265: if (ent->energy>500 || apolloflag & 1)
266: curobj->energy -= tmpblast /
267: ((apolloflag & 1)
268: ? 20
269: : (5+abs(ent->velx)+abs(ent->vely))
270: / ((damflag[NOSHIELDS]>>3)+1)+1);
271: else
272: curobj->energy -= tmpblast;
273: if (rand_mod(1 + tmp - curobj->energy) > 100
274: || ent->energy < (entmax>>1)) {
275: if (debug & 128 ||
276: (damage <= smarts/10 &&
277: !rand_mod(6-smarts/20-massacre) )) {
278: tmp = rand_mod(MAXDAMAGE);
279: if (damflag[tmp]) {
280: if (damflag[tmp] < 60)
281: damflag[tmp] += rand_mod(60);
282: }
283: else {
284: damflag[tmp] =
285: rand_mod(smarts+10)+2;
286: damage++;
287: }
288: }
289: }
290: break;
291: }
292: case Base:
293: if (base->energy > 1000 || apolloflag & 2)
294: curobj->energy -= tmpblast /
295: ((apolloflag & 2)?20:5);
296: else
297: curobj->energy -= tmpblast;
298: break;
299: case Crusher:
300: if (tmpblast > 132767)
301: curobj->energy -= (tmpblast - 100000);
302: else if (tmpblast >= 100000) {
303: curobj->energy += (tmpblast - 100000);
304: if (curobj->energy > 32767)
305: curobj->energy = 32767;
306: }
307: else /* vulnerable while feeding */
308: curobj->energy -= tmpblast;
309: break;
310: case Enemy:
311: curobj->energy -= tmpblast*10/enemshields;
312: break;
313: default:
314: curobj->energy -= tmpblast;
315: break;
316: }
317: if (curobj->energy < 0) { /* killed it? */
318: switch (curobj->image) {
319: case 'A':
320: tmpblast = 100000;
321: make_blast(y,x,8192L,1);
322: numapollos = apolloflag = 0;
323: numstars--;
324: numenemies--;
325: curscore += 5000;
326: deados = 0;
327: break;
328: case 'E': case 'e': case 'C': case 'c':
329: ent = 0;
330: numents--;
331: if (base)
332: status = 2;
333: else
334: status = 3;
335: deados = 0;
336: break;
337: case 'B': case 'b':
338: base = 0;
339: numbases--;
340: if (ent)
341: status = entmode;
342: else
343: status = 3;
344: deados = 0;
345: break;
346: case '&': {
347: int i, xxx, yyy;
348:
349: for (i = 0; i < YSIZE; i++)
350: yblasted[i] &= 1;
351: for (i = 0; i < XSIZE; i++)
352: xblasted[i] &= 1;
353: numamoebas = 0; /* ignore amb[][] now */
354: for (yyy = 0; yyy < YSIZE; yyy++) {
355: for (xxx = 0; xxx < XSIZE; xxx++) {
356: if (amb[yyy][xxx] == '~' &&
357: !occupant[yyy][xxx]) {
358: mvaddch(yyy+1,xxx*2,' ');
359: }
360: }
361: }
362: numenemies--;
363: curscore += 10000;
364: if (curobj == enemies)
365: enemies = curobj->next;
366: deados = 0;
367: break;
368: }
369: case '<': case '>': {
370: int i;
371:
372: numenemies--;
373: numcrushes = 0;
374: curscore += 10000;
375: if (curobj == movers)
376: movers = curobj->next;
377: if (curobj == enemies)
378: enemies = curobj->next;
379: deados = 0;
380:
381: tmpblast = 100000;
382: make_blast(y,(x+XSIZE00)%XSIZE,10000L,0);
383: if (curobj->image == '<') {
384: for (i=XSIZE00; i<=XSIZE01; i++)
385: make_blast(y,(x+i)%XSIZE,
386: 10000L,0);
387: for (i=XSIZE00; i<=XSIZE02; i++)
388: make_blast(y,(x+i)%XSIZE,
389: 10000L,0);
390: make_blast(y,(x+XSIZE03)%XSIZE,
391: 10000L,1);
392: for (i=XSIZE00; i<=XSIZE08; i++)
393: make_blast(y,(x+i)%XSIZE,
394: 10000L,0);
395: }
396: else {
397: for (i=XSIZE00; i>=XSIZE99; i--)
398: make_blast(y,(x+i)%XSIZE,
399: 10000L,0);
400: for (i=XSIZE00; i>=XSIZE98; i--)
401: make_blast(y,(x+i)%XSIZE,
402: 10000L,0);
403: make_blast(y,(x+XSIZE97)%XSIZE,
404: 10000L,1);
405: for (i=XSIZE00; i>=XSIZE92; i--)
406: make_blast(y,(x+i)%XSIZE,
407: 10000L,0);
408: }
409: }
410: break;
411: case 'K':
412: numenemies--;
413: curscore += curobj->mass;
414: if (curobj == enemies)
415: enemies = curobj->next;
416: deados = 0;
417: break;
418: case 'T':
419: numenemies--;
420: curscore += curobj->mass*3/2;
421: if (curobj == enemies)
422: enemies = curobj->next;
423: deados = 0;
424: break;
425: case 'R': case ' ': case 'P':
426: numenemies--;
427: if (curobj->flags & PIRATE)
428: curscore += curobj->mass;
429: else
430: curscore += curobj->mass*3;
431: if (curobj == enemies)
432: enemies = curobj->next;
433: deados = 0;
434: break;
435: case 'G':
436: numenemies--;
437: numgorns--;
438: tmpblast = 100000;
439: if (madgorns)
440: curscore += curobj->mass/2;
441: else
442: curscore += curobj->mass*2;
443: if (curobj == enemies)
444: enemies = curobj->next;
445: {
446: int xxx,yyy;
447:
448: for (xxx = -1; xxx<=1; xxx++)
449: for (yyy = -1; yyy<=1; yyy++)
450: if (rand_mod(2+massacre))
451: fire_torp(curobj,
452: yyy,xxx);
453: }
454: deados = 0;
455: break;
456: case '@':
457: numinhab--;
458: /* FALL THROUGH */
459: case '*':
460: banging = TRUE;
461: numstars--;
462: break;
463: case '|': case '-': case '/': case '\\':
464: tmpblast = 100000;
465: make_blast(y,x,curobj->mass,1);
466: banging = TRUE;
467: deados = 0;
468: break;
469: case 'x':
470: curscore += 10;
471: deados = 0;
472: break;
473: case 'X':
474: curscore += 100;
475: numxes--;
476: deados = 0;
477: break;
478: case '0':
479: curscore += 35;
480: numos--;
481: deados += 3;
482: break;
483: case 'o':
484: curscore += 100;
485: numos--;
486: deados++;
487: break;
488: case 'O':
489: curscore += 200;
490: numos--;
491: deados += 2;
492: break;
493: case 'M':
494: deadmudds++;
495: inumfriends--;
496: numfriends--;
497: if (curobj == enemies)
498: enemies = curobj->next;
499: break;
500: case 'Q': case 'W': case 'Y': case 'U':
501: case 'I': case 'S': case 'D': case 'H':
502: case 'J': case 'L': case 'Z': case 'V':
503: case 'F':
504: numfriends--;
505: if (curobj == enemies)
506: enemies = curobj->next;
507: if (inumfriends < 10)
508: madfriends += 500;
509: else
510: madfriends += 10000/inumfriends;
511: break;
512: }
513: if (tmpblast < 100000)
514: make_blast(y,x,curobj->mass,1);
515: unmake_object(curobj);
516: }
517: else { /* didn't kill anything */
518: if (!biggie)
519: biggie = curobj;
520: else {
521: if (biggie->mass > curobj->mass)
522: bounce(curobj);
523: else {
524: bounce(biggie);
525: biggie = curobj;
526: }
527: }
528: }
529: }
530: if (biggie) {
531: occupant[y][x] = biggie;
532: if (numamoebas && biggie->image == ' ')
533: mvaddch(y+1,x*2, amb[y][x]);
534: else
535: mvaddch(y+1,x*2, biggie->image);
536: }
537: else {
538: occupant[y][x] = 0;
539: mvaddch(y+1, x*2, numamoebas ? amb[y][x] : ' ');
540: }
541: }
542: }
543: }
544: }
545: }
546: }
547: do_bangs();
548: if (numcrushes && movers->type == Crusher)
549: movers->vely = 0;
550: if (curobj = base) {
551: char ch;
552:
553: curobj->velx = 0;
554: curobj->vely = 0;
555: curobj->energy += 25*lookaround(curobj->posy,curobj->posx,Star);
556: if (curobj->energy > basemax)
557: curobj->energy = basemax;
558: if (curobj->energy >= 1000)
559: ch = 'B';
560: else
561: ch = 'b';
562: if (ch != curobj->image) {
563: setimage(curobj, ch);
564: }
565: }
566: if (curobj = ent) {
567: char ch;
568:
569: if (entmode == 0) {
570: curobj->velx = 0;
571: curobj->vely = 0;
572: }
573: if (base && !cloaking && !curobj->velx && !curobj->vely &&
574: lookfor(curobj->posy,curobj->posx,Base)) {
575: int tmp;
576:
577: #ifdef lint
578: tmp = 0;
579: #else
580: tmp = (int) (base->energy - 1000 < entmax - curobj->energy ?
581: base->energy - 1000 : entmax - curobj->energy);
582: #endif
583: if (tmp < 0)
584: tmp = 0;
585: curobj->energy += tmp;
586: base->energy -= tmp;
587: tmp = (btorp < 50 - etorp ?
588: btorp : 50 - etorp);
589: etorp += tmp;
590: btorp -= tmp;
591: if (damage) {
592: tmp = rand_mod(MAXDAMAGE);
593: if (damflag[tmp] > 5) {
594: damflag[tmp] = rand_mod(5)+1;
595: }
596: }
597: }
598: if (curobj->energy >= 500 && (!damage || !damflag[NOSHIELDS]))
599: ch = cloaked?'C':'E';
600: else
601: ch = cloaked?'c':'e';
602: if (ch != curobj->image) {
603: setimage(curobj, ch);
604: }
605: }
606: }
607:
608: int
609: lookaround(y, x, what)
610: Reg1 int y;
611: Reg2 int x;
612: Reg4 char what;
613: {
614: Reg3 OBJECT *obj;
615: Reg5 int count=0;
616: Reg6 int xp;
617: Reg7 int xm;
618:
619: if ((obj=occupant[y][xp=(x+XSIZE01)%XSIZE])&&obj->type == what) /* 0, 1 */
620: count++;
621: if ((obj=occupant[y][xm=(x+XSIZE99)%XSIZE])&&obj->type == what) /* 0, -1 */
622: count++;
623: if ((obj=occupant[y=(y+YSIZE99)%YSIZE][xp])&&obj->type == what) /* -1, 1 */
624: count++;
625: if ((obj=occupant[y][x])&&obj->type == what) /* -1, 0 */
626: count++;
627: if ((obj=occupant[y][xm])&&obj->type == what) /* -1, -1 */
628: count++;
629: if ((obj=occupant[y=(y+2)%YSIZE][xp])&&obj->type == what) /* 1, 1 */
630: count++;
631: if ((obj=occupant[y][x])&&obj->type == what) /* 1, 0 */
632: count++;
633: if ((obj=occupant[y][xm])&&obj->type == what) /* 1, -1 */
634: count++;
635: return (count);
636: }
637:
638: int
639: lookfor(y, x, what)
640: Reg1 int y;
641: Reg2 int x;
642: Reg4 char what;
643: {
644: Reg3 OBJECT *obj;
645: Reg5 int xp;
646: Reg6 int xm;
647:
648: if ((obj=occupant[y][xp=(x+XSIZE01)%XSIZE])&&obj->type == what ||/* 0, 1 */
649: (obj=occupant[y][xm=(x+XSIZE99)%XSIZE])&&obj->type == what ||/* 0, -1 */
650: (obj=occupant[y=(y+YSIZE99)%YSIZE][xp])&&obj->type == what ||/* -1, 1 */
651: (obj=occupant[y][x])&&obj->type == what ||/* -1, 0 */
652: (obj=occupant[y][xm])&&obj->type == what ||/* -1,-1 */
653: (obj=occupant[y=(y+2)%YSIZE][xp])&&obj->type == what ||/* 1, 1 */
654: (obj=occupant[y][x])&&obj->type == what ||/* 1, 0 */
655: (obj=occupant[y][xm])&&obj->type == what) /* 1, -1 */
656: return(1);
657: return (0);
658: }
659:
660: OBJECT*
661: lookimg(y, x, what)
662: Reg1 int y;
663: Reg2 int x;
664: Reg4 char what;
665: {
666: Reg3 OBJECT *obj;
667: Reg5 int xp;
668: Reg6 int xm;
669:
670: if ((obj=occupant[y][xp=(x+XSIZE01)%XSIZE])&&obj->image==what ||/* 0, 1 */
671: (obj=occupant[y][xm=(x+XSIZE99)%XSIZE])&&obj->image==what ||/* 0, -1 */
672: (obj=occupant[y=(y+YSIZE99)%YSIZE][xp])&&obj->image==what ||/* -1, 1 */
673: (obj=occupant[y][x])&&obj->image==what ||/* -1, 0 */
674: (obj=occupant[y][xm])&&obj->image==what ||/* -1,-1 */
675: (obj=occupant[y=(y+2)%YSIZE][xp])&&obj->image==what ||/* 1, 1 */
676: (obj=occupant[y][x])&&obj->image==what ||/* 1, 0 */
677: (obj=occupant[y][xm])&&obj->image==what) /* 1, -1 */
678: return obj;
679: return Null(OBJECT*);
680: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.