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