diff srogue/rings.c @ 36:2128c7dc8a40

Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
author elwin
date Thu, 25 Nov 2010 12:21:41 +0000
parents
children 3aa87373c908
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/srogue/rings.c	Thu Nov 25 12:21:41 2010 +0000
@@ -0,0 +1,492 @@
+/*
+ * routines dealing specifically with rings
+ *
+ * @(#)rings.c	9.0	(rdk)	 7/17/84
+ *
+ * Super-Rogue
+ * Copyright (C) 1984 Robert D. Kindelberger
+ * All rights reserved.
+ *
+ * Based on "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 "rogue.h"
+#include "rogue.ext"
+
+/*
+ * ring_on:
+ *	Put on a ring
+ */
+ring_on()
+{
+	reg struct object *obj;
+	reg struct linked_list *item;
+	reg int ring, wh;
+	char buf[LINLEN];
+	bool okring;
+
+	if (cur_ring[LEFT] != NULL && cur_ring[RIGHT] != NULL) {
+		msg("Already wearing two rings.");
+		after = FALSE;
+		return;
+	}
+	/*
+	 * Make certain that it is somethings that we want to wear
+	 */
+	if ((item = get_item("put on", RING)) == NULL)
+		return;
+	obj = OBJPTR(item);
+	if (obj->o_type != RING) {
+		msg("That won't fit on your finger.");
+		return;
+	}
+	/*
+	 * find out which hand to put it on
+	 */
+	if (is_current(obj))
+		return;
+	if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL) {
+		if ((ring = gethand(FALSE)) < 0)
+			return;
+	}
+	else if (cur_ring[LEFT] == NULL)
+		ring = LEFT;
+	else
+		ring = RIGHT;
+	cur_ring[ring] = obj;
+	wh = obj->o_which;
+	/*
+	 * okring = FALSE when:
+	 * 1) ring is cursed and benefit = plus
+	 * 2) ring is blessed and benefit = minus
+	 */
+	okring = !((obj->o_ac > 0 && o_on(obj, ISCURSED)) ||
+	          (obj->o_ac < 0 && o_on(obj, ISBLESS)));
+	/*
+	 * Calculate the effect it has on the poor guy (if possible).
+	 */
+	if (okring) {
+		switch (wh) {
+			case R_SPEED:
+				if (--obj->o_ac < 0) {
+					obj->o_ac = 0;
+					setoflg(obj,ISCURSED);
+				}
+				else {
+					add_haste(FALSE);
+					msg("You find yourself moving must faster.");
+				}
+			when R_GIANT:				/* to 24 */
+				him->s_ef.a_str = MAXSTR;
+			when R_ADDSTR:
+				chg_abil(STR,obj->o_ac,FROMRING);
+			when R_KNOW:
+				chg_abil(WIS,obj->o_ac,FROMRING);
+			when R_DEX:
+				chg_abil(DEX,obj->o_ac,FROMRING);
+			when R_CONST:
+				chg_abil(CON,obj->o_ac,FROMRING);
+			when R_SEEINVIS:
+				player.t_flags |= CANSEE;
+				light(&hero);
+				mvwaddch(cw, hero.y, hero.x, PLAYER);
+			when R_AGGR:
+				aggravate();
+			when R_HEAVY:
+				updpack();			/* new pack weight */
+			when R_BLIND:
+				r_know[R_BLIND] = TRUE;
+				player.t_flags |= ISBLIND;
+				look(FALSE);
+			when R_SLOW:
+				player.t_flags |= ISSLOW;
+			when R_SAPEM:
+				fuse(sapem,TRUE,150);
+			when R_LIGHT: {
+				struct room *rop;
+
+				r_know[R_LIGHT] = TRUE;
+				if ((rop = player.t_room) != NULL) {
+					rop->r_flags &= ~ISDARK;
+					light(&hero);
+					mvwaddch(cw, hero.y, hero.x, PLAYER);
+				}
+			}
+		}
+	}
+	if (r_know[wh] && r_guess[wh]) {
+		free(r_guess[wh]);
+		r_guess[wh] = NULL;
+	}
+	else if(!r_know[wh] && r_guess[wh] == NULL) {
+		mpos = 0;
+		strcpy(buf, r_stones[wh]);
+		msg(callit);
+		if (get_str(buf, cw) == NORM) {
+			r_guess[wh] = new(strlen(buf) + 1);
+			strcpy(r_guess[wh], buf);
+		}
+	}
+	mpos = 0;
+	msg("Now wearing %s",inv_name(obj,TRUE));
+	ringfood = ring_eat();
+	nochange = FALSE;
+}
+
+
+/*
+ * ring_off:
+ *	Take off some ring
+ */
+ring_off()
+{
+	reg int ring;
+	reg struct object *obj;
+	
+	if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL) {
+		msg("You're not wearing any rings.");
+		return;
+	}
+	else if (cur_ring[LEFT] == NULL)
+		ring = RIGHT;
+	else if (cur_ring[RIGHT] == NULL)
+		ring = LEFT;
+	else
+		if ((ring = gethand(TRUE)) < 0)
+			return;
+	mpos = 0;
+	obj = cur_ring[ring];
+	if (obj == NULL) {
+		msg("Not wearing such a ring.");
+		return;
+	}
+	if (dropcheck(obj)) {
+		msg("Was wearing %s", inv_name(obj, TRUE));
+		nochange = FALSE;
+		ringfood = ring_eat();
+	}
+}
+
+
+/*
+ * toss_ring:
+ *	Remove a ring and stop its effects
+ */
+toss_ring(what)
+struct object *what;
+{
+	bool okring;
+
+	/*
+	 * okring = FALSE when:
+	 * 1) ring is cursed and benefit = plus
+	 * 2) ring is blessed and benefit = minus
+	 */
+	okring = !((what->o_ac > 0 && o_on(what, ISCURSED)) ||
+	          (what->o_ac < 0 && o_on(what, ISBLESS)));
+
+	cur_ring[what == cur_ring[LEFT] ? LEFT : RIGHT] = NULL;
+	if (okring) {
+		switch (what->o_which) {
+			case R_SPEED:
+				extinguish(nohaste);
+				nohaste(FALSE);
+			when R_BLIND:
+				sight(FALSE);
+			when R_SLOW:
+				player.t_flags &= ~ISSLOW;
+			when R_SAPEM:
+				extinguish(sapem);
+			when R_GIANT:
+				him->s_ef = him->s_re;
+				ringabil();
+			when R_ADDSTR:
+				chg_abil(STR,-what->o_ac,FALSE);
+			when R_KNOW:
+				chg_abil(WIS,-what->o_ac,FALSE);
+			when R_DEX:
+				chg_abil(DEX,-what->o_ac,FALSE);
+			when R_CONST:
+				chg_abil(CON,-what->o_ac,FALSE);
+			when R_SEEINVIS:
+				player.t_flags &= ~CANSEE;
+				extinguish(unsee);
+				light(&hero);
+				mvwaddch(cw, hero.y, hero.x, PLAYER);
+		}
+	}
+}
+
+
+/*
+ * gethand:
+ *	Get a hand to wear a ring
+ */
+gethand(isrmv)
+bool isrmv;
+{
+	reg int c;
+	char *ptr;
+	struct object *obj;
+
+	while(1) {
+		addmsg("Left or Right ring");
+		if (isrmv)
+			addmsg(starlist);
+		addmsg("? ");
+		endmsg();
+		c = readchar();
+		if (isupper(c))
+			c = tolower(c);
+		if (c == '*' && isrmv) {
+			wclear(hw);
+			obj = cur_ring[LEFT];
+			if (obj != NULL)
+				ptr = inv_name(obj, TRUE);
+			else
+				ptr = "none";
+			wprintw(hw, "L)  %s\n\r",ptr);
+			obj = cur_ring[RIGHT];
+			if (obj != NULL)
+				ptr = inv_name(obj, TRUE);
+			else
+				ptr = "none";
+			wprintw(hw, "R)  %s\n\r", ptr);
+			wprintw(hw, "\n\r\nWhich hand? ");
+			draw(hw);
+			c = readchar();
+			if (isupper(c))
+				c = tolower(c);
+			restscr(cw);
+		}
+		if (c == 'l')
+			return LEFT;
+		else if (c == 'r')
+			return RIGHT;
+		else if (c == ESCAPE)
+			return -1;
+		mpos = 0;
+		msg("L or R");
+	}
+}
+
+/*
+ * ring_eat:
+ *	How much food do the hero's rings use up?
+ */
+ring_eat()
+{
+	reg struct object *lb;
+	reg int hand, i, howmuch;
+	bool addit;
+
+	howmuch = 0;
+	addit = TRUE;
+	for (i = LEFT; i <= RIGHT ; i += 1) {
+		lb = cur_ring[i];
+		if (lb != NULL) {
+			switch (lb->o_which) {
+				case R_REGEN:
+				case R_GIANT:
+					howmuch += 2;
+				when R_SPEED:
+				case R_SUSTSTR:
+				case R_SUSAB:
+					howmuch += 1;
+				when R_SEARCH:
+					howmuch += (rnd(100) < 33);
+				when R_DIGEST:
+					switch(lb->o_ac) {
+						case -3: if (rnd(100) < 25)
+									howmuch += 3;
+						when -2: if (rnd(100) < 50)
+									howmuch += 2;
+						when -1: howmuch += 1;
+						when  0: howmuch -= (rnd(100) < 50);
+						when  3: if (rnd(100) < 25)
+									howmuch -= 3;
+						when  2: if (rnd(100) < 50)
+									howmuch -= 2;
+						default: howmuch -= 1;
+					}
+				otherwise:
+					addit = FALSE;
+			}
+			if (addit) {
+				if (o_on(lb, ISBLESS))
+					howmuch -= 1;
+				else if (o_on(lb, ISCURSED))
+					howmuch += 1;
+			}
+		}
+	}
+	return howmuch;
+}
+
+
+/*
+ * ring_num:
+ *	Print ring bonuses
+ */
+char *
+ring_num(what)
+struct object *what;
+{
+	static char number[5];
+
+	number[0] = '\0';
+	if (o_on(what,ISKNOW) || o_on(what,ISPOST)) {
+		if (magring(what)) {	/* only rings with numbers */
+			number[0] = ' ';
+			strcpy(&number[1], num(what->o_ac, 0));
+		}
+	}
+	return number;
+}
+
+
+/*
+ * magring:
+ *	Returns TRUE if a ring has a number, i.e. +2
+ */
+magring(what)
+struct object *what;
+{
+	switch(what->o_which) {
+		case R_SPEED:
+		case R_ADDSTR:
+		case R_PROTECT:
+		case R_ADDHIT:
+		case R_ADDDAM:
+		case R_DIGEST:
+		case R_CONST:
+		case R_KNOW:
+		case R_DEX:
+			return TRUE;
+		default:
+			return FALSE;
+	}
+}
+
+
+/*
+ * ringabil:
+ *	Compute effective abilities due to rings
+ */
+ringabil()
+{
+	reg struct object *rptr;
+	reg int i;
+
+	for(i = LEFT; i <= RIGHT; i++) {
+		rptr = cur_ring[i];
+		if (rptr != NULL) {
+			switch(rptr->o_which) {
+				case R_ADDSTR:
+					chg_abil(STR,rptr->o_ac,FROMRING);
+				when R_DEX: 
+					chg_abil(DEX,rptr->o_ac,FROMRING);
+				when R_KNOW:
+					chg_abil(WIS,rptr->o_ac,FROMRING);
+				when R_CONST:
+					chg_abil(CON,rptr->o_ac,FROMRING);
+			}
+		}
+	}
+}
+
+
+/*
+ * init_ring:
+ *	Initialize a ring
+ */
+init_ring(what,fromwiz)
+struct object *what;
+bool fromwiz;			/* TRUE when from wizards */
+{
+	reg int much;
+
+	switch (what->o_which) {
+		case R_DIGEST:		/* -3 to +3 rings */
+		case R_ADDSTR:
+		case R_PROTECT:
+		case R_ADDHIT:
+		case R_ADDDAM:
+		case R_DEX:
+		case R_KNOW:
+		case R_CONST:
+			if (fromwiz) {
+				much = getbless();		/* get wizards response */
+			}
+			else {						/* normal users */
+				if (rnd(100) < 25)
+					much = -rnd(3) - 1;
+				else
+					much = rnd(3) + 1;
+			}
+			what->o_ac = much;
+			if (much < 0)
+				setoflg(what,ISCURSED);
+		when R_SPEED:
+			what->o_ac = rnd(4) + 1;
+		when R_AGGR:
+		case R_DELUS:
+		case R_HEAVY:
+		case R_BLIND:
+		case R_SLOW:
+		case R_SAPEM:
+		case R_TELEPORT:
+			what->o_ac = 0;
+			setoflg(what,ISCURSED);	
+		when R_GIANT:
+			what->o_ac = 25;		/* lots !! of STR */
+		otherwise:
+			what->o_ac = 1;
+	}
+	what->o_type = RING;
+	what->o_weight = things[TYP_RING].mi_wght;
+	what->o_typname = things[TYP_RING].mi_name;
+	what->o_vol = itemvol(what);
+}
+
+/*
+ * ringex:
+ *	Get extra gains from rings
+ */
+ringex(rtype)
+int rtype;
+{
+	reg int howmuch = 0;
+
+	if (isring(LEFT, rtype))
+		howmuch += cur_ring[LEFT]->o_ac;
+	if (isring(RIGHT, rtype))
+		howmuch += cur_ring[RIGHT]->o_ac;
+	return howmuch;
+}
+
+/*
+ * iswearing:
+ *	Returns TRUE when the hero is wearing a certain type of ring
+ */
+iswearing(ring)
+int ring;
+{
+	return (isring(LEFT,ring) || isring(RIGHT,ring));
+}
+
+/*
+ * isring:
+ *	Returns TRUE if a ring is on a hand
+ */
+isring(hand,ring)
+int hand, ring;
+{
+	if (cur_ring[hand] != NULL && cur_ring[hand]->o_which == ring)
+		return TRUE;
+	return FALSE;
+}