402 lines
9.5 KiB
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;
|
|
}
|
|
}
|