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. */
9 if(TOTING(OBJ)) return(2011);
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;
22 L9011: if(FIXED[OBJ] != 0) return(2011);
23 if(OBJ != WATER && OBJ != OIL) goto L9017;
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;
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);
39 L9014: if((OBJ == BIRD || OBJ == CAGE) && (PROP[BIRD] == 1 || -1-PROP[BIRD] ==
40 1))CARRY(BIRD+CAGE-OBJ,LOC);
43 if(OBJ == BOTTLE && K != 0)PLACE[K]= -1;
44 if(!GSTONE(OBJ) || PROP[OBJ] == 0) return(2009);
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. */
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;
64 if(CLOSED) return(19000);
66 /* SET PROP FOR USE BY TRAVEL OPTIONS */
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);
73 if(OBJ != BIRD) return(2012);
75 if(FOREST(LOC))PROP[BIRD]=2;
78 L9023: if(!(GSTONE(OBJ) && AT(CAVITY) && PROP[CAVITY] != 0)) goto L9024;
82 if(!HERE(RUG) || !((OBJ == EMRALD && PROP[RUG] != 2) || (OBJ == RUBY &&
83 PROP[RUG] == 2))) goto L9021;
85 if(TOTING(RUG))SPK=220;
86 if(OBJ == RUBY)SPK=221;
88 if(SPK == 220) goto L9021;
91 if(K == 2)K=PLAC[SAPPH];
95 L9024: if(OBJ != COINS || !HERE(VEND)) goto L9025;
101 L9025: if(OBJ != BIRD || !AT(DRAGON) || PROP[DRAGON] != 0) goto L9026;
107 L9026: if(OBJ != BEAR || !AT(TROLL)) goto L9027;
111 MOVE(TROLL2,PLAC[TROLL]);
112 MOVE(TROLL2+100,FIXD[TROLL]);
117 L9027: if(OBJ == VASE && LOC != PLAC[PILLOW]) goto L9028;
122 if(AT(PILLOW))PROP[VASE]=0;
123 PSPEAK(VASE,PROP[VASE]+1);
124 if(PROP[VASE] != 0)FIXED[VASE]= -1;
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. */
132 int attack(FILE *input) {
134 if(OBJ != 0) goto L9124;
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;
151 if(CLOSED) return(2011);
155 L9125: if(OBJ != VEND) goto L9126;
156 PSPEAK(VEND,PROP[VEND]+2);
157 PROP[VEND]=3-PROP[VEND];
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. */
177 GETIN(input,WD1,WD1X,WD2,WD2X);
178 if(WD1 != MAKEWD(25) && WD1 != MAKEWD(250519)) return(2607);
182 K=(PLAC[DRAGON]+FIXD[DRAGON])/2;
188 for (OBJ=1; OBJ<=100; OBJ++) {
189 if(PLACE[OBJ] == PLAC[DRAGON] || PLACE[OBJ] == FIXD[DRAGON])MOVE(OBJ,K);
200 /* 9129 */ for (I=1; I<=5; I++) {
201 if(DLOC[I] != LOC) goto L9129;
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. */
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));
222 if(I > 0) goto L9172;
224 if(AT(DRAGON) && PROP[DRAGON] == 0) goto L9175;
226 if(AT(TROLL)) goto L9175;
228 if(AT(OGRE)) goto L9175;
229 if(HERE(BEAR) && PROP[BEAR] == 0) goto L9176;
231 return(attack(cmdin));
234 if(randrange(7) < DFLAG) goto L9175;
239 if(DKILL == 1)SPK=149;
245 /* This'll teach him to throw the axe at the bear! */
253 /* But throwing food is another story. */
258 /* Snarf a treasure for the troll. */
262 DROP(TROLL2,PLAC[TROLL]);
263 DROP(TROLL2+100,FIXD[TROLL]);
268 /* Feed. If bird, no seed. Snake, dragon, troll: quip. If dwarf, make him
269 * mad. Bear, special. */
272 if(OBJ != BIRD) goto L9212;
276 L9212: if(OBJ != SNAKE && OBJ != DRAGON && OBJ != TROLL) goto L9213;
278 if(OBJ == DRAGON && PROP[DRAGON] != 0)SPK=110;
279 if(OBJ == TROLL)SPK=182;
280 if(OBJ != SNAKE || CLOSED || !HERE(BIRD)) return(2011);
286 L9213: if(OBJ != DWARF) goto L9214;
287 if(!HERE(FOOD)) return(2011);
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);
303 L9215: if(OBJ != OGRE) goto L9216;
304 if(HERE(FOOD))SPK=202;
311 /* Fill. Bottle or urn must be empty, and liquid available. (Vase is nasty.) */
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);
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;
325 if(TOTING(BOTTLE))PLACE[K]= -1;
330 if(LIQLOC(LOC) == 0)SPK=144;
331 if(LIQLOC(LOC) == 0 || !TOTING(VASE)) return(2011);
335 return(discard(true));
338 if(PROP[URN] != 0) return(2011);
341 if(K == 0 || !HERE(BOTTLE)) return(2011);
344 if(K == OIL)PROP[URN]=1;