NetBSD/games/warp/them.c

402 lines
9.5 KiB
C

/* Header: them.c,v 7.0.1.5 86/12/12 17:05:41 lwall Exp */
/* Log: them.c,v
* Revision 7.0.1.5 86/12/12 17:05:41 lwall
* Baseline for net release.
*
* Revision 7.0.1.4 86/10/20 12:32:38 lwall
* Wasn't clearing FRIENDLY flag on pirate creation.
*
* Revision 7.0.1.3 86/10/20 12:15:33 lwall
* Was trying to create pirates from cloaked pirates.
*
* Revision 7.0.1.2 86/10/17 10:03:44 lwall
* Fixed Romulan writing spaces while cloaked.
*
* Revision 7.0.1.1 86/10/16 10:53:39 lwall
* Added Damage. Fixed random bugs.
*
* Revision 7.0 86/10/08 15:14:15 lwall
* Split into separate files. Added amoebas and pirates.
*
*/
#include "EXTERN.h"
#include "warp.h"
#include "bang.h"
#include "object.h"
#include "move.h"
#include "score.h"
#include "term.h"
#include "us.h"
#include "util.h"
#include "weapon.h"
#include "INTERN.h"
#include "them.h"
void
them_init(void)
{
;
}
void
their_smarts(void)
{
OBJECT *curkl;
OBJECT *obj = NULL;
int prob;
int count;
int y = 0;
int x = 0;
if (numcrushes && (obj=movers)->type == Crusher) {
if (numamoebas) {
y = obj->posy;
x = (obj->posx+(obj->image=='<'?1:-1)+XSIZE00)%XSIZE;
if (amb[y][x] == '~') {
obj->velx = 0; /* stop and munch amoeba */
modify_amoeba(y,x,1,' ',(int)rand_mod(5+ambsize/10)+1);
if (occupant[y][x] == nuke) /* except go for nucleus */
obj->velx = (obj->image=='<' ? 1 : -1);
}
else if (!obj->velx) {
if (!rand_mod(4))
obj->image = rand_mod(2) ? '<' : '>';
obj->velx = obj->image == '<' ? 1 : -1;
}
}
obj->vely += (rand_mod(222) - 111) / 100;
if (!(rand_mod(100))) {
setimage(obj, (obj->velx *= -1) < 0 ? '>' : '<');
}
}
if (numamoebas) {
if (!rand_mod(3))
nuke->velx = nuke->vely = 0;
if (nuke->strategy && ambsize < 90 && !rand_mod(200-smarts))
modify_amoeba(0,0,0,'~',(int)rand_mod(10));
if (ambsize > 200 || (ambsize > 100 && !rand_mod(15)))
modify_amoeba(yamblast,xamblast,2,' ',(ambsize-100)/5);
}
for (curkl = enemies; curkl->type == Enemy; curkl = curkl->next) {
if ((curkl->flags & (CLOAKS|FRIENDLY)) == CLOAKS &&
(curkl->image != ' ') &&
(curkl->energy > 300 || massacre) ) {
setimage(curkl, ' ');
}
if (madgorns)
prob = 3;
else if (curkl->vely || curkl->velx)
prob = massacre?10:20;
else if ((curkl->flags & (PIRATE|FRIENDLY)) == PIRATE) {
/* pirates want to sit sometimes */
if (curkl->strategy) {
if ((obj = lookimg(curkl->posy, curkl->posx, '@')) ||
(obj = lookimg(curkl->posy, curkl->posx, 'B')) ) {
make_plink(obj->posy, obj->posx);
if (!--curkl->strategy) { /* clock ran down */
if (obj->image == '@') {
obj->image = '*';
numinhab--;
if (obj->flags & STATIC)
mvaddch(obj->posy+1,obj->posx*2,obj->image);
if (curkl->energy < 20000)
curkl->energy += 5000;
}
prob = 2; /* our work here is done */
}
else if (obj->image == 'B') {
btorp -= rand_mod(50);
if (btorp < 0)
btorp = 0;
obj->energy -= rand_mod(500);
if (obj->energy < 0)
obj->energy = 0;
prob = 10000; /* stay here */
}
else
prob = 10000;
}
else { /* it went away--go elsewhere */
prob = 4;
curkl->strategy = 0;
}
}
else if (lookimg(curkl->posy, curkl->posx, '@') ||
lookimg(curkl->posy, curkl->posx, 'B')) {
curkl->strategy = rand_mod(15)+5;
prob = 10000;
}
else
prob = 4;
}
else if (curkl->image == 'M') { /* Mudd wants to sit sometimes */
if ((obj = lookimg(curkl->posy, curkl->posx, 'E')) ||
(obj = lookimg(curkl->posy, curkl->posx, 'B')) ) {
if (obj->image == 'B') {
btorp -= rand_mod(40);
if (btorp < 0)
btorp = 0;
obj->energy -= rand_mod(100);
if (obj->energy < 0)
obj->energy = 0;
}
else if (!obj->vely && !obj->velx) {
etorp -= rand_mod(10);
if (etorp < 0)
etorp = 0;
obj->energy -= rand_mod(20);
if (obj->energy < 0)
obj->energy = 0;
}
prob = 10000; /* stay here */
}
else /* it went away--go elsewhere */
prob = 4;
}
else if (curkl->flags & FRIENDLY) {
if (curkl->energy < 10000 &&
lookimg(curkl->posy, curkl->posx, '@') ) {
curkl->energy += 100;
prob = 20; /* do some loading */
}
else
prob = 4;
}
else if (curkl->image == '&') {
if (curkl->flags & COUNTDOWN) {
if (curkl->strategy)
curkl->strategy--;
else
curkl->flags &= ~COUNTDOWN;
prob = 100; /* someone's feeding us, so sit still */
}
else
prob = 4;
}
else
prob = 4; /* don't sit still too long */
count = 11;
for (;;) {
if (--count <= 0) /* no opening, just ram something */
break;
#ifdef lint
prob = prob;
#endif
if (!(rand_mod(prob))) /* turn randomly occasionally */
goto accell;
y=(curkl->posy+curkl->vely+YSIZE00)%YSIZE; /* find prospective */
x=(curkl->posx+curkl->velx+XSIZE00)%XSIZE; /* new position */
if (numamoebas) {
if (curkl == nuke) {
if (amb[y][x] != '~')
goto accell; /* never move nucleus from protoplasm */
}
else {
if (amb[y][x] == '~' && rand_mod(2)) {
yamblast = y;
xamblast = x;
goto accell;
}
}
}
obj = occupant[y][x];
if (!obj) break; /* is anyone there? */
switch (obj->type) {
case Star:
if (obj->image == '@' && (curkl->flags & PIRATE)) {
if (curkl->image != 'P' && curkl->image != ' ') {
if (curkl->flags & FRIENDLY) {
curkl->flags &= ~FRIENDLY;
curkl->energy += 1000;
possiblescore += curkl->mass;
inumfriends--;
numfriends--;
inumenemies++;
numenemies++;
}
curkl->image = 'P';
}
break; /* go ahead and ram the star */
}
goto accell; /* try not to ram stars */
case Torp:
if (!obj->vely && !obj->velx && (rand_mod(100) <= smarts) &&
(obj->image == 'o' || obj->image == 'O' || obj->image == 'X'))
goto accell; /* try not to ram "friendly" torps */
break;
case Web:
if (curkl->image != 'T')
goto accell; /* non-Tholians shouldn't ram web */
if (count <= 5)
break; /* Tholians retrace web if desperate */
if (obj->image ==
(curkl->vely?
(curkl->velx?
(curkl->velx==curkl->vely?
'\\'
:
'/'
)
:
'|'
)
:
'-'
)
) goto accell; /* Tholians try not to retrace web */
break; /* No problem with crossing web */
}
break; /* okay to move over object */
accell:
/* determine maximum velocity */
if (massacre && curkl->image != 'T') {
curkl->vely = rand_mod(7) - 3;
curkl->velx = rand_mod(7) - 3;
}
else if (curkl->image == '&') {
if (rand_mod(2)) {
curkl->vely = rand_mod(3) - 1;
curkl->velx = rand_mod(3) - 1;
}
else {
curkl->vely = curkl->strategy & 3;
if (curkl->vely & 2)
curkl->vely = -1;
curkl->velx = (curkl->strategy >> 2) & 3;
if (curkl->velx & 2)
curkl->velx = -1;
}
}
else if (curkl->energy >= 2500 && curkl->image != 'T') {
curkl->vely = rand_mod(5) - 2;
curkl->velx = rand_mod(5) - 2;
}
else {
curkl->vely = rand_mod(3) - 1;
curkl->velx = rand_mod(3) - 1;
}
}
if (count != 10) {
if (curkl->image == ' ') {
setimage(curkl, curkl->flags & PIRATE ? 'P' : 'R');
}
if (!count) {
curkl->vely = 0;
curkl->velx = 0;
}
}
if (curkl->image == 'G' && (base||ent) &&
!rand_mod((103-smarts)*10) ) {
int xxx,yyy;
for (xxx = -1; xxx<=1; xxx++)
for (yyy = -1; yyy<=1; yyy++)
if ((xxx||yyy) && rand_mod(2))
fire_torp(curkl,yyy,xxx);
}
else if (curkl->image == 'T' && (curkl->velx || curkl->vely)) {
make_object(Web,
curkl->vely?
(curkl->velx?
(curkl->velx==curkl->vely?
'\\'
:
'/'
)
:
'|'
)
:
'-',
curkl->posy,curkl->posx,0,0,32767L,32767L,&root);
if (obj && obj->type == Web) {
unmake_object(obj);
occupant[y][x] = NULL;
}
}
}
/* klingon-style fighting */
if (numamoebas)
attack(nuke);
attack(base);
if (ent && (!cloaked || ent->image=='E' || ent->image=='e'))
attack(ent);
}
void
modify_amoeba(int y, int x, int where, int ch, int quant)
{
int dy;
int dx;
int count = 15;
if (!numamoebas)
return;
if (!where || (where==1 && rand_mod(2))) {
y = nuke->posy;
x = nuke->posx;
}
if (nuke->strategy && rand_mod(3)) {
dy = nuke->strategy & 3;
if (dy & 2)
dy = -1;
dx = (nuke->strategy >> 2) & 3;
if (dx & 2)
dx = -1;
if (ch == ' ') { /* take from the tail */
dy = -dy;
dx = -dx;
}
if (!rand_mod(100))
nuke->strategy = rand_mod(256);
}
else {
dy = rand_mod(3) - 1;
dx = rand_mod(3) - 1;
}
if (!dy && !dx)
return;
do {
if (--count < 0)
return;
y = (y + dy + YSIZE00) % YSIZE;
x = (x + dx + XSIZE00) % XSIZE;
} while (amb[y][x] != ' ');
if (ch == ' ') {
y = (y - dy + YSIZE00) % YSIZE;
x = (x - dx + XSIZE00) % XSIZE;
}
if (ambsize > 100 && quant > 2) {
quant >>= (ambsize/100);
}
if ((nuke->energy += quant << 6) > 32767)
nuke->energy = 32767;
count = quant << 3; /* endless loop catcher */
while (count-- > 0 && quant > 0) {
if (amb[y][x] != ch) {
quant--;
amb[y][x] = ch;
if (ch == '~') {
ambsize++;
yblasted[y] |= 2;
xblasted[x] |= 2;
blasted = true;
}
else
ambsize--;
if (!occupant[y][x])
mvaddch(y+1,x*2,ch);
}
y = (y + rand_mod(3) + YSIZE99) % YSIZE;
x = (x + rand_mod(3) + XSIZE99) % XSIZE;
}
}