diff arogue5/misc.c @ 63:0ed67132cf10

Import Advanced Rogue 5.8 from the Roguelike Restoration Project (r1490)
author elwin
date Thu, 09 Aug 2012 22:58:48 +0000
parents
children c49f7927b0fa
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/misc.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,736 @@
+/*
+ * routines dealing specifically with miscellaneous magic
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+
+/*
+ * See if a monster has some magic it can use.  Use it and return TRUE if so.
+ */
+bool
+m_use_item(monster, monst_pos, defend_pos)
+register struct thing *monster;
+register coord *monst_pos, *defend_pos;
+{
+    register struct linked_list *pitem;
+    register struct object *obj;
+    register coord *shoot_dir = can_shoot(monst_pos, defend_pos);
+    int dist=DISTANCE(monst_pos->y, monst_pos->x, defend_pos->y, defend_pos->x);
+
+    for (pitem=monster->t_pack; pitem; pitem=next(pitem)) {
+	obj = OBJPTR(pitem);
+	if (obj->o_type != RELIC) continue;	/* Only care about relics now */
+	switch (obj->o_which) {
+	    case MING_STAFF: {
+		static struct object missile = {
+		  MISSILE, {0,0}, "", 0, "", "0d4 " , NULL, 0, WS_MISSILE, 100, 1
+		};
+
+		if (shoot_dir != NULL) {
+		    sprintf(missile.o_hurldmg, "%dd4", monster->t_stats.s_lvl);
+		    do_motion(&missile, shoot_dir->y, shoot_dir->x, monster);
+		    hit_monster(unc(missile.o_pos), &missile, monster);
+		    return(TRUE);
+		}
+	    }
+	    when ASMO_ROD:
+		/* The bolt must be able to reach the defendant */
+		if (shoot_dir != NULL && dist < BOLT_LENGTH * BOLT_LENGTH) {
+		    char *name;
+
+		    switch (rnd(3)) { /* Select a function */
+			case 0:	   name = "lightning bolt";
+			when 1:	   name = "flame";
+			otherwise: name = "ice";
+		    }
+		    shoot_bolt(	monster, 
+				*monst_pos, 
+				*shoot_dir, 
+				FALSE, 
+				monster->t_index, 
+				name, 
+				roll(monster->t_stats.s_lvl,6));
+		    return(TRUE);
+		}
+	    when BRIAN_MANDOLIN:
+		/* The defendant must be the player and within 2 spaces */
+		if (ce(*defend_pos, hero) && dist < 9 && no_command == 0 &&
+		    rnd(100) < 33) {
+		    if (!save(VS_MAGIC, &player, -4) &&
+			!ISWEARING(R_ALERT)) {
+			msg("Some beautiful music enthralls you.");
+			no_command += FREEZETIME;
+		    }
+		    else msg("You wince at a sour note.");
+		    return(TRUE);
+		}
+	    when GERYON_HORN:
+		/* The defendant must be the player and within 2 spaces */
+		if (ce(*defend_pos, hero) && dist < 9 &&
+		    (off(player, ISFLEE) || player.t_dest != &monster->t_pos)
+		    && rnd(100) < 33) {
+		    if (!ISWEARING(R_HEROISM) &&
+			!save(VS_MAGIC, &player, -4)) {
+			    turn_on(player, ISFLEE);
+			    player.t_dest = &monster->t_pos;
+			    msg("A shrill blast terrifies you.");
+		    }
+		    else msg("A shrill blast sends chills up your spine.");
+		    return(TRUE);
+		}
+	}
+    }
+    return(FALSE);
+}
+ 
+/*
+ * add something to the contents of something else
+ */
+put_contents(bag, item)
+register struct object *bag;		/* the holder of the items */
+register struct linked_list *item;	/* the item to put inside  */
+{
+    register struct linked_list *titem;
+    register struct object *tobj;
+
+    bag->o_ac++;
+    tobj = OBJPTR(item);
+    for (titem = bag->contents; titem != NULL; titem = next(titem)) {
+	if ((OBJPTR(titem))->o_which == tobj->o_which)
+	    break;
+    }
+    if (titem == NULL) {	/* if not a duplicate put at beginning */
+	attach(bag->contents, item);
+    }
+    else {
+	item->l_prev = titem;
+	item->l_next = titem->l_next;
+	if (next(titem) != NULL) 
+	    (titem->l_next)->l_prev = item;
+	titem->l_next = item;
+    }
+}
+
+/*
+ * remove something from something else
+ */
+take_contents(bag, item)
+register struct object *bag;		/* the holder of the items */
+register struct linked_list *item;
+{
+
+    if (bag->o_ac <= 0) {
+	msg("Nothing to take out");
+	return;
+    }
+    bag->o_ac--;
+    detach(bag->contents, item);
+    if (!add_pack(item, FALSE, NULL))
+	put_contents(bag, item);
+}
+
+
+do_bag(item)
+register struct linked_list *item;
+{
+
+    register struct linked_list *titem = NULL;
+    register struct object *obj;
+    bool doit = TRUE;
+
+    obj = OBJPTR(item);
+    while (doit) {
+	msg("What do you want to do? (* for a list): ");
+	mpos = 0;
+	switch (readchar()) {
+	    case EOF:
+	    case ESCAPE:
+		msg ("");
+		doit = FALSE;
+	    when '1':
+		inventory(obj->contents, ALL);
+
+	    when '2':
+		if (obj->o_ac >= MAXCONTENTS) {
+		    msg("the %s is full", m_magic[obj->o_which].mi_name);
+		    break;
+		}
+		switch (obj->o_which) {
+		case MM_BEAKER: titem = get_item(pack, "put in", POTION);
+		when MM_BOOK:   titem = get_item(pack, "put in", SCROLL);
+		}
+		if (titem == NULL)
+		    break;
+		detach(pack, titem);
+		inpack--;
+		put_contents(obj, titem);
+	    
+	    when '3':
+		titem = get_item(obj->contents,"take out",ALL);
+		if (titem == NULL)
+		    break;
+		take_contents(obj, titem);
+		
+	    when '4': 
+		switch (obj->o_which) {
+		case MM_BEAKER: 
+		    titem = get_item(obj->contents,"quaff",ALL);
+		    if (titem == NULL)
+			break;
+		    obj->o_ac--;
+		    detach(obj->contents, titem);
+		    quaff((OBJPTR(titem))->o_which, 
+			  (OBJPTR(titem))->o_flags & (ISCURSED | ISBLESSED),
+			  TRUE);
+		    o_discard(titem);
+		when MM_BOOK:   
+		    if (on(player, ISBLIND)) {
+			msg("You can't see to read anything");
+			break;
+		    }
+		    titem = get_item(obj->contents,"read",ALL);
+		    if (titem == NULL)
+			break;
+		    obj->o_ac--;
+		    detach(obj->contents, titem);
+		    read_scroll((OBJPTR(titem))->o_which, 
+			        (OBJPTR(titem))->o_flags & (ISCURSED|ISBLESSED),
+				TRUE);
+		    o_discard(titem);
+		}
+		doit = FALSE;
+
+	    otherwise:
+		wclear(hw);
+		touchwin(hw);
+		mvwaddstr(hw,0,0,"The following operations are available:");
+		mvwaddstr(hw,2,0,"[1]\tInventory\n");
+		wprintw(hw,"[2]\tPut something in the %s\n",
+			m_magic[obj->o_which].mi_name);
+		wprintw(hw,"[3]\tTake something out of the %s\n",
+			m_magic[obj->o_which].mi_name);
+		switch(obj->o_which) {
+		    case MM_BEAKER: waddstr(hw,"[4]\tQuaff a potion\n");
+		    when MM_BOOK:   waddstr(hw,"[4]\tRead a scroll\n");
+		}
+		waddstr(hw,"[ESC]\tLeave this menu\n");
+		mvwaddstr(hw, LINES-1, 0, spacemsg);
+		draw(hw);
+		wait_for (hw,' ');
+		clearok(cw, TRUE);
+		touchwin(cw);
+	}
+    }
+}
+
+do_panic()
+{
+    register int x,y;
+    register struct linked_list *mon;
+    register struct thing *th;
+
+    for (x = hero.x-2; x <= hero.x+2; x++) {
+	for (y = hero.y-2; y <= hero.y+2; y++) {
+	    if (y < 1 || x < 0 || y > LINES - 3  || x > COLS - 1) 
+		continue;
+	    if (isalpha(mvwinch(mw, y, x))) {
+		if ((mon = find_mons(y, x)) != NULL) {
+		    th = THINGPTR(mon);
+		    if (!on(*th, ISUNDEAD) && !save(VS_MAGIC, th, 0)) {
+			turn_on(*th, ISFLEE);
+			turn_on(*th, WASTURNED);
+
+			/* If monster was suffocating, stop it */
+			if (on(*th, DIDSUFFOCATE)) {
+			    turn_off(*th, DIDSUFFOCATE);
+			    extinguish(suffocate);
+			}
+
+			/* If monster held us, stop it */
+			if (on(*th, DIDHOLD) && (--hold_count == 0))
+				turn_off(player, ISHELD);
+			turn_off(*th, DIDHOLD);
+		    }
+		    runto(th, &hero);
+		}
+	    }
+	}
+    }
+}
+
+/*
+ * print miscellaneous magic bonuses
+ */
+char *
+misc_name(obj)
+register struct object *obj;
+{
+    static char buf[LINELEN];
+    char buf1[LINELEN];
+
+    buf[0] = '\0';
+    buf1[0] = '\0';
+    if (!(obj->o_flags & ISKNOW))
+	return (m_magic[obj->o_which].mi_name);
+    switch (obj->o_which) {
+	case MM_BRACERS:
+	case MM_PROTECT:
+	    strcat(buf, num(obj->o_ac, 0));
+	    strcat(buf, " ");
+    }
+    switch (obj->o_which) {
+	case MM_G_OGRE:
+	case MM_G_DEXTERITY:
+	case MM_JEWEL:
+	case MM_STRANGLE:
+	case MM_R_POWERLESS:
+	case MM_DANCE:
+	    if (obj->o_flags & ISCURSED)
+		strcat(buf, "cursed ");
+    }
+    strcat(buf, m_magic[obj->o_which].mi_name);
+    switch (obj->o_which) {
+	case MM_JUG:
+	    if (obj->o_ac == JUG_EMPTY)
+		strcat(buf1, " [empty]");
+	    else if (p_know[obj->o_ac])
+		sprintf(buf1, " [containing a potion of %s (%s)]",
+			p_magic[obj->o_ac].mi_name,
+			p_colors[obj->o_ac]);
+	    else sprintf(buf1, " [containing a%s %s liquid]", 
+			vowelstr(p_colors[obj->o_ac]),