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