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
8void
9take_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
38int
39dosit()
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	    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#endif
121	} else if(IS_ALTAR(typ)) {
122
123	    You(sit_message, defsyms[S_altar].explanation);
124	    altar_wrath(u.ux, u.uy);
125
126	} else if(IS_GRAVE(typ)) {
127
128	    You(sit_message, defsyms[S_grave].explanation);
129
130	} else if(typ == STAIRS) {
131
132	    You(sit_message, "stairs");
133
134	} else if(typ == LADDER) {
135
136	    You(sit_message, "ladder");
137
138	} else if (is_lava(u.ux, u.uy)) {
139
140	    /* must be WWalking */
141	    You(sit_message, "lava");
142	    burn_away_slime();
143	    if (likes_lava(youmonst.data)) {
144		pline_The("lava feels warm.");
145		return 1;
146	    }
147	    pline_The("lava burns you!");
148	    losehp(d((Fire_resistance ? 2 : 10), 10),
149		   "sitting on lava", KILLED_BY);
150
151	} else if (is_ice(u.ux, u.uy)) {
152
153	    You(sit_message, defsyms[S_ice].explanation);
154	    if (!Cold_resistance) pline_The("ice feels cold.");
155
156	} else if (typ == DRAWBRIDGE_DOWN) {
157
158	    You(sit_message, "drawbridge");
159
160	} else if(IS_THRONE(typ)) {
161
162	    You(sit_message, defsyms[S_throne].explanation);
163	    if (rnd(6) > 4)  {
164		switch (rnd(13))  {
165		    case 1:
166			(void) adjattrib(rn2(A_MAX), -rn1(4,3), FALSE);
167			losehp(rnd(10), "cursed throne", KILLED_BY_AN);
168			break;
169		    case 2:
170			(void) adjattrib(rn2(A_MAX), 1, FALSE);
171			break;
172		    case 3:
173			pline("A%s electric shock shoots through your body!",
174			      (Shock_resistance) ? "n" : " massive");
175			losehp(Shock_resistance ? rnd(6) : rnd(30),
176			       "electric chair", KILLED_BY_AN);
177			exercise(A_CON, FALSE);
178			break;
179		    case 4:
180			You_feel("much, much better!");
181			if (Upolyd) {
182			    if (u.mh >= (u.mhmax - 5))  u.mhmax += 4;
183			    u.mh = u.mhmax;
184			}
185			if(u.uhp >= (u.uhpmax - 5))  u.uhpmax += 4;
186			u.uhp = u.uhpmax;
187			make_blinded(0L,TRUE);
188			make_sick(0L, (char *) 0, FALSE, SICK_ALL);
189			heal_legs();
190			flags.botl = 1;
191			break;
192		    case 5:
193			take_gold();
194			break;
195		    case 6:
196			if(u.uluck + rn2(5) < 0) {
197			    You_feel("your luck is changing.");
198			    change_luck(1);
199			} else	    makewish();
200			break;
201		    case 7:
202			{
203			register int cnt = rnd(10);
204
205			pline("A voice echoes:");
206			verbalize("Thy audience hath been summoned, %s!",
207				  flags.female ? "Dame" : "Sire");
208			while(cnt--)
209			    (void) makemon(courtmon(), u.ux, u.uy, NO_MM_FLAGS);
210			break;
211			}
212		    case 8:
213			pline("A voice echoes:");
214			verbalize("By thy Imperious order, %s...",
215				  flags.female ? "Dame" : "Sire");
216			do_genocide(5);	/* REALLY|ONTHRONE, see do_genocide() */
217			break;
218		    case 9:
219			pline("A voice echoes:");
220	verbalize("A curse upon thee for sitting upon this most holy throne!");
221			if (Luck > 0)  {
222			    make_blinded(Blinded + rn1(100,250),TRUE);
223			} else	    rndcurse();
224			break;
225		    case 10:
226			if (Luck < 0 || (HSee_invisible & INTRINSIC))  {
227				if (level.flags.nommap) {
228					pline(
229					"A terrible drone fills your head!");
230					make_confused(HConfusion + rnd(30),
231									FALSE);
232				} else {
233					pline("An image forms in your mind.");
234					do_mapping();
235				}
236			} else  {
237				Your("vision becomes clear.");
238				HSee_invisible |= FROMOUTSIDE;
239				newsym(u.ux, u.uy);
240			}
241			break;
242		    case 11:
243			if (Luck < 0)  {
244			    You_feel("threatened.");
245			    aggravate();
246			} else  {
247
248			    You_feel("a wrenching sensation.");
249			    tele();		/* teleport him */
250			}
251			break;
252		    case 12:
253			You("are granted an insight!");
254			if (invent) {
255			    /* rn2(5) agrees w/seffects() */
256			    identify_pack(rn2(5));
257			}
258			break;
259		    case 13:
260			Your("mind turns into a pretzel!");
261			make_confused(HConfusion + rn1(7,16),FALSE);
262			break;
263		    default:	impossible("throne effect");
264				break;
265		}
266	    } else {
267		if (is_prince(youmonst.data))
268		    You_feel("very comfortable here.");
269		else
270		    You_feel("somehow out of place...");
271	    }
272
273	    if (!rn2(3) && IS_THRONE(levl[u.ux][u.uy].typ)) {
274		/* may have teleported */
275		levl[u.ux][u.uy].typ = ROOM;
276		pline_The("throne vanishes in a puff of logic.");
277		newsym(u.ux,u.uy);
278	    }
279
280	} else if (lays_eggs(youmonst.data)) {
281		struct obj *uegg;
282
283		if (!flags.female) {
284			pline("Males can't lay eggs!");
285			return 0;
286		}
287
288		if (u.uhunger < (int)objects[EGG].oc_nutrition) {
289			You("don't have enough energy to lay an egg.");
290			return 0;
291		}
292
293		uegg = mksobj(EGG, FALSE, FALSE);
294		uegg->spe = 1;
295		uegg->quan = 1;
296		uegg->owt = weight(uegg);
297		uegg->corpsenm = egg_type_from_parent(u.umonnum, FALSE);
298		uegg->known = uegg->dknown = 1;
299		attach_egg_hatch_timeout(uegg);
300		You("lay an egg.");
301		dropy(uegg);
302		stackobj(uegg);
303		morehungry((int)objects[EGG].oc_nutrition);
304	} else if (u.uswallow)
305		There("are no seats in here!");
306	else
307		pline("Having fun sitting on the %s?", surface(u.ux,u.uy));
308	return(1);
309}
310
311void
312rndcurse()			/* curse a few inventory items at random! */
313{
314	int	nobj = 0;
315	int	cnt, onum;
316	struct	obj	*otmp;
317	static const char mal_aura[] = "feel a malignant aura surround %s.";
318
319	if (uwep && (uwep->oartifact == ART_MAGICBANE) && rn2(20)) {
320	    You(mal_aura, "the magic-absorbing blade");
321	    return;
322	}
323
324	if(Antimagic) {
325	    shieldeff(u.ux, u.uy);
326	    You(mal_aura, "you");
327	}
328
329	for (otmp = invent; otmp; otmp = otmp->nobj) {
330#ifdef GOLDOBJ
331	    /* gold isn't subject to being cursed or blessed */
332	    if (otmp->oclass == COIN_CLASS) continue;
333#endif
334	    nobj++;
335	}
336	if (nobj) {
337	    for (cnt = rnd(6/((!!Antimagic) + (!!Half_spell_damage) + 1));
338		 cnt > 0; cnt--)  {
339		onum = rnd(nobj);
340		for (otmp = invent; otmp; otmp = otmp->nobj) {
341#ifdef GOLDOBJ
342		    /* as above */
343		    if (otmp->oclass == COIN_CLASS) continue;
344#endif
345		    if (--onum == 0) break;	/* found the target */
346		}
347		/* the !otmp case should never happen; picking an already
348		   cursed item happens--avoid "resists" message in that case */
349		if (!otmp || otmp->cursed) continue;	/* next target */
350
351		if(otmp->oartifact && spec_ability(otmp, SPFX_INTEL) &&
352		   rn2(10) < 8) {
353		    pline("%s!", Tobjnam(otmp, "resist"));
354		    continue;
355		}
356
357		if(otmp->blessed)
358			unbless(otmp);
359		else
360			curse(otmp);
361	    }
362	    update_inventory();
363	}
364
365#ifdef STEED
366	/* treat steed's saddle as extended part of hero's inventory */
367	if (u.usteed && !rn2(4) &&
368		(otmp = which_armor(u.usteed, W_SADDLE)) != 0 &&
369		!otmp->cursed) {	/* skip if already cursed */
370	    if (otmp->blessed)
371		unbless(otmp);
372	    else
373		curse(otmp);
374	    if (!Blind) {
375		pline("%s %s %s.",
376		      s_suffix(upstart(y_monnam(u.usteed))),
377		      aobjnam(otmp, "glow"),
378		      hcolor(otmp->cursed ? NH_BLACK : (const char *)"brown"));
379		otmp->bknown = TRUE;
380	    }
381	}
382#endif	/*STEED*/
383}
384
385void
386attrcurse()			/* remove a random INTRINSIC ability */
387{
388	switch(rnd(11)) {
389	case 1 : if (HFire_resistance & INTRINSIC) {
390			HFire_resistance &= ~INTRINSIC;
391			You_feel("warmer.");
392			break;
393		}
394	case 2 : if (HTeleportation & INTRINSIC) {
395			HTeleportation &= ~INTRINSIC;
396			You_feel("less jumpy.");
397			break;
398		}
399	case 3 : if (HPoison_resistance & INTRINSIC) {
400			HPoison_resistance &= ~INTRINSIC;
401			You_feel("a little sick!");
402			break;
403		}
404	case 4 : if (HTelepat & INTRINSIC) {
405			HTelepat &= ~INTRINSIC;
406			if (Blind && !Blind_telepat)
407			    see_monsters();	/* Can't sense mons anymore! */
408			Your("senses fail!");
409			break;
410		}
411	case 5 : if (HCold_resistance & INTRINSIC) {
412			HCold_resistance &= ~INTRINSIC;
413			You_feel("cooler.");
414			break;
415		}
416	case 6 : if (HInvis & INTRINSIC) {
417			HInvis &= ~INTRINSIC;
418			You_feel("paranoid.");
419			break;
420		}
421	case 7 : if (HSee_invisible & INTRINSIC) {
422			HSee_invisible &= ~INTRINSIC;
423			You("%s!", Hallucination ? "tawt you taw a puttie tat"
424						: "thought you saw something");
425			break;
426		}
427	case 8 : if (HFast & INTRINSIC) {
428			HFast &= ~INTRINSIC;
429			You_feel("slower.");
430			break;
431		}
432	case 9 : if (HStealth & INTRINSIC) {
433			HStealth &= ~INTRINSIC;
434			You_feel("clumsy.");
435			break;
436		}
437	case 10: if (HProtection & INTRINSIC) {
438			HProtection &= ~INTRINSIC;
439			You_feel("vulnerable.");
440			break;
441		}
442	case 11: if (HAggravate_monster & INTRINSIC) {
443			HAggravate_monster &= ~INTRINSIC;
444			You_feel("less attractive.");
445			break;
446		}
447	default: break;
448	}
449}
450
451/*sit.c*/
452