xref: /openbsd/games/trek/klmove.c (revision db3296cf)
1 /*	$OpenBSD: klmove.c,v 1.4 2003/06/03 03:01:41 millert Exp $	*/
2 /*	$NetBSD: klmove.c,v 1.3 1995/04/22 10:59:07 cgd 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 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)klmove.c	8.1 (Berkeley) 5/31/93";
36 #else
37 static char rcsid[] = "$OpenBSD: klmove.c,v 1.4 2003/06/03 03:01:41 millert 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
68 klmove(fl)
69 int	fl;
70 {
71 	int		n;
72 	struct kling	*k;
73 	double		dx, dy;
74 	int		nextx, nexty;
75 	int		lookx, looky;
76 	int		motion;
77 	int		fudgex, fudgey;
78 	int		qx, qy;
79 	double		bigger;
80 	int		i;
81 
82 #	ifdef xTRACE
83 	if (Trace)
84 		printf("klmove: fl = %d, Etc.nkling = %d\n", fl, Etc.nkling);
85 #	endif
86 	for (n = 0; n < Etc.nkling; n++)
87 	{
88 		k = &Etc.klingon[n];
89 		i = 100;
90 		if (fl)
91 			i = 100.0 * k->power / Param.klingpwr;
92 		if (ranf(i) >= Param.moveprob[2 * Move.newquad + fl])
93 			continue;
94 		/* compute distance to move */
95 		motion = ranf(75) - 25;
96 		motion *= k->avgdist * Param.movefac[2 * Move.newquad + fl];
97 		/* compute direction */
98 		dx = Ship.sectx - k->x + ranf(3) - 1;
99 		dy = Ship.secty - k->y + ranf(3) - 1;
100 		bigger = dx;
101 		if (dy > bigger)
102 			bigger = dy;
103 		if (bigger == 0.0)
104 			bigger = 1.0;
105 		dx = dx / bigger + 0.5;
106 		dy = dy / bigger + 0.5;
107 		if (motion < 0)
108 		{
109 			motion = -motion;
110 			dx = -dx;
111 			dy = -dy;
112 		}
113 		fudgex = fudgey = 1;
114 		/* try to move the klingon */
115 		nextx = k->x;
116 		nexty = k->y;
117 		for (; motion > 0; motion--)
118 		{
119 			lookx = nextx + dx;
120 			looky = nexty + dy;
121 			if (lookx < 0 || lookx >= NSECTS || looky < 0 || looky >= NSECTS)
122 			{
123 				/* new quadrant */
124 				qx = Ship.quadx;
125 				qy = Ship.quady;
126 				if (lookx < 0)
127 					qx -= 1;
128 				else
129 					if (lookx >= NSECTS)
130 						qx += 1;
131 				if (looky < 0)
132 					qy -= 1;
133 				else
134 					if (looky >= NSECTS)
135 						qy += 1;
136 				if (qx < 0 || qx >= NQUADS || qy < 0 || qy >= NQUADS ||
137 						Quad[qx][qy].stars < 0 || Quad[qx][qy].klings > MAXKLQUAD - 1)
138 					break;
139 				if (!damaged(SRSCAN))
140 				{
141 					printf("Klingon at %d,%d escapes to quadrant %d,%d\n",
142 						k->x, k->y, qx, qy);
143 					motion = Quad[qx][qy].scanned;
144 					if (motion >= 0 && motion < 1000)
145 						Quad[qx][qy].scanned += 100;
146 					motion = Quad[Ship.quadx][Ship.quady].scanned;
147 					if (motion >= 0 && motion < 1000)
148 						Quad[Ship.quadx][Ship.quady].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 			{
160 				lookx = nextx + fudgex;
161 				if (lookx < 0 || lookx >= NSECTS)
162 					lookx = nextx + dx;
163 				if (Sect[lookx][looky] != EMPTY)
164 				{
165 					fudgex = -fudgex;
166 					looky = nexty + fudgey;
167 					if (looky < 0 || looky >= NSECTS || Sect[lookx][looky] != EMPTY)
168 					{
169 						fudgey = -fudgey;
170 						break;
171 					}
172 				}
173 			}
174 			nextx = lookx;
175 			nexty = looky;
176 		}
177 		if (k && (k->x != nextx || k->y != nexty))
178 		{
179 			if (!damaged(SRSCAN))
180 				printf("Klingon at %d,%d moves to %d,%d\n",
181 					k->x, k->y, nextx, nexty);
182 			Sect[k->x][k->y] = EMPTY;
183 			Sect[k->x = nextx][k->y = nexty] = KLINGON;
184 		}
185 	}
186 	compkldist(0);
187 }
188