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