source: trunk/minix/commands/advent/travel.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 6.6 KB
Line 
1/* module TRAVEL.C *
2 * Routine to handle motion requests */
3
4
5#include <stdio.h>
6#include <stdlib.h>
7#include "advent.h"
8#include "advdec.h"
9#include "advcave.h"
10
11struct trav travel[MAXTRAV];
12static int kalflg;
13static int bcrossing = 0;
14static int phuce[2][4] = {158, 160, 167, 166,
15 160, 158, 166, 167};
16
17_PROTOTYPE(static void goback, (void));
18_PROTOTYPE(static void ck_kal, (void));
19_PROTOTYPE(static void dotrav, (void));
20_PROTOTYPE(static void badmove, (void));
21_PROTOTYPE(static void spcmove, (int rdest));
22
23void domove()
24{
25 gettrav(g.loc, travel);
26 switch (motion) {
27 case NULLX:
28 break;
29 case BACK:
30 goback();
31 break;
32 case CAVE:
33 if (outside(g.loc))
34 rspeak(57);
35 else
36 rspeak(58);
37 break;
38 default:
39 g.oldloc2 = g.oldloc;
40 g.oldloc = g.loc;
41 dotrav();
42 }
43 newtravel = TRUE;
44 return;
45}
46
47/*
48 Routine to handle request to return
49 from whence we came!
50*/
51static void goback()
52{
53 int kk, k2, want, temp;
54 struct trav strav[MAXTRAV];
55
56 want = forced(g.oldloc) ? g.oldloc2 : g.oldloc;
57 g.oldloc2 = g.oldloc;
58 g.oldloc = g.loc;
59 k2 = 0;
60 if (want == g.loc) {
61 rspeak(91);
62 ck_kal();
63 return;
64 }
65 for (kk = 0; travel[kk].tdest != -1; ++kk) {
66 if (!travel[kk].tcond && travel[kk].tdest == want) {
67 motion = travel[kk].tverb;
68 dotrav();
69 return;
70 }
71 if (!travel[kk].tcond) {
72 temp = travel[kk].tdest;
73 gettrav(temp, strav);
74 if (forced(temp) && strav[0].tdest == want)
75 k2 = temp;
76 }
77 }
78 if (k2) {
79 motion = travel[k2].tverb;
80 dotrav();
81 } else
82 rspeak(140);
83 ck_kal();
84 return;
85}
86
87static void ck_kal()
88{
89 if (g.newloc >= 242 && g.newloc <= 247) {
90 if (g.newloc == 242)
91 kalflg = 0;
92 else if (g.newloc == (g.oldloc + 1))
93 kalflg++;
94 else
95 kalflg = -10;
96 }
97}
98
99/*
100 Routine to figure out a new location
101 given current location and a motion.
102*/
103static void dotrav()
104{
105 unsigned char mvflag, hitflag, kk;
106 int rdest, rverb, rcond, robject;
107 int pctt;
108
109 g.newloc = g.loc;
110 mvflag = hitflag = 0;
111 pctt = ranz(100);
112
113 for (kk = 0; travel[kk].tdest >= 0 && !mvflag; ++kk) {
114 rdest = travel[kk].tdest;
115 rverb = travel[kk].tverb;
116 rcond = travel[kk].tcond;
117 robject = rcond % 100;
118
119 if ((rverb != 1) && (rverb != motion) && !hitflag)
120 continue;
121 ++hitflag;
122 switch (rcond / 100) {
123 case 0:
124 if ((rcond == 0) || (pctt < rcond))
125 ++mvflag;
126 break;
127 case 1:
128 if (robject == 0)
129 ++mvflag;
130 else if (toting(robject))
131 ++mvflag;
132 break;
133 case 2:
134 if (toting(robject) || at(robject))
135 ++mvflag;
136 break;
137 case 3:
138 case 4:
139 case 5:
140 case 7:
141 if (g.prop[robject] != (rcond / 100) - 3)
142 ++mvflag;
143 break;
144 default:
145 bug(37);
146 }
147 }
148 if (!mvflag)
149 badmove();
150 else if (rdest > 500)
151 rspeak(rdest - 500);
152 else if (rdest > 300)
153 spcmove(rdest);
154 else {
155 g.newloc = rdest;
156 ck_kal();
157 }
158 newtravel = TRUE;
159 return;
160}
161
162/*
163 The player tried a poor move option.
164*/
165static void badmove()
166{
167 int msg;
168
169 msg = 12;
170 if (motion >= 43 && motion <= 50)
171 msg = 9;
172 if (motion == 29 || motion == 30)
173 msg = 9;
174 if (motion == 7 || motion == 36 || motion == 37)
175 msg = 10;
176 if (motion == 11 || motion == 19)
177 msg = 11;
178 if (motion == 62 || motion == 65 || motion == 82)
179 msg = 42;
180 if (motion == 17)
181 msg = 80;
182 rspeak(msg);
183 return;
184}
185
186/*
187 Routine to handle very special movement.
188*/
189static void spcmove(rdest)
190int rdest;
191{
192 int load, obj, k;
193
194 switch (rdest - 300) {
195 case 1: /* plover movement via alcove */
196 load = burden(0);
197 if (!load || (load == burden(EMERALD) && holding(EMERALD)))
198 g.newloc = (99 + 100) - g.loc;
199 else
200 rspeak(117);
201 break;
202 case 2: /* trying to remove plover, bad
203 route */
204 if (enclosed(EMERALD))
205 extract(EMERALD);
206 drop(EMERALD, g.loc);
207 g.newloc = 33;
208 break;
209 case 3: /* troll bridge */
210 if (g.prop[TROLL] == 1) {
211 pspeak(TROLL, 1);
212 g.prop[TROLL] = 0;
213 move(TROLL2, 0);
214 move((TROLL2 + MAXOBJ), 0);
215 move(TROLL, plac[TROLL]);
216 move((TROLL + MAXOBJ), fixd[TROLL]);
217 juggle(CHASM);
218 g.newloc = g.loc;
219 } else {
220 g.newloc = plac[TROLL] + fixd[TROLL] - g.loc;
221 if (g.prop[TROLL] == 0)
222 g.prop[TROLL] = 1;
223 if (toting(BEAR)) {
224 rspeak(162);
225 g.prop[CHASM] = 1;
226 g.prop[TROLL] = 2;
227 drop(BEAR, g.newloc);
228 g.fixed[BEAR] = -1;
229 g.prop[BEAR] = 3;
230 if (g.prop[SPICES] < 0)
231 ++g.tally2;
232 g.oldloc2 = g.newloc;
233 death();
234 }
235 }
236 break;
237 case 4:
238 /* Growing or shrinking in area of tiny door. Each time he
239 does this, everything must be moved to the new loc.
240 Presumably, all his possesions are shrunk or streched along
241 with him. Phuce[2][4] is an array containg four pairs of
242 "here" (K) and "there" (KK) locations. */
243 k = phuce[0][g.loc - 161];
244 g.newloc = phuce[1][g.loc - 161];
245 for (obj = 1; obj < MAXOBJ; obj++) {
246 if (obj == BOAT)
247 continue;
248 if (g.place[obj] == k && (g.fixed[obj] == 0 || g.fixed[obj] == -1))
249 move(obj, g.newloc);
250 }
251 break;
252 case 5:
253 /* Phone booth in rotunda. Trying to shove past gnome, to get
254 into phone booth. */
255 if ((g.prop[BOOTH] == 0 && pct(35)) || g.visited[g.loc] == 1) {
256 rspeak(263);
257 g.prop[BOOTH] = 1;
258 move(GNOME, 188);
259 } else {
260 if (g.prop[BOOTH] == 1)
261 rspeak(253);
262 else
263 g.newloc = 189;
264 }
265 break;
266 case 6:
267 /* Collapsing clay bridge. He can cross with three (or fewer)
268 thing. If more, of if carrying obviously heavy things, he
269 may end up in the drink. */
270 g.newloc = g.loc == 235 ? 190 : 235;
271 bcrossing++;
272 load = burden(0);
273 if (load > 4) {
274 k = (load + bcrossing) * 6 - 10;
275 if (!pct(k))
276 rspeak(318);
277 else {
278 rspeak(319);
279 g.newloc = 236;
280 if (holding(LAMP))
281 move(LAMP, 236);
282 if (toting(AXE) && enclosed(AXE))
283 extract(AXE);
284 if (holding(AXE))
285 move(AXE, 208);
286 for (obj = 1; obj < MAXOBJ; obj++)
287 if (toting(obj))
288 destroy(obj);
289 g.prop[CHASM2] = 1;
290 }
291 }
292 break;
293 case 7:
294 /* Kaleidoscope code is here. */
295 if (kalflg == 5) {
296 g.newloc = 248;
297 g.oldloc = 247;
298 } else {
299 g.newloc = 242 + ranz(5);
300 g.oldloc = g.newloc - 1;
301 kalflg = g.newloc == 242 ? 0 : -10;
302 }
303 break;
304 default:
305 bug(38);
306 }
307 return;
308}
309
310/*
311 Routine to fill travel array for a given location
312*/
313void gettrav(loc, travel)
314int loc;
315struct trav *travel;
316{
317 int i;
318 long t, *lptr;
319
320 lptr = cave[loc - 1];
321 for (i = 0; i < MAXTRAV; i++) {
322 t = *lptr++;
323 if (!(t)) {
324 travel->tdest = -1; /* end of array */
325 return; /* terminate for loop */
326 }
327 travel->tverb = (int) (t % 1000);
328 t /= 1000;
329 travel->tdest = (int) (t % 1000);
330 t /= 1000;
331 travel->tcond = (int) (t % 1000);
332 travel++;
333 }
334 bug(25);
335 return;
336}
Note: See TracBrowser for help on using the repository browser.