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: }