DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T e

⟦bfd742cb4⟧ TextFile

    Length: 13518 (0x34ce)
    Types: TextFile
    Names: »enemycom.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/Trek73/src/enemycom.c« 

TextFile

#ident "@(#) TREK73 $Header: enemycom.c,v 1.1 87/10/09 11:05:38 okamoto Exp $"
/*
 * $Source: /ccc/okamoto/src/trek/src/RCS/enemycom.c,v $
 *
 * $Header: enemycom.c,v 1.1 87/10/09 11:05:38 okamoto Exp $
 *
 * $Log:	enemycom.c,v $
 * Revision 1.1  87/10/09  11:05:38  11:05:38  okamoto (Jeff Okamoto)
 * Initial revision
 * 
 */
/*
 * TREK73: enemycom.c
 *
 * Enemy strategy sub-routines
 *
 * e_attack, e_checkarms, e_checkprobe, e_cloak_off, e_cloak_on,
 * e_closetorps, e_destruct, e_evade, e_jettison, e_launchprobe,
 * e_loadtubes, e_lockphasers, e_locktubes, e_phasers, e_pursue,
 * e_runaway, e_torpedo
 *
 */

#include "externs.h"


/*
 * This routine turns the ship at speed towards its target
 */
int
e_attack(sp, fed)
struct ship *sp;
struct ship *fed;
{
	float	speed;
	float	tmpf;

	tmpf = fabs(fed->warp);
	if (fabs(sp->warp) >= tmpf + 2.0 || (is_dead(sp, S_WARP)))
		return 0;
	if ((speed = tmpf + randm(2) + 2.0) > sp->max_speed)
		speed = sp->max_speed;
	(void) e_pursue(sp, fed, speed);
	if (cansee(sp) && syswork(fed, S_SENSOR))
		printf("%s:  %s attacking.\n", helmsman, sp->name);
	return 1;
}


/*
 * Returns the number of currently loaded, undamaged weapons
 */
int
e_checkarms(sp)
struct ship *sp;
{
	register int i;
	register int arms;

	arms = 0;
	for (i=0; i<sp->num_phasers; i++)
		if (!(sp->phasers[i].status & P_DAMAGED) &&
		    (sp->phasers[i].load >= 0))
			arms++;
	for (i=0; i<sp->num_tubes; i++)
		if (!(sp->tubes[i].status & T_DAMAGED) &&
		    (sp->tubes[i].load >= 0))
			arms++;
#ifdef TRACE
	if (trace)
		printf("*** Checkarms: Returning %d\n", arms);
#endif
	return arms;
}


/*
 * returns 1 if evasive action being taken (to avoid probe)
 */
int
e_checkprobe(sp)
struct ship *sp;
{
	register struct list *lp;
	register int range;
	register struct torpedo *tp;

	/*
	 * If we are cloaked, do not bother with this.
	 * Since probes cannot detect us when cloaked.
	 */
	if (cantsee(sp))
		return 0;
	for (lp = &head; lp != tail; lp = lp->fwd) {
		if (lp->type != I_PROBE)
			continue;
		tp = lp->data.tp;
		range = rangefind(sp->x, tp->x, sp->y, tp->y);
#ifdef TRACE
		if (trace)
			printf("*** Checkprobe: Range = %d\n", range);
#endif
		if (range < 2000) {
			(void) e_evade(sp, tp->x, tp->y, I_PROBE);
			return 1;
		}
	}
	return 0;
}


/*
 * Returns 1 if cloaking device was turned off
 */
int
e_cloak_off(sp, fed)
struct ship *sp;
struct ship *fed;
{
	if (sp->cloaking != C_ON)
		return 0;
	sp->cloaking = C_OFF;
	sp->cloak_delay = 4;
	if (syswork(sp, S_SENSOR)) {
		printf("%s:  The %s has reappeared on our sensors %d\n",
		    science, sp->name, rangefind(sp->x, sp->position.x,
		    sp->y, sp->position.y));
		puts("   megameters from its projected position.");
	}
	fed = fed;		/* LINT */
	return 1;
}


/*
 * Returns 1 if cloaking device was turned on
 */
int
e_cloak_on(sp, fed)
struct ship *sp;
struct ship *fed;
{
	if ((sp->cloak_delay > 0) || (sp->cloaking != C_OFF))
		return 0;
	sp->cloaking = C_ON;
	sp->position.x = sp->x;
	sp->position.y = sp->y;
	sp->position.warp = sp->warp;
	sp->position.course = sp->course;
	if (syswork(fed, S_SENSOR))
		printf("%s:  The %s has disappeared from our sensors.\n",
		    science, sp->name);
	fed = fed;		/* LINT */
	return 1;
}


/*
 * Returns 1 if firing phasers at or evading nearby torpedoes
 */
int
e_closetorps(sp, fed)
struct ship *sp;
struct ship *fed;
{
	register struct list *lp;
	register int range;
	register struct torpedo *tp;
	struct	torpedo *bad;

	/*
	 * If we are cloaked, forget about this.
	 * Since prox fuses won't affect us under cloak
	 */
	if (cantsee(sp))
		return 0;
	bad = NULL;
	for (lp = &head; lp != tail; lp = lp->fwd) {
		if (lp->type != I_TORPEDO)
			continue;
		tp = lp->data.tp;
		if (tp->from != fed)
			continue;
		range = rangefind(sp->x, tp->x, sp->y, tp->y);
#ifdef TRACE
		if (trace)
			printf("*** Checktorp: Range = %d\n", range);
#endif
		if (range < 1200) {
			bad = tp;
			/*
			 * fire phasers - hope they're pointing in
			 * the right direction!
			 */
			if (e_phasers(sp, (struct ship *) NULL))
				return 1;
		}
	}
	/*
	 * we can't get a phaser shot off.
	 * try and evade (although hopeless)
	 */
	if (bad != NULL) {
#ifdef TRACE
		if (trace)
			printf("*** Checktorp: Cannot fire phasers!  Evade!\n");
#endif
		(void) e_evade(sp, tp->x, tp->y, I_TORPEDO);
		return 1;
	}
	return 0;
}


/*
 * goodbye, cruel world (Returns 1 if self-destruct was initiated)
 */
int
e_destruct(sp, fed)
struct ship *sp, *fed;
{
	if (sp->delay < 5.0)
		return 0;
	sp->delay = 5.0;
	(void) e_cloak_off(sp, fed);
	sp->cloaking = C_NONE;
	if (syswork(fed, S_SENSOR)) {
		printf("%s: The %s is overloading what remains of it's\n",
		    science, sp->name);
		puts("   antimatter pods -- obviously a suicidal gesture.");
		puts("   Estimate detonation in five seconds.");
	}
	return 1;
}


/*
 * Advance to the rear! (Always returns 1)
 */
int
e_evade(sp, x, y, type)
struct ship *sp;
int x;
int y;
int type;		/* Currently unused */
{
	register float newcourse;
	float	bear;

	bear = bearing(sp->x, x, sp->y, y);
	if (cansee(sp) && syswork(shiplist[0], S_SENSOR))
		printf("%s taking evasive action!\n", sp->name);
	switch (randm(3)) {
		case 1:
			newcourse = rectify(bear - 90.0);
			break;
		case 2:
			newcourse = rectify(bear + 90.0);
			break;
		case 3:
			newcourse = rectify(bear + 180.0);
			break;
		default:
			printf("error in evade()\n");
			break;
	}
	sp->target = NULL;
	sp->newcourse = newcourse;
	sp->newwarp = 2 + randm((int)(sp->max_speed - 3));
	if (is_dead(sp, S_WARP))
		sp->newwarp = 1.0;
#ifdef TRACE
	if (trace) {
		printf("*** Evade: Newcourse = %3.0f\n", newcourse);
		printf("*** Evade: Newwarp = %.2f\n", sp->newwarp);
	}
#endif
	type = type;	/* LINT */
	return 1;
}


/*
 * Returns 1 if engineering was jettisoned
 */
int
e_jettison(sp, fed)
struct ship *sp, *fed;
{
	register struct list *lp;
	register struct torpedo *tp;

	if (is_dead(sp, S_ENG))
		return 0;
	(void) e_cloak_off(sp, fed);
	if (syswork(shiplist[0], S_SENSOR)) {
		printf("%s: Sensors indicate debris being left by\n", science);
		printf("   the %s.  Insufficient mass . . .\n", sp->name);
	}
	lp = newitem(I_ENG);
	tp = lp->data.tp = MKNODE(struct torpedo, *, 1);
	if (tp == (struct torpedo *)NULL) {
		fprintf(stderr, "e_jettison: malloc failed\n");
		exit(2);
	}
	tp->id = new_slot();
	/*
	 * ship slows to warp 1.0 when jettisonning engineering
	 */
	tp->newspeed = 0.0;
	tp->speed = sp->warp;
	tp->target = NULL;
	tp->course = sp->course;
	tp->x = sp->x;
	tp->y = sp->y;
	tp->prox = 0;
	tp->timedelay = 10.;
	tp->fuel = sp->energy;
	tp->type = TP_ENGINEERING;
	sp->energy = sp->pods = 0;
	sp->regen = 0.0;
	tp->from = sp;
	if (sp->newwarp < -1.0)
		sp->newwarp = -0.99;
	if (sp->newwarp > 1.0)
		sp->newwarp = 0.99;
	sp->max_speed = 1.0;
	sp->status[S_ENG] = 100;	/* List as destroyed */
	sp->status[S_WARP] = 100;
	sp->cloaking = C_NONE;
	sp->t_blind_left = sp->t_blind_right = sp->p_blind_left =
	    sp->p_blind_right = 180;
	return 1;
}


/*
 * Returns 1 if a probe was launched
 */
int
e_launchprobe(sp, fed)
struct ship *sp;
struct ship *fed;
{
	register int i;
	register struct list *lp;
	register struct torpedo *tp;

	if (!syswork(sp, S_PROBE) || sp->energy <= 10 || cantsee(sp))
		return 0;
	/*
	 * fed ship has to be going slow before we'll launch
	 * a probe at it.
	 */
	if (fabs(fed->warp) > 1.0)
		return 0;
	lp = newitem(I_PROBE);
	tp = lp->data.tp = MKNODE(struct torpedo, *, 1);
	if (tp == (struct torpedo *)NULL) {
		fprintf(stderr, "e_launchprobe: malloc failed\n");
		exit(2);
	}
	tp->from = sp;
	tp->speed = sp->warp;
	tp->newspeed = 3.0;
	tp->target = fed;
	tp->course = bearing(sp->x, fed->x, sp->y, fed->y);
	tp->x = sp->x;
	tp->y = sp->y;
	tp->prox = 200 + randm(200);
	tp->timedelay = 15.;
	tp->id = new_slot();
	if ((i = randm(15) + 10) > sp->energy)
		i = sp->energy;
	tp->fuel = i;
	tp->type = TP_PROBE;
	sp->energy -= i;
	sp->pods -= i;
	printf("%s launching probe #%d\n", sp->name, tp->id);
	return 1;
}


/*
 * Returns the number of tubes that were loaded
 */
int
e_loadtubes(sp)
struct ship *sp;
{
	register int i;
	register int j;
	register int loaded;
	register int below;

	below = 10;
	loaded = 0;
	for (i=0; i<sp->num_tubes; i++) {
		if (sp->energy <= below)
			break;
		if (sp->tubes[i].status & T_DAMAGED)
			continue;
		j = min(sp->energy, 10 - sp->tubes[i].load);
		if (j == 0)
			continue;
		sp->energy -= j;
		sp->pods -= j;
		sp->tubes[i].load += j;
		loaded++;
	}
#ifdef TRACE
	if (trace)
		printf("*** Load tubes: Loaded %d tubes\n", loaded);
#endif
	return loaded;
}


/*
 * Returns the number of phasers that were locked
 */
int
e_lockphasers(sp, fed)
struct ship *sp;
struct ship *fed;
{
	register int i;
	register int banks;

	banks = 0;
	for (i=0; i<sp->num_phasers; i++) {
		if (sp->phasers[i].status & P_DAMAGED)
			continue;
		if (sp->phasers[i].target != NULL)
			continue;
		sp->phasers[i].target = fed;
		banks++;
	}
#ifdef TRACE
	if (trace)
		printf("*** Lock phasers: Locked %d phasers\n", banks);
#endif
	return banks;
}


/*
 * Returns number of tubes locked
 */
int
e_locktubes(sp, fed)
struct ship *sp;
struct ship *fed;
{
	register int i;
	register int tubes;

	tubes = 0;
	for (i=0; i<sp->num_tubes; i++) {
		if (sp->tubes[i].status & T_DAMAGED)
			continue;
		if (sp->tubes[i].target != NULL)
			continue;
		sp->tubes[i].target = fed;
		tubes++;
	}
#ifdef TRACE
	if (trace)
		printf("*** Lock tubes: Locked %d tubes\n", tubes);
#endif
	return tubes;
}


/*
 * returns the number of banks we're going to fire
 * it also sets them up to fire.
 */
int
e_phasers(sp, fed)
struct ship *sp;
struct ship *fed;
{
	register int i;
	register int banks;
	register int hit;
	register int howmany;
	float bear;

	banks = 0;
	howmany = randm(sp->num_phasers / 2) + sp->num_phasers / 2;
	sp->p_spread = 10 + randm(12);
	for (i=0; i<sp->num_phasers; i++) {
		if ((sp->phasers[i].status & P_DAMAGED) ||
		    (sp->phasers[i].load == 0))
			continue;
		if (fed != NULL) {
			if (sp->phasers[i].target == NULL)
				continue;
			bear = bearing(sp->x, fed->x, sp->y, fed->y);
			hit = phaser_hit(sp, fed->x, fed->y, &sp->phasers[i], bear);
			if (hit <= 0)
				continue;
		}
		banks++;
		sp->phasers[i].status |= P_FIRING;
		if (banks >= howmany)
			break;
	}
	return banks;
}


/*
 * This routine will turn the ship, slowing down if necessary to
 * facilitate the turn.  (Always returns 1)
 */
int
e_pursue(sp, fed, speed)
struct ship *sp;
struct ship *fed;
float speed;
{
	float	bear;
	float	coursediff;

	bear = bearing(sp->x, fed->x, sp->y, fed->y);
	/*
	 * do a quick turn if our speed is > max_warp - 2 and
	 * (thus) we are never going to bear on the fed ship
	 * speed = max_warp / 2 is a magic cookie.  Feel free to change.
	 */
	coursediff = rectify(sp->course - bear);
	if (coursediff > 180.0)
		coursediff -= 360.0;
	if (speed >= sp->max_speed - 2 && fabs(coursediff) > 10)
		speed = (int)(sp->max_speed / 2);
	sp->target = fed;
	sp->newcourse = bear;
	sp->newwarp = speed;
	if (speed > 1 && is_dead(sp, S_WARP))
		sp->newwarp = 0.99;
#ifdef TRACE
	if (trace) {
		printf("*** Pursue: Newcourse = %.2f\n", sp->newcourse);
		printf("*** Pursue: Newwarp = %.2f\n", sp->newwarp);
	}
#endif
	return 1;
}


/*
 * This routine has the enemy ship turn its strongest shield towards
 * the enemy and then accelerate to 2/3 maximum speed.  (Always
 * returns 1)
 */
int
e_runaway(sp, fed)
struct ship *sp;
struct ship *fed;
{
	register double bear;
	register int strong;
	register double strength;
	register double temp;
	register int sign;
	register float course;
	register int i;

	bear = bearing(sp->x, fed->x, sp->y, fed->y);
	/*
	 * Find the strongest shield
	 */
	strong = 0;
	strength = 0.;
	for (i=0; i< SHIELDS; i++) {
		temp = sp->shields[i].eff * sp->shields[i].drain *
		    (i == 0 ? SHIELD1 : 1.);
		if (temp > strength) {
			strong = i;
			strength = temp;
		}
	}
	switch (strong) {
		case 0:	course = bear;
			sign = -1;
			break;
		case 1:	course = rectify(bear - 90);
			sign = 1;
			break;
		case 2:	course = rectify(bear + 180);
			sign = 1;
			break;
		case 3:	course = rectify(bear + 90);
			sign = 1;
			break;
	}
	sp->target = NULL;
	sp->newcourse = course;
	sp->newwarp = 2 / 3 * sp->max_speed * sign;
	if (sp->newwarp > 1.0 && is_dead(sp, S_WARP))
		sp->newwarp = 0.99;
	if (cansee(sp) && syswork(fed, S_SENSOR))
		printf("%s: The %s is retreating.\n", helmsman, sp->name);
#ifdef TRACE
	if (trace) {
		printf("*** Runaway: Newcourse = %.2f\n", sp->newcourse);
		printf("*** Runaway: Newwarp = %.2f\n", sp->newwarp);
	}
#endif
	return 1;
}


/*
 * Returns the number of tubes we're going to fire
 * Also sets them up to fire
 */
int
e_torpedo(sp)
struct ship *sp;
{
	register int i;
	register int tubes;
	register int howmany;
	register struct ship *sp1;
	register int range;

	/*
	 * don't shoot if someone might be in the way
	 * (i.e. proximity fuse will go off right as the
	 * torps leave the tubes!)
	 */
	for (i=1; i <= shipnum; i++) {
		sp1 = shiplist[i];
		/* This must check for dead ships too! */
		if (sp1 == sp)
			continue;
		range = rangefind(sp->x, sp1->x, sp->y, sp1->y);
		if (range <= 400)
			return 0;
	}
	tubes = 0;
	/* This is not and should not be dependent on the
	   number of tubes one has */
	howmany = randm(2) + 1;		
	for (i=0; i<sp->num_tubes; i++) {
		if ((sp->tubes[i].status & T_DAMAGED)
		    || (sp->tubes[i].load == 0))
			continue;
		if (sp->tubes[i].target == NULL)
			continue;
		tubes++;
		sp->tubes[i].status |= T_FIRING;
		if (tubes >= howmany)
			break;
	}
	return tubes;
}