1 /* SCCS Id: @(#)sit.c 3.4 2002/09/21 */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
4
5 #include "hack.h"
6 #include "artifact.h"
7
8 STATIC_DCL void FDECL(curse_objects, (struct obj *, int, boolean));
9
10 void
take_gold()11 take_gold()
12 {
13 #ifndef GOLDOBJ
14 if (u.ugold <= 0) {
15 You_feel("a strange sensation.");
16 } else {
17 You("notice you have no gold!");
18 u.ugold = 0;
19 flags.botl = 1;
20 }
21 #else
22 struct obj *otmp, *nobj;
23 int lost_money = 0;
24 for (otmp = invent; otmp; otmp = nobj) {
25 nobj = otmp->nobj;
26 if (otmp->oclass == COIN_CLASS) {
27 lost_money = 1;
28 delobj(otmp);
29 }
30 }
31 if (!lost_money) {
32 You_feel("a strange sensation.");
33 } else {
34 You("notice you have no money!");
35 flags.botl = 1;
36 }
37 #endif
38 }
39
40 int
dosit()41 dosit()
42 {
43 static const char sit_message[] = "sit on the %s.";
44 register struct trap *trap;
45 register int typ = levl[u.ux][u.uy].typ;
46
47
48 #ifdef STEED
49 if (u.usteed) {
50 You("are already sitting on %s.", mon_nam(u.usteed));
51 return (0);
52 }
53 #endif
54
55 if(!can_reach_floor()) {
56 if (Levitation)
57 You("tumble in place.");
58 else
59 You("are sitting on air.");
60 return 0;
61 } else if (is_pool(u.ux, u.uy) && !Underwater) { /* water walking */
62 goto in_water;
63 }
64
65 if(OBJ_AT(u.ux, u.uy)) {
66 register struct obj *obj;
67
68 obj = level.objects[u.ux][u.uy];
69 You("sit on %s.", the(xname(obj)));
70 if (!(Is_box(obj) || objects[obj->otyp].oc_material == CLOTH))
71 pline("It's not very comfortable...");
72
73 } else if ((trap = t_at(u.ux, u.uy)) != 0 ||
74 (u.utrap && (u.utraptype >= TT_LAVA))) {
75
76 if (u.utrap) {
77 exercise(A_WIS, FALSE); /* you're getting stuck longer */
78 if(u.utraptype == TT_BEARTRAP) {
79 You_cant("sit down with your %s in the bear trap.", body_part(FOOT));
80 u.utrap++;
81 } else if(u.utraptype == TT_PIT) {
82 if(trap->ttyp == SPIKED_PIT) {
83 You("sit down on a spike. Ouch!");
84 losehp(1, "sitting on an iron spike", KILLED_BY);
85 exercise(A_STR, FALSE);
86 } else
87 You("sit down in the pit.");
88 u.utrap += rn2(5);
89 } else if(u.utraptype == TT_WEB) {
90 You("sit in the spider web and get entangled further!");
91 u.utrap += rn1(10, 5);
92 } else if(u.utraptype == TT_LAVA) {
93 /* Must have fire resistance or they'd be dead already */
94 You("sit in the lava!");
95 u.utrap += rnd(4);
96 losehp(d(2,10), "sitting in lava", KILLED_BY);
97 } else if(u.utraptype == TT_INFLOOR) {
98 You_cant("maneuver to sit!");
99 u.utrap++;
100 }
101 } else {
102 You("sit down.");
103 dotrap(trap, 0);
104 }
105 } else if(Underwater || Is_waterlevel(&u.uz)) {
106 if (Is_waterlevel(&u.uz))
107 There("are no cushions floating nearby.");
108 else
109 You("sit down on the muddy bottom.");
110 } else if(is_pool(u.ux, u.uy)) {
111 in_water:
112 You("sit in the water.");
113 if (!rn2(10) && uarm)
114 (void) rust_dmg(uarm, "armor", 1, TRUE, &youmonst);
115 if (!rn2(10) && uarmf && uarmf->otyp != WATER_WALKING_BOOTS)
116 (void) rust_dmg(uarm, "armor", 1, TRUE, &youmonst);
117 #ifdef SINKS
118 } else if(IS_SINK(typ)) {
119
120 You(sit_message, defsyms[S_sink].explanation);
121 Your("%s gets wet.", humanoid(youmonst.data) ? "rump" : "underside");
122 #endif
123 } else if(IS_ALTAR(typ)) {
124
125 You(sit_message, defsyms[S_altar].explanation);
126 altar_wrath(u.ux, u.uy);
127
128 } else if(IS_GRAVE(typ)) {
129
130 You(sit_message, defsyms[S_grave].explanation);
131
132 } else if(typ == STAIRS) {
133
134 You(sit_message, "stairs");
135
136 } else if(typ == LADDER) {
137
138 You(sit_message, "ladder");
139
140 } else if (is_lava(u.ux, u.uy)) {
141
142 /* must be WWalking */
143 You(sit_message, "lava");
144 burn_away_slime();
145 if (likes_lava(youmonst.data)) {
146 pline_The("lava feels warm.");
147 return 1;
148 }
149 pline_The("lava burns you!");
150 losehp(d((Fire_resistance ? 2 : 10), 10),
151 "sitting on lava", KILLED_BY);
152
153 } else if (is_ice(u.ux, u.uy)) {
154
155 You(sit_message, defsyms[S_ice].explanation);
156 if (!Cold_resistance) pline_The("ice feels cold.");
157
158 } else if (typ == DRAWBRIDGE_DOWN) {
159
160 You(sit_message, "drawbridge");
161
162 } else if(IS_THRONE(typ)) {
163
164 You(sit_message, defsyms[S_throne].explanation);
165 if (rnd(6) > 4) {
166 switch (rnd(13)) {
167 case 1:
168 (void) adjattrib(rn2(A_MAX), -rn1(4,3), FALSE);
169 losehp(rnd(10), "cursed throne", KILLED_BY_AN);
170 break;
171 case 2:
172 (void) adjattrib(rn2(A_MAX), 1, FALSE);
173 break;
174 case 3:
175 pline("A%s electric shock shoots through your body!",
176 (Shock_resistance) ? "n" : " massive");
177 losehp(Shock_resistance ? rnd(6) : rnd(30),
178 "electric chair", KILLED_BY_AN);
179 exercise(A_CON, FALSE);
180 break;
181 case 4:
182 You_feel("much, much better!");
183 if (Upolyd) {
184 if (u.mh >= (u.mhmax - 5)) u.mhmax += 4;
185 u.mh = u.mhmax;
186 }
187 if(u.uhp >= (u.uhpmax - 5)) u.uhpmax += 4;
188 u.uhp = u.uhpmax;
189 make_blinded(0L,TRUE);
190 make_sick(0L, (char *) 0, FALSE, SICK_ALL);
191 heal_legs();
192 flags.botl = 1;
193 break;
194 case 5:
195 take_gold();
196 break;
197 case 6:
198 if (u.uluck + rn2(5) < 0) {
199 You_feel("your luck is changing.");
200 change_luck(1);
201 } else {
202 fix_attributes_and_properties((struct obj *)0, 6);
203 }
204 break;
205 case 7:
206 {
207 register int cnt = rnd(10);
208
209 pline("A voice echoes:");
210 verbalize("Thy audience hath been summoned, %s!",
211 flags.female ? "Dame" : "Sire");
212 while(cnt--)
213 (void) makemon(courtmon(), u.ux, u.uy, NO_MM_FLAGS);
214 break;
215 }
216 case 8:
217 pline("A voice echoes:");
218 verbalize("By thy Imperious order, %s...",
219 flags.female ? "Dame" : "Sire");
220 do_genocide(5, FALSE); /* REALLY|ONTHRONE, see do_genocide() */
221 break;
222 case 9:
223 pline("A voice echoes:");
224 verbalize("A curse upon thee for sitting upon this most holy throne!");
225 if (Luck > 0) {
226 make_blinded(Blinded + rn1(100,250),TRUE);
227 } else rndcurse();
228 break;
229 case 10:
230 if (Luck < 0 || (HSee_invisible & INTRINSIC)) {
231 if (level.flags.nommap) {
232 pline(
233 "A terrible drone fills your head!");
234 make_confused(HConfusion + rnd(30),
235 FALSE);
236 } else {
237 pline("An image forms in your mind.");
238 do_mapping();
239 }
240 } else {
241 Your("vision becomes clear.");
242 HSee_invisible |= FROMOUTSIDE;
243 newsym(u.ux, u.uy);
244 }
245 break;
246 case 11:
247 if (Luck < 0) {
248 You_feel("threatened.");
249 aggravate();
250 } else {
251
252 You_feel("a wrenching sensation.");
253 tele(); /* teleport him */
254 }
255 break;
256 case 12:
257 You("are granted an insight!");
258 if (invent) {
259 /* rn2(5) agrees w/seffects() */
260 identify_pack(rn2(5));
261 }
262 break;
263 case 13:
264 Your("mind turns into a pretzel!");
265 make_confused(HConfusion + rn1(7,16),FALSE);
266 break;
267 default: impossible("throne effect");
268 break;
269 }
270 } else {
271 if (is_prince(youmonst.data))
272 You_feel("very comfortable here.");
273 else
274 You_feel("somehow out of place...");
275 }
276
277 if (!rn2(3) && IS_THRONE(levl[u.ux][u.uy].typ)) {
278 /* may have teleported */
279 levl[u.ux][u.uy].typ = ROOM;
280 pline_The("throne vanishes in a puff of logic.");
281 newsym(u.ux,u.uy);
282 }
283
284 } else if (lays_eggs(youmonst.data)) {
285 struct obj *uegg;
286
287 if (!flags.female) {
288 pline("Males can't lay eggs!");
289 return 0;
290 }
291
292 if (u.uhunger < (int)objects[EGG].oc_nutrition) {
293 You("don't have enough energy to lay an egg.");
294 return 0;
295 }
296
297 uegg = mksobj(EGG, FALSE, FALSE);
298 uegg->spe = 1;
299 uegg->quan = 1;
300 uegg->owt = weight(uegg);
301 uegg->corpsenm = egg_type_from_parent(u.umonnum, FALSE);
302 uegg->known = uegg->dknown = 1;
303 attach_egg_hatch_timeout(uegg);
304 You("lay an egg.");
305 dropy(uegg);
306 stackobj(uegg);
307 morehungry((int)objects[EGG].oc_nutrition);
308 } else if (u.uswallow)
309 There("are no seats in here!");
310 else
311 pline("Having fun sitting on the %s?", surface(u.ux,u.uy));
312 return(1);
313 }
314
315 void
rndcurse()316 rndcurse() /* curse a few inventory items at random! */
317 {
318 struct obj *otmp;
319 static const char mal_aura[] = "feel a malignant aura surround %s.";
320
321 if (uwep && (uwep->oartifact == ART_MAGICBANE) && rn2(20)) {
322 You(mal_aura, "the magic-absorbing blade");
323 return;
324 }
325
326 if(Antimagic) {
327 shieldeff(u.ux, u.uy);
328 You(mal_aura, "you");
329 }
330
331 curse_objects(invent,
332 rnd(6/((!!Antimagic) + (!!Half_spell_damage) + 1)), TRUE);
333
334 #ifdef STEED
335 /* treat steed's saddle as extended part of hero's inventory */
336 if (u.usteed && !rn2(4) &&
337 (otmp = which_armor(u.usteed, W_SADDLE)) != 0 &&
338 !otmp->cursed) { /* skip if already cursed */
339 if (otmp->blessed)
340 unbless(otmp);
341 else
342 curse(otmp);
343 if (!Blind) {
344 pline("%s %s %s.",
345 s_suffix(upstart(y_monnam(u.usteed))),
346 aobjnam(otmp, "glow"),
347 hcolor(otmp->cursed ? NH_BLACK : (const char *)"brown"));
348 otmp->bknown = TRUE;
349 }
350 }
351 #endif /*STEED*/
352 }
353
354 void
curse_objects(firstobj,ncurse,showmsg)355 curse_objects(firstobj, ncurse, showmsg)
356 struct obj *firstobj;
357 int ncurse;
358 boolean showmsg;
359 {
360 struct obj *otmp;
361 int cnt, onum;
362 int nobj = 0;
363
364 for (otmp = firstobj; otmp; otmp = otmp->nobj) {
365 #ifdef GOLDOBJ
366 /* gold isn't subject to being cursed or blessed */
367 if (otmp->oclass == COIN_CLASS) continue;
368 #endif
369 nobj++;
370 }
371 if (nobj) {
372 for (cnt = ncurse; cnt > 0; cnt--) {
373 onum = rnd(nobj);
374 for (otmp = firstobj; otmp; otmp = otmp->nobj) {
375 #ifdef GOLDOBJ
376 /* as above */
377 if (otmp->oclass == COIN_CLASS) continue;
378 #endif
379 if (--onum == 0) break; /* found the target */
380 }
381 /* the !otmp case should never happen; picking an already
382 cursed item happens--avoid "resists" message in that case */
383 if (!otmp) continue; /* next target */
384 else if (otmp->cursed) {
385 if (Is_container(otmp))
386 curse_objects(otmp->cobj, 1, FALSE);
387 continue;
388 }
389
390 if(otmp->oartifact && spec_ability(otmp, SPFX_INTEL) &&
391 rn2(10) < 8) {
392 if (showmsg)
393 pline("%s!", Tobjnam(otmp, "resist"));
394 continue;
395 }
396
397 if(otmp->blessed)
398 unbless(otmp);
399 else
400 curse(otmp);
401 }
402 update_inventory();
403 }
404 }
405
406 void
attrcurse()407 attrcurse() /* remove a random INTRINSIC ability */
408 {
409 switch(rnd(11)) {
410 case 1 : if (HFire_resistance & INTRINSIC) {
411 HFire_resistance &= ~INTRINSIC;
412 You_feel("warmer.");
413 break;
414 }
415 case 2 : if (HTeleportation & INTRINSIC) {
416 HTeleportation &= ~INTRINSIC;
417 You_feel("less jumpy.");
418 break;
419 }
420 case 3 : if (HPoison_resistance & INTRINSIC) {
421 HPoison_resistance &= ~INTRINSIC;
422 You_feel("a little sick!");
423 break;
424 }
425 case 4 : if (HTelepat & INTRINSIC) {
426 HTelepat &= ~INTRINSIC;
427 if (Blind && !Blind_telepat)
428 see_monsters(); /* Can't sense mons anymore! */
429 Your("senses fail!");
430 break;
431 }
432 case 5 : if (HCold_resistance & INTRINSIC) {
433 HCold_resistance &= ~INTRINSIC;
434 You_feel("cooler.");
435 break;
436 }
437 case 6 : if (HInvis & INTRINSIC) {
438 HInvis &= ~INTRINSIC;
439 You_feel("paranoid.");
440 break;
441 }
442 case 7 : if (HSee_invisible & INTRINSIC) {
443 HSee_invisible &= ~INTRINSIC;
444 You("%s!", Hallucination ? "tawt you taw a puttie tat"
445 : "thought you saw something");
446 break;
447 }
448 case 8 : if (HFast & INTRINSIC) {
449 HFast &= ~INTRINSIC;
450 You_feel("slower.");
451 break;
452 }
453 case 9 : if (HStealth & INTRINSIC) {
454 HStealth &= ~INTRINSIC;
455 You_feel("clumsy.");
456 break;
457 }
458 case 10: if (HProtection & INTRINSIC) {
459 HProtection &= ~INTRINSIC;
460 You_feel("vulnerable.");
461 u.ublessed = 0; /* fix for C343-189 */
462 break;
463 }
464 case 11: if (HAggravate_monster & INTRINSIC) {
465 HAggravate_monster &= ~INTRINSIC;
466 You_feel("less attractive.");
467 break;
468 }
469 default: break;
470 }
471 }
472
473 /*sit.c*/
474