1: /* $Header: init.c,v 7.0.1.4 86/12/12 16:58:03 lwall Exp $ */ 2: 3: /* $Log: init.c,v $ 4: * Revision 7.0.1.4 86/12/12 16:58:03 lwall 5: * Baseline for net release. 6: * 7: * Revision 7.0.1.3 86/10/20 14:35:31 lwall 8: * Picked some lint. 9: * 10: * Revision 7.0.1.2 86/10/17 15:53:30 lwall 11: * Added random walk star fields. 12: * 13: * Revision 7.0.1.1 86/10/16 10:51:19 lwall 14: * Added Damage. Fixed random bugs. 15: * 16: * Revision 7.0 86/10/08 15:12:10 lwall 17: * Split into separate files. Added amoebas and pirates. 18: * 19: */ 20: 21: #include "EXTERN.h" 22: #include "warp.h" 23: #include "bang.h" 24: #include "object.h" 25: #include "move.h" 26: #include "play.h" 27: #include "score.h" 28: #include "term.h" 29: #include "them.h" 30: #include "us.h" 31: #include "util.h" 32: #include "weapon.h" 33: #include "INTERN.h" 34: #include "init.h" 35: 36: void 37: initialize() 38: { 39: Reg1 int i; 40: Reg2 int x; 41: Reg3 int y; 42: Reg4 int dist; 43: Reg5 int ydist; 44: Reg6 int xdist; 45: long e; 46: int yoff, xoff, ypred, xpred; 47: Reg7 OBJECT *obj; 48: char ch; 49: FILE *mapfp = NULL; 50: bool tmptholspec; 51: int inhabjackpot; 52: long inhenergy; 53: int walksplit = 200; 54: static char *distname[] = 55: {" #"," -"," \\"," /", 56: " |"," *"," `"," '"}; 57: 58: cloaking = madgorns = FALSE; 59: deados = madfriends = 0; 60: curscore = possiblescore = 0L; 61: yamblast = xamblast = ambsize = 0; 62: if (smarts > 90) 63: massacre = TRUE; 64: scandist = (massacre?20:15); 65: antibase = (smarts>60?1:(smarts>40?2:(smarts>25?4:100))); 66: sm35 = (smarts>35?35:smarts); 67: sm45 = (smarts>45?45:smarts); 68: sm50 = (smarts>50?50:smarts); 69: sm55 = (smarts>55?55:smarts); 70: sm80 = (smarts>80?80:smarts); 71: sm95 = (smarts>95?95:smarts); 72: super = (smarts>50?smarts-50:0); 73: enemshields = 10 + super/2; /* (scaled by 10) 1 @ 50 .. 3 @ 90 */ 74: if (smarts>90) 75: enemshields += (smarts-90)*10; /* lay it on thick: ~13 @ 99 */ 76: entmax = (smarts>=75?5000:(smarts>=50?4000:(smarts>=40?3000:2000))); 77: basemax = (smarts>=75?20000:(smarts>=50?15000:(smarts>=40?12500:10000))); 78: 79: clear(); 80: while (root.next != &root) { 81: root.next = root.next->next; 82: free_object(root.next->prev); 83: } 84: root.prev = &root; 85: enemies = movers = NULL; 86: numos = numxes = 0; 87: #if defined(vax) && XYSIZEx4 == 3680 88: asm("movc5 $0,_occupant,$0,$3680,_occupant"); 89: asm("movc5 $0,_blast,$0,$3680,_blast"); /* 3680 = XYSIZEx4 */ 90: asm("movc5 $0,_amb,$32,$920,_amb"); 91: #else 92: for (y=0;y<YSIZE;y++) 93: for (x=0;x<XSIZE;x++) { 94: occupant[y][x] = 0; 95: blast[y][x] = 0; 96: amb[y][x] = ' '; 97: } 98: #endif 99: for (y=0; y<YSIZE; y++) 100: yblasted[y] = 0; 101: for (x=0; x<XSIZE; x++) 102: xblasted[x] = 0; 103: blasted = FALSE; 104: if (!starspec) 105: if (smarts < 15) 106: inumstars = 50 + rand_mod(50); 107: else if (smarts < 50 || smarts > 85) 108: inumstars = exdis(800) + rand_mod(100) + 1; 109: else /* too few stars makes 50..85 too hard */ 110: inumstars = exdis(700) + rand_mod(150-super*2) + 50+super*2; 111: tmptholspec = (smarts > 15 && inumstars < 450 && ! rand_mod(90-sm80)); 112: if (!klingspec) { 113: inumenemies = rand_mod((smarts+1)/2) + 1; 114: if (massacre || tmptholspec) 115: inumenemies += 10; 116: } 117: if (!friendspec) 118: inumfriends = rand_mod(smarts/8+1); 119: if (!piratespec) 120: inumpirates = rand_mod(inumfriends/2+1); 121: if (inumfriends+inumenemies+inumstars > YSIZE*XSIZE-20) 122: inumstars = YSIZE*XSIZE-20 - inumenemies - inumfriends; 123: if (inumstars < 0) { 124: inumfriends += inumstars; 125: inumstars = 0; 126: } 127: if (inumfriends < 0) { 128: inumenemies += inumfriends; 129: inumfriends = 0; 130: } 131: if (inumenemies < 0) 132: inumenemies = 0; 133: numstars = inumstars; 134: inuminhab = numinhab = 0; 135: inumroms = inumthols = inumgorns = 0; 136: numapollos = apolspec || massacre ? 1 : 137: ((!numstars || rand_mod(2) || smarts < 10) ? 0 : 1); 138: inumapollos = apolloflag = 0; 139: realapollo = NULL; 140: inumcrushes = numcrushes = 141: crushspec||massacre?1:(rand_mod(2000) < inumstars); 142: inumenemies += inumcrushes; 143: inumamoebas = numamoebas = (amoebaspec ? 1 : 144: !rand_mod(inumcrushes?3-massacre:8) ); /* < and & are fun together */ 145: inumenemies += inumamoebas; 146: if (!rand_mod(40)) { 147: inhabjackpot = 32767; 148: inumfriends += rand_mod(10); 149: inumpirates += rand_mod(10); 150: } 151: else 152: inhabjackpot = inumpirates; 153: inhenergy = 30000-super*150; 154: if (!rand_mod(10)) 155: inhenergy = 50000; 156: if (!rand_mod(4)) 157: inhenergy += rand_mod(3500+super*150); 158: numfriends = inumfriends; 159: numpirates = inumpirates; 160: numenemies = inumenemies; 161: deadmudds = 0; 162: 163: /* do stars */ 164: 165: stars_again: 166: if (prespec) 167: dist = 4; 168: else if (numstars > 750) 169: dist = 0; 170: else 171: dist = rand_mod(starspec||smarts<=5?3:5); 172: if (debugging) { 173: real_y = real_x = -100; 174: printf("\r\n"); 175: } 176: switch (dist) { 177: case 0: /* uniform random */ 178: ydist = xdist = 0; 179: if (inumstars < 700 && !rand_mod(3-(inumstars<50))) { 180: ydist = xdist = 6; /* well, maybe not so random */ 181: y = rand_mod(YSIZE); 182: x = rand_mod(XSIZE); 183: if (rand_mod(2)) 184: walksplit = inumstars/(exdis(40)+1); 185: } 186: if (debugging) 187: printf(" R\r\n"); 188: break; 189: case 1: case 2: /* clumped, maybe skewed, maybe superposed */ 190: ydist = rand_mod(4); 191: xdist = rand_mod(2); 192: if (debugging) 193: printf("%s\r\n",distname[ydist+4*xdist]); 194: yoff = rand_mod(YSIZE); 195: xoff = rand_mod(XSIZE); 196: if (dist == 2) 197: dist = numstars/2 + exdis(numstars/2) - exdis(numstars/2); 198: else 199: dist = 0; 200: break; 201: case 3: case 4: /* predefined or residual */ 202: scenario_again: 203: if (debugging) 204: printf(" P\r\n"); 205: dist = 0; 206: Sprintf(spbuf,"smap.%d", 207: (prescene>=0?prescene:rand_mod(MAPS)) ); 208: if ((mapfp = fopen(spbuf,"r")) != NULL && 209: fgets(spbuf,10,mapfp) != NULL ) { 210: inumstars = numstars = atoi(spbuf); 211: if (inumenemies+inumstars > YSIZE*XSIZE-20) 212: inumstars = numstars = YSIZE*XSIZE-20 - inumenemies; 213: ydist = rand_mod(2) + 4; /* flip y axis? */ 214: xdist = rand_mod(2) + 4; /* flip x axis? */ 215: yoff = rand_mod(YSIZE); /* how much to shift y */ 216: xoff = rand_mod(XSIZE); /* how much to shift x */ 217: } 218: else { 219: prespec = FALSE; 220: prescene = -1; 221: if (rand_mod(2)) 222: goto scenario_again; 223: goto stars_again; 224: } 225: break; 226: } 227: for (i = 1; i <= numstars; i++) { 228: if (dist && i == dist) { /* flip to another skewing? */ 229: ydist = rand_mod(4); 230: xdist = rand_mod(2); 231: if (!rand_mod(4)) { 232: ydist = xdist = 6; 233: if (debugging) 234: printf("&\r\n"); 235: } 236: else if (debugging) 237: printf("%s\r\n",distname[ydist+4*xdist]); 238: yoff = rand_mod(YSIZE); 239: xoff = rand_mod(XSIZE); 240: dist = 0; 241: } 242: do { /* until an open spot found */ 243: switch (xdist) { 244: case 0: 245: x = rand_mod(XSIZE); /* pick from 0..39, uniform */ 246: break; 247: case 1: case 2: case 3: 248: #ifndef lint 249: x = (int)((((double)(myrand()-HALFRAND)) * 250: ((double)(myrand()-HALFRAND))/RANDRAND) 251: * 20.0) + xoff; /* pick from -20..20, clumped */ 252: #endif 253: break; 254: case 4: 255: if (fscanf(mapfp,"%d %d\n",&ypred,&xpred) == EOF) 256: ydist = xdist = 0; 257: x = xpred + xoff; 258: break; 259: case 5: 260: if (fscanf(mapfp,"%d %d\n",&ypred,&xpred) == EOF) 261: ydist = xdist = 0; 262: x = -xpred + xoff; 263: break; 264: case 6: 265: x += rand_mod(3) - 1; 266: break; 267: } 268: switch (ydist) { 269: case 0: 270: y = rand_mod(YSIZE); 271: break; 272: case 1: 273: #ifndef lint 274: y = (int)((((double)(myrand()-HALFRAND)) * 275: ((double)(myrand()-HALFRAND))/RANDRAND) 276: * 12.0) + yoff; /* pick from -12..12, clumped */ 277: #endif 278: break; 279: case 2: 280: #ifndef lint 281: y = (int)((((double)(myrand()-HALFRAND)) * 282: ((double)(myrand()-HALFRAND))/RANDRAND) 283: * 12.0) + yoff + x*YSIZE/XSIZE; 284: /* clumped & skewed */ 285: #endif 286: break; 287: case 3: 288: #ifndef lint 289: y = (int)((((double)(myrand()-HALFRAND)) * 290: ((double)(myrand()-HALFRAND))/RANDRAND) 291: * 12.0) + yoff - x*YSIZE/XSIZE; 292: /* clumped & skewed */ 293: #endif 294: break; 295: case 4: 296: y = ypred + yoff; 297: break; 298: case 5: 299: y = -ypred + yoff; 300: break; 301: case 6: 302: y += rand_mod(3) - 1; 303: #ifdef lint 304: walksplit = walksplit; 305: #endif 306: if (!rand_mod(walksplit)) { 307: y = rand_mod(YSIZE); 308: x = rand_mod(XSIZE); 309: } 310: break; 311: } 312: while (x<0) x += XSIZE00; 313: while (y<0) y += YSIZE00; 314: x %= XSIZE; 315: y %= YSIZE; 316: } while (occupant[y][x]); 317: e = rand_mod(32768); 318: if (--inhabjackpot > 0 || e >= inhenergy) { 319: ch = '@'; 320: if (inhabjackpot && e < 10000) 321: e += 10000; 322: inuminhab = ++numinhab; 323: } 324: else { 325: ch = '*'; 326: } 327: obj = make_object(Star,ch,y,x,0,0,e+rand_mod(super*100+1),e/4,&root); 328: obj->flags |= STATIC; 329: } 330: if (inumstars > 30 && inhabjackpot <= 0 && 331: !rand_mod(3 - (inumstars > 400) - (inhenergy > 32768)) ) { 332: int initx; 333: int inity; 334: 335: x = initx = obj->posx; 336: y = inity = obj->posy; 337: while (rand_mod(2) && inuminhab < inumstars/2) { 338: for (i=rand_mod(smarts)*2+20; i; i--) { 339: if ((obj = occupant[y][x]) && obj->image == '*') { 340: setimage(obj,'@'); 341: if (obj->energy < 10000) 342: obj->energy += 20000; /* the benefits of civilization */ 343: inuminhab = ++numinhab; 344: } 345: if (i&15) { 346: y = (y + rand_mod(3) + YSIZE99) % YSIZE; 347: x = (x + rand_mod(3) + XSIZE99) % XSIZE; 348: } 349: else { /* don't wander too far */ 350: y = inity; 351: x = initx; 352: } 353: } 354: x = initx = rand_mod(XSIZE); 355: y = inity = rand_mod(YSIZE); 356: } 357: } 358: if (mapfp != NULL) 359: Fclose(mapfp); 360: if (numcrushes) { 361: do { 362: x = rand_mod(XSIZE); 363: y = rand_mod(YSIZE); 364: } while (occupant[y][x]); 365: movers = make_object(Crusher,'<',y,x,0,1,32767L,32768L,&root); 366: possiblescore += 10000; 367: } 368: ient = (numents != 0); 369: if (ient) { 370: do { 371: x = rand_mod(XSIZE); 372: y = rand_mod(YSIZE); 373: } while (occupant[y][x]); 374: e = entmax; 375: ent = make_object(Enterprise,'E',y,x,0,0,e,e/2,&root); 376: if (!movers) 377: movers = ent; 378: } 379: ibase = (numbases != 0); 380: if (ibase) { 381: e = 52-super; 382: do { 383: x = rand_mod(XSIZE); 384: y = rand_mod(YSIZE); 385: } while (occupant[y][x] || lookaround(y,x,Star) * 7 < e--); 386: e = basemax; 387: base = make_object(Base, 'B',y,x,0,0,e,e/4,&root); 388: if (!movers) 389: movers = base; 390: } 391: if (numamoebas) { 392: do { 393: x = rand_mod(XSIZE); 394: y = rand_mod(YSIZE); 395: } while (occupant[y][x]); 396: nuke = make_object(Enemy,'&',y,x,0,0,32767L, 397: (long)entmax+entmax+rand_mod(entmax),&root); 398: possiblescore += 10000; 399: amb[y][x] = '~'; 400: if (rand_mod(2)) 401: modify_amoeba(y,x,2,'~',(int)rand_mod(smarts<<1));/* just make blob */ 402: else { 403: for (i=smarts/10+1; i; i--) { 404: nuke->strategy = rand_mod(256); /* random direction */ 405: modify_amoeba(y,x,2,'~',(int)rand_mod(5)); 406: modify_amoeba(y,x,2,'~',(int)rand_mod(5)); 407: modify_amoeba(y,x,2,'~',(int)rand_mod(5)); 408: modify_amoeba(y,x,2,'~',(int)rand_mod(5)); /* extend pseudopod */ 409: } 410: } 411: if (!enemies) 412: enemies = nuke; 413: if (!movers) 414: movers = nuke; 415: } 416: if (rand_mod(27-sm50/2) && !romspec && !gornspec) 417: dist = 27-sm50/2; 418: else 419: dist = rand_mod(4) + 1; 420: for (i = 1+inumcrushes+inumamoebas; i <= numenemies; i++) { 421: do { 422: x = rand_mod(XSIZE); 423: y = rand_mod(YSIZE); 424: } while (occupant[y][x]); 425: if (rand_mod(dist)) { 426: if (!tholspec && !tmptholspec && rand_mod((inumstars*3)/sm50+2)) 427: ch = 'K'; 428: else { 429: ch = 'T'; 430: inumthols++; 431: } 432: } 433: else { 434: if (romspec == gornspec) 435: e = 50; 436: else if (gornspec) 437: e = 10; 438: else 439: e = 90; 440: if (rand_mod(100) < e) { 441: ch = 'R'; 442: inumroms++; 443: } 444: else { 445: ch = 'G'; 446: inumgorns++; 447: } 448: } 449: if (possiblescore > ENTBOUNDARY - 10000) 450: e = (ENTBOUNDARY - possiblescore) / 5; 451: else 452: e = 250 + (sm50-1) * 30 * 20 / numenemies+1; 453: #ifndef lint 454: e = exdis((int)e) + e - exdis((int)e); 455: obj = make_object(Enemy,ch,y,x,0,0, 456: e + rand_mod(super*200+2) + 10000*massacre,e/4,&root); 457: #endif 458: e /= 4; 459: switch (ch) { 460: case 'K': 461: possiblescore += e; 462: break; 463: case 'T': 464: possiblescore += e*3/2; 465: break; 466: case 'G': 467: possiblescore += e*2; 468: break; 469: case 'R': 470: possiblescore += e*3; 471: obj->flags |= CLOAKS; 472: break; 473: } 474: if (!enemies) 475: enemies = obj; 476: if (!movers) 477: movers = obj; 478: } 479: numgorns = inumgorns; 480: for (i=0; i<numfriends; i++) { 481: do { 482: x = rand_mod(XSIZE); 483: y = rand_mod(YSIZE); 484: } while (occupant[y][x]); 485: e = 250 + (sm50-1) * 30 * 20 / numenemies+1; 486: #ifndef lint 487: e = exdis((int)e) + e - exdis((int)e); 488: #endif 489: { 490: static char let[] = "QWYUISDHJLZVMFFFFFFFFF"; 491: 492: dist = rand_mod(20); 493: ch = let[dist]; 494: } /* grr, venix doesn't like indexing into string */ 495: obj = make_object(Enemy,ch,y,x,0,0, 496: e + rand_mod(super*200+2),e/4,&root); 497: if (numpirates-- > 0) { 498: obj->flags |= PIRATE; 499: if (smarts >= 20 && !rand_mod(10-smarts/10)) 500: obj->flags |= CLOAKS; 501: } 502: obj->flags |= FRIENDLY; 503: if (!enemies) 504: enemies = obj; 505: if (!movers) 506: movers = obj; 507: } 508: if (!movers) 509: movers = &root; 510: if (!enemies) 511: enemies = &root; 512: if (ent) 513: mvaddch(ent->posy+1, ent->posx*2, ent->image); 514: if (base) 515: mvaddch(base->posy+1, base->posx*2, base->image); 516: sleep(2); 517: { 518: Reg7 OBJECT *curobj; 519: 520: for (curobj = root.next; curobj != &root; curobj = curobj->next) { 521: mvaddch(curobj->posy+1, curobj->posx*2, curobj->image); 522: } 523: } 524: 525: for (i=0;i<2;i++) for (y=0;y<3;y++) for (x=0;x<3;x++) 526: isatorp[i][y][x]=0; 527: 528: whenok = 0; 529: timer = 0; 530: finish = 0; 531: bombed_out = FALSE; 532: if (ent) 533: entmode = status = 0; 534: else 535: if (base) 536: status = 2; 537: else 538: status = 3; 539: 540: Sprintf(spbuf, 541: "%-4s E: %4d %2d B: %5d %3d Enemies: %-3d Stars: %-3d Stardate%5d.%1d %9ld", 542: " ", 0, 0, 0, 0, 0, 0, smarts * 100, 0, 0L); 543: mvaddstr(0,0,spbuf); 544: oldeenergy = oldbenergy = oldcurscore = 545: oldstatus = oldetorp = oldbtorp = oldstrs = oldenemies = -1; 546: /* force everything to fill in */ 547: damage = olddamage = 0; 548: for (i=0; i<MAXDAMAGE; i++) 549: damflag[i] = 0; 550: btorp = 500; 551: etorp = 50; 552: }