Merge branch 'vendor/DHCPCD'
[dragonfly.git] / games / trek / attack.c
1 /*      @(#)attack.c    8.1 (Berkeley) 5/31/93                          */
2 /*      $NetBSD: attack.c,v 1.9 2009/05/24 22:55:03 dholland Exp $      */
3
4 /*
5  * Copyright (c) 1980, 1993
6  *      The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 #include <stdio.h>
34 #include <math.h>
35 #include "trek.h"
36
37 /*
38 **  Klingon Attack Routine
39 **
40 **      This routine performs the Klingon attack provided that
41 **      (1) Something happened this move (i.e., not free), and
42 **      (2) You are not cloaked.  Note that if you issue the
43 **      cloak command, you are not considered cloaked until you
44 **      expend some time.
45 **
46 **      Klingons are permitted to move both before and after the
47 **      attack.  They will tend to move toward you before the
48 **      attack and away from you after the attack.
49 **
50 **      Under certain conditions you can get a critical hit.  This
51 **      sort of hit damages devices.  The probability that a given
52 **      device is damaged depends on the device.  Well protected
53 **      devices (such as the computer, which is in the core of the
54 **      ship and has considerable redundancy) almost never get
55 **      damaged, whereas devices which are exposed (such as the
56 **      warp engines) or which are particularly delicate (such as
57 **      the transporter) have a much higher probability of being
58 **      damaged.
59 **
60 **      The actual amount of damage (i.e., how long it takes to fix
61 **      it) depends on the amount of the hit and the "damfac[]"
62 **      entry for the particular device.
63 **
64 **      Casualties can also occur.
65 **
66 **  resting -- set if attack while resting
67 */
68
69 void
70 attack(int resting)
71 {
72         int             hit, i, l;
73         int             maxhit, tothit, shldabsb;
74         double          chgfac, propor, extradm;
75         double          dustfac, tothe;
76         int             cas;
77         int             hitflag;
78
79         if (Move.free)
80                 return;
81         if (Etc.nkling <= 0 || Quad[Ship.quadx][Ship.quady].stars < 0)
82                 return;
83         if (Ship.cloaked && Ship.cloakgood)
84                 return;
85         /* move before attack */
86         klmove(0);
87         if (Ship.cond == DOCKED) {
88                 if (!resting)
89                         printf("Starbase shields protect the %s\n",
90                                 Ship.shipname);
91                 return;
92         }
93         /* setup shield effectiveness */
94         chgfac = 1.0;
95         if (Move.shldchg)
96                 chgfac = 0.25 + 0.50 * franf();
97         maxhit = tothit = 0;
98         hitflag = 0;
99
100         /* let each Klingon do his damndest */
101         for (i = 0; i < Etc.nkling; i++) {
102                 /* if he's low on power he won't attack */
103                 if (Etc.klingon[i].power < 20)
104                         continue;
105                 if (!hitflag) {
106                         printf("\nStardate %.2f: Klingon attack:\n",
107                                 Now.date);
108                         hitflag++;
109                 }
110                 /* complete the hit */
111                 dustfac = 0.90 + 0.01 * franf();
112                 tothe = Etc.klingon[i].avgdist;
113                 hit = Etc.klingon[i].power * pow(dustfac, tothe) * Param.hitfac;
114                 /* deplete his energy */
115                 dustfac = Etc.klingon[i].power;
116                 Etc.klingon[i].power = dustfac * Param.phasfac *
117                         (1.0 + (franf() - 0.5) * 0.2);
118                 /* see how much of hit shields will absorb */
119                 shldabsb = 0;
120                 if (Ship.shldup || Move.shldchg) {
121                         propor = Ship.shield;
122                         propor /= Param.shield;
123                         shldabsb = propor * chgfac * hit;
124                         if (shldabsb > Ship.shield)
125                                 shldabsb = Ship.shield;
126                         Ship.shield -= shldabsb;
127                 }
128                 /* actually do the hit */
129                 printf("\aHIT: %d units", hit);
130                 if (!damaged(SRSCAN))
131                         printf(" from %d,%d",
132                                 Etc.klingon[i].x, Etc.klingon[i].y);
133                 cas = (shldabsb * 100) / hit;
134                 hit -= shldabsb;
135                 if (shldabsb > 0)
136                         printf(", shields absorb %d%%, effective hit %d\n",
137                                 cas, hit);
138                 else
139                         printf("\n");
140                 tothit += hit;
141                 if (hit > maxhit)
142                         maxhit = hit;
143                 Ship.energy -= hit;
144                 /* see if damages occurred */
145                 if (hit >= (15 - Game.skill) * (25 - ranf(12))) {
146                         printf("\aCRITICAL HIT!!!\a\n");
147                         /* select a device from probability vector */
148                         cas = ranf(1000);
149                         for (l = 0; cas >= 0; l++)
150                                 cas -= Param.damprob[l];
151                         l -= 1;
152                         /* compute amount of damage */
153                         extradm = (hit * Param.damfac[l]) /
154                                 (75 + ranf(25)) + 0.5;
155                         /* damage the device */
156                         damage(l, extradm);
157                         if (damaged(SHIELD)) {
158                                 if (Ship.shldup)
159                                         printf("Sulu: Shields knocked down, "
160                                                "captain.\n");
161                                 Ship.shldup = 0;
162                                 Move.shldchg = 0;
163                         }
164                 }
165                 if (Ship.energy <= 0)
166                         lose(L_DSTRYD);
167         }
168
169         /* see what our casualities are like */
170         if (maxhit >= 200 || tothit >= 500) {
171                 cas = tothit * 0.015 * franf();
172                 if (cas >= 2) {
173                         printf("McCoy: we suffered %d casualties in that "
174                                "attack.\n",
175                                 cas);
176                         Game.deaths += cas;
177                         Ship.crew -= cas;
178                 }
179         }
180
181         /* allow Klingons to move after attacking */
182         klmove(1);
183
184         return;
185 }