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