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 36void 37initialize(void) 38{ 39 int i; 40 int x; 41 int y; 42 int dist; 43 int ydist = 0; 44 int xdist = 0; 45 long e; 46 int yoff = 0, xoff = 0, ypred, xpred; 47 OBJECT *obj = NULL; 48 char ch; 49 FILE *mapfp = NULL; 50 bool tmptholspec; 51 int inhabjackpot; 52 long inhenergy; 53 int walksplit = 200; 54 static const 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 } 112 tmptholspec = (smarts > 15 && inumstars < 450 && ! rand_mod(90-sm80)); 113 if (!klingspec) { 114 inumenemies = rand_mod((smarts+1)/2) + 1; 115 if (massacre || tmptholspec) 116 inumenemies += 10; 117 } 118 if (!friendspec) 119 inumfriends = rand_mod(smarts/8+1); 120 if (!piratespec) 121 inumpirates = rand_mod(inumfriends/2+1); 122 if (inumfriends+inumenemies+inumstars > YSIZE*XSIZE-20) 123 inumstars = YSIZE*XSIZE-20 - inumenemies - inumfriends; 124 if (inumstars < 0) { 125 inumfriends += inumstars; 126 inumstars = 0; 127 } 128 if (inumfriends < 0) { 129 inumenemies += inumfriends; 130 inumfriends = 0; 131 } 132 if (inumenemies < 0) 133 inumenemies = 0; 134 numstars = inumstars; 135 inuminhab = numinhab = 0; 136 inumroms = inumthols = inumgorns = 0; 137 numapollos = apolspec || massacre ? 1 : 138 ((!numstars || rand_mod(2) || smarts < 10) ? 0 : 1); 139 inumapollos = apolloflag = 0; 140 realapollo = NULL; 141 inumcrushes = numcrushes = 142 crushspec||massacre?1:(rand_mod(2000) < inumstars); 143 inumenemies += inumcrushes; 144 inumamoebas = numamoebas = (amoebaspec ? 1 : 145 !rand_mod(inumcrushes?3-massacre:8) ); /* < and & are fun together */ 146 inumenemies += inumamoebas; 147 if (!rand_mod(40)) { 148 inhabjackpot = 32767; 149 inumfriends += rand_mod(10); 150 inumpirates += rand_mod(10); 151 } 152 else 153 inhabjackpot = inumpirates; 154 inhenergy = 30000-super*150; 155 if (!rand_mod(10)) 156 inhenergy = 50000; 157 if (!rand_mod(4)) 158 inhenergy += rand_mod(3500+super*150); 159 numfriends = inumfriends; 160 numpirates = inumpirates; 161 numenemies = inumenemies; 162 deadmudds = 0; 163 164 /* do stars */ 165 166stars_again: 167 if (prespec) 168 dist = 4; 169 else if (numstars > 750) 170 dist = 0; 171 else 172 dist = rand_mod(starspec||smarts<=5?3:5); 173 if (debugging) { 174 real_y = real_x = -100; 175 printf("\r\n"); 176 } 177 switch (dist) { 178 case 0: /* uniform random */ 179 ydist = xdist = 0; 180 if (inumstars < 700 && !rand_mod(3-(inumstars<50))) { 181 ydist = xdist = 6; /* well, maybe not so random */ 182 y = rand_mod(YSIZE); 183 x = rand_mod(XSIZE); 184 if (rand_mod(2)) 185 walksplit = inumstars/(exdis(40)+1); 186 } 187 if (debugging) 188 printf(" R\r\n"); 189 break; 190 case 1: case 2: /* clumped, maybe skewed, maybe superposed */ 191 ydist = rand_mod(4); 192 xdist = rand_mod(2); 193 if (debugging) 194 printf("%s\r\n",distname[ydist+4*xdist]); 195 yoff = rand_mod(YSIZE); 196 xoff = rand_mod(XSIZE); 197 if (dist == 2) 198 dist = numstars/2 + exdis(numstars/2) - exdis(numstars/2); 199 else 200 dist = 0; 201 break; 202 case 3: case 4: /* predefined or residual */ 203 scenario_again: 204 if (debugging) 205 printf(" P\r\n"); 206 dist = 0; 207 snprintf(spbuf, sizeof(spbuf), "smap.%d", 208 (prescene>=0?prescene:rand_mod(MAPS)) ); 209 if ((mapfp = fopen(spbuf,"r")) != NULL && 210 fgets(spbuf,10,mapfp) != NULL ) { 211 inumstars = numstars = atoi(spbuf); 212 if (inumenemies+inumstars > YSIZE*XSIZE-20) 213 inumstars = numstars = YSIZE*XSIZE-20 - inumenemies; 214 ydist = rand_mod(2) + 4; /* flip y axis? */ 215 xdist = rand_mod(2) + 4; /* flip x axis? */ 216 yoff = rand_mod(YSIZE); /* how much to shift y */ 217 xoff = rand_mod(XSIZE); /* how much to shift x */ 218 } 219 else { 220 prespec = false; 221 prescene = -1; 222 if (rand_mod(2)) 223 goto scenario_again; 224 goto stars_again; 225 } 226 break; 227 } 228 for (i = 1; i <= numstars; i++) { 229 if (dist && i == dist) { /* flip to another skewing? */ 230 ydist = rand_mod(4); 231 xdist = rand_mod(2); 232 if (!rand_mod(4)) { 233 ydist = xdist = 6; 234 if (debugging) 235 printf("&\r\n"); 236 } 237 else if (debugging) 238 printf("%s\r\n",distname[ydist+4*xdist]); 239 yoff = rand_mod(YSIZE); 240 xoff = rand_mod(XSIZE); 241 dist = 0; 242 } 243 do { /* until an open spot found */ 244 switch (xdist) { 245 case 0: 246 x = rand_mod(XSIZE); /* pick from 0..39, uniform */ 247 break; 248 case 1: case 2: case 3: 249 x = (int)((((double)(myrand()-HALFRAND)) * 250 ((double)(myrand()-HALFRAND))/RANDRAND) 251 * 20.0) + xoff; /* pick from -20..20, clumped */ 252 break; 253 case 4: 254 if (fscanf(mapfp,"%d %d\n",&ypred,&xpred) == EOF) 255 ydist = xdist = 0; 256 x = xpred + xoff; 257 break; 258 case 5: 259 if (fscanf(mapfp,"%d %d\n",&ypred,&xpred) == EOF) 260 ydist = xdist = 0; 261 x = -xpred + xoff; 262 break; 263 case 6: 264 x += rand_mod(3) - 1; 265 break; 266 } 267 switch (ydist) { 268 case 0: 269 y = rand_mod(YSIZE); 270 break; 271 case 1: 272 y = (int)((((double)(myrand()-HALFRAND)) * 273 ((double)(myrand()-HALFRAND))/RANDRAND) 274 * 12.0) + yoff; /* pick from -12..12, clumped */ 275 break; 276 case 2: 277#ifndef lint 278 y = (int)((((double)(myrand()-HALFRAND)) * 279 ((double)(myrand()-HALFRAND))/RANDRAND) 280 * 12.0) + yoff + x*YSIZE/XSIZE; 281 /* clumped & skewed */ 282#endif 283 break; 284 case 3: 285#ifndef lint 286 y = (int)((((double)(myrand()-HALFRAND)) * 287 ((double)(myrand()-HALFRAND))/RANDRAND) 288 * 12.0) + yoff - x*YSIZE/XSIZE; 289 /* clumped & skewed */ 290#endif 291 break; 292 case 4: 293 y = ypred + yoff; 294 break; 295 case 5: 296 y = -ypred + yoff; 297 break; 298 case 6: 299 y += rand_mod(3) - 1; 300#ifdef lint 301 walksplit = walksplit; 302#endif 303 if (!rand_mod(walksplit)) { 304 y = rand_mod(YSIZE); 305 x = rand_mod(XSIZE); 306 } 307 break; 308 } 309 while (x<0) x += XSIZE00; 310 while (y<0) y += YSIZE00; 311 x %= XSIZE; 312 y %= YSIZE; 313 } while (occupant[y][x]); 314 e = rand_mod(32768); 315 if (--inhabjackpot > 0 || e >= inhenergy) { 316 ch = '@'; 317 if (inhabjackpot && e < 10000) 318 e += 10000; 319 inuminhab = ++numinhab; 320 } 321 else { 322 ch = '*'; 323 } 324 obj = make_object(Star,ch,y,x,0,0,e+rand_mod(super*100+1),e/4,&root); 325 obj->flags |= STATIC; 326 } 327 if (inumstars > 30 && inhabjackpot <= 0 && 328 !rand_mod(3 - (inumstars > 400) - (inhenergy > 32768)) ) { 329 int initx; 330 int inity; 331 332 x = initx = obj->posx; 333 y = inity = obj->posy; 334 while (rand_mod(2) && inuminhab < inumstars/2) { 335 for (i=rand_mod(smarts)*2+20; i; i--) { 336 if ((obj = occupant[y][x]) && obj->image == '*') { 337 setimage(obj,'@'); 338 if (obj->energy < 10000) 339 obj->energy += 20000; /* the benefits of civilization */ 340 inuminhab = ++numinhab; 341 } 342 if (i&15) { 343 y = (y + rand_mod(3) + YSIZE99) % YSIZE; 344 x = (x + rand_mod(3) + XSIZE99) % XSIZE; 345 } 346 else { /* don't wander too far */ 347 y = inity; 348 x = initx; 349 } 350 } 351 x = initx = rand_mod(XSIZE); 352 y = inity = rand_mod(YSIZE); 353 } 354 } 355 if (mapfp != NULL) 356 fclose(mapfp); 357 if (numcrushes) { 358 do { 359 x = rand_mod(XSIZE); 360 y = rand_mod(YSIZE); 361 } while (occupant[y][x]); 362 movers = make_object(Crusher,'<',y,x,0,1,32767L,32768L,&root); 363 possiblescore += 10000; 364 } 365 ient = (numents != 0); 366 if (ient) { 367 do { 368 x = rand_mod(XSIZE); 369 y = rand_mod(YSIZE); 370 } while (occupant[y][x]); 371 e = entmax; 372 ent = make_object(Enterprise,'E',y,x,0,0,e,e/2,&root); 373 if (!movers) 374 movers = ent; 375 } 376 ibase = (numbases != 0); 377 if (ibase) { 378 e = 52-super; 379 do { 380 x = rand_mod(XSIZE); 381 y = rand_mod(YSIZE); 382 } while (occupant[y][x] || lookaround(y,x,Star) * 7 < e--); 383 e = basemax; 384 base = make_object(Base, 'B',y,x,0,0,e,e/4,&root); 385 if (!movers) 386 movers = base; 387 } 388 if (numamoebas) { 389 do { 390 x = rand_mod(XSIZE); 391 y = rand_mod(YSIZE); 392 } while (occupant[y][x]); 393 nuke = make_object(Enemy,'&',y,x,0,0,32767L, 394 (long)entmax+entmax+rand_mod(entmax),&root); 395 possiblescore += 10000; 396 amb[y][x] = '~'; 397 if (rand_mod(2)) 398 modify_amoeba(y,x,2,'~',(int)rand_mod(smarts<<1));/* just make blob */ 399 else { 400 for (i=smarts/10+1; i; i--) { 401 nuke->strategy = rand_mod(256); /* random direction */ 402 modify_amoeba(y,x,2,'~',(int)rand_mod(5)); 403 modify_amoeba(y,x,2,'~',(int)rand_mod(5)); 404 modify_amoeba(y,x,2,'~',(int)rand_mod(5)); 405 modify_amoeba(y,x,2,'~',(int)rand_mod(5)); /* extend pseudopod */ 406 } 407 } 408 if (!enemies) 409 enemies = nuke; 410 if (!movers) 411 movers = nuke; 412 } 413 if (rand_mod(27-sm50/2) && !romspec && !gornspec) 414 dist = 27-sm50/2; 415 else 416 dist = rand_mod(4) + 1; 417 for (i = 1+inumcrushes+inumamoebas; i <= numenemies; i++) { 418 do { 419 x = rand_mod(XSIZE); 420 y = rand_mod(YSIZE); 421 } while (occupant[y][x]); 422 if (rand_mod(dist)) { 423 if (!tholspec && !tmptholspec && rand_mod((inumstars*3)/sm50+2)) 424 ch = 'K'; 425 else { 426 ch = 'T'; 427 inumthols++; 428 } 429 } 430 else { 431 if (romspec == gornspec) 432 e = 50; 433 else if (gornspec) 434 e = 10; 435 else 436 e = 90; 437 if (rand_mod(100) < e) { 438 ch = 'R'; 439 inumroms++; 440 } 441 else { 442 ch = 'G'; 443 inumgorns++; 444 } 445 } 446 if (possiblescore > ENTBOUNDARY - 10000) 447 e = (ENTBOUNDARY - possiblescore) / 5; 448 else 449 e = 250 + (sm50-1) * 30 * 20 / numenemies+1; 450#ifndef lint 451 e = exdis((int)e) + e - exdis((int)e); 452 obj = make_object(Enemy,ch,y,x,0,0, 453 e + rand_mod(super*200+2) + 10000*massacre,e/4,&root); 454#endif 455 e /= 4; 456 switch (ch) { 457 case 'K': 458 possiblescore += e; 459 break; 460 case 'T': 461 possiblescore += e*3/2; 462 break; 463 case 'G': 464 possiblescore += e*2; 465 break; 466 case 'R': 467 possiblescore += e*3; 468 obj->flags |= CLOAKS; 469 break; 470 } 471 if (!enemies) 472 enemies = obj; 473 if (!movers) 474 movers = obj; 475 } 476 numgorns = inumgorns; 477 for (i=0; i<numfriends; i++) { 478 do { 479 x = rand_mod(XSIZE); 480 y = rand_mod(YSIZE); 481 } while (occupant[y][x]); 482 e = 250 + (sm50-1) * 30 * 20 / numenemies+1; 483#ifndef lint 484 e = exdis((int)e) + e - exdis((int)e); 485#endif 486 { 487 static char let[] = "QWYUISDHJLZVMFFFFFFFFF"; 488 489 dist = rand_mod(20); 490 ch = let[dist]; 491 } /* grr, venix doesn't like strchring into string */ 492 obj = make_object(Enemy,ch,y,x,0,0, 493 e + rand_mod(super*200+2),e/4,&root); 494 if (numpirates-- > 0) { 495 obj->flags |= PIRATE; 496 if (smarts >= 20 && !rand_mod(10-smarts/10)) 497 obj->flags |= CLOAKS; 498 } 499 obj->flags |= FRIENDLY; 500 if (!enemies) 501 enemies = obj; 502 if (!movers) 503 movers = obj; 504 } 505 if (!movers) 506 movers = &root; 507 if (!enemies) 508 enemies = &root; 509 if (ent) 510 mvaddch(ent->posy+1, ent->posx*2, ent->image); 511 if (base) 512 mvaddch(base->posy+1, base->posx*2, base->image); 513 sleep(2); 514 { 515 OBJECT *curobj; 516 517 for (curobj = root.next; curobj != &root; curobj = curobj->next) { 518 mvaddch(curobj->posy+1, curobj->posx*2, curobj->image); 519 } 520 } 521 522 for (i=0;i<2;i++) for (y=0;y<3;y++) for (x=0;x<3;x++) 523 isatorp[i][y][x]=0; 524 525 whenok = 0; 526 timer = 0; 527 finish = 0; 528 bombed_out = false; 529 if (ent) 530 entmode = status = 0; 531 else 532 if (base) 533 status = 2; 534 else 535 status = 3; 536 537 snprintf(spbuf, sizeof(spbuf), 538 "%-4s E: %4d %2d B: %5d %3d Enemies: %-3d Stars: %-3d Stardate%5d.%1d %9ld", 539 " ", 0, 0, 0, 0, 0, 0, smarts * 100, 0, 0L); 540 mvaddstr(0,0,spbuf); 541 oldeenergy = oldbenergy = oldcurscore = 542 oldstatus = oldetorp = oldbtorp = oldstrs = oldenemies = -1; 543 /* force everything to fill in */ 544 damage = olddamage = 0; 545 for (i=0; i<MAXDAMAGE; i++) 546 damflag[i] = 0; 547 btorp = 500; 548 etorp = 50; 549} 550