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