xref: /openbsd-src/games/trek/klmove.c (revision 11da2480c68e9717c510fd663096c44c53785231)
1 /*	$OpenBSD: klmove.c,v 1.7 2016/01/07 14:37:51 mestre 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 #include <stdio.h>
34 
35 #include "trek.h"
36 
37 /*
38 **  Move Klingons Around
39 **
40 **	This is a largely incomprehensible block of code that moves
41 **	Klingons around in a quadrant.  It was written in a very
42 **	"program as you go" fashion, and is a prime candidate for
43 **	rewriting.
44 **
45 **	The flag `fl' is zero before an attack, one after an attack,
46 **	and two if you are leaving a quadrant.  This serves to
47 **	change the probability and distance that it moves.
48 **
49 **	Basically, what it will try to do is to move a certain number
50 **	of steps either toward you or away from you.  It will avoid
51 **	stars whenever possible.  Nextx and nexty are the next
52 **	sector to move to on a per-Klingon basis; they are roughly
53 **	equivalent to Ship.sectx and Ship.secty for the starship.  Lookx and
54 **	looky are the sector that you are going to look at to see
55 **	if you can move their.  Dx and dy are the increment.  Fudgex
56 **	and fudgey are the things you change around to change your
57 **	course around stars.
58 */
59 
60 void
klmove(int fl)61 klmove(int fl)
62 {
63 	int		n;
64 	struct kling	*k;
65 	double		dx, dy;
66 	int		nextx, nexty;
67 	int		lookx, looky;
68 	int		motion;
69 	int		fudgex, fudgey;
70 	int		qx, qy;
71 	double		bigger;
72 	int		i;
73 
74 #	ifdef xTRACE
75 	if (Trace)
76 		printf("klmove: fl = %d, Etc.nkling = %d\n", fl, Etc.nkling);
77 #	endif
78 	for (n = 0; n < Etc.nkling; n++)
79 	{
80 		k = &Etc.klingon[n];
81 		i = 100;
82 		if (fl)
83 			i = 100.0 * k->power / Param.klingpwr;
84 		if (ranf(i) >= Param.moveprob[2 * Move.newquad + fl])
85 			continue;
86 		/* compute distance to move */
87 		motion = ranf(75) - 25;
88 		motion *= k->avgdist * Param.movefac[2 * Move.newquad + fl];
89 		/* compute direction */
90 		dx = Ship.sectx - k->x + ranf(3) - 1;
91 		dy = Ship.secty - k->y + ranf(3) - 1;
92 		bigger = dx;
93 		if (dy > bigger)
94 			bigger = dy;
95 		if (bigger == 0.0)
96 			bigger = 1.0;
97 		dx = dx / bigger + 0.5;
98 		dy = dy / bigger + 0.5;
99 		if (motion < 0)
100 		{
101 			motion = -motion;
102 			dx = -dx;
103 			dy = -dy;
104 		}
105 		fudgex = fudgey = 1;
106 		/* try to move the klingon */
107 		nextx = k->x;
108 		nexty = k->y;
109 		for (; motion > 0; motion--)
110 		{
111 			lookx = nextx + dx;
112 			looky = nexty + dy;
113 			if (lookx < 0 || lookx >= NSECTS || looky < 0 || looky >= NSECTS)
114 			{
115 				/* new quadrant */
116 				qx = Ship.quadx;
117 				qy = Ship.quady;
118 				if (lookx < 0)
119 					qx -= 1;
120 				else
121 					if (lookx >= NSECTS)
122 						qx += 1;
123 				if (looky < 0)
124 					qy -= 1;
125 				else
126 					if (looky >= NSECTS)
127 						qy += 1;
128 				if (qx < 0 || qx >= NQUADS || qy < 0 || qy >= NQUADS ||
129 						Quad[qx][qy].stars < 0 || Quad[qx][qy].klings > MAXKLQUAD - 1)
130 					break;
131 				if (!damaged(SRSCAN))
132 				{
133 					printf("Klingon at %d,%d escapes to quadrant %d,%d\n",
134 						k->x, k->y, qx, qy);
135 					motion = Quad[qx][qy].scanned;
136 					if (motion >= 0 && motion < 1000)
137 						Quad[qx][qy].scanned += 100;
138 					motion = Quad[Ship.quadx][Ship.quady].scanned;
139 					if (motion >= 0 && motion < 1000)
140 						Quad[Ship.quadx][Ship.quady].scanned -= 100;
141 				}
142 				Sect[k->x][k->y] = EMPTY;
143 				Quad[qx][qy].klings += 1;
144 				Etc.nkling -= 1;
145 				*k = Etc.klingon[Etc.nkling];
146 				Quad[Ship.quadx][Ship.quady].klings -= 1;
147 				k = 0;
148 				break;
149 			}
150 			if (Sect[lookx][looky] != EMPTY)
151 			{
152 				lookx = nextx + fudgex;
153 				if (lookx < 0 || lookx >= NSECTS)
154 					lookx = nextx + dx;
155 				if (Sect[lookx][looky] != EMPTY)
156 				{
157 					fudgex = -fudgex;
158 					looky = nexty + fudgey;
159 					if (looky < 0 || looky >= NSECTS || Sect[lookx][looky] != EMPTY)
160 					{
161 						fudgey = -fudgey;
162 						break;
163 					}
164 				}
165 			}
166 			nextx = lookx;
167 			nexty = looky;
168 		}
169 		if (k && (k->x != nextx || k->y != nexty))
170 		{
171 			if (!damaged(SRSCAN))
172 				printf("Klingon at %d,%d moves to %d,%d\n",
173 					k->x, k->y, nextx, nexty);
174 			Sect[k->x][k->y] = EMPTY;
175 			Sect[k->x = nextx][k->y = nexty] = KLINGON;
176 		}
177 	}
178 	compkldist(0);
179 }
180