1 | /*
2 | * $Log: po_get.c,v $
3 | * Revision 1.8 2005/02/14 00:54:46 millis
4 | * Bug 400, allow dyslexic siege spelling
5 | *
6 | * Revision 1.7 2003/11/09 18:35:37 millis
7 | * Fix bug 248 (allow '_' in country names)
8 | *
9 | * Revision 1.6 2003/05/02 22:22:59 millis
10 | * Added artillery/cannon strings
11 | *
12 | * Revision 1.5 2003/01/14 13:56:46 millis
13 | * Updated with ustv merged changed
14 | *
15 | * Revision 1.4.2.1 2003/01/13 16:04:55 millis
16 | * ustv latest versions
17 | *
18 | * Revision 1.4 2001/12/11 12:08:36 miller
19 | * Added extra "trafo to" action
20 | *
21 | * Revision 1.3 2001/07/01 23:19:29 miller
22 | * Change function signature
23 | *
24 | * Revision 1.2 2000/11/14 14:27:37 miller
25 | * Added support for wing units
26 | *
27 | * Revision 1.1 1998/02/28 17:49:42 david
28 | * Initial revision
29 | *
30 | * Revision 1.1 1996/10/20 12:29:45 rpaar
31 | * Morrolan v9.0
32 | */
33 |
34 | /* p_get.c
35 |
36 | * Copyright 1987, Lowe.
37 | *
38 | * Diplomacy is a trademark of the Avalon Hill Game Company, Baltimore,
39 | * Maryland, all rights reserved; used with permission.
40 | *
41 | * Redistribution and use in source and binary forms are permitted
42 | * provided that it is for non-profit purposes, that this and the
43 | * above notices are preserved and that due credit is given to Mr.
44 | * Lowe.
45 | */
46 |
47 | /*
48 | * 02 Dec 1999 Millis Miller Added 'wing' ptions for F_WINGS
49 | * 04 Dec 1999 Millis Miller Added 'transform' option for builds
50 | */
51 |
52 |
53 | #include <stdlib.h>
54 | #include <string.h>
55 |
56 | #include "dip.h"
57 | #include "functions.h"
58 | #include "porder.h"
59 |
60 | char *get_action(char *l, char *a)
61 | {
62 |
63 | /* Look for an appropriate action word for an order */
64 |
65 | int i;
66 | static char *words[] =
67 | {"0",
68 | "trafo to", "trafo", "transform to", "transforms to", "transforms", "transform", "tr#",
69 | "besieges", "besiege", "sieges", "siege",
70 | "beseiges", "beseige", "seiges", "seige", /* for the dyslexic! */
71 | "b#",
72 | "convoys", "convoy", "transports", "transport", "t",
73 | "fast ferry", "ferry", "ff", "f",
74 | "disbands", "disband",
75 | "debarks to", "disembarks to", "deboards to",
76 | "debarks", "disembarks", "deboards",
77 | "debark to", "disembark to", "deboard to",
78 | "debark", "disembark", "deboard", "dk",
79 | "embarks", "emboards", "boards",
80 | "embark", "emboard", "board", "em", "e",
81 | "holds", "hold", "stands", "stand", "h",
82 | "lift siege", "lifts siege", "lifts", "lift", "ls", "l#",
83 | "->", "-", "move to#", "moves to#", "moves", "move", "m",
84 | "proxy to#", "give proxy to#", "proxy", "p#",
85 | "supports", "support", "s",
86 | "convert to#", "converts to#", "converts", "convert",
87 | "conversion", "conversion to#",
88 | "d", "c",
89 | "air", "airlift", "airlifts", "air lift", "air lifts", "a"
90 | };
91 |
92 | static char reply[] =
93 | {'x',
94 | 't', 't', 't', 't', 't', 't', 't',
95 | 'b', 'b', 'b', 'b', 'b',
96 | 'b', 'b', 'b', 'b',
97 | 'c', 'c', 'c', 'c', 'c',
98 | 'c', 'c', 'c', 'c',
99 | 'd', 'd',
100 | 'k', 'k', 'k',
101 | 'k', 'k', 'k',
102 | 'k', 'k', 'k',
103 | 'k', 'k', 'k', 'k',
104 | 'e', 'e', 'e',
105 | 'e', 'e', 'e', 'e', 'e',
106 | 'h', 'h', 'h', 'h', 'h',
107 | 'l', 'l', 'l', 'l', 'l', 'l',
108 | 'm', 'm', 'm', 'm', 'm', 'm', 'm',
109 | 'p', 'p', 'p', 'p',
110 | 's', 's', 's',
111 | 'v', 'v', 'v', 'v',
112 | 'v', 'v',
113 | 'D', 'C',
114 | 'a', 'a', 'a', 'a', 'a', 'a'
115 | };
116 |
117 |
118 | l = lookfor(l, words, nentry(words), &i);
119 | *a = reply[i];
120 | if (*a == 'C') {
121 | if (dipent.flags & F_MACH) {
122 | *a = 'v';
123 | } else {
124 | *a = 'c';
125 | }
126 | }
127 | if (*a == 'D') {
128 | if (dipent.phase[5] == 'R') {
129 | *a = 'd';
130 | } else {
131 | *a = 'k';
132 | }
133 | }
134 | return l;
135 | }
136 |
137 | /*
138 | * TODO figure out what the -99999 assignment to a char is doing,
139 | * and why we immediately terminate the string pointed to by d
140 | */
141 |
142 | char *get_amount(char *l, int *d)
143 | {
144 |
145 | /* Look for an amount of money */
146 |
147 | char *s;
148 | int i, j;
149 |
150 | static char *words[] =
151 | {"0", "d#", "ducats#", "ducat#"};
152 |
153 | s = l;
154 | *d = 0;
155 | do {
156 | j = 1;
157 | if (*s == '+')
158 | s++;
159 | if (*s == '-') {
160 | j = -1;
161 | s++;
162 | }
163 | while (isspace(*s))
164 | s++;
165 | *d += atoi(s) * j;
166 | for (j = 0; isdigit(*s); s++)
167 | j++;
168 | s = lookfor(s, words, nentry(words), &i);
169 | while (isspace(*s))
170 | s++;
171 | } while (*s == '-' || *s == '+');
172 |
173 | if (j == 0) {
174 | *d = -99999;
175 | return l;
176 | }
177 | return s;
178 |
179 | }
180 |
181 | char *get_duration(char *l, int *d)
182 | {
183 |
184 | /*
185 | * Look for a duration of one or two years for a bank loan.
186 | */
187 |
188 | int i;
189 |
190 | static char *words[] =
191 | {"0", "for", "1 year", "one year", "one", "1",
192 | "at", "20 %", "20 percent", "20",
193 | "2 years", "two years", "two", "2",
194 | "50 %", "50 percent", "50"};
195 |
196 | static unsigned char reply[] =
197 | {0, 200, 1, 1, 1, 1,
198 | 200, 1, 1, 1,
199 | 2, 2, 2, 2,
200 | 2, 2, 2};
201 |
202 | do {
203 | l = lookfor(l, words, nentry(words), &i);
204 | } while (reply[i] == 200);
205 | *d = reply[i];
206 | return l;
207 |
208 | }
209 |
210 | char *get_expense(char *l, char *e)
211 | {
212 |
213 | /* Look for an appropriate action word for an expense order */
214 |
215 | int i;
216 |
217 | static char *words[] =
218 | {"0", "pay", "give", "loan",
219 | "borrow",
220 | "ally", "allies", "alliance", "allow",
221 | "unally", "not allies", "unalliance",
222 | "don't allow", "dont allow",
223 | "expense", "exp", "e#"};
224 |
225 | static char reply[] =
226 | {'x', 'p', 'p', 'p',
227 | 'b',
228 | 'a', 'a', 'a', 'a',
229 | 'u', 'u', 'u',
230 | 'u', 'u',
231 | 'e', 'e', 'e'};
232 |
233 |
234 | l = lookfor(l, words, nentry(words), &i);
235 | *e = reply[i];
236 | return l;
237 |
238 | }
239 |
240 | char *get_exptype(char *l, char *e)
241 | {
242 |
243 | /* Look for an appropriate action word for an expense order */
244 |
245 | int i;
246 |
247 | static char *words[] =
248 | {"0", "famine relief", "fr#", "famine", "relief",
249 | "pacify rebellion", "pr#", "pacify",
250 | "counter-bribe", "cb#", "counter",
251 | "disband", "d#",
252 | "buy", "purchase", "b#",
253 | "garrison to autonomous", "gta", "g#",
254 | "autonomous", "to autonomous", "to a#",
255 | "cause rebellion", "cr#", "cause", "rebellion",
256 | "assassinate", "a#"};
257 | static char reply[] =
258 | {'x', 'f', 'f', 'f', 'f',
259 | 'p', 'p', 'p',
260 | 'c', 'c', 'c',
261 | 'd', 'd',
262 | 'b', 'b', 'b',
263 | 'g', 'g', 'g',
264 | 'g', 'g', 'g',
265 | 'r', 'r', 'r', 'r',
266 | 'a', 'a'};
267 |
268 |
269 | l = lookfor(l, words, nentry(words), &i);
270 | *e = reply[i];
271 | return l;
272 |
273 | }
274 |
275 | char *get_order(char *l, char *o)
276 | {
277 |
278 | /* Look for an appropriate action word for a build order */
279 |
280 | int i;
281 |
282 | static char *words[] =
283 | {"0", "build", "b#", "debuild",
284 | "remove", "r#", "disband", "d#",
285 | "maintain", "m#",
286 | "waive", "w#",
287 | "transform", "trafo", "t#",
288 | "home", "nohome", "no home",
289 | "erase", "zap", "restore",
290 | "own" };
291 | static char reply[] =
292 | {'x', 'b', 'b', 'r',
293 | 'r', 'r', 'r', 'r',
294 | 'm', 'm',
295 | 'w', 'w',
296 | 't', 't', 't',
297 | 'h', 'n', 'n',
298 | 'c', 'z', 's',
299 | 'o'
300 | };
301 |
302 |
303 | l = lookfor(l, words, nentry(words), &i);
304 | *o = reply[i];
305 | return l;
306 |
307 | }
308 |
309 | char *get_power(char *l, int *o)
310 | {
311 |
312 | /*
313 | * Look for an appropriate name for a power.
314 | */
315 |
316 | char *s;
317 | int i, n;
318 |
319 |
320 | *o = 0;
321 | while (isspace(*l))
322 | l++;
323 | for (n = 0, s = l; isalnum(*s) || *s == '-' || *s == '_' ; s++, n++);
324 | if (n < 2)
325 | return l;
326 | for (i = 1; i < WILD_PLAYER; i++) {
327 | if (dipent.pl[i] != 'x' &&
328 | (!strncasecmp(l, owners[i], n) || !strncasecmp(l, powers[i], n))) {
329 | *o = i;
330 | while (isspace(*s))
331 | s++;
332 | return s;
333 | }
334 | }
335 | return l;
336 |
337 | }
338 |
339 | char *get_stype(char *l, char *t)
340 | {
341 |
342 | /*
343 | * Check for special unit type identifiers.
344 | */
345 |
346 | int i;
347 | static char *words[] =
348 | {"0", "citizen's militia", "militia", "cm#",
349 | "elite mercenary", "mercenary",
350 | "elite mercenaries", "mercenaries", "em#",
351 | "elite professional", "professional", "ep#"};
352 |
353 | static char reply[] =
354 | {'x', 'c', 'c', 'c', 'm', 'm', 'm', 'm', 'm', 'p', 'p', 'p'};
355 |
356 | l = lookfor(l, words, nentry(words), &i);
357 | *t = reply[i];
358 | return l;
359 |
360 | }
361 |
362 | char *get_type(char *l, char *t)
363 | {
364 |
365 | /*
366 | * Check input for optional unit type of 'a', 'army', 'f' or 'fleet', 'w' or 'wing'.
367 | *
368 | * Exit: t = Unit type or 'x' if invalid.
369 | */
370 |
371 | #define F_ANY 0x01
372 |
373 | int i;
374 | char *s;
375 |
376 | static char *words[] =
377 | {"0", "army / fleet", "a/f#", "af#",
378 | "wing", "w#",
379 | "army", "a#",
380 | "fleet", "f#",
381 | "garrison", "g#",
382 | "artillery", "cannon", "r#",
383 | "unit",
384 | "spy"};
385 |
386 | static char reply[] =
387 | {'x', 'T', 'T', 'T',
388 | 'W', 'W',
389 | 'A', 'A',
390 | 'F', 'F',
391 | 'G', 'G',
392 | 'R', 'R', 'R',
393 | 'U',
394 | 'S'};
395 |
396 | static int flags[] =
397 | {0, F_AFRULES, F_AFRULES, F_AFRULES,
398 | F_WINGS, F_WINGS,
399 | F_ANY, F_ANY,
400 | F_ANY, F_ANY,
401 | F_MACH, F_MACH,
402 | F_ANY, F_ANY, F_ANY,
403 | F_ANY,
404 | F_BLIND};
405 |
406 | s = lookfor(l, words, nentry(words), &i);
407 | if (flags[i] & (dipent.flags | F_ANY)) {
408 | *t = reply[i];
409 | return s;
410 | } else {
411 | *t = reply[0];
412 | return l;
413 | }
414 |
415 | }
416 |