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