rogue

Ken Arnold's Rogue
git clone https://git.woozle.org/neale/rogue.git

Neale Pickett  ·  2011-10-13

ether.c

  1/*
  2 * Function(s) for dealing with potions
  3 *
  4 * @(#)ether.c	4.46 (Berkeley) 06/07/83
  5 */
  6
  7#include <curses.h>
  8#include <ctype.h>
  9#include "netprot.h"
 10
 11typedef struct
 12{
 13    int pa_flags;
 14    void (*pa_daemon)(void);
 15    int pa_time;
 16    char *pa_high, *pa_straight;
 17} PACT;
 18
 19static PACT P_actions[] =
 20{
 21	{ ISHUH,	unconfuse,	HUHDURATION,	/* P_CONFUSE */
 22		"what a tripy feeling!",
 23		"wait, what's going on here. Huh? What? Who?" },
 24	{ ISHALU,	come_down,	SEEDURATION,	/* P_LSD */
 25		"Oh, wow!  Everything seems so cosmic!",
 26		"Oh, wow!  Everything seems so cosmic!" },
 27	{ 0,		NULL,	0 },			/* P_POISON */
 28	{ 0,		NULL,	0 },			/* P_STRENGTH */
 29	{ CANSEE,	unsee,	SEEDURATION,		/* P_SEEINVIS */
 30		Prbuf,
 31		Prbuf },
 32	{ 0,		NULL,	0 },			/* P_HEALING */
 33	{ 0,		NULL,	0 },			/* P_MFIND */
 34	{ 0,		NULL,	0 },			/* P_TFIND  */
 35	{ 0,		NULL,	0 },			/* P_RAISE */
 36	{ 0,		NULL,	0 },			/* P_XHEAL */
 37	{ 0,		NULL,	0 },			/* P_HASTE */
 38	{ 0,		NULL,	0 },			/* P_RESTORE */
 39	{ ISBLIND,	sight,	SEEDURATION,		/* P_BLIND */
 40		"oh, bummer!  Everything is dark!  Help!",
 41		"a cloak of darkness falls around you" },
 42	{ ISLEVIT,	land,	HEALTIME,		/* P_LEVIT */
 43		"oh, wow!  You're floating in the air!",
 44		"you start to float in the air" }
 45};
 46
 47/*
 48 * quaff:
 49 *	Quaff a potion from the pack
 50 */
 51void
 52quaff(void)
 53{
 54    THING *obj, *tp, *mp;
 55    bool discardit = FALSE;
 56    bool show, trip;
 57
 58    obj = get_item("quaff", POTION);
 59    /*
 60     * Make certain that it is somethings that we want to drink
 61     */
 62    if (obj == NULL)
 63	return;
 64    if (obj->o_type != POTION)
 65    {
 66	if (!Terse)
 67	    msg("yuk! Why would you want to drink that?");
 68	else
 69	    msg("that's undrinkable");
 70	return;
 71    }
 72    if (obj == Cur_weapon)
 73	Cur_weapon = NULL;
 74
 75    /*
 76     * Calculate the effect it has on the poor guy.
 77     */
 78    trip = on(Player, ISHALU);
 79    discardit = (obj->o_count == 1);
 80    leave_pack(obj, FALSE, FALSE);
 81    switch (obj->o_which)
 82    {
 83	when P_CONFUSE:
 84	    do_pot(P_CONFUSE, !trip);
 85	when P_POISON:
 86	    Pot_info[P_POISON].oi_know = TRUE;
 87	    if (ISWEARING(R_SUSTSTR))
 88		msg("you feel momentarily sick");
 89	    else
 90	    {
 91		chg_str(-(rnd(3) + 1));
 92		msg("you feel very sick now");
 93		come_down();
 94	    }
 95	when P_HEALING:
 96	    Pot_info[P_HEALING].oi_know = TRUE;
 97	    if ((Pstats.s_hpt += roll(Pstats.s_lvl, 4)) > Max_hp)
 98		Pstats.s_hpt = ++Max_hp;
 99	    sight();
100	    msg("you begin to feel better");
101	when P_STRENGTH:
102	    Pot_info[P_STRENGTH].oi_know = TRUE;
103	    chg_str(1);
104	    msg("you feel stronger, now.  What bulging muscles!");
105	when P_MFIND:
106	    Player.t_flags |= SEEMONST;
107	    fuse(turn_see, TRUE, HUHDURATION, AFTER);
108	    if (!turn_see(FALSE))
109		msg("you have a %s feeling for a moment, then it passes",
110		    choose_str("normal", "strange"));
111	when P_TFIND:
112	    /*
113	     * Potion of magic detection.  Show the potions and scrolls
114	     */
115	    show = FALSE;
116	    if (Lvl_obj != NULL)
117	    {
118		wclear(Hw);
119		for (tp = Lvl_obj; tp != NULL; tp = next(tp))
120		{
121		    if (is_magic(tp))
122		    {
123			show = TRUE;
124			wmove(Hw, tp->o_pos.y, tp->o_pos.x);
125			waddch(Hw, MAGIC);
126			Pot_info[P_TFIND].oi_know = TRUE;
127		    }
128		}
129		for (mp = Mlist; mp != NULL; mp = next(mp))
130		{
131		    for (tp = mp->t_pack; tp != NULL; tp = next(tp))
132		    {
133			if (is_magic(tp))
134			{
135			    show = TRUE;
136			    wmove(Hw, mp->t_pos.y, mp->t_pos.x);
137			    waddch(Hw, MAGIC);
138			}
139		    }
140		}
141	    }
142	    if (show)
143	    {
144		Pot_info[P_TFIND].oi_know = TRUE;
145		show_win("You sense the presence of magic on this level.--More--");
146	    }
147	    else
148		msg("you have a %s feeling for a moment, then it passes",
149		    choose_str("normal", "strange"));
150	when P_LSD:
151	    if (!trip)
152	    {
153		if (on(Player, SEEMONST))
154		    turn_see(FALSE);
155		start_daemon(visuals, 0, BEFORE);
156		Seenstairs = seen_stairs();
157	    }
158	    do_pot(P_LSD, TRUE);
159	when P_SEEINVIS:
160	    sprintf(Prbuf, "this potion tastes like %s juice", Fruit);
161	    show = on(Player, CANSEE);
162	    do_pot(P_SEEINVIS, FALSE);
163	    if (!show)
164		invis_on();
165	    sight();
166	when P_RAISE:
167	    Pot_info[P_RAISE].oi_know = TRUE;
168	    msg("you suddenly feel much more skillful");
169	    raise_level();
170	when P_XHEAL:
171	    Pot_info[P_XHEAL].oi_know = TRUE;
172	    if ((Pstats.s_hpt += roll(Pstats.s_lvl, 8)) > Max_hp)
173	    {
174		if (Pstats.s_hpt > Max_hp + Pstats.s_lvl + 1)
175		    ++Max_hp;
176		Pstats.s_hpt = ++Max_hp;
177	    }
178	    sight();
179	    come_down();
180	    msg("you begin to feel much better");
181	when P_HASTE:
182	    Pot_info[P_HASTE].oi_know = TRUE;
183	    After = FALSE;
184	    if (add_haste(TRUE))
185		msg("you feel yourself moving much faster");
186	when P_RESTORE:
187	    if (ISRING(LEFT, R_ADDSTR))
188		add_str(&Pstats.s_str, -Cur_ring[LEFT]->o_arm);
189	    if (ISRING(RIGHT, R_ADDSTR))
190		add_str(&Pstats.s_str, -Cur_ring[RIGHT]->o_arm);
191	    if (Pstats.s_str < Max_stats.s_str)
192		Pstats.s_str = Max_stats.s_str;
193	    if (ISRING(LEFT, R_ADDSTR))
194		add_str(&Pstats.s_str, Cur_ring[LEFT]->o_arm);
195	    if (ISRING(RIGHT, R_ADDSTR))
196		add_str(&Pstats.s_str, Cur_ring[RIGHT]->o_arm);
197	    msg("hey, this tastes great.  It make you feel warm all over");
198	when P_BLIND:
199	    do_pot(P_BLIND, TRUE);
200	when P_LEVIT:
201	    do_pot(P_LEVIT, TRUE);
202#ifdef MASTER
203	otherwise:
204	    msg("what an odd tasting potion!");
205	    return;
206#endif
207    }
208    status();
209    /*
210     * Throw the item away
211     */
212
213    call_it(&Pot_info[obj->o_which]);
214
215    if (discardit)
216	discard(obj);
217    return;
218}
219
220/*
221 * is_magic:
222 *	Returns true if an object radiates magic
223 */
224bool
225is_magic(THING *obj)
226{
227    switch (obj->o_type)
228    {
229	case ARMOR:
230	    return (obj->o_flags&ISPROT) || obj->o_arm != A_class[obj->o_which];
231	case WEAPON:
232	    return obj->o_hplus != 0 || obj->o_dplus != 0;
233	case POTION:
234	case SCROLL:
235	case STICK:
236	case RING:
237	case AMULET:
238	    return TRUE;
239    }
240    return FALSE;
241}
242
243/*
244 * invis_on:
245 *	Turn on the ability to see invisible
246 */
247void
248invis_on(void)
249{
250    THING *mp;
251
252    Player.t_flags |= CANSEE;
253    for (mp = Mlist; mp != NULL; mp = next(mp))
254	if (on(*mp, ISINVIS) && see_monst(mp) && !on(Player, ISHALU))
255	    mvaddch(mp->t_pos.y, mp->t_pos.x, mp->t_disguise);
256}
257
258/*
259 * turn_see:
260 *	Put on or off seeing monsters on this level
261 */
262bool
263turn_see(bool turn_off)
264{
265    THING *mp;
266    bool can_see, add_new;
267
268    add_new = FALSE;
269    for (mp = Mlist; mp != NULL; mp = next(mp))
270    {
271	move(mp->t_pos.y, mp->t_pos.x);
272	can_see = see_monst(mp);
273	if (turn_off)
274	{
275	    if (!can_see)
276		addch(mp->t_oldch);
277	}
278	else
279	{
280	    if (!can_see)
281		standout();
282	    if (!on(Player, ISHALU))
283		addch(mp->t_type);
284	    else
285		addch(rnd(26) + 'A');
286	    if (!can_see)
287	    {
288		standend();
289		add_new++;
290	    }
291	}
292    }
293    if (turn_off)
294	Player.t_flags &= ~SEEMONST;
295    else
296	Player.t_flags |= SEEMONST;
297    return add_new;
298}
299
300/*
301 * seen_stairs:
302 *	Return TRUE if the player has seen the stairs
303 */
304bool
305seen_stairs(void)
306{
307    THING	*tp;
308
309    move(Stairs.y, Stairs.x);
310    if (inch() == STAIRS)			/* it's on the map */
311	return TRUE;
312    if (ce(Hero, Stairs))			/* It's under him */
313	return TRUE;
314
315    /*
316     * if a monster is on the stairs, this gets hairy
317     */
318    if ((tp = moat(Stairs.y, Stairs.x)) != NULL)
319    {
320	if (see_monst(tp) && on(*tp, ISRUN))	/* if it's visible and awake */
321	    return TRUE;			/* it must have moved there */
322
323	if (on(Player, SEEMONST)		/* if she can detect monster */
324	    && tp->t_oldch == STAIRS)		/* and there once were stairs */
325		return TRUE;			/* it must have moved there */
326    }
327    return FALSE;
328}
329
330/*
331 * raise_level:
332 *	The guy just magically went up a level.
333 */
334void
335raise_level(void)
336{
337    Pstats.s_exp = E_levels[Pstats.s_lvl-1] + 1L;
338    check_level();
339}
340
341/*
342 * do_pot:
343 *	Do a potion with standard setup.  This means it uses a fuse and
344 *	turns on a flag
345 */
346void
347do_pot(int type, bool knowit)
348{
349    PACT *pp;
350    int t;
351
352    pp = &P_actions[type];
353    if (!Pot_info[type].oi_know)
354	Pot_info[type].oi_know = knowit;
355    t = spread(pp->pa_time);
356    if (!on(Player, pp->pa_flags))
357    {
358	Player.t_flags |= pp->pa_flags;
359	fuse(pp->pa_daemon, 0, t, AFTER);
360	look(FALSE);
361    }
362    else
363	lengthen(pp->pa_daemon, t);
364    msg(choose_str(pp->pa_high, pp->pa_straight));
365}