xref: /openbsd/games/sail/pl_5.c (revision 4cfece93)
1 /*	$OpenBSD: pl_5.c,v 1.9 2016/01/08 20:26:33 mestre Exp $	*/
2 /*	$NetBSD: pl_5.c,v 1.4 1995/04/24 12:25:21 cgd Exp $	*/
3 
4 /*
5  * Copyright (c) 1983, 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 <ctype.h>
34 #include <signal.h>
35 #include <string.h>
36 
37 #include "extern.h"
38 #include "machdep.h"
39 #include "player.h"
40 
41 #define turnfirst(x) (*x == 'r' || *x == 'l')
42 
43 void
44 acceptmove(void)
45 {
46 	int ta;
47 	int ma;
48 	char af;
49 	int moved = 0;
50 	int vma, dir;
51 	char prompt[60];
52 	char buf[60], last = '\0';
53 	char *p;
54 
55 	if (!mc->crew3 || snagged(ms) || !windspeed) {
56 		Msg("Unable to move");
57 		return;
58 	}
59 
60 	ta = maxturns(ms, &af);
61 	ma = maxmove(ms, mf->dir, 0);
62 	(void) snprintf(prompt, sizeof prompt,
63 		"move (%d,%c%d): ", ma, af ? '\'' : ' ', ta);
64 	sgetstr(prompt, buf, sizeof buf);
65 	dir = mf->dir;
66 	vma = ma;
67 	for (p = buf; *p; p++)
68 		switch (*p) {
69 		case 'l':
70 			dir -= 2;
71 		case 'r':
72 			if (++dir == 0)
73 				dir = 8;
74 			else if (dir == 9)
75 				dir = 1;
76 			if (last == 't') {
77 				Msg("Ship can't turn that fast.");
78 				*p-- = '\0';
79 			}
80 			last = 't';
81 			ma--;
82 			ta--;
83 			vma = min(ma, maxmove(ms, dir, 0));
84 			if ((ta < 0 && moved) || (vma < 0 && moved))
85 				*p-- = '\0';
86 			break;
87 		case 'b':
88 			ma--;
89 			vma--;
90 			last = 'b';
91 			if ((ta < 0 && moved) || (vma < 0 && moved))
92 				*p-- = '\0';
93 			break;
94 		case '0':
95 		case 'd':
96 			*p-- = '\0';
97 			break;
98 		case '\n':
99 			*p-- = '\0';
100 			break;
101 		case '1': case '2': case '3': case '4':
102 		case '5': case '6': case '7':
103 			if (last == '0') {
104 				Msg("Can't move that fast.");
105 				*p-- = '\0';
106 			}
107 			last = '0';
108 			moved = 1;
109 			ma -= *p - '0';
110 			vma -= *p - '0';
111 			if ((ta < 0 && moved) || (vma < 0 && moved))
112 				*p-- = '\0';
113 			break;
114 		default:
115 			if (!isspace((unsigned char)*p)) {
116 				Msg("Input error.");
117 				*p-- = '\0';
118 			}
119 		}
120 	if ((ta < 0 && moved) || (vma < 0 && moved)
121 	    || (af && turnfirst(buf) && moved)) {
122 		Msg("Movement error.");
123 		if (ta < 0 && moved) {
124 			if (mf->FS == 1) {
125 				Write(W_FS, ms, 0, 0, 0, 0);
126 				Msg("No hands to set full sails.");
127 			}
128 		} else if (ma >= 0)
129 			buf[1] = '\0';
130 	}
131 	if (af && !moved) {
132 		if (mf->FS == 1) {
133 			Write(W_FS, ms, 0, 0, 0, 0);
134 			Msg("No hands to set full sails.");
135 		}
136 	}
137 	if (*buf)
138 		(void) strlcpy(movebuf, buf, sizeof movebuf);
139 	else
140 		(void) strlcpy(movebuf, "d", sizeof movebuf);
141 	Writestr(W_MOVE, ms, movebuf);
142 	Msg("Helm: %s.", movebuf);
143 }
144 
145 void
146 acceptboard(void)
147 {
148 	struct ship *sp;
149 	int n;
150 	int crew[3];
151 	int men = 0;
152 	char c;
153 
154 	crew[0] = mc->crew1;
155 	crew[1] = mc->crew2;
156 	crew[2] = mc->crew3;
157 	for (n = 0; n < NBP; n++) {
158 		if (mf->OBP[n].turnsent)
159 			    men += mf->OBP[n].mensent;
160 	}
161 	for (n = 0; n < NBP; n++) {
162 		if (mf->DBP[n].turnsent)
163 			    men += mf->DBP[n].mensent;
164 	}
165 	if (men) {
166 		crew[0] = men/100 ? 0 : crew[0] != 0;
167 		crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
168 		crew[2] = men%10 ? 0 : crew[2] != 0;
169 	} else {
170 		crew[0] = crew[0] != 0;
171 		crew[1] = crew[1] != 0;
172 		crew[2] = crew[2] != 0;
173 	}
174 	foreachship(sp) {
175 		if (sp == ms || sp->file->dir == 0 || range(ms, sp) > 1)
176 			continue;
177 		if (ms->nationality == capship(sp)->nationality)
178 			continue;
179 		if (meleeing(ms, sp) && crew[2]) {
180 			c = sgetch("How many more to board the $$? ",
181 				sp, 1);
182 			parties(crew, sp, 0, c);
183 		} else if ((fouled2(ms, sp) || grappled2(ms, sp)) && crew[2]) {
184 			c = sgetch("Crew sections to board the $$ (3 max) ?", sp, 1);
185 			parties(crew, sp, 0, c);
186 		}
187 	}
188 	if (crew[2]) {
189 		c = sgetch("How many sections to repel boarders? ",
190 			(struct ship *)0, 1);
191 		parties(crew, ms, 1, c);
192 	}
193 	blockalarm();
194 	draw_slot();
195 	unblockalarm();
196 }
197 
198 void
199 parties(int crew[3], struct ship *to, int isdefense, int buf)
200 {
201 	int k, j, men;
202 	struct BP *ptr;
203 	int temp[3];
204 
205 	for (k = 0; k < 3; k++)
206 		temp[k] = crew[k];
207 	if (isdigit((unsigned char)buf)) {
208 		ptr = isdefense ? to->file->DBP : to->file->OBP;
209 		for (j = 0; j < NBP && ptr[j].turnsent; j++)
210 			;
211 		if (j < NBP && buf > '0') {
212 			men = 0;
213 			for (k = 0; k < 3 && buf > '0'; k++) {
214 				men += crew[k]
215 					* (k == 0 ? 100 : (k == 1 ? 10 : 1));
216 				crew[k] = 0;
217 				if (men)
218 					buf--;
219 			}
220 			if (buf > '0')
221 				Msg("Sending all crew sections.");
222 			Write(isdefense ? W_DBP : W_OBP, ms,
223 				j, turn, to->file->index, men);
224 			if (isdefense) {
225 				(void) wmove(slot_w, 2, 0);
226 				for (k=0; k < NBP; k++)
227 					if (temp[k] && !crew[k])
228 						(void) waddch(slot_w, k + '1');
229 					else
230 						(void) wmove(slot_w, 2, 1 + k);
231 				(void) mvwaddstr(slot_w, 3, 0, "DBP");
232 				makemsg(ms, "repelling boarders");
233 			} else {
234 				(void) wmove(slot_w, 0, 0);
235 				for (k=0; k < NBP; k++)
236 					if (temp[k] && !crew[k])
237 						(void) waddch(slot_w, k + '1');
238 					else
239 						(void) wmove(slot_w, 0, 1 + k);
240 				(void) mvwaddstr(slot_w, 1, 0, "OBP");
241 				makesignal(ms, "boarding the $$", to);
242 			}
243 			blockalarm();
244 			(void) wrefresh(slot_w);
245 			unblockalarm();
246 		} else
247 			Msg("Sending no crew sections.");
248 	}
249 }
250