xref: /csrg-svn/games/trek/attack.c (revision 11657)
1*11657Smckusick #ifndef lint
2*11657Smckusick static char sccsid[] = "@(#)attack.c	4.1	(Berkeley)	03/23/83";
3*11657Smckusick #endif not lint
4*11657Smckusick 
5*11657Smckusick # include	"trek.h"
6*11657Smckusick 
7*11657Smckusick /*
8*11657Smckusick **  Klingon Attack Routine
9*11657Smckusick **
10*11657Smckusick **	This routine performs the Klingon attack provided that
11*11657Smckusick **	(1) Something happened this move (i.e., not free), and
12*11657Smckusick **	(2) You are not cloaked.  Note that if you issue the
13*11657Smckusick **	cloak command, you are not considered cloaked until you
14*11657Smckusick **	expend some time.
15*11657Smckusick **
16*11657Smckusick **	Klingons are permitted to move both before and after the
17*11657Smckusick **	attack.  They will tend to move toward you before the
18*11657Smckusick **	attack and away from you after the attack.
19*11657Smckusick **
20*11657Smckusick **	Under certain conditions you can get a critical hit.  This
21*11657Smckusick **	sort of hit damages devices.  The probability that a given
22*11657Smckusick **	device is damaged depends on the device.  Well protected
23*11657Smckusick **	devices (such as the computer, which is in the core of the
24*11657Smckusick **	ship and has considerable redundancy) almost never get
25*11657Smckusick **	damaged, whereas devices which are exposed (such as the
26*11657Smckusick **	warp engines) or which are particularly delicate (such as
27*11657Smckusick **	the transporter) have a much higher probability of being
28*11657Smckusick **	damaged.
29*11657Smckusick **
30*11657Smckusick **	The actual amount of damage (i.e., how long it takes to fix
31*11657Smckusick **	it) depends on the amount of the hit and the "damfac[]"
32*11657Smckusick **	entry for the particular device.
33*11657Smckusick **
34*11657Smckusick **	Casualties can also occur.
35*11657Smckusick */
36*11657Smckusick 
37*11657Smckusick attack(resting)
38*11657Smckusick int	resting;	/* set if attack while resting */
39*11657Smckusick {
40*11657Smckusick 	register int		hit, i, l;
41*11657Smckusick 	int			maxhit, tothit, shldabsb;
42*11657Smckusick 	double			chgfac, propor, extradm;
43*11657Smckusick 	double			dustfac, tothe;
44*11657Smckusick 	int			cas;
45*11657Smckusick 	int			hitflag;
46*11657Smckusick 
47*11657Smckusick 	if (Move.free)
48*11657Smckusick 		return;
49*11657Smckusick 	if (Etc.nkling <= 0 || Quad[Ship.quadx][Ship.quady].stars < 0)
50*11657Smckusick 		return;
51*11657Smckusick 	if (Ship.cloaked && Ship.cloakgood)
52*11657Smckusick 		return;
53*11657Smckusick 	/* move before attack */
54*11657Smckusick 	klmove(0);
55*11657Smckusick 	if (Ship.cond == DOCKED)
56*11657Smckusick 	{
57*11657Smckusick 		if (!resting)
58*11657Smckusick 			printf("Starbase shields protect the %s\n", Ship.shipname);
59*11657Smckusick 		return;
60*11657Smckusick 	}
61*11657Smckusick 	/* setup shield effectiveness */
62*11657Smckusick 	chgfac = 1.0;
63*11657Smckusick 	if (Move.shldchg)
64*11657Smckusick 		chgfac = 0.25 + 0.50 * franf();
65*11657Smckusick 	maxhit = tothit = 0;
66*11657Smckusick 	hitflag = 0;
67*11657Smckusick 
68*11657Smckusick 	/* let each Klingon do his damndest */
69*11657Smckusick 	for (i = 0; i < Etc.nkling; i++)
70*11657Smckusick 	{
71*11657Smckusick 		/* if he's low on power he won't attack */
72*11657Smckusick 		if (Etc.klingon[i].power < 20)
73*11657Smckusick 			continue;
74*11657Smckusick 		if (!hitflag)
75*11657Smckusick 		{
76*11657Smckusick 			printf("\nStardate %.2f: Klingon attack:\n",
77*11657Smckusick 				Now.date);
78*11657Smckusick 			hitflag++;
79*11657Smckusick 		}
80*11657Smckusick 		/* complete the hit */
81*11657Smckusick 		dustfac = 0.90 + 0.01 * franf();
82*11657Smckusick 		tothe = Etc.klingon[i].avgdist;
83*11657Smckusick 		hit = Etc.klingon[i].power * pow(dustfac, tothe) * Param.hitfac;
84*11657Smckusick 		/* deplete his energy */
85*11657Smckusick 		dustfac = Etc.klingon[i].power;
86*11657Smckusick 		Etc.klingon[i].power = dustfac * Param.phasfac * (1.0 + (franf() - 0.5) * 0.2);
87*11657Smckusick 		/* see how much of hit shields will absorb */
88*11657Smckusick 		shldabsb = 0;
89*11657Smckusick 		if (Ship.shldup || Move.shldchg)
90*11657Smckusick 		{
91*11657Smckusick 			propor = Ship.shield;
92*11657Smckusick 			propor =/ Param.shield;
93*11657Smckusick 			shldabsb = propor * chgfac * hit;
94*11657Smckusick 			if (shldabsb > Ship.shield)
95*11657Smckusick 				shldabsb = Ship.shield;
96*11657Smckusick 			Ship.shield =- shldabsb;
97*11657Smckusick 		}
98*11657Smckusick 		/* actually do the hit */
99*11657Smckusick 		printf("HIT: %d units", hit);
100*11657Smckusick 		if (!damaged(SRSCAN))
101*11657Smckusick 			printf(" from %d,%d", Etc.klingon[i].x, Etc.klingon[i].y);
102*11657Smckusick 		cas = (shldabsb * 100) / hit;
103*11657Smckusick 		hit =- shldabsb;
104*11657Smckusick 		if (shldabsb > 0)
105*11657Smckusick 			printf(", shields absorb %d%%, effective hit %d\n",
106*11657Smckusick 				cas, hit);
107*11657Smckusick 		else
108*11657Smckusick 			printf("\n");
109*11657Smckusick 		tothit =+ hit;
110*11657Smckusick 		if (hit > maxhit)
111*11657Smckusick 			maxhit = hit;
112*11657Smckusick 		Ship.energy =- hit;
113*11657Smckusick 		/* see if damages occurred */
114*11657Smckusick 		if (hit >= (15 - Game.skill) * (25 - ranf(12)))
115*11657Smckusick 		{
116*11657Smckusick 			printf("CRITICAL HIT!!!\n");
117*11657Smckusick 			/* select a device from probability vector */
118*11657Smckusick 			cas = ranf(1000);
119*11657Smckusick 			for (l = 0; cas >= 0; l++)
120*11657Smckusick 				cas =- Param.damprob[l];
121*11657Smckusick 			l =- 1;
122*11657Smckusick 			/* compute amount of damage */
123*11657Smckusick 			extradm = (hit * Param.damfac[l]) / (75 + ranf(25)) + 0.5;
124*11657Smckusick 			/* damage the device */
125*11657Smckusick 			damage(l, extradm);
126*11657Smckusick 			if (damaged(SHIELD))
127*11657Smckusick 			{
128*11657Smckusick 				if (Ship.shldup)
129*11657Smckusick 					printf("Sulu: Shields knocked down, captain.\n");
130*11657Smckusick 				Ship.shldup = 0;
131*11657Smckusick 				Move.shldchg = 0;
132*11657Smckusick 			}
133*11657Smckusick 		}
134*11657Smckusick 		if (Ship.energy <= 0)
135*11657Smckusick 			lose(L_DSTRYD);
136*11657Smckusick 	}
137*11657Smckusick 
138*11657Smckusick 	/* see what our casualities are like */
139*11657Smckusick 	if (maxhit >= 200 || tothit >= 500)
140*11657Smckusick 	{
141*11657Smckusick 		cas = tothit * 0.015 * franf();
142*11657Smckusick 		if (cas >= 2)
143*11657Smckusick 		{
144*11657Smckusick 			printf("McCoy: we suffered %d casualties in that attack.\n",
145*11657Smckusick 				cas);
146*11657Smckusick 			Game.deaths =+ cas;
147*11657Smckusick 			Ship.crew =- cas;
148*11657Smckusick 		}
149*11657Smckusick 	}
150*11657Smckusick 
151*11657Smckusick 	/* allow Klingons to move after attacking */
152*11657Smckusick 	klmove(1);
153*11657Smckusick 
154*11657Smckusick 	return;
155*11657Smckusick }
156