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. */
10 if (TOTING(obj)) return(2011);
12 if (obj == PLANT && game.prop[PLANT] <= 0)SPK=115;
13 if (obj == BEAR && game.prop[BEAR] == 1)SPK=169;
14 if (obj == CHAIN && game.prop[BEAR] != 0)SPK=170;
15 if (obj == URN)SPK=215;
16 if (obj == CAVITY)SPK=217;
17 if (obj == BLOOD)SPK=239;
18 if (obj == RUG && game.prop[RUG] == 2)SPK=222;
19 if (obj == SIGN)SPK=196;
24 if (game.fixed[obj] != 0)
26 if (obj == WATER || obj == OIL) {
27 if (!HERE(BOTTLE) || LIQ(0) != obj) {
28 if (TOTING(BOTTLE) && game.prop[BOTTLE] == 1)
30 if (game.prop[BOTTLE] != 1)SPK=105;
31 if (!TOTING(BOTTLE))SPK=104;
38 if (game.holdng >= INVLIMIT)
40 if (obj == BIRD && game.prop[BIRD] != 1 && -1-game.prop[BIRD] != 1) {
41 if (game.prop[BIRD] == 2) {
46 if (!TOTING(CAGE))SPK=27;
47 if (TOTING(ROD))SPK=26;
48 if (SPK/2 == 13) return(2011);
51 if ((obj==BIRD || obj==CAGE) && (game.prop[BIRD]==1 || -1-game.prop[BIRD]==1))
52 CARRY(BIRD+CAGE-obj,game.loc);
54 if (obj == BOTTLE && LIQ(0) != 0)
55 game.place[LIQ(0)] = -1;
56 if (!GSTONE(obj) || game.prop[obj] == 0)
63 /* Discard object. "Throw" also comes here for most objects. Special cases for
64 * bird (might attack snake or dragon) and cage (might contain bird) and vase.
65 * Drop coins at vending machine for extra batteries. */
67 int discard(long obj, bool just_do_it) {
68 if (just_do_it) goto L9021;
69 if (TOTING(ROD2) && obj == ROD && !TOTING(ROD))obj=ROD2;
70 if (!TOTING(obj)) return(2011);
71 if (obj != BIRD || !HERE(SNAKE)) goto L9023;
73 if (game.closed) return(19000);
75 /* Set game.prop for use by travel options */
78 if (K == obj)obj=BOTTLE;
79 if (obj == BOTTLE && K != 0)game.place[K]=0;
80 if (obj == CAGE && game.prop[BIRD] == 1)DROP(BIRD,game.loc);
82 if (obj != BIRD) return(2012);
84 if (FOREST(game.loc))game.prop[BIRD]=2;
87 L9023: if (!(GSTONE(obj) && AT(CAVITY) && game.prop[CAVITY] != 0)) goto L9024;
91 if (!HERE(RUG) || !((obj == EMRALD && game.prop[RUG] != 2) || (obj == RUBY &&
92 game.prop[RUG] == 2))) goto L9021;
94 if (TOTING(RUG))SPK=220;
95 if (obj == RUBY)SPK=221;
97 if (SPK == 220) goto L9021;
100 if (K == 2)K=PLAC[SAPPH];
101 MOVE(RUG+NOBJECTS,K);
104 L9024: if (obj != COINS || !HERE(VEND)) goto L9025;
106 DROP(BATTER,game.loc);
110 L9025: if (obj != BIRD || !AT(DRAGON) || game.prop[DRAGON] != 0) goto L9026;
116 L9026: if (obj != BEAR || !AT(TROLL)) goto L9027;
119 MOVE(TROLL+NOBJECTS,0);
120 MOVE(TROLL2,PLAC[TROLL]);
121 MOVE(TROLL2+NOBJECTS,FIXD[TROLL]);
126 L9027: if (obj == VASE && game.loc != PLAC[PILLOW]) goto L9028;
130 L9028: game.prop[VASE]=2;
131 if (AT(PILLOW))game.prop[VASE]=0;
132 PSPEAK(VASE,game.prop[VASE]+1);
133 if (game.prop[VASE] != 0)game.fixed[VASE]= -1;
137 /* Attack. Assume target if unambiguous. "Throw" also links here. Attackable
138 * objects fall into two categories: enemies (snake, dwarf, etc.) and others
139 * (bird, clam, machine). Ambiguous if 2 enemies, or no enemies but 2 others. */
141 int attack(FILE *input, long obj, long verb) {
143 if (obj != 0) goto L9124;
145 if (HERE(SNAKE))obj=obj*NOBJECTS+SNAKE;
146 if (AT(DRAGON) && game.prop[DRAGON] == 0)obj=obj*NOBJECTS+DRAGON;
147 if (AT(TROLL))obj=obj*NOBJECTS+TROLL;
148 if (AT(OGRE))obj=obj*NOBJECTS+OGRE;
149 if (HERE(BEAR) && game.prop[BEAR] == 0)obj=obj*NOBJECTS+BEAR;
150 if (obj > NOBJECTS) return(8000);
151 if (obj != 0) goto L9124;
152 /* Can't attack bird or machine by throwing axe. */
153 if (HERE(BIRD) && verb != THROW)obj=BIRD;
154 if (HERE(VEND) && verb != THROW)obj=obj*NOBJECTS+VEND;
155 /* Clam and oyster both treated as clam for intransitive case;
157 if (HERE(CLAM) || HERE(OYSTER))obj=NOBJECTS*obj+CLAM;
158 if (obj > NOBJECTS) return(8000);
159 L9124: if (obj == BIRD) {
161 if (game.closed) return(2011);
166 L9125: if (obj == VEND) {
167 PSPEAK(VEND,game.prop[VEND]+2);
168 game.prop[VEND]=3-game.prop[VEND];
173 if (obj == CLAM || obj == OYSTER)SPK=150;
174 if (obj == SNAKE)SPK=46;
175 if (obj == DWARF)SPK=49;
176 if (obj == DWARF && game.closed) return(19000);
177 if (obj == DRAGON)SPK=167;
178 if (obj == TROLL)SPK=157;
179 if (obj == OGRE)SPK=203;
180 if (obj == OGRE && I > 0) goto L9128;
181 if (obj == BEAR)SPK=165+(game.prop[BEAR]+1)/2;
182 if (obj != DRAGON || game.prop[DRAGON] != 0) return(2011);
183 /* Fun stuff for dragon. If he insists on attacking it, win!
184 * Set game.prop to dead, move dragon to central loc (still
185 * fixed), move rug there (not fixed), and move him there,
186 * too. Then do a null motion to get new description. */
188 GETIN(input,WD1,WD1X,WD2,WD2X);
189 if (WD1 != MAKEWD(25) && WD1 != MAKEWD(250519)) return(2607);
193 K=(PLAC[DRAGON]+FIXD[DRAGON])/2;
194 MOVE(DRAGON+NOBJECTS,-1);
195 MOVE(RUG+NOBJECTS,0);
199 for (obj=1; obj<=NOBJECTS; obj++) {
200 if (game.place[obj] == PLAC[DRAGON] || game.place[obj] == FIXD[DRAGON])MOVE(obj,K);
211 for (I=1; I < PIRATE; I++) {
212 if (game.dloc[I] == game.loc) {
222 int throw(FILE *cmdin, long obj, long verb)
223 /* Throw. Same as discard unless axe. Then same as attack except
224 * ignore bird, and if dwarf is present then one might be killed.
225 * (Only way to do so!) Axe also special for dragon, bear, and
226 * troll. Treasures special for troll. */
228 if (TOTING(ROD2) && obj == ROD && !TOTING(ROD))obj=ROD2;
231 if (obj >= 50 && obj <= MAXTRS && AT(TROLL))
233 if (obj == FOOD && HERE(BEAR))
236 return(discard(obj, false));
241 if (AT(DRAGON) && game.prop[DRAGON] == 0)
249 if (HERE(BEAR) && game.prop[BEAR] == 0)
251 return(attack(cmdin, 0, verb));
255 if (randrange(NDWARVES+1) < game.dflag) goto L9175;
259 game.dkill=game.dkill+1;
260 if (game.dkill == 1)SPK=149;
267 /* This'll teach him to throw the axe at the bear! */
276 /* But throwing food is another story. */
283 /* Snarf a treasure for the troll. */
286 MOVE(TROLL+NOBJECTS,0);
287 DROP(TROLL2,PLAC[TROLL]);
288 DROP(TROLL2+NOBJECTS,FIXD[TROLL]);
294 /* Feed. If bird, no seed. Snake, dragon, troll: quip. If dwarf, make him
295 * mad. Bear, special. */
302 if (!(obj != SNAKE && obj != DRAGON && obj != TROLL)) {
304 if (obj == DRAGON && game.prop[DRAGON] != 0)SPK=110;
305 if (obj == TROLL)SPK=182;
306 if (obj != SNAKE || game.closed || !HERE(BIRD))
318 game.dflag=game.dflag+2;
323 if (game.prop[BEAR] == 0)SPK=102;
324 if (game.prop[BEAR] == 3)SPK=110;
346 /* Fill. Bottle or urn must be empty, and liquid available. (Vase
352 if (LIQLOC(game.loc) == 0)SPK=144;
353 if (LIQLOC(game.loc) == 0 || !TOTING(VASE))
357 game.fixed[VASE]= -1;
358 return(discard(obj, true));
363 if (game.prop[URN] != 0) return(2011);
366 if (k == 0 || !HERE(BOTTLE)) return(2011);
369 if (k == OIL)game.prop[URN]=1;
370 SPK=211+game.prop[URN];
374 if (obj != 0 && obj != BOTTLE)
376 if (obj == 0 && !HERE(BOTTLE))
379 if (LIQLOC(game.loc) == 0)
381 if (HERE(URN) && game.prop[URN] != 0)
387 game.prop[BOTTLE]=MOD(COND[game.loc],4)/2*2;