xref: /csrg-svn/games/trek/attack.c (revision 60857)
121264Sdist /*
2*60857Sbostic  * Copyright (c) 1980, 1993
3*60857Sbostic  *	The Regents of the University of California.  All rights reserved.
434205Sbostic  *
542605Sbostic  * %sccs.include.redist.c%
621264Sdist  */
721264Sdist 
811657Smckusick #ifndef lint
9*60857Sbostic static char sccsid[] = "@(#)attack.c	8.1 (Berkeley) 05/31/93";
1034205Sbostic #endif /* not lint */
1111657Smckusick 
1211657Smckusick # include	"trek.h"
1311657Smckusick 
1411657Smckusick /*
1511657Smckusick **  Klingon Attack Routine
1611657Smckusick **
1711657Smckusick **	This routine performs the Klingon attack provided that
1811657Smckusick **	(1) Something happened this move (i.e., not free), and
1911657Smckusick **	(2) You are not cloaked.  Note that if you issue the
2011657Smckusick **	cloak command, you are not considered cloaked until you
2111657Smckusick **	expend some time.
2211657Smckusick **
2311657Smckusick **	Klingons are permitted to move both before and after the
2411657Smckusick **	attack.  They will tend to move toward you before the
2511657Smckusick **	attack and away from you after the attack.
2611657Smckusick **
2711657Smckusick **	Under certain conditions you can get a critical hit.  This
2811657Smckusick **	sort of hit damages devices.  The probability that a given
2911657Smckusick **	device is damaged depends on the device.  Well protected
3011657Smckusick **	devices (such as the computer, which is in the core of the
3111657Smckusick **	ship and has considerable redundancy) almost never get
3211657Smckusick **	damaged, whereas devices which are exposed (such as the
3311657Smckusick **	warp engines) or which are particularly delicate (such as
3411657Smckusick **	the transporter) have a much higher probability of being
3511657Smckusick **	damaged.
3611657Smckusick **
3711657Smckusick **	The actual amount of damage (i.e., how long it takes to fix
3811657Smckusick **	it) depends on the amount of the hit and the "damfac[]"
3911657Smckusick **	entry for the particular device.
4011657Smckusick **
4111657Smckusick **	Casualties can also occur.
4211657Smckusick */
4311657Smckusick 
attack(resting)4411657Smckusick attack(resting)
4511657Smckusick int	resting;	/* set if attack while resting */
4611657Smckusick {
4711657Smckusick 	register int		hit, i, l;
4811657Smckusick 	int			maxhit, tothit, shldabsb;
4911657Smckusick 	double			chgfac, propor, extradm;
5011657Smckusick 	double			dustfac, tothe;
5111657Smckusick 	int			cas;
5211657Smckusick 	int			hitflag;
5311657Smckusick 
5411657Smckusick 	if (Move.free)
5511657Smckusick 		return;
5611657Smckusick 	if (Etc.nkling <= 0 || Quad[Ship.quadx][Ship.quady].stars < 0)
5711657Smckusick 		return;
5811657Smckusick 	if (Ship.cloaked && Ship.cloakgood)
5911657Smckusick 		return;
6011657Smckusick 	/* move before attack */
6111657Smckusick 	klmove(0);
6211657Smckusick 	if (Ship.cond == DOCKED)
6311657Smckusick 	{
6411657Smckusick 		if (!resting)
6511657Smckusick 			printf("Starbase shields protect the %s\n", Ship.shipname);
6611657Smckusick 		return;
6711657Smckusick 	}
6811657Smckusick 	/* setup shield effectiveness */
6911657Smckusick 	chgfac = 1.0;
7011657Smckusick 	if (Move.shldchg)
7111657Smckusick 		chgfac = 0.25 + 0.50 * franf();
7211657Smckusick 	maxhit = tothit = 0;
7311657Smckusick 	hitflag = 0;
7411657Smckusick 
7511657Smckusick 	/* let each Klingon do his damndest */
7611657Smckusick 	for (i = 0; i < Etc.nkling; i++)
7711657Smckusick 	{
7811657Smckusick 		/* if he's low on power he won't attack */
7911657Smckusick 		if (Etc.klingon[i].power < 20)
8011657Smckusick 			continue;
8111657Smckusick 		if (!hitflag)
8211657Smckusick 		{
8311657Smckusick 			printf("\nStardate %.2f: Klingon attack:\n",
8411657Smckusick 				Now.date);
8511657Smckusick 			hitflag++;
8611657Smckusick 		}
8711657Smckusick 		/* complete the hit */
8811657Smckusick 		dustfac = 0.90 + 0.01 * franf();
8911657Smckusick 		tothe = Etc.klingon[i].avgdist;
9011657Smckusick 		hit = Etc.klingon[i].power * pow(dustfac, tothe) * Param.hitfac;
9111657Smckusick 		/* deplete his energy */
9211657Smckusick 		dustfac = Etc.klingon[i].power;
9311657Smckusick 		Etc.klingon[i].power = dustfac * Param.phasfac * (1.0 + (franf() - 0.5) * 0.2);
9411657Smckusick 		/* see how much of hit shields will absorb */
9511657Smckusick 		shldabsb = 0;
9611657Smckusick 		if (Ship.shldup || Move.shldchg)
9711657Smckusick 		{
9811657Smckusick 			propor = Ship.shield;
9912343Slayer 			propor /= Param.shield;
10011657Smckusick 			shldabsb = propor * chgfac * hit;
10111657Smckusick 			if (shldabsb > Ship.shield)
10211657Smckusick 				shldabsb = Ship.shield;
10312343Slayer 			Ship.shield -= shldabsb;
10411657Smckusick 		}
10511657Smckusick 		/* actually do the hit */
10611657Smckusick 		printf("HIT: %d units", hit);
10711657Smckusick 		if (!damaged(SRSCAN))
10811657Smckusick 			printf(" from %d,%d", Etc.klingon[i].x, Etc.klingon[i].y);
10911657Smckusick 		cas = (shldabsb * 100) / hit;
11012343Slayer 		hit -= shldabsb;
11111657Smckusick 		if (shldabsb > 0)
11211657Smckusick 			printf(", shields absorb %d%%, effective hit %d\n",
11311657Smckusick 				cas, hit);
11411657Smckusick 		else
11511657Smckusick 			printf("\n");
11612343Slayer 		tothit += hit;
11711657Smckusick 		if (hit > maxhit)
11811657Smckusick 			maxhit = hit;
11912343Slayer 		Ship.energy -= hit;
12011657Smckusick 		/* see if damages occurred */
12111657Smckusick 		if (hit >= (15 - Game.skill) * (25 - ranf(12)))
12211657Smckusick 		{
12311657Smckusick 			printf("CRITICAL HIT!!!\n");
12411657Smckusick 			/* select a device from probability vector */
12511657Smckusick 			cas = ranf(1000);
12611657Smckusick 			for (l = 0; cas >= 0; l++)
12712343Slayer 				cas -= Param.damprob[l];
12812343Slayer 			l -= 1;
12911657Smckusick 			/* compute amount of damage */
13011657Smckusick 			extradm = (hit * Param.damfac[l]) / (75 + ranf(25)) + 0.5;
13111657Smckusick 			/* damage the device */
13211657Smckusick 			damage(l, extradm);
13311657Smckusick 			if (damaged(SHIELD))
13411657Smckusick 			{
13511657Smckusick 				if (Ship.shldup)
13611657Smckusick 					printf("Sulu: Shields knocked down, captain.\n");
13711657Smckusick 				Ship.shldup = 0;
13811657Smckusick 				Move.shldchg = 0;
13911657Smckusick 			}
14011657Smckusick 		}
14111657Smckusick 		if (Ship.energy <= 0)
14211657Smckusick 			lose(L_DSTRYD);
14311657Smckusick 	}
14411657Smckusick 
14511657Smckusick 	/* see what our casualities are like */
14611657Smckusick 	if (maxhit >= 200 || tothit >= 500)
14711657Smckusick 	{
14811657Smckusick 		cas = tothit * 0.015 * franf();
14911657Smckusick 		if (cas >= 2)
15011657Smckusick 		{
15111657Smckusick 			printf("McCoy: we suffered %d casualties in that attack.\n",
15211657Smckusick 				cas);
15312343Slayer 			Game.deaths += cas;
15412343Slayer 			Ship.crew -= cas;
15511657Smckusick 		}
15611657Smckusick 	}
15711657Smckusick 
15811657Smckusick 	/* allow Klingons to move after attacking */
15911657Smckusick 	klmove(1);
16011657Smckusick 
16111657Smckusick 	return;
16211657Smckusick }
163