diff rogue3/misc.c @ 0:527e2150eaf0

Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
author edwarj4
date Tue, 13 Oct 2009 13:33:34 +0000
parents
children e7862a021609
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue3/misc.c	Tue Oct 13 13:33:34 2009 +0000
@@ -0,0 +1,431 @@
+/*
+ * all sorts of miscellaneous routines
+ *
+ * @(#)misc.c	3.13 (Berkeley) 6/15/81
+ *
+ * Rogue: Exploring the Dungeons of Doom
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+#include <ctype.h>
+
+/*
+ * tr_name:
+ *	print the name of a trap
+ */
+
+char *
+tr_name(int ch)
+{
+    char *s = "";
+
+    switch (ch)
+    {
+	case TRAPDOOR:
+	    s = terse ? "A trapdoor." : "You found a trapdoor.";
+	when BEARTRAP:
+	    s = terse ? "A beartrap." : "You found a beartrap.";
+	when SLEEPTRAP:
+	    s = terse ? "A sleeping gas trap.":"You found a sleeping gas trap.";
+	when ARROWTRAP:
+	    s = terse ? "An arrow trap." : "You found an arrow trap.";
+	when TELTRAP:
+	    s = terse ? "A teleport trap." : "You found a teleport trap.";
+	when DARTTRAP:
+	    s = terse ? "A dart trap." : "You found a poison dart trap.";
+    }
+    return s;
+}
+
+/*
+ * Look:
+ *	A quick glance all around the player
+ */
+
+void
+look(int wakeup)
+{
+    int x, y;
+    int ch;
+    int oldx, oldy;
+    int inpass;
+    int passcount = 0;
+    struct room *rp;
+    int ey, ex;
+
+    getyx(cw, oldy, oldx);
+    if (oldrp != NULL && (oldrp->r_flags & ISDARK) && off(player, ISBLIND))
+    {
+	for (x = oldpos.x - 1; x <= oldpos.x + 1; x++)
+	    for (y = oldpos.y - 1; y <= oldpos.y + 1; y++)
+		if ((y != hero.y || x != hero.x) && show(y, x) == FLOOR)
+		    mvwaddch(cw, y, x, ' ');
+    }
+    inpass = ((rp = roomin(&hero)) == NULL);
+    ey = hero.y + 1;
+    ex = hero.x + 1;
+    for (x = hero.x - 1; x <= ex; x++)
+	if (x >= 0 && x < COLS) for (y = hero.y - 1; y <= ey; y++)
+	{
+	    if (y <= 0 || y >= LINES - 1)
+		continue;
+	    if (isupper(mvwinch(mw, y, x)))
+	    {
+		struct linked_list *it;
+		struct thing *tp;
+
+		if (wakeup)
+		    it = wake_monster(y, x);
+		else
+		    it = find_mons(y, x);
+		tp = (struct thing *) ldata(it);
+		if ((tp->t_oldch = mvinch(y, x)) == TRAP)
+		    tp->t_oldch =
+			(trap_at(y,x)->tr_flags&ISFOUND) ? TRAP : FLOOR;
+		if (tp->t_oldch == FLOOR && (rp != NULL) && (rp->r_flags & ISDARK)
+		    && off(player, ISBLIND))
+			tp->t_oldch = ' ';
+	    }
+	    /*
+	     * Secret doors show as walls
+	     */
+	    if ((ch = show(y, x)) == SECRETDOOR)
+		ch = secretdoor(y, x);
+	    /*
+	     * Don't show room walls if he is in a passage
+	     */
+	    if (off(player, ISBLIND))
+	    {
+		if (y == hero.y && x == hero.x
+		 || (inpass && (ch == '-' || ch == '|')))
+			continue;
+	    }
+	    else if (y != hero.y || x != hero.x)
+		continue;
+	    wmove(cw, y, x);
+	    waddch(cw, ch);
+	    if (door_stop && !firstmove && running)
+	    {
+		switch (runch)
+		{
+		    case 'h':
+			if (x == ex)
+			    continue;
+		    when 'j':
+			if (y == hero.y - 1)
+			    continue;
+		    when 'k':
+			if (y == ey)
+			    continue;
+		    when 'l':
+			if (x == hero.x - 1)
+			    continue;
+		    when 'y':
+			if ((x + y) - (hero.x + hero.y) >= 1)
+			    continue;
+		    when 'u':
+			if ((y - x) - (hero.y - hero.x) >= 1)
+			    continue;
+		    when 'n':
+			if ((x + y) - (hero.x + hero.y) <= -1)
+			    continue;
+		    when 'b':
+			if ((y - x) - (hero.y - hero.x) <= -1)
+			    continue;
+		}
+		switch (ch)
+		{
+		    case DOOR:
+			if (x == hero.x || y == hero.y)
+			    running = FALSE;
+			break;
+		    case PASSAGE:
+			if (x == hero.x || y == hero.y)
+			    passcount++;
+			break;
+		    case FLOOR:
+		    case '|':
+		    case '-':
+		    case ' ':
+			break;
+		    default:
+			running = FALSE;
+			break;
+		}
+	    }
+	}
+    if (door_stop && !firstmove && passcount > 1)
+	running = FALSE;
+    mvwaddch(cw, hero.y, hero.x, PLAYER);
+    wmove(cw, oldy, oldx);
+    oldpos = hero;
+    oldrp = rp;
+}
+
+/*
+ * secret_door:
+ *	Figure out what a secret door looks like.
+ */
+
+int
+secretdoor(int y, int x)
+{
+    int i;
+    struct room *rp;
+    coord *cpp;
+    static coord cp;
+
+    cp.y = y;
+    cp.x = x;
+    cpp = &cp;
+    for (rp = rooms, i = 0; i < MAXROOMS; rp++, i++)
+	if (inroom(rp, cpp))
+	    if (y == rp->r_pos.y || y == rp->r_pos.y + rp->r_max.y - 1)
+		return('-');
+	    else
+		return('|');
+
+    return('p');
+}
+
+/*
+ * find_obj:
+ *	find the unclaimed object at y, x
+ */
+
+struct linked_list *
+find_obj(int y, int x)
+{
+    struct linked_list *obj;
+    struct object *op;
+
+    for (obj = lvl_obj; obj != NULL; obj = next(obj))
+    {
+	op = (struct object *) ldata(obj);
+	if (op->o_pos.y == y && op->o_pos.x == x)
+		return obj;
+    }
+    sprintf(prbuf, "Non-object %d,%d", y, x);
+    debug(prbuf);
+    return NULL;
+}
+
+/*
+ * eat:
+ *	She wants to eat something, so let her try
+ */
+
+void
+eat()
+{
+    struct linked_list *item;
+    struct object *obj;
+
+    if ((item = get_item("eat", FOOD)) == NULL)
+	return;
+    obj = (struct object *) ldata(item);
+    if (obj->o_type != FOOD)
+    {
+	if (!terse)
+	    msg("Ugh, you would get ill if you ate that.");
+	else
+	    msg("That's Inedible!");
+	return;
+    }
+    inpack--;
+    if (obj->o_which == 1)
+	msg("My, that was a yummy %s", fruit);
+    else
+	if (rnd(100) > 70)
+	{
+	    msg("Yuk, this food tastes awful");
+	    pstats.s_exp++;
+	    check_level();
+	}
+	else
+	    msg("Yum, that tasted good");
+    if ((food_left += HUNGERTIME + rnd(400) - 200) > STOMACHSIZE)
+	food_left = STOMACHSIZE;
+    hungry_state = 0;
+    if (obj == cur_weapon)
+	cur_weapon = NULL;
+    if (--obj->o_count < 1)
+    {
+	detach(pack, item);
+	discard(item);
+    }
+}
+
+/*
+ * Used to modify the playes strength
+ * it keeps track of the highest it has been, just in case
+ */
+
+void
+chg_str(int amt)
+{
+    if (amt == 0)
+	return;
+    if (amt > 0)
+    {
+	while (amt--)
+	{
+	    if (pstats.s_str.st_str < 18)
+		pstats.s_str.st_str++;
+	    else if (pstats.s_str.st_add == 0)
+		pstats.s_str.st_add = rnd(50) + 1;
+	    else if (pstats.s_str.st_add <= 50)
+		pstats.s_str.st_add = 51 + rnd(24);
+	    else if (pstats.s_str.st_add <= 75)
+		pstats.s_str.st_add = 76 + rnd(14);
+	    else if (pstats.s_str.st_add <= 90)
+		pstats.s_str.st_add = 91;
+	    else if (pstats.s_str.st_add < 100)
+		pstats.s_str.st_add++;
+	}
+	if (pstats.s_str.st_str > max_stats.s_str.st_str ||
+	    (pstats.s_str.st_str == 18 &&
+	     pstats.s_str.st_add > max_stats.s_str.st_add))
+		max_stats.s_str = pstats.s_str;
+    }
+    else
+    {
+	while (amt++)
+	{
+	    if (pstats.s_str.st_str < 18 || pstats.s_str.st_add == 0)
+		pstats.s_str.st_str--;
+	    else if (pstats.s_str.st_add < 51)
+		pstats.s_str.st_add = 0;
+	    else if (pstats.s_str.st_add < 76)
+		pstats.s_str.st_add = 1 + rnd(50);
+	    else if (pstats.s_str.st_add < 91)
+		pstats.s_str.st_add = 51 + rnd(25);
+	    else if (pstats.s_str.st_add < 100)
+		pstats.s_str.st_add = 76 + rnd(14);
+	    else
+		pstats.s_str.st_add = 91 + rnd(8);
+	}
+	if (pstats.s_str.st_str < 3)
+	    pstats.s_str.st_str = 3;
+    }
+}
+
+/*
+ * add_haste:
+ *	add a haste to the player
+ */
+
+void
+add_haste(int potion)
+{
+    if (on(player, ISHASTE))
+    {
+	msg("You faint from exhaustion.");
+	no_command += rnd(8);
+	extinguish(nohaste);
+    }
+    else
+    {
+	player.t_flags |= ISHASTE;
+	if (potion)
+	    fuse(nohaste, 0, rnd(4)+4, AFTER);
+    }
+}
+
+/*
+ * aggravate:
+ *	aggravate all the monsters on this level
+ */
+
+void
+aggravate()
+{
+    struct linked_list *mi;
+
+    for (mi = mlist; mi != NULL; mi = next(mi))
+	runto(&((struct thing *) ldata(mi))->t_pos, &hero);
+}
+
+/*
+ * for printfs: if string starts with a vowel, return "n" for an "an"
+ */
+char *
+vowelstr(char *str)
+{
+    switch (*str)
+    {
+	case 'a':
+	case 'e':
+	case 'i':
+	case 'o':
+	case 'u':
+	    return "n";
+	default:
+	    return "";
+    }
+}
+
+/* 
+ * see if the object is one of the currently used items
+ */
+int
+is_current(struct object *obj)
+{
+    if (obj == NULL)
+	return FALSE;
+    if (obj == cur_armor || obj == cur_weapon || obj == cur_ring[LEFT]
+	|| obj == cur_ring[RIGHT])
+    {
+	msg(terse ? "In use." : "That's already in use.");
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * set up the direction co_ordinate for use in varios "prefix" commands
+ */
+int
+get_dir()
+{
+    char *prompt;
+    int gotit;
+
+    if (!terse)
+	msg(prompt = "Which direction? ");
+    else
+	prompt = "Direction: ";
+    do
+    {
+	gotit = TRUE;
+	switch (readchar(cw))
+	{
+	    case 'h': case'H': delta.y =  0; delta.x = -1;
+	    when 'j': case'J': delta.y =  1; delta.x =  0;
+	    when 'k': case'K': delta.y = -1; delta.x =  0;
+	    when 'l': case'L': delta.y =  0; delta.x =  1;
+	    when 'y': case'Y': delta.y = -1; delta.x = -1;
+	    when 'u': case'U': delta.y = -1; delta.x =  1;
+	    when 'b': case'B': delta.y =  1; delta.x = -1;
+	    when 'n': case'N': delta.y =  1; delta.x =  1;
+	    when ESCAPE: return FALSE;
+	    otherwise:
+		mpos = 0;
+		msg(prompt);
+		gotit = FALSE;
+	}
+    } until (gotit);
+    if (on(player, ISHUH) && rnd(100) > 80)
+	do
+	{
+	    delta.y = rnd(3) - 1;
+	    delta.x = rnd(3) - 1;
+	} while (delta.y == 0 && delta.x == 0);
+    mpos = 0;
+    return TRUE;
+}