1*25995Smckusick /* 2*25995Smckusick * Copyright (c) 1980 Regents of the University of California. 3*25995Smckusick * All rights reserved. The Berkeley software License Agreement 4*25995Smckusick * specifies the terms and conditions for redistribution. 5*25995Smckusick */ 6*25995Smckusick 711701Smckusick #ifndef lint 8*25995Smckusick static char sccsid[] = "@(#)torped.c 5.1 (Berkeley) 01/29/86"; 911701Smckusick #endif not lint 1011701Smckusick 1112738Slayer # include <stdio.h> 1211701Smckusick # include "trek.h" 1311701Smckusick 1411701Smckusick /* 1511701Smckusick ** PHOTON TORPEDO CONTROL 1611701Smckusick ** 1711701Smckusick ** Either one or three photon torpedoes are fired. If three 1811701Smckusick ** are fired, it is called a "burst" and you also specify 1911701Smckusick ** a spread angle. 2011701Smckusick ** 2111701Smckusick ** Torpedoes are never 100% accurate. There is always a random 2211701Smckusick ** cludge factor in their course which is increased if you have 2311701Smckusick ** your shields up. Hence, you will find that they are more 2411701Smckusick ** accurate at close range. However, they have the advantage that 2511701Smckusick ** at long range they don't lose any of their power as phasers 2611701Smckusick ** do, i.e., a hit is a hit is a hit, by any other name. 2711701Smckusick ** 2811701Smckusick ** When the course spreads too much, you get a misfire, and the 2911701Smckusick ** course is randomized even more. You also have the chance that 3011701Smckusick ** the misfire damages your torpedo tubes. 3111701Smckusick */ 3211701Smckusick 3311701Smckusick 3411701Smckusick torped() 3511701Smckusick { 3611701Smckusick register int ix, iy; 3711701Smckusick double x, y, dx, dy; 3811701Smckusick double angle; 3911701Smckusick int course, course2; 4011701Smckusick register int k; 4111701Smckusick double bigger; 4211701Smckusick double sectsize; 4311701Smckusick int burst; 4411701Smckusick int n; 4511701Smckusick 4611701Smckusick if (Ship.cloaked) 4711701Smckusick { 4811701Smckusick return (printf("Federation regulations do not permit attack while cloaked.\n")); 4911701Smckusick } 5011701Smckusick if (check_out(TORPED)) 5111701Smckusick return; 5211701Smckusick if (Ship.torped <= 0) 5311701Smckusick { 5411701Smckusick return (printf("All photon torpedos expended\n")); 5511701Smckusick } 5611701Smckusick 5711701Smckusick /* get the course */ 5811701Smckusick course = getintpar("Torpedo course"); 5911701Smckusick if (course < 0 || course > 360) 6011701Smckusick return; 6111701Smckusick burst = -1; 6211701Smckusick 6311701Smckusick /* need at least three torpedoes for a burst */ 6411701Smckusick if (Ship.torped < 3) 6511701Smckusick { 6611701Smckusick printf("No-burst mode selected\n"); 6711701Smckusick burst = 0; 6811701Smckusick } 6911701Smckusick else 7011701Smckusick { 7111701Smckusick /* see if the user wants one */ 7211701Smckusick if (!testnl()) 7311701Smckusick { 7412738Slayer k = ungetc(cgetc(0), stdin); 7511701Smckusick if (k >= '0' && k <= '9') 7611701Smckusick burst = 1; 7711701Smckusick } 7811701Smckusick } 7911701Smckusick if (burst < 0) 8011701Smckusick { 8111701Smckusick burst = getynpar("Do you want a burst"); 8211701Smckusick } 8311701Smckusick if (burst) 8411701Smckusick { 8511701Smckusick burst = getintpar("burst angle"); 8611701Smckusick if (burst <= 0) 8711701Smckusick return; 8811701Smckusick if (burst > 15) 8911701Smckusick return (printf("Maximum burst angle is 15 degrees\n")); 9011701Smckusick } 9111701Smckusick sectsize = NSECTS; 9211701Smckusick n = -1; 9311701Smckusick if (burst) 9411701Smckusick { 9511701Smckusick n = 1; 9612344Slayer course -= burst; 9711701Smckusick } 9811701Smckusick for (; n && n <= 3; n++) 9911701Smckusick { 10011701Smckusick /* select a nice random course */ 10111701Smckusick course2 = course + randcourse(n); 10211701Smckusick angle = course2 * 0.0174532925; /* convert to radians */ 10311701Smckusick dx = -cos(angle); 10411701Smckusick dy = sin(angle); 10511701Smckusick bigger = fabs(dx); 10611701Smckusick x = fabs(dy); 10711701Smckusick if (x > bigger) 10811701Smckusick bigger = x; 10912344Slayer dx /= bigger; 11012344Slayer dy /= bigger; 11111701Smckusick x = Ship.sectx + 0.5; 11211701Smckusick y = Ship.secty + 0.5; 11311701Smckusick if (Ship.cond != DOCKED) 11412344Slayer Ship.torped -= 1; 11511701Smckusick printf("Torpedo track"); 11611701Smckusick if (n > 0) 11711701Smckusick printf(", torpedo number %d", n); 11811701Smckusick printf(":\n%6.1f\t%4.1f\n", x, y); 11911701Smckusick while (1) 12011701Smckusick { 12112344Slayer ix = x += dx; 12212344Slayer iy = y += dy; 12311701Smckusick if (x < 0.0 || x >= sectsize || y < 0.0 || y >= sectsize) 12411701Smckusick { 12511701Smckusick printf("Torpedo missed\n"); 12611701Smckusick break; 12711701Smckusick } 12811701Smckusick printf("%6.1f\t%4.1f\n", x, y); 12911701Smckusick switch (Sect[ix][iy]) 13011701Smckusick { 13111701Smckusick case EMPTY: 13211701Smckusick continue; 13311701Smckusick 13411701Smckusick case HOLE: 13511701Smckusick printf("Torpedo disappears into a black hole\n"); 13611701Smckusick break; 13711701Smckusick 13811701Smckusick case KLINGON: 13911701Smckusick for (k = 0; k < Etc.nkling; k++) 14011701Smckusick { 14111701Smckusick if (Etc.klingon[k].x != ix || Etc.klingon[k].y != iy) 14211701Smckusick continue; 14312344Slayer Etc.klingon[k].power -= 500 + ranf(501); 14411701Smckusick if (Etc.klingon[k].power > 0) 14511701Smckusick { 14611701Smckusick printf("*** Hit on Klingon at %d,%d: extensive damages\n", 14711701Smckusick ix, iy); 14811701Smckusick break; 14911701Smckusick } 15011701Smckusick killk(ix, iy); 15111701Smckusick break; 15211701Smckusick } 15311701Smckusick break; 15411701Smckusick 15511701Smckusick case STAR: 15611701Smckusick nova(ix, iy); 15711701Smckusick break; 15811701Smckusick 15911701Smckusick case INHABIT: 16011701Smckusick kills(ix, iy, -1); 16111701Smckusick break; 16211701Smckusick 16311701Smckusick case BASE: 16411701Smckusick killb(Ship.quadx, Ship.quady); 16512344Slayer Game.killb += 1; 16611701Smckusick break; 16711701Smckusick default: 16811701Smckusick printf("Unknown object %c at %d,%d destroyed\n", 16911701Smckusick Sect[ix][iy], ix, iy); 17011701Smckusick Sect[ix][iy] = EMPTY; 17111701Smckusick break; 17211701Smckusick } 17311701Smckusick break; 17411701Smckusick } 17511701Smckusick if (damaged(TORPED) || Quad[Ship.quadx][Ship.quady].stars < 0) 17611701Smckusick break; 17712344Slayer course += burst; 17811701Smckusick } 17911701Smckusick Move.free = 0; 18011701Smckusick } 18111701Smckusick 18211701Smckusick 18311701Smckusick /* 18411701Smckusick ** RANDOMIZE COURSE 18511701Smckusick ** 18611701Smckusick ** This routine randomizes the course for torpedo number 'n'. 18711701Smckusick ** Other things handled by this routine are misfires, damages 18811701Smckusick ** to the tubes, etc. 18911701Smckusick */ 19011701Smckusick 19111701Smckusick randcourse(n) 19211701Smckusick int n; 19311701Smckusick { 19411701Smckusick double r; 19511701Smckusick register int d; 19611701Smckusick 19711701Smckusick d = ((franf() + franf()) - 1.0) * 20; 19811701Smckusick if (abs(d) > 12) 19911701Smckusick { 20011701Smckusick printf("Photon tubes misfire"); 20111701Smckusick if (n < 0) 20211701Smckusick printf("\n"); 20311701Smckusick else 20411701Smckusick printf(" on torpedo %d\n", n); 20511701Smckusick if (ranf(2)) 20611701Smckusick { 20711701Smckusick damage(TORPED, 0.2 * abs(d) * (franf() + 1.0)); 20811701Smckusick } 20912344Slayer d *= 1.0 + 2.0 * franf(); 21011701Smckusick } 21111701Smckusick if (Ship.shldup || Ship.cond == DOCKED) 21211701Smckusick { 21311701Smckusick r = Ship.shield; 21411701Smckusick r = 1.0 + r / Param.shield; 21511701Smckusick if (Ship.cond == DOCKED) 21611701Smckusick r = 2.0; 21712344Slayer d *= r; 21811701Smckusick } 21911701Smckusick return (d); 22011701Smckusick } 221