view arogue5/sticks.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 source

/*
 * Functions to implement the various sticks one might find
 * while wandering around the dungeon.
 *
 * Advanced Rogue
 * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
 * 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 "curses.h"
#include <ctype.h>
#include "rogue.h"


/*
 * zap a stick and see what happens
 */
do_zap(gotdir, which, flag)
bool gotdir;
int which;
int flag;
{
    register struct linked_list *item;
    register struct object *obj = NULL;
    register struct thing *tp;
    register int y, x;
    struct linked_list *nitem;
    struct object *nobj;
    bool cursed, blessed, is_stick;

    blessed = FALSE;
    cursed = FALSE;
    is_stick = FALSE;

    if (which == 0) {
	if ((item = get_item(pack, "zap with", ZAPPABLE)) == NULL)
	    return(FALSE);
	obj = OBJPTR(item);

	/* Handle relics specially here */
	if (obj->o_type == RELIC) {
	    switch (obj->o_which) {
		case ORCUS_WAND:
		    msg(nothing);
		    return(TRUE);
		when MING_STAFF:
		    which = WS_MISSILE;
		when ASMO_ROD:
		    switch (rnd(3)) {
			case 0:
			    which = WS_ELECT;
			when 1:
			    which = WS_COLD;
			otherwise:
			    which = WS_FIRE;
		    }
	    }
	    cursed = FALSE;
	    blessed = FALSE;
	}
	else {
	    which = obj->o_which;
	    ws_know[which] = TRUE;
	    cursed = (obj->o_flags & ISCURSED) != 0;
	    blessed = (obj->o_flags & ISBLESSED) != 0;
	    is_stick = TRUE;
	}
    }
    else {
	cursed = flag & ISCURSED;
	blessed = flag & ISBLESSED;
    }
    switch (which) {	/* no direction for these */
	case WS_LIGHT:
	case WS_DRAIN:
	case WS_CHARGE:
	case WS_CURING:
	    break;

	default:
	    if (!get_dir())
		return(FALSE);
	    if (!gotdir) {
		do {
		    delta.y = rnd(3) - 1;
		    delta.x = rnd(3) - 1;
		} while (delta.y == 0 && delta.x == 0);
	    }
    }

    if (is_stick) {
	if (obj->o_charges < 1) {
	    msg(nothing);
	    return(TRUE);
	}
	obj->o_charges--;
    }
    if (which == WS_WONDER) {
	switch (rnd(14)) {
	    case  0: which = WS_ELECT;
	    when  1: which = WS_FIRE;
	    when  2: which = WS_COLD;
	    when  3: which = WS_POLYMORPH;
	    when  4: which = WS_MISSILE;
	    when  5: which = WS_SLOW_M;
	    when  6: which = WS_TELMON;
	    when  7: which = WS_CANCEL;
	    when  8: which = WS_CONFMON;
	    when  9: which = WS_DISINTEGRATE;
	    when 10: which = WS_PETRIFY;
	    when 11: which = WS_PARALYZE;
	    when 12: which = WS_MDEG;
	    when 13: which = WS_FEAR;
	}
	if(ws_magic[which].mi_curse>0 && rnd(100)<=ws_magic[which].mi_curse){
	    cursed = TRUE;
	    blessed = FALSE;
	}
    }

    switch (which) {
	case WS_LIGHT:
	    /*
	     * Reddy Kilowat wand.  Light up the room
	     */
	    blue_light(blessed, cursed);
	when WS_DRAIN:
	    /*
	     * Take away 1/2 of hero's hit points, then take it away
	     * evenly from the monsters in the room or next to hero
	     * if he is in a passage (but leave the monsters alone
	     * if the stick is cursed)
	     */
	    if (pstats.s_hpt < 2) {
		msg("You are too weak to use it.");
		return(TRUE);
	    }
	    if (cursed)
		pstats.s_hpt /= 2;
	    else
		drain(hero.y-1, hero.y+1, hero.x-1, hero.x+1);
	when WS_POLYMORPH:
	case WS_TELMON:
	case WS_CANCEL:
	{
	    register char monster, oldch;
	    register int rm;

	    y = hero.y;
	    x = hero.x;
	    while (shoot_ok(winat(y, x))) {
		y += delta.y;
		x += delta.x;
	    }
	    if (isalpha(monster = CCHAR( mvwinch(mw, y, x) ))) {
		register struct room *rp;

		item = find_mons(y, x);
		tp = THINGPTR(item);
		/* if the monster gets the saving throw, leave the case */
		if (save(VS_MAGIC, tp, 0)) {
		    msg(nothing);
		    break;
		}

		/* Unhold player */
		if (on(*tp, DIDHOLD)) {
		    turn_off(*tp, DIDHOLD);
		    if (--hold_count == 0) turn_off(player, ISHELD);
		}
		/* unsuffocate player */
		if (on(*tp, DIDSUFFOCATE)) {
		    turn_off(*tp, DIDSUFFOCATE);
		    extinguish(suffocate);
		}
		rp = roomin(&tp->t_pos);
		/*
		 * check to see if room should go dark
		 */
		if (on(*tp, HASFIRE)) {
		    if (rp != NULL) {