Add html production for convenience generating the website.
[open-adventure.git] / actions2.c
1 #include "advent.h"
2 #include "funcs.h"
3
4 /*  Carry an object.  Special cases for bird and cage (if bird in cage, can't
5  *  take one without the other).  Liquids also special, since they depend on
6  *  status of bottle.  Also various side effects, etc. */
7
8 int carry(void) {
9         if(TOTING(OBJ)) return(2011);
10         SPK=25;
11         if(OBJ == PLANT && PROP[PLANT] <= 0)SPK=115;
12         if(OBJ == BEAR && PROP[BEAR] == 1)SPK=169;
13         if(OBJ == CHAIN && PROP[BEAR] != 0)SPK=170;
14         if(OBJ == URN)SPK=215;
15         if(OBJ == CAVITY)SPK=217;
16         if(OBJ == BLOOD)SPK=239;
17         if(OBJ == RUG && PROP[RUG] == 2)SPK=222;
18         if(OBJ == SIGN)SPK=196;
19         if(OBJ != MESSAG) goto L9011;
20         SPK=190;
21         DSTROY(MESSAG);
22 L9011:  if(FIXED[OBJ] != 0) return(2011);
23         if(OBJ != WATER && OBJ != OIL) goto L9017;
24         K=OBJ;
25         OBJ=BOTTLE;
26         if(HERE(BOTTLE) && LIQ(0) == K) goto L9017;
27         if(TOTING(BOTTLE) && PROP[BOTTLE] == 1) return(fill());
28         if(PROP[BOTTLE] != 1)SPK=105;
29         if(!TOTING(BOTTLE))SPK=104;
30          return(2011);
31 L9017:  SPK=92;
32         if(HOLDNG >= 7) return(2011);
33         if(OBJ != BIRD || PROP[BIRD] == 1 || -1-PROP[BIRD] == 1) goto L9014;
34         if(PROP[BIRD] == 2) goto L9015;
35         if(!TOTING(CAGE))SPK=27;
36         if(TOTING(ROD))SPK=26;
37         if(SPK/2 == 13) return(2011);
38         PROP[BIRD]=1;
39 L9014:  if((OBJ == BIRD || OBJ == CAGE) && (PROP[BIRD] == 1 || -1-PROP[BIRD] ==
40                 1))CARRY(BIRD+CAGE-OBJ,LOC);
41         CARRY(OBJ,LOC);
42         K=LIQ(0);
43         if(OBJ == BOTTLE && K != 0)PLACE[K]= -1;
44         if(!GSTONE(OBJ) || PROP[OBJ] == 0) return(2009);
45         PROP[OBJ]=0;
46         PROP[CAVITY]=1;
47          return(2009);
48
49 L9015:  SPK=238;
50         DSTROY(BIRD);
51          return(2011);
52 }
53
54 /*  Discard object.  "Throw" also comes here for most objects.  Special cases for
55  *  bird (might attack snake or dragon) and cage (might contain bird) and vase.
56  *  Drop coins at vending machine for extra batteries. */
57
58 int discard(bool just_do_it) {
59         if(just_do_it) goto L9021;
60         if(TOTING(ROD2) && OBJ == ROD && !TOTING(ROD))OBJ=ROD2;
61         if(!TOTING(OBJ)) return(2011);
62         if(OBJ != BIRD || !HERE(SNAKE)) goto L9023;
63         RSPEAK(30);
64         if(CLOSED) return(19000);
65         DSTROY(SNAKE);
66 /*  SET PROP FOR USE BY TRAVEL OPTIONS */
67         PROP[SNAKE]=1;
68 L9021:  K=LIQ(0);
69         if(K == OBJ)OBJ=BOTTLE;
70         if(OBJ == BOTTLE && K != 0)PLACE[K]=0;
71         if(OBJ == CAGE && PROP[BIRD] == 1)DROP(BIRD,LOC);
72         DROP(OBJ,LOC);
73         if(OBJ != BIRD) return(2012);
74         PROP[BIRD]=0;
75         if(FOREST(LOC))PROP[BIRD]=2;
76          return(2012);
77
78 L9023:  if(!(GSTONE(OBJ) && AT(CAVITY) && PROP[CAVITY] != 0)) goto L9024;
79         RSPEAK(218);
80         PROP[OBJ]=1;
81         PROP[CAVITY]=0;
82         if(!HERE(RUG) || !((OBJ == EMRALD && PROP[RUG] != 2) || (OBJ == RUBY &&
83                 PROP[RUG] == 2))) goto L9021;
84         SPK=219;
85         if(TOTING(RUG))SPK=220;
86         if(OBJ == RUBY)SPK=221;
87         RSPEAK(SPK);
88         if(SPK == 220) goto L9021;
89         K=2-PROP[RUG];
90         PROP[RUG]=K;
91         if(K == 2)K=PLAC[SAPPH];
92         MOVE(RUG+100,K);
93          goto L9021;
94
95 L9024:  if(OBJ != COINS || !HERE(VEND)) goto L9025;
96         DSTROY(COINS);
97         DROP(BATTER,LOC);
98         PSPEAK(BATTER,0);
99          return(2012);
100
101 L9025:  if(OBJ != BIRD || !AT(DRAGON) || PROP[DRAGON] != 0) goto L9026;
102         RSPEAK(154);
103         DSTROY(BIRD);
104         PROP[BIRD]=0;
105          return(2012);
106
107 L9026:  if(OBJ != BEAR || !AT(TROLL)) goto L9027;
108         RSPEAK(163);
109         MOVE(TROLL,0);
110         MOVE(TROLL+100,0);
111         MOVE(TROLL2,PLAC[TROLL]);
112         MOVE(TROLL2+100,FIXD[TROLL]);
113         JUGGLE(CHASM);
114         PROP[TROLL]=2;
115          goto L9021;
116
117 L9027:  if(OBJ == VASE && LOC != PLAC[PILLOW]) goto L9028;
118         RSPEAK(54);
119          goto L9021;
120
121 L9028:  PROP[VASE]=2;
122         if(AT(PILLOW))PROP[VASE]=0;
123         PSPEAK(VASE,PROP[VASE]+1);
124         if(PROP[VASE] != 0)FIXED[VASE]= -1;
125          goto L9021;
126 }
127
128 /*  Attack.  Assume target if unambiguous.  "Throw" also links here.  Attackable
129  *  objects fall into two categories: enemies (snake, dwarf, etc.)  and others
130  *  (bird, clam, machine).  Ambiguous if 2 enemies, or no enemies but 2 others. */
131
132 int attack(FILE *input) {
133         I=ATDWRF(LOC);
134         if(OBJ != 0) goto L9124;
135         if(I > 0)OBJ=DWARF;
136         if(HERE(SNAKE))OBJ=OBJ*100+SNAKE;
137         if(AT(DRAGON) && PROP[DRAGON] == 0)OBJ=OBJ*100+DRAGON;
138         if(AT(TROLL))OBJ=OBJ*100+TROLL;
139         if(AT(OGRE))OBJ=OBJ*100+OGRE;
140         if(HERE(BEAR) && PROP[BEAR] == 0)OBJ=OBJ*100+BEAR;
141         if(OBJ > 100) return(8000);
142         if(OBJ != 0) goto L9124;
143 /*  CAN'T ATTACK BIRD OR MACHINE BY THROWING AXE. */
144         if(HERE(BIRD) && VERB != THROW)OBJ=BIRD;
145         if(HERE(VEND) && VERB != THROW)OBJ=OBJ*100+VEND;
146 /*  CLAM AND OYSTER BOTH TREATED AS CLAM FOR INTRANSITIVE CASE; NO HARM DONE. */
147         if(HERE(CLAM) || HERE(OYSTER))OBJ=100*OBJ+CLAM;
148         if(OBJ > 100) return(8000);
149 L9124:  if(OBJ != BIRD) goto L9125;
150         SPK=137;
151         if(CLOSED) return(2011);
152         DSTROY(BIRD);
153         PROP[BIRD]=0;
154         SPK=45;
155 L9125:  if(OBJ != VEND) goto L9126;
156         PSPEAK(VEND,PROP[VEND]+2);
157         PROP[VEND]=3-PROP[VEND];
158          return(2012);
159
160 L9126:  if(OBJ == 0)SPK=44;
161         if(OBJ == CLAM || OBJ == OYSTER)SPK=150;
162         if(OBJ == SNAKE)SPK=46;
163         if(OBJ == DWARF)SPK=49;
164         if(OBJ == DWARF && CLOSED) return(19000);
165         if(OBJ == DRAGON)SPK=167;
166         if(OBJ == TROLL)SPK=157;
167         if(OBJ == OGRE)SPK=203;
168         if(OBJ == OGRE && I > 0) goto L9128;
169         if(OBJ == BEAR)SPK=165+(PROP[BEAR]+1)/2;
170         if(OBJ != DRAGON || PROP[DRAGON] != 0) return(2011);
171 /*  Fun stuff for dragon.  If he insists on attacking it, win!  Set PROP to dead,
172  *  move dragon to central loc (still fixed), move rug there (not fixed), and
173  *  move him there, too.  Then do a null motion to get new description. */
174         RSPEAK(49);
175         VERB=0;
176         OBJ=0;
177         GETIN(input,WD1,WD1X,WD2,WD2X);
178         if(WD1 != MAKEWD(25) && WD1 != MAKEWD(250519)) return(2607);
179         PSPEAK(DRAGON,3);
180         PROP[DRAGON]=1;
181         PROP[RUG]=0;
182         K=(PLAC[DRAGON]+FIXD[DRAGON])/2;
183         MOVE(DRAGON+100,-1);
184         MOVE(RUG+100,0);
185         MOVE(DRAGON,K);
186         MOVE(RUG,K);
187         DROP(BLOOD,K);
188         for (OBJ=1; OBJ<=100; OBJ++) {
189         if(PLACE[OBJ] == PLAC[DRAGON] || PLACE[OBJ] == FIXD[DRAGON])MOVE(OBJ,K);
190         /*etc*/ ;
191         } /* end loop */
192         LOC=K;
193         K=NUL;
194          return(8);
195
196 L9128:  RSPEAK(SPK);
197         RSPEAK(6);
198         DSTROY(OGRE);
199         K=0;
200         /* 9129 */ for (I=1; I<=5; I++) {
201         if(DLOC[I] != LOC) goto L9129;
202         K=K+1;
203         DLOC[I]=61;
204         DSEEN[I]=false;
205 L9129:  /*etc*/ ;
206         } /* end loop */
207         SPK=SPK+1+1/K;
208          return(2011);
209 }
210
211 /*  Throw.  Same as discard unless axe.  Then same as attack except ignore bird,
212  *  and if dwarf is present then one might be killed.  (Only way to do so!)
213  *  Axe also special for dragon, bear, and troll.  Treasures special for troll. */
214
215 int throw(FILE *cmdin) {
216         if(TOTING(ROD2) && OBJ == ROD && !TOTING(ROD))OBJ=ROD2;
217         if(!TOTING(OBJ)) return(2011);
218         if(OBJ >= 50 && OBJ <= MAXTRS && AT(TROLL)) goto L9178;
219         if(OBJ == FOOD && HERE(BEAR)) goto L9177;
220         if(OBJ != AXE) return(discard(false));
221         I=ATDWRF(LOC);
222         if(I > 0) goto L9172;
223         SPK=152;
224         if(AT(DRAGON) && PROP[DRAGON] == 0) goto L9175;
225         SPK=158;
226         if(AT(TROLL)) goto L9175;
227         SPK=203;
228         if(AT(OGRE)) goto L9175;
229         if(HERE(BEAR) && PROP[BEAR] == 0) goto L9176;
230         OBJ=0;
231         return(attack(cmdin));
232
233 L9172:  SPK=48;
234         if(randrange(7) < DFLAG) goto L9175;
235         DSEEN[I]=false;
236         DLOC[I]=0;
237         SPK=47;
238         DKILL=DKILL+1;
239         if(DKILL == 1)SPK=149;
240 L9175:  RSPEAK(SPK);
241         DROP(AXE,LOC);
242         K=NUL;
243          return(8);
244
245 /*  This'll teach him to throw the axe at the bear! */
246 L9176:  SPK=164;
247         DROP(AXE,LOC);
248         FIXED[AXE]= -1;
249         PROP[AXE]=1;
250         JUGGLE(BEAR);
251          return(2011);
252
253 /*  But throwing food is another story. */
254 L9177:  OBJ=BEAR;
255         return(feed());
256
257 L9178:  SPK=159;
258 /*  Snarf a treasure for the troll. */
259         DROP(OBJ,0);
260         MOVE(TROLL,0);
261         MOVE(TROLL+100,0);
262         DROP(TROLL2,PLAC[TROLL]);
263         DROP(TROLL2+100,FIXD[TROLL]);
264         JUGGLE(CHASM);
265          return(2011);
266 }
267
268 /*  Feed.  If bird, no seed.  Snake, dragon, troll: quip.  If dwarf, make him
269  *  mad.  Bear, special. */
270
271 int feed() {
272         if(OBJ != BIRD) goto L9212;
273         SPK=100;
274          return(2011);
275
276 L9212:  if(OBJ != SNAKE && OBJ != DRAGON && OBJ != TROLL) goto L9213;
277         SPK=102;
278         if(OBJ == DRAGON && PROP[DRAGON] != 0)SPK=110;
279         if(OBJ == TROLL)SPK=182;
280         if(OBJ != SNAKE || CLOSED || !HERE(BIRD)) return(2011);
281         SPK=101;
282         DSTROY(BIRD);
283         PROP[BIRD]=0;
284          return(2011);
285
286 L9213:  if(OBJ != DWARF) goto L9214;
287         if(!HERE(FOOD)) return(2011);
288         SPK=103;
289         DFLAG=DFLAG+2;
290          return(2011);
291
292 L9214:  if(OBJ != BEAR) goto L9215;
293         if(PROP[BEAR] == 0)SPK=102;
294         if(PROP[BEAR] == 3)SPK=110;
295         if(!HERE(FOOD)) return(2011);
296         DSTROY(FOOD);
297         PROP[BEAR]=1;
298         FIXED[AXE]=0;
299         PROP[AXE]=0;
300         SPK=168;
301          return(2011);
302
303 L9215:  if(OBJ != OGRE) goto L9216;
304         if(HERE(FOOD))SPK=202;
305          return(2011);
306
307 L9216:  SPK=14;
308          return(2011);
309 }
310
311 /*  Fill.  Bottle or urn must be empty, and liquid available.  (Vase is nasty.) */
312
313 int fill() {
314         if(OBJ == VASE) goto L9222;
315         if(OBJ == URN) goto L9224;
316         if(OBJ != 0 && OBJ != BOTTLE) return(2011);
317         if(OBJ == 0 && !HERE(BOTTLE)) return(8000);
318         SPK=107;
319         if(LIQLOC(LOC) == 0)SPK=106;
320         if(HERE(URN) && PROP[URN] != 0)SPK=214;
321         if(LIQ(0) != 0)SPK=105;
322         if(SPK != 107) return(2011);
323         PROP[BOTTLE]=MOD(COND[LOC],4)/2*2;
324         K=LIQ(0);
325         if(TOTING(BOTTLE))PLACE[K]= -1;
326         if(K == OIL)SPK=108;
327          return(2011);
328
329 L9222:  SPK=29;
330         if(LIQLOC(LOC) == 0)SPK=144;
331         if(LIQLOC(LOC) == 0 || !TOTING(VASE)) return(2011);
332         RSPEAK(145);
333         PROP[VASE]=2;
334         FIXED[VASE]= -1;
335          return(discard(true));
336
337 L9224:  SPK=213;
338         if(PROP[URN] != 0) return(2011);
339         SPK=144;
340         K=LIQ(0);
341         if(K == 0 || !HERE(BOTTLE)) return(2011);
342         PLACE[K]=0;
343         PROP[BOTTLE]=1;
344         if(K == OIL)PROP[URN]=1;
345         SPK=211+PROP[URN];
346          return(2011);
347 }