121285Sdist /*
2*60857Sbostic * Copyright (c) 1980, 1993
3*60857Sbostic * The Regents of the University of California. All rights reserved.
434205Sbostic *
542606Sbostic * %sccs.include.redist.c%
621285Sdist */
721285Sdist
811684Smckusick #ifndef lint
9*60857Sbostic static char sccsid[] = "@(#)move.c 8.1 (Berkeley) 05/31/93";
1034205Sbostic #endif /* not lint */
1111684Smckusick
1211684Smckusick # include "trek.h"
1311684Smckusick
1411684Smckusick /*
1511684Smckusick ** Move Under Warp or Impulse Power
1611684Smckusick **
1711684Smckusick ** `Ramflag' is set if we are to be allowed to ram stars,
1811684Smckusick ** Klingons, etc. This is passed from warp(), which gets it from
1911684Smckusick ** either play() or ram(). Course is the course (0 -> 360) at
2011684Smckusick ** which we want to move. `Speed' is the speed we
2111684Smckusick ** want to go, and `time' is the expected time. It
2211684Smckusick ** can get cut short if a long range tractor beam is to occur. We
2311684Smckusick ** cut short the move so that the user doesn't get docked time and
2411684Smckusick ** energy for distance which he didn't travel.
2511684Smckusick **
2611684Smckusick ** We check the course through the current quadrant to see that he
2711684Smckusick ** doesn't run into anything. After that, though, space sort of
2811684Smckusick ** bends around him. Note that this puts us in the awkward posi-
2911684Smckusick ** tion of being able to be dropped into a sector which is com-
3011684Smckusick ** pletely surrounded by stars. Oh Well.
3111684Smckusick **
3211684Smckusick ** If the SINS (Space Inertial Navigation System) is out, we ran-
3311684Smckusick ** domize the course accordingly before ever starting to move.
3411684Smckusick ** We will still move in a straight line.
3511684Smckusick **
3611684Smckusick ** Note that if your computer is out, you ram things anyway. In
3711684Smckusick ** other words, if your computer and sins are both out, you're in
3811684Smckusick ** potentially very bad shape.
3911684Smckusick **
4011684Smckusick ** Klingons get a chance to zap you as you leave the quadrant.
4111684Smckusick ** By the way, they also try to follow you (heh heh).
4211684Smckusick **
4311684Smckusick ** Return value is the actual amount of time used.
4411684Smckusick **
4511684Smckusick **
4611684Smckusick ** Uses trace flag 4.
4711684Smckusick */
4811684Smckusick
move(ramflag,course,time,speed)4912738Slayer double move(ramflag, course, time, speed)
5011684Smckusick int ramflag;
5111684Smckusick int course;
5212738Slayer double time;
5312738Slayer double speed;
5411684Smckusick {
5511684Smckusick double angle;
5612738Slayer double x, y, dx, dy;
5711684Smckusick register int ix, iy;
5811684Smckusick double bigger;
5911684Smckusick int n;
6011684Smckusick register int i;
6112738Slayer double dist;
6212738Slayer double sectsize;
6311684Smckusick double xn;
6412738Slayer double evtime;
6511684Smckusick
6611684Smckusick # ifdef xTRACE
6711684Smckusick if (Trace)
6811684Smckusick printf("move: ramflag %d course %d time %.2f speed %.2f\n",
6911684Smckusick ramflag, course, time, speed);
7011684Smckusick # endif
7111684Smckusick sectsize = NSECTS;
7211684Smckusick /* initialize delta factors for move */
7311684Smckusick angle = course * 0.0174532925;
7411684Smckusick if (damaged(SINS))
7512344Slayer angle += Param.navigcrud[1] * (franf() - 0.5);
7611684Smckusick else
7711684Smckusick if (Ship.sinsbad)
7812344Slayer angle += Param.navigcrud[0] * (franf() - 0.5);
7911684Smckusick dx = -cos(angle);
8011684Smckusick dy = sin(angle);
8111684Smckusick bigger = fabs(dx);
8211684Smckusick dist = fabs(dy);
8311684Smckusick if (dist > bigger)
8411684Smckusick bigger = dist;
8512344Slayer dx /= bigger;
8612344Slayer dy /= bigger;
8711684Smckusick
8811684Smckusick /* check for long range tractor beams */
8911684Smckusick /**** TEMPORARY CODE == DEBUGGING ****/
9011684Smckusick evtime = Now.eventptr[E_LRTB]->date - Now.date;
9111684Smckusick # ifdef xTRACE
9211684Smckusick if (Trace)
9311684Smckusick printf("E.ep = %u, ->evcode = %d, ->date = %.2f, evtime = %.2f\n",
9411684Smckusick Now.eventptr[E_LRTB], Now.eventptr[E_LRTB]->evcode,
9511684Smckusick Now.eventptr[E_LRTB]->date, evtime);
9611684Smckusick # endif
9711684Smckusick if (time > evtime && Etc.nkling < 3)
9811684Smckusick {
9911684Smckusick /* then we got a LRTB */
10012344Slayer evtime += 0.005;
10111684Smckusick time = evtime;
10211684Smckusick }
10311684Smckusick else
10411684Smckusick evtime = -1.0e50;
10511684Smckusick dist = time * speed;
10611684Smckusick
10711684Smckusick /* move within quadrant */
10811684Smckusick Sect[Ship.sectx][Ship.secty] = EMPTY;
10911684Smckusick x = Ship.sectx + 0.5;
11011684Smckusick y = Ship.secty + 0.5;
11111684Smckusick xn = NSECTS * dist * bigger;
11211684Smckusick n = xn + 0.5;
11311684Smckusick # ifdef xTRACE
11411684Smckusick if (Trace)
11511684Smckusick printf("dx = %.2f, dy = %.2f, xn = %.2f, n = %d\n", dx, dy, xn, n);
11611684Smckusick # endif
11711684Smckusick Move.free = 0;
11811684Smckusick
11911684Smckusick for (i = 0; i < n; i++)
12011684Smckusick {
12112344Slayer ix = (x += dx);
12212344Slayer iy = (y += dy);
12311684Smckusick # ifdef xTRACE
12411684Smckusick if (Trace)
12511684Smckusick printf("ix = %d, x = %.2f, iy = %d, y = %.2f\n", ix, x, iy, y);
12611684Smckusick # endif
12711684Smckusick if (x < 0.0 || y < 0.0 || x >= sectsize || y >= sectsize)
12811684Smckusick {
12911684Smckusick /* enter new quadrant */
13011684Smckusick dx = Ship.quadx * NSECTS + Ship.sectx + dx * xn;
13111684Smckusick dy = Ship.quady * NSECTS + Ship.secty + dy * xn;
13211684Smckusick if (dx < 0.0)
13311684Smckusick ix = -1;
13411684Smckusick else
13511684Smckusick ix = dx + 0.5;
13611684Smckusick if (dy < 0.0)
13711684Smckusick iy = -1;
13811684Smckusick else
13911684Smckusick iy = dy + 0.5;
14011684Smckusick # ifdef xTRACE
14111684Smckusick if (Trace)
14211684Smckusick printf("New quad: ix = %d, iy = %d\n", ix, iy);
14311684Smckusick # endif
14411684Smckusick Ship.sectx = x;
14511684Smckusick Ship.secty = y;
14611684Smckusick compkldist(0);
14711684Smckusick Move.newquad = 2;
14811684Smckusick attack(0);
14911684Smckusick checkcond();
15011684Smckusick Ship.quadx = ix / NSECTS;
15111684Smckusick Ship.quady = iy / NSECTS;
15211684Smckusick Ship.sectx = ix % NSECTS;
15311684Smckusick Ship.secty = iy % NSECTS;
15411684Smckusick if (ix < 0 || Ship.quadx >= NQUADS || iy < 0 || Ship.quady >= NQUADS)
15511684Smckusick if (!damaged(COMPUTER))
15611684Smckusick {
15711684Smckusick dumpme(0);
15811684Smckusick }
15911684Smckusick else
16011684Smckusick lose(L_NEGENB);
16111684Smckusick initquad(0);
16211684Smckusick n = 0;
16311684Smckusick break;
16411684Smckusick }
16511684Smckusick if (Sect[ix][iy] != EMPTY)
16611684Smckusick {
16711684Smckusick /* we just hit something */
16811684Smckusick if (!damaged(COMPUTER) && ramflag <= 0)
16911684Smckusick {
17011684Smckusick ix = x - dx;
17111684Smckusick iy = y - dy;
17211684Smckusick printf("Computer reports navigation error; %s stopped at %d,%d\n",
17311684Smckusick Ship.shipname, ix, iy);
17412344Slayer Ship.energy -= Param.stopengy * speed;
17511684Smckusick break;
17611684Smckusick }
17711684Smckusick /* test for a black hole */
17811684Smckusick if (Sect[ix][iy] == HOLE)
17911684Smckusick {
18011684Smckusick /* get dumped elsewhere in the galaxy */
18111684Smckusick dumpme(1);
18211684Smckusick initquad(0);
18311684Smckusick n = 0;
18411684Smckusick break;
18511684Smckusick }
18611684Smckusick ram(ix, iy);
18711684Smckusick break;
18811684Smckusick }
18911684Smckusick }
19011684Smckusick if (n > 0)
19111684Smckusick {
19211684Smckusick dx = Ship.sectx - ix;
19311684Smckusick dy = Ship.secty - iy;
19411684Smckusick dist = sqrt(dx * dx + dy * dy) / NSECTS;
19511684Smckusick time = dist / speed;
19611684Smckusick if (evtime > time)
19711684Smckusick time = evtime; /* spring the LRTB trap */
19811684Smckusick Ship.sectx = ix;
19911684Smckusick Ship.secty = iy;
20011684Smckusick }
20111684Smckusick Sect[Ship.sectx][Ship.secty] = Ship.ship;
20211684Smckusick compkldist(0);
20311684Smckusick return (time);
20411684Smckusick }
205