Home | History | Annotate | Line # | Download | only in warp
      1  1.2     kamil /* Header: them.c,v 7.0.1.5 86/12/12 17:05:41 lwall Exp */
      2  1.1     kamil 
      3  1.2     kamil /* Log:	them.c,v
      4  1.1     kamil  * Revision 7.0.1.5  86/12/12  17:05:41  lwall
      5  1.1     kamil  * Baseline for net release.
      6  1.4    rillig  *
      7  1.1     kamil  * Revision 7.0.1.4  86/10/20  12:32:38  lwall
      8  1.1     kamil  * Wasn't clearing FRIENDLY flag on pirate creation.
      9  1.4    rillig  *
     10  1.1     kamil  * Revision 7.0.1.3  86/10/20  12:15:33  lwall
     11  1.1     kamil  * Was trying to create pirates from cloaked pirates.
     12  1.4    rillig  *
     13  1.1     kamil  * Revision 7.0.1.2  86/10/17  10:03:44  lwall
     14  1.1     kamil  * Fixed Romulan writing spaces while cloaked.
     15  1.4    rillig  *
     16  1.1     kamil  * Revision 7.0.1.1  86/10/16  10:53:39  lwall
     17  1.1     kamil  * Added Damage.  Fixed random bugs.
     18  1.4    rillig  *
     19  1.1     kamil  * Revision 7.0  86/10/08  15:14:15  lwall
     20  1.1     kamil  * Split into separate files.  Added amoebas and pirates.
     21  1.4    rillig  *
     22  1.1     kamil  */
     23  1.1     kamil 
     24  1.1     kamil #include "EXTERN.h"
     25  1.1     kamil #include "warp.h"
     26  1.1     kamil #include "bang.h"
     27  1.1     kamil #include "object.h"
     28  1.1     kamil #include "move.h"
     29  1.1     kamil #include "score.h"
     30  1.1     kamil #include "term.h"
     31  1.1     kamil #include "us.h"
     32  1.1     kamil #include "util.h"
     33  1.1     kamil #include "weapon.h"
     34  1.1     kamil #include "INTERN.h"
     35  1.1     kamil #include "them.h"
     36  1.1     kamil 
     37  1.1     kamil void
     38  1.3  christos them_init(void)
     39  1.1     kamil {
     40  1.1     kamil     ;
     41  1.1     kamil }
     42  1.1     kamil 
     43  1.1     kamil void
     44  1.3  christos their_smarts(void)
     45  1.1     kamil {
     46  1.3  christos     OBJECT *curkl;
     47  1.3  christos     OBJECT *obj = NULL;
     48  1.3  christos     int prob;
     49  1.3  christos     int count;
     50  1.3  christos     int y = 0;
     51  1.3  christos     int x = 0;
     52  1.1     kamil 
     53  1.1     kamil     if (numcrushes && (obj=movers)->type == Crusher) {
     54  1.1     kamil 	if (numamoebas) {
     55  1.1     kamil 	    y = obj->posy;
     56  1.1     kamil 	    x = (obj->posx+(obj->image=='<'?1:-1)+XSIZE00)%XSIZE;
     57  1.1     kamil 	    if (amb[y][x] == '~') {
     58  1.1     kamil 		obj->velx = 0;		/* stop and munch amoeba */
     59  1.1     kamil 		modify_amoeba(y,x,1,' ',(int)rand_mod(5+ambsize/10)+1);
     60  1.1     kamil 		if (occupant[y][x] == nuke)	/* except go for nucleus */
     61  1.1     kamil 		    obj->velx = (obj->image=='<' ? 1 : -1);
     62  1.1     kamil 	    }
     63  1.1     kamil 	    else if (!obj->velx) {
     64  1.1     kamil 		if (!rand_mod(4))
     65  1.1     kamil 		    obj->image = rand_mod(2) ? '<' : '>';
     66  1.1     kamil 		obj->velx = obj->image == '<' ? 1 : -1;
     67  1.1     kamil 	    }
     68  1.1     kamil 	}
     69  1.1     kamil 	obj->vely += (rand_mod(222) - 111) / 100;
     70  1.1     kamil 	if (!(rand_mod(100))) {
     71  1.1     kamil 	    setimage(obj, (obj->velx *= -1) < 0 ? '>' : '<');
     72  1.1     kamil 	}
     73  1.1     kamil     }
     74  1.1     kamil     if (numamoebas) {
     75  1.1     kamil 	if (!rand_mod(3))
     76  1.1     kamil 	    nuke->velx = nuke->vely = 0;
     77  1.1     kamil 	if (nuke->strategy && ambsize < 90 && !rand_mod(200-smarts))
     78  1.1     kamil 	    modify_amoeba(0,0,0,'~',(int)rand_mod(10));
     79  1.1     kamil 	if (ambsize > 200 || (ambsize > 100 && !rand_mod(15)))
     80  1.1     kamil 	    modify_amoeba(yamblast,xamblast,2,' ',(ambsize-100)/5);
     81  1.1     kamil     }
     82  1.1     kamil     for (curkl = enemies; curkl->type == Enemy; curkl = curkl->next) {
     83  1.1     kamil 	if ((curkl->flags & (CLOAKS|FRIENDLY)) == CLOAKS &&
     84  1.1     kamil 	    (curkl->image != ' ') &&
     85  1.1     kamil 	    (curkl->energy > 300 || massacre) ) {
     86  1.1     kamil 	    setimage(curkl, ' ');
     87  1.1     kamil 	}
     88  1.1     kamil 	if (madgorns)
     89  1.1     kamil 	    prob = 3;
     90  1.1     kamil 	else if (curkl->vely || curkl->velx)
     91  1.1     kamil 	    prob = massacre?10:20;
     92  1.1     kamil 	else if ((curkl->flags & (PIRATE|FRIENDLY)) == PIRATE) {
     93  1.1     kamil 				/* pirates want to sit sometimes */
     94  1.1     kamil 	    if (curkl->strategy) {
     95  1.1     kamil 		if ((obj = lookimg(curkl->posy, curkl->posx, '@')) ||
     96  1.1     kamil 		    (obj = lookimg(curkl->posy, curkl->posx, 'B')) ) {
     97  1.1     kamil 		    make_plink(obj->posy, obj->posx);
     98  1.1     kamil 		    if (!--curkl->strategy) {	/* clock ran down */
     99  1.1     kamil 			if (obj->image == '@') {
    100  1.1     kamil 			    obj->image = '*';
    101  1.1     kamil 			    numinhab--;
    102  1.1     kamil 			    if (obj->flags & STATIC)
    103  1.1     kamil 				mvaddch(obj->posy+1,obj->posx*2,obj->image);
    104  1.1     kamil 			    if (curkl->energy < 20000)
    105  1.1     kamil 				curkl->energy += 5000;
    106  1.1     kamil 			}
    107  1.1     kamil 			prob = 2;	/* our work here is done */
    108  1.1     kamil 		    }
    109  1.1     kamil 		    else if (obj->image == 'B') {
    110  1.1     kamil 			btorp -= rand_mod(50);
    111  1.1     kamil 			if (btorp < 0)
    112  1.1     kamil 			    btorp = 0;
    113  1.1     kamil 			obj->energy -= rand_mod(500);
    114  1.1     kamil 			if (obj->energy < 0)
    115  1.1     kamil 			    obj->energy = 0;
    116  1.1     kamil 			prob = 10000;		/* stay here */
    117  1.1     kamil 		    }
    118  1.1     kamil 		    else
    119  1.1     kamil 			prob = 10000;
    120  1.1     kamil 		}
    121  1.1     kamil 		else {		/* it went away--go elsewhere */
    122  1.1     kamil 		    prob = 4;
    123  1.1     kamil 		    curkl->strategy = 0;
    124  1.1     kamil 		}
    125  1.1     kamil 	    }
    126  1.1     kamil 	    else if (lookimg(curkl->posy, curkl->posx, '@') ||
    127  1.1     kamil 		     lookimg(curkl->posy, curkl->posx, 'B')) {
    128  1.1     kamil 		curkl->strategy = rand_mod(15)+5;
    129  1.1     kamil 		prob = 10000;
    130  1.1     kamil 	    }
    131  1.1     kamil 	    else
    132  1.1     kamil 		prob = 4;
    133  1.1     kamil 	}
    134  1.1     kamil 	else if (curkl->image == 'M') {	/* Mudd wants to sit sometimes */
    135  1.1     kamil 	    if ((obj = lookimg(curkl->posy, curkl->posx, 'E')) ||
    136  1.1     kamil 		(obj = lookimg(curkl->posy, curkl->posx, 'B')) ) {
    137  1.1     kamil 		if (obj->image == 'B') {
    138  1.1     kamil 		    btorp -= rand_mod(40);
    139  1.1     kamil 		    if (btorp < 0)
    140  1.1     kamil 			btorp = 0;
    141  1.1     kamil 		    obj->energy -= rand_mod(100);
    142  1.1     kamil 		    if (obj->energy < 0)
    143  1.1     kamil 			obj->energy = 0;
    144  1.1     kamil 		}
    145  1.1     kamil 		else if (!obj->vely && !obj->velx) {
    146  1.1     kamil 		    etorp -= rand_mod(10);
    147  1.1     kamil 		    if (etorp < 0)
    148  1.1     kamil 			etorp = 0;
    149  1.1     kamil 		    obj->energy -= rand_mod(20);
    150  1.1     kamil 		    if (obj->energy < 0)
    151  1.1     kamil 			obj->energy = 0;
    152  1.1     kamil 		}
    153  1.1     kamil 		prob = 10000;		/* stay here */
    154  1.1     kamil 	    }
    155  1.1     kamil 	    else		/* it went away--go elsewhere */
    156  1.1     kamil 		prob = 4;
    157  1.1     kamil 	}
    158  1.1     kamil 	else if (curkl->flags & FRIENDLY) {
    159  1.1     kamil 	    if (curkl->energy < 10000 &&
    160  1.1     kamil 	      lookimg(curkl->posy, curkl->posx, '@') ) {
    161  1.1     kamil 		curkl->energy += 100;
    162  1.1     kamil 		prob = 20;	/* do some loading */
    163  1.1     kamil 	    }
    164  1.1     kamil 	    else
    165  1.1     kamil 		prob = 4;
    166  1.1     kamil 	}
    167  1.1     kamil 	else if (curkl->image == '&') {
    168  1.1     kamil 	    if (curkl->flags & COUNTDOWN) {
    169  1.1     kamil 		if (curkl->strategy)
    170  1.1     kamil 		    curkl->strategy--;
    171  1.1     kamil 		else
    172  1.1     kamil 		    curkl->flags &= ~COUNTDOWN;
    173  1.1     kamil 		prob = 100;	/* someone's feeding us, so sit still */
    174  1.1     kamil 	    }
    175  1.1     kamil 	    else
    176  1.1     kamil 		prob = 4;
    177  1.1     kamil 	}
    178  1.1     kamil 	else
    179  1.1     kamil 	    prob = 4;			/* don't sit still too long */
    180  1.1     kamil 	count = 11;
    181  1.1     kamil 	for (;;) {
    182  1.1     kamil 	    if (--count <= 0)		/* no opening, just ram something */
    183  1.1     kamil 		break;
    184  1.1     kamil 
    185  1.1     kamil #ifdef lint
    186  1.1     kamil 	    prob = prob;
    187  1.1     kamil #endif
    188  1.1     kamil 	    if (!(rand_mod(prob)))	/* turn randomly occasionally */
    189  1.1     kamil 		goto accell;
    190  1.1     kamil 
    191  1.1     kamil 	    y=(curkl->posy+curkl->vely+YSIZE00)%YSIZE;	/* find prospective */
    192  1.1     kamil 	    x=(curkl->posx+curkl->velx+XSIZE00)%XSIZE;	/*   new position */
    193  1.1     kamil 
    194  1.1     kamil 	    if (numamoebas) {
    195  1.1     kamil 		if (curkl == nuke) {
    196  1.1     kamil 		    if (amb[y][x] != '~')
    197  1.1     kamil 			goto accell;	/* never move nucleus from protoplasm */
    198  1.1     kamil 		}
    199  1.1     kamil 		else {
    200  1.1     kamil 		    if (amb[y][x] == '~' && rand_mod(2)) {
    201  1.1     kamil 			yamblast = y;
    202  1.1     kamil 			xamblast = x;
    203  1.1     kamil 			goto accell;
    204  1.1     kamil 		    }
    205  1.1     kamil 		}
    206  1.1     kamil 	    }
    207  1.1     kamil 
    208  1.1     kamil 	    obj = occupant[y][x];
    209  1.1     kamil 	    if (!obj) break;		/* is anyone there? */
    210  1.1     kamil 
    211  1.1     kamil 	    switch (obj->type) {
    212  1.1     kamil 	    case Star:
    213  1.1     kamil 		if (obj->image == '@' && (curkl->flags & PIRATE)) {
    214  1.1     kamil 		    if (curkl->image != 'P' && curkl->image != ' ') {
    215  1.1     kamil 			if (curkl->flags & FRIENDLY) {
    216  1.1     kamil 			    curkl->flags &= ~FRIENDLY;
    217  1.1     kamil 			    curkl->energy += 1000;
    218  1.1     kamil 			    possiblescore += curkl->mass;
    219  1.1     kamil 			    inumfriends--;
    220  1.1     kamil 			    numfriends--;
    221  1.1     kamil 			    inumenemies++;
    222  1.1     kamil 			    numenemies++;
    223  1.1     kamil 			}
    224  1.1     kamil 			curkl->image = 'P';
    225  1.1     kamil 		    }
    226  1.1     kamil 		    break;		/* go ahead and ram the star */
    227  1.1     kamil 		}
    228  1.1     kamil 		goto accell;		/* try not to ram stars */
    229  1.1     kamil 	    case Torp:
    230  1.1     kamil 		if (!obj->vely && !obj->velx && (rand_mod(100) <= smarts) &&
    231  1.1     kamil 		  (obj->image == 'o' || obj->image == 'O' || obj->image == 'X'))
    232  1.1     kamil 		    goto accell;	/* try not to ram "friendly" torps */
    233  1.1     kamil 		break;
    234  1.1     kamil 	    case Web:
    235  1.1     kamil 		if (curkl->image != 'T')
    236  1.1     kamil 		    goto accell;	/* non-Tholians shouldn't ram web */
    237  1.1     kamil 		if (count <= 5)
    238  1.1     kamil 		    break;		/* Tholians retrace web if desperate */
    239  1.1     kamil 		if (obj->image ==
    240  1.1     kamil 		    (curkl->vely?
    241  1.1     kamil 		     (curkl->velx?
    242  1.1     kamil 		      (curkl->velx==curkl->vely?
    243  1.1     kamil 		       '\\'
    244  1.1     kamil 		      :
    245  1.1     kamil 		       '/'
    246  1.1     kamil 		      )
    247  1.1     kamil 		     :
    248  1.1     kamil 		      '|'
    249  1.1     kamil 		     )
    250  1.1     kamil 		    :
    251  1.1     kamil 		     '-'
    252  1.1     kamil 		    )
    253  1.1     kamil 		   ) goto accell;	/* Tholians try not to retrace web */
    254  1.1     kamil 		break;			/* No problem with crossing web */
    255  1.1     kamil 	    }
    256  1.1     kamil 	    break;			/* okay to move over object */
    257  1.1     kamil 
    258  1.1     kamil 	accell:
    259  1.1     kamil 	    /* determine maximum velocity */
    260  1.1     kamil 	    if (massacre && curkl->image != 'T') {
    261  1.1     kamil 		curkl->vely = rand_mod(7) - 3;
    262  1.1     kamil 		curkl->velx = rand_mod(7) - 3;
    263  1.1     kamil 	    }
    264  1.1     kamil 	    else if (curkl->image == '&') {
    265  1.1     kamil 		if (rand_mod(2)) {
    266  1.1     kamil 		    curkl->vely = rand_mod(3) - 1;
    267  1.1     kamil 		    curkl->velx = rand_mod(3) - 1;
    268  1.1     kamil 		}
    269  1.1     kamil 		else {
    270  1.1     kamil 		    curkl->vely = curkl->strategy & 3;
    271  1.1     kamil 		    if (curkl->vely & 2)
    272  1.1     kamil 			curkl->vely = -1;
    273  1.1     kamil 		    curkl->velx = (curkl->strategy >> 2) & 3;
    274  1.1     kamil 		    if (curkl->velx & 2)
    275  1.1     kamil 			curkl->velx = -1;
    276  1.1     kamil 		}
    277  1.1     kamil 	    }
    278  1.1     kamil 	    else if (curkl->energy >= 2500 && curkl->image != 'T') {
    279  1.1     kamil 		curkl->vely = rand_mod(5) - 2;
    280  1.1     kamil 		curkl->velx = rand_mod(5) - 2;
    281  1.1     kamil 	    }
    282  1.1     kamil 	    else {
    283  1.1     kamil 		curkl->vely = rand_mod(3) - 1;
    284  1.1     kamil 		curkl->velx = rand_mod(3) - 1;
    285  1.1     kamil 	    }
    286  1.1     kamil 	}
    287  1.1     kamil 	if (count != 10) {
    288  1.1     kamil 	    if (curkl->image == ' ') {
    289  1.1     kamil 		setimage(curkl, curkl->flags & PIRATE ? 'P' : 'R');
    290  1.1     kamil 	    }
    291  1.1     kamil 	    if (!count) {
    292  1.1     kamil 		curkl->vely = 0;
    293  1.1     kamil 		curkl->velx = 0;
    294  1.1     kamil 	    }
    295  1.1     kamil 	}
    296  1.1     kamil 	if (curkl->image == 'G' && (base||ent) &&
    297  1.1     kamil 	    !rand_mod((103-smarts)*10) ) {
    298  1.1     kamil 	    int xxx,yyy;
    299  1.1     kamil 
    300  1.1     kamil 	    for (xxx = -1; xxx<=1; xxx++)
    301  1.1     kamil 		for (yyy = -1; yyy<=1; yyy++)
    302  1.1     kamil 		    if ((xxx||yyy) && rand_mod(2))
    303  1.1     kamil 			fire_torp(curkl,yyy,xxx);
    304  1.1     kamil 	}
    305  1.1     kamil 	else if (curkl->image == 'T' && (curkl->velx || curkl->vely)) {
    306  1.3  christos 	    make_object(Web,
    307  1.1     kamil             curkl->vely?
    308  1.1     kamil 	     (curkl->velx?
    309  1.1     kamil 	      (curkl->velx==curkl->vely?
    310  1.1     kamil 	       '\\'
    311  1.1     kamil 	      :
    312  1.1     kamil 	       '/'
    313  1.1     kamil 	      )
    314  1.1     kamil 	     :
    315  1.1     kamil 	      '|'
    316  1.1     kamil 	     )
    317  1.1     kamil 	    :
    318  1.1     kamil 	     '-',
    319  1.1     kamil 	    curkl->posy,curkl->posx,0,0,32767L,32767L,&root);
    320  1.1     kamil 	    if (obj && obj->type == Web) {
    321  1.1     kamil 		unmake_object(obj);
    322  1.3  christos 		occupant[y][x] = NULL;
    323  1.1     kamil 	    }
    324  1.1     kamil 	}
    325  1.1     kamil     }
    326  1.1     kamil     /* klingon-style fighting */
    327  1.1     kamil     if (numamoebas)
    328  1.1     kamil 	attack(nuke);
    329  1.1     kamil     attack(base);
    330  1.1     kamil     if (ent && (!cloaked || ent->image=='E' || ent->image=='e'))
    331  1.1     kamil 	attack(ent);
    332  1.1     kamil }
    333  1.1     kamil 
    334  1.1     kamil void
    335  1.3  christos modify_amoeba(int y, int x, int where, int ch, int quant)
    336  1.1     kamil {
    337  1.3  christos     int dy;
    338  1.3  christos     int dx;
    339  1.3  christos     int count = 15;
    340  1.1     kamil 
    341  1.1     kamil     if (!numamoebas)
    342  1.1     kamil 	return;
    343  1.1     kamil     if (!where || (where==1 && rand_mod(2))) {
    344  1.1     kamil 	y = nuke->posy;
    345  1.1     kamil 	x = nuke->posx;
    346  1.1     kamil     }
    347  1.1     kamil     if (nuke->strategy && rand_mod(3)) {
    348  1.1     kamil 	dy = nuke->strategy & 3;
    349  1.1     kamil 	if (dy & 2)
    350  1.1     kamil 	    dy = -1;
    351  1.1     kamil 	dx = (nuke->strategy >> 2) & 3;
    352  1.1     kamil 	if (dx & 2)
    353  1.1     kamil 	    dx = -1;
    354  1.1     kamil 	if (ch == ' ') {		/* take from the tail */
    355  1.1     kamil 	    dy = -dy;
    356  1.1     kamil 	    dx = -dx;
    357  1.1     kamil 	}
    358  1.1     kamil 	if (!rand_mod(100))
    359  1.1     kamil 	    nuke->strategy = rand_mod(256);
    360  1.1     kamil     }
    361  1.1     kamil     else {
    362  1.1     kamil 	dy = rand_mod(3) - 1;
    363  1.1     kamil 	dx = rand_mod(3) - 1;
    364  1.1     kamil     }
    365  1.1     kamil     if (!dy && !dx)
    366  1.1     kamil 	return;
    367  1.1     kamil     do {
    368  1.1     kamil 	if (--count < 0)
    369  1.1     kamil 	    return;
    370  1.1     kamil 	y = (y + dy + YSIZE00) % YSIZE;
    371  1.1     kamil 	x = (x + dx + XSIZE00) % XSIZE;
    372  1.1     kamil     } while (amb[y][x] != ' ');
    373  1.1     kamil     if (ch == ' ') {
    374  1.1     kamil 	y = (y - dy + YSIZE00) % YSIZE;
    375  1.1     kamil 	x = (x - dx + XSIZE00) % XSIZE;
    376  1.1     kamil     }
    377  1.1     kamil     if (ambsize > 100 && quant > 2) {
    378  1.1     kamil 	quant >>= (ambsize/100);
    379  1.1     kamil     }
    380  1.1     kamil     if ((nuke->energy += quant << 6) > 32767)
    381  1.1     kamil 	nuke->energy = 32767;
    382  1.1     kamil     count = quant << 3;		/* endless loop catcher */
    383  1.1     kamil     while (count-- > 0 && quant > 0) {
    384  1.1     kamil 	if (amb[y][x] != ch) {
    385  1.1     kamil 	    quant--;
    386  1.1     kamil 	    amb[y][x] = ch;
    387  1.1     kamil 	    if (ch == '~') {
    388  1.1     kamil 		ambsize++;
    389  1.1     kamil 		yblasted[y] |= 2;
    390  1.1     kamil 		xblasted[x] |= 2;
    391  1.3  christos 		blasted = true;
    392  1.1     kamil 	    }
    393  1.1     kamil 	    else
    394  1.1     kamil 		ambsize--;
    395  1.1     kamil 	    if (!occupant[y][x])
    396  1.1     kamil 		mvaddch(y+1,x*2,ch);
    397  1.1     kamil 	}
    398  1.1     kamil 	y = (y + rand_mod(3) + YSIZE99) % YSIZE;
    399  1.1     kamil 	x = (x + rand_mod(3) + XSIZE99) % XSIZE;
    400  1.1     kamil     }
    401  1.1     kamil }
    402