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() 39: { 40: ; 41: } 42: 43: void 44: their_smarts() 45: { 46: Reg1 OBJECT *curkl; 47: Reg2 OBJECT *obj; 48: Reg3 int prob; 49: Reg4 int count; 50: Reg5 int y; 51: Reg6 int x; 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(OBJECT*); 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(y,x,where,ch,quant) 336: Reg1 int y; 337: Reg2 int x; 338: int where; 339: Reg6 int ch; 340: Reg7 int quant; 341: { 342: Reg3 int dy; 343: Reg4 int dx; 344: Reg5 int count = 15; 345: 346: if (!numamoebas) 347: return; 348: if (!where || (where==1 && rand_mod(2))) { 349: y = nuke->posy; 350: x = nuke->posx; 351: } 352: if (nuke->strategy && rand_mod(3)) { 353: dy = nuke->strategy & 3; 354: if (dy & 2) 355: dy = -1; 356: dx = (nuke->strategy >> 2) & 3; 357: if (dx & 2) 358: dx = -1; 359: if (ch == ' ') { /* take from the tail */ 360: dy = -dy; 361: dx = -dx; 362: } 363: if (!rand_mod(100)) 364: nuke->strategy = rand_mod(256); 365: } 366: else { 367: dy = rand_mod(3) - 1; 368: dx = rand_mod(3) - 1; 369: } 370: if (!dy && !dx) 371: return; 372: do { 373: if (--count < 0) 374: return; 375: y = (y + dy + YSIZE00) % YSIZE; 376: x = (x + dx + XSIZE00) % XSIZE; 377: } while (amb[y][x] != ' '); 378: if (ch == ' ') { 379: y = (y - dy + YSIZE00) % YSIZE; 380: x = (x - dx + XSIZE00) % XSIZE; 381: } 382: if (ambsize > 100 && quant > 2) { 383: quant >>= (ambsize/100); 384: } 385: if ((nuke->energy += quant << 6) > 32767) 386: nuke->energy = 32767; 387: count = quant << 3; /* endless loop catcher */ 388: while (count-- > 0 && quant > 0) { 389: if (amb[y][x] != ch) { 390: quant--; 391: amb[y][x] = ch; 392: if (ch == '~') { 393: ambsize++; 394: yblasted[y] |= 2; 395: xblasted[x] |= 2; 396: blasted = TRUE; 397: } 398: else 399: ambsize--; 400: if (!occupant[y][x]) 401: mvaddch(y+1,x*2,ch); 402: } 403: y = (y + rand_mod(3) + YSIZE99) % YSIZE; 404: x = (x + rand_mod(3) + XSIZE99) % XSIZE; 405: } 406: }