1 /*        $NetBSD: klmove.c,v 1.9 2009/05/24 22:55:03 dholland Exp $  */
2 
3 /*
4  * Copyright (c) 1980, 1993
5  *        The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)klmove.c    8.1 (Berkeley) 5/31/93";
36 #else
37 __RCSID("$NetBSD: klmove.c,v 1.9 2009/05/24 22:55:03 dholland Exp $");
38 #endif
39 #endif /* not lint */
40 
41 #include <stdio.h>
42 #include "trek.h"
43 
44 /*
45 **  Move Klingons Around
46 **
47 **        This is a largely incomprehensible block of code that moves
48 **        Klingons around in a quadrant.  It was written in a very
49 **        "program as you go" fashion, and is a prime candidate for
50 **        rewriting.
51 **
52 **        The flag `fl' is zero before an attack, one after an attack,
53 **        and two if you are leaving a quadrant.  This serves to
54 **        change the probability and distance that it moves.
55 **
56 **        Basically, what it will try to do is to move a certain number
57 **        of steps either toward you or away from you.  It will avoid
58 **        stars whenever possible.  Nextx and nexty are the next
59 **        sector to move to on a per-Klingon basis; they are roughly
60 **        equivalent to Ship.sectx and Ship.secty for the starship.  Lookx and
61 **        looky are the sector that you are going to look at to see
62 **        if you can move their.  Dx and dy are the increment.  Fudgex
63 **        and fudgey are the things you change around to change your
64 **        course around stars.
65 */
66 
67 void
klmove(int fl)68 klmove(int fl)
69 {
70           int                           n;
71           struct kling        *k;
72           double                        dx, dy;
73           int                           nextx, nexty;
74           int                 lookx, looky;
75           int                           motion;
76           int                           fudgex, fudgey;
77           int                           qx, qy;
78           double                        bigger;
79           int                           i;
80 
81 #ifdef xTRACE
82           if (Trace)
83                     printf("klmove: fl = %d, Etc.nkling = %d\n", fl, Etc.nkling);
84 #endif
85           for (n = 0; n < Etc.nkling; n++) {
86                     k = &Etc.klingon[n];
87                     i = 100;
88                     if (fl)
89                               i = 100.0 * k->power / Param.klingpwr;
90                     if (ranf(i) >= Param.moveprob[2 * Move.newquad + fl])
91                               continue;
92                     /* compute distance to move */
93                     motion = ranf(75) - 25;
94                     motion *= k->avgdist * Param.movefac[2 * Move.newquad + fl];
95                     /* compute direction */
96                     dx = Ship.sectx - k->x + ranf(3) - 1;
97                     dy = Ship.secty - k->y + ranf(3) - 1;
98                     bigger = dx;
99                     if (dy > bigger)
100                               bigger = dy;
101                     if (bigger == 0.0)
102                               bigger = 1.0;
103                     dx = dx / bigger + 0.5;
104                     dy = dy / bigger + 0.5;
105                     if (motion < 0) {
106                               motion = -motion;
107                               dx = -dx;
108                               dy = -dy;
109                     }
110                     fudgex = fudgey = 1;
111                     /* try to move the klingon */
112                     nextx = k->x;
113                     nexty = k->y;
114                     for (; motion > 0; motion--) {
115                               lookx = nextx + dx;
116                               looky = nexty + dy;
117                               if (lookx < 0 || lookx >= NSECTS ||
118                                   looky < 0 || looky >= NSECTS) {
119                                         /* new quadrant */
120                                         qx = Ship.quadx;
121                                         qy = Ship.quady;
122                                         if (lookx < 0)
123                                                   qx -= 1;
124                                         else
125                                                   if (lookx >= NSECTS)
126                                                             qx += 1;
127                                         if (looky < 0)
128                                                   qy -= 1;
129                                         else
130                                                   if (looky >= NSECTS)
131                                                             qy += 1;
132                                         if (qx < 0 || qx >= NQUADS ||
133                                             qy < 0 || qy >= NQUADS ||
134                                             Quad[qx][qy].stars < 0 ||
135                                             Quad[qx][qy].klings > MAXKLQUAD - 1)
136                                                   break;
137                                         if (!damaged(SRSCAN)) {
138                                                   printf("Klingon at %d,%d escapes to "
139                                                          "quadrant %d,%d\n",
140                                                             k->x, k->y, qx, qy);
141                                                   motion = Quad[qx][qy].scanned;
142                                                   if (motion >= 0 && motion < 1000)
143                                                             Quad[qx][qy].scanned += 100;
144                                                   motion = Quad[Ship.quadx][Ship.quady]
145                                                             .scanned;
146                                                   if (motion >= 0 && motion < 1000)
147                                                             Quad[Ship.quadx][Ship.quady]
148                                                                       .scanned -= 100;
149                                         }
150                                         Sect[k->x][k->y] = EMPTY;
151                                         Quad[qx][qy].klings += 1;
152                                         Etc.nkling -= 1;
153                                         *k = Etc.klingon[Etc.nkling];
154                                         Quad[Ship.quadx][Ship.quady].klings -= 1;
155                                         k = 0;
156                                         break;
157                               }
158                               if (Sect[lookx][looky] != EMPTY) {
159                                         lookx = nextx + fudgex;
160                                         if (lookx < 0 || lookx >= NSECTS)
161                                                   lookx = nextx + dx;
162                                         if (Sect[lookx][looky] != EMPTY) {
163                                                   fudgex = -fudgex;
164                                                   looky = nexty + fudgey;
165                                                   if (looky < 0 || looky >= NSECTS ||
166                                                       Sect[lookx][looky] != EMPTY) {
167                                                             fudgey = -fudgey;
168                                                             break;
169                                                   }
170                                         }
171                               }
172                               nextx = lookx;
173                               nexty = looky;
174                     }
175                     if (k && (k->x != nextx || k->y != nexty)) {
176                               if (!damaged(SRSCAN))
177                                         printf("Klingon at %d,%d moves to %d,%d\n",
178                                                   k->x, k->y, nextx, nexty);
179                               Sect[k->x][k->y] = EMPTY;
180                               Sect[k->x = nextx][k->y = nexty] = KLINGON;
181                     }
182           }
183           compkldist(0);
184 }
185