Example #1
0
/**
 * Display a row of the spell menu
 */
static void spell_menu_display(struct menu *m, int oid, bool cursor,
		int row, int col, int wid)
{
	struct spell_menu_data *d = menu_priv(m);
	int spell_index = d->spells[oid];
	const struct class_spell *spell = spell_by_index(spell_index);

	char help[30];
	char out[80];

	int attr;
	const char *illegible = NULL;
	const char *comment = NULL;

	if (spell->slevel >= 99) {
		illegible = "(illegible)";
		attr = COLOUR_L_DARK;
	} else if (player->spell_flags[spell_index] & PY_SPELL_FORGOTTEN) {
		comment = " forgotten";
		attr = COLOUR_YELLOW;
	} else if (player->spell_flags[spell_index] & PY_SPELL_LEARNED) {
		if (player->spell_flags[spell_index] & PY_SPELL_WORKED) {
			/* Get extra info */
			get_spell_info(spell_index, help, sizeof(help));
			comment = help;
			attr = COLOUR_WHITE;
		} else {
			comment = " untried";
			attr = COLOUR_L_GREEN;
		}
	} else if (spell->slevel <= player->lev) {
		comment = " unknown";
		attr = COLOUR_L_BLUE;
	} else {
		comment = " difficult";
		attr = COLOUR_RED;
	}

	/* Dump the spell --(-- */
	strnfmt(out, sizeof(out), "%-30s%2d %4d %3d%%%s", spell->name,
			spell->slevel, spell->smana, spell_chance(spell_index), comment);
	c_prt(attr, illegible ? illegible : out, row, col);
}
Example #2
0
/* Cast the specified spell */
bool spell_cast(int spell, int dir)
{
    int chance;
    int plev = p_ptr->lev;
    bool failed = FALSE;
    int py = p_ptr->py;
    int px = p_ptr->px;

    /* Get the spell */
    const magic_type *mt_ptr = &mp_ptr->info[spell];

    /* Spell failure chance */
    chance = spell_chance(spell);

    /* Specialty Ability */
    if (player_has(PF_HEIGHTEN_MAGIC))
	plev += 1 + ((p_ptr->heighten_power + 5) / 10);
    if (player_has(PF_CHANNELING))
	plev += get_channeling_boost();

    /* Failed spell */
    if (randint0(100) < chance) {
	failed = TRUE;

	if (OPT(flush_failure))
	    flush();
	msg(magic_desc[mp_ptr->spell_realm][SPELL_FAIL]);
    }

    /* Process spell */
    else {
	/* Cast the spell */
	if (!cast_spell(mp_ptr->spell_book, mt_ptr->index, dir, plev))
	    return FALSE;

	/* A spell was cast */
	sound(MSG_SPELL);


	/* A spell was cast or a prayer prayed */
	if (!(p_ptr->spell_flags[spell] & PY_SPELL_WORKED)){
	    int e = mt_ptr->sexp;

	    /* The spell worked */
	    p_ptr->spell_flags[spell] |= PY_SPELL_WORKED;

	    /* Gain experience */
	    gain_exp(e * mt_ptr->slevel);
	    
	    /* Redraw object recall */
	    p_ptr->redraw |= (PR_OBJECT);
	}
    }

    /* Hack - simplify rune of mana calculations by fully draining the rune
     * first */
    if (cave_trap_specific(py, px, RUNE_MANA) && 
	(mana_reserve <= mt_ptr->smana)	&& (mt_ptr->index != 60)) 
    {
	p_ptr->csp += mana_reserve;
	mana_reserve = 0;
    }

    /* Rune of mana can take less mana than specified */
    if (mt_ptr->index == 60) {
	/* Standard mana amount */
	int mana = 40;

	/* Already full? */
	if (mana_reserve >= MAX_MANA_RESERVE) {
	    /* Use no mana */
	    mana = 0;
	}

	/* Don't put in more than we have */
	else if (p_ptr->csp < mana)
	    mana = p_ptr->csp;

	/* Don't put in more than it will hold */
	if (mana_reserve + mana > MAX_MANA_RESERVE)
	    mana = MAX_MANA_RESERVE - mana_reserve;

	/* Deduct */
	p_ptr->csp -= mana;
    }

    /* Use mana from a rune if possible */
    else if (cave_trap_specific(py, px, RUNE_MANA)
	     && (mana_reserve > mt_ptr->smana)) {
	mana_reserve -= mt_ptr->smana;
    }

    /* Sufficient mana */
    else if (mt_ptr->smana <= p_ptr->csp) {
	/* Use some mana */
	p_ptr->csp -= mt_ptr->smana;

	/* Specialty ability Harmony */
	if ((failed == FALSE) & (player_has(PF_HARMONY))) {
	    int frac, boost;

	    /* Percentage of max hp to be regained */
	    frac = 3 + (mt_ptr->smana / 3);

	    /* Cap at 10 % */
	    if (frac > 10)
		frac = 10;

	    /* Calculate fractional bonus */
	    boost = (frac * p_ptr->mhp) / 100;

	    /* Apply bonus */
	    (void) hp_player(boost);
	}
    }

    /* Over-exert the player */
    else {
	int oops = mt_ptr->smana - p_ptr->csp;

	/* No mana left */
	p_ptr->csp = 0;
	p_ptr->csp_frac = 0;

	/* Message */
	if (mp_ptr->spell_realm == REALM_NECROMANTIC)
	    msg("You collapse after the ritual!");
	else
	    msg("You faint from the effort!");

	/* Hack -- Bypass free action */
	(void) inc_timed(TMD_PARALYZED, randint1(5 * oops + 1), TRUE);

	/* Damage CON (possibly permanently) */
	if (randint0(100) < 50) {
	    bool perm = (randint0(100) < 25);

	    /* Message */
	    msg("You have damaged your health!");

	    /* Reduce constitution */
	    (void) dec_stat(A_CON, 15 + randint1(10), perm);
	}
    }


    /* Redraw mana */
    p_ptr->redraw |= (PR_MANA);

    return TRUE;
}
Example #3
0
static void _dump_book(doc_ptr doc, int realm, int book)
{
    int          k_idx = lookup_kind(realm2tval(realm), book);
    int          i, increment = 64;
    caster_info *caster_ptr = get_caster_info();

    if ((p_ptr->pclass == CLASS_SORCERER) || (p_ptr->pclass == CLASS_RED_MAGE)) increment = 0;
    else if (realm == p_ptr->realm1) increment = 0;
    else if (realm == p_ptr->realm2) increment = 32;

    if (realm == REALM_HISSATSU)
    {
        doc_printf(doc, "<color:G>    %-25.25s Lvl  SP %-15.15s  Cast</color>\n", k_name + k_info[k_idx].name, "Desc");
    }
    else
    {
        if (caster_ptr && (caster_ptr->options & CASTER_USE_HP))
            doc_printf(doc, "<color:G>    %-23.23s Profic Lvl  HP Fail %-15.15s  Cast Fail</color>\n", k_name + k_info[k_idx].name, "Desc");
        else
            doc_printf(doc, "<color:G>    %-23.23s Profic Lvl  SP Fail %-15.15s  Cast Fail</color>\n", k_name + k_info[k_idx].name, "Desc");
    }

    for (i = 0; i < 8; i++)
    {
        int         s_idx = book * 8 + i;
        magic_type *s_ptr;
        int         cost;
        bool        max = FALSE;
        char        proficiency[10];
        char        info[80];
        cptr        comment;
        char        line[160];
        char        color = 'w';

        if (is_magic(realm))
            s_ptr = &mp_ptr->info[realm - 1][s_idx];
        else
            s_ptr = &technic_info[realm - MIN_TECHNIC][s_idx];

        if (s_ptr->slevel >= 99) continue;

        if (realm == REALM_HISSATSU)
            cost = s_ptr->smana;
        else
        {
            s16b exp = experience_of_spell(s_idx, realm);
            int  exp_level = spell_exp_level(exp);
            
            cost = mod_need_mana(s_ptr->smana, s_idx, realm);

            max = FALSE;
            if (!increment && (exp_level == EXP_LEVEL_MASTER)) max = TRUE;
            else if ((increment == 32) && (exp_level >= EXP_LEVEL_EXPERT)) max = TRUE;
            else if ((p_ptr->pclass == CLASS_RED_MAGE) && (exp_level >= EXP_LEVEL_SKILLED)) max = TRUE;

            strncpy(proficiency, exp_level_str[exp_level], 4);
            proficiency[3] = ']';
            proficiency[4] = '\0';
        }

        strcpy(info, do_spell(realm, s_idx, SPELL_INFO));
        comment = info;
        
        if (p_ptr->pclass == CLASS_SORCERER || p_ptr->pclass == CLASS_RED_MAGE)
        {
            if (s_ptr->slevel > p_ptr->max_plv)
            {
                comment = "unknown";
                color = 'D';
            }
            else if (s_ptr->slevel > p_ptr->lev)
            {
                comment = "forgotten";
                color = 'y';
            }
        }
        else if ((realm == p_ptr->realm1) ?
            ((p_ptr->spell_forgotten1 & (1L << s_idx))) :
            ((p_ptr->spell_forgotten2 & (1L << s_idx))))
        {
            comment = "forgotten";
            color = 'y';
        }
        else if (!((realm == p_ptr->realm1) ?
            (p_ptr->spell_learned1 & (1L << s_idx)) :
            (p_ptr->spell_learned2 & (1L << s_idx))))
        {
            comment = "unknown";
            if (s_ptr->slevel > p_ptr->lev)
                color = 'D';
            else
                color = 'B';
        }
        else if (!((realm == p_ptr->realm1) ?
            (p_ptr->spell_worked1 & (1L << s_idx)) :
            (p_ptr->spell_worked2 & (1L << s_idx))))
        {
            comment = "untried";
        }

        sprintf(line, " %c) ", I2A(i));
        if (realm == REALM_HISSATSU)
        {
            spell_stats_ptr stats = spell_stats_old(realm, s_idx);
            strcat(
                line, 
                format(
                    "<color:%c>%-25s %3d %3d %-15.15s %5d</color>",
                    color,
                    do_spell(realm, s_idx, SPELL_NAME),
                    s_ptr->slevel, 
                    cost, 
                    comment,
                    stats->ct_cast
                )
            );
        }
        else
        {
            spell_stats_ptr stats = spell_stats_old(realm, s_idx);
            strcat(
                line, 
                format(
                    "<color:%c>%-25s%c%-4s %3d %3d %3d%% %-15.15s %5d %4d %3d%%</color>",
                    color,
                    do_spell(realm, s_idx, SPELL_NAME),
                    (max ? '!' : ' '), 
                    proficiency,
                    s_ptr->slevel, 
                    cost, 
                    spell_chance(s_idx, realm), 
                    comment,
                    stats->ct_cast, 
                    stats->ct_fail,
                    spell_stats_fail(stats)
                )
            );
        }

        doc_printf(doc, "%s\n", line);
    }
    doc_newline(doc);
}
Example #4
0
/**
 * Display a row of the spell menu
 */
static void spell_menu_display(menu_type * m, int oid, bool cursor,
							   int row, int col, int wid)
{
	struct spell_menu_data *d = menu_priv(m);
	int spell = d->spells[oid];
	const magic_type *s_ptr = &mp_ptr->info[spell];

	char help[30];

	int attr_name, attr_extra, attr_book;
	int tval = mp_ptr->spell_book;
	const char *comment = NULL;

	/* Choose appropriate spellbook color. */
	if (tval == TV_MAGIC_BOOK) {
		if (d->book_sval < SV_BOOK_MIN_GOOD)
			attr_book = TERM_L_RED;
		else
			attr_book = TERM_RED;
	} else if (tval == TV_PRAYER_BOOK) {
		if (d->book_sval < SV_BOOK_MIN_GOOD)
			attr_book = TERM_L_BLUE;
		else
			attr_book = TERM_BLUE;
	} else if (tval == TV_DRUID_BOOK) {
		if (d->book_sval < SV_BOOK_MIN_GOOD)
			attr_book = TERM_L_GREEN;
		else
			attr_book = TERM_GREEN;
	} else if (tval == TV_NECRO_BOOK) {
		if (d->book_sval < SV_BOOK_MIN_GOOD)
			attr_book = TERM_L_PURPLE;
		else
			attr_book = TERM_PURPLE;
	} else
		attr_book = TERM_WHITE;

	if (p_ptr->spell_flags[spell] & PY_SPELL_FORGOTTEN) {
		comment = " forgotten";
		attr_name = TERM_L_WHITE;
		attr_extra = TERM_L_WHITE;
	} else if (p_ptr->spell_flags[spell] & PY_SPELL_LEARNED) {
		if (p_ptr->spell_flags[spell] & PY_SPELL_WORKED) {
			/* Get extra info */
			get_spell_info(mp_ptr->spell_book, s_ptr->index, help,
						   sizeof(help));
			comment = help;
			attr_name = attr_book;
			attr_extra = TERM_DEEP_L_BLUE;
		} else {
			comment = " untried";
			attr_name = TERM_WHITE;
			attr_extra = TERM_WHITE;
		}
	} else if (s_ptr->slevel <= p_ptr->lev) {
		comment = " unknown";
		attr_extra = TERM_L_WHITE;
		attr_name = TERM_WHITE;
	} else {
		comment = " difficult";
		attr_extra = TERM_MUD;
		attr_name = TERM_MUD;
	}

	/* Dump the spell --(-- */
	c_put_str(attr_name, format("%-30s", get_spell_name(s_ptr->index)),
			  row, col);
	put_str(format
			("%2d %4d %3d%%", s_ptr->slevel, s_ptr->smana,
			 spell_chance(spell)), row, col + 30);
	c_put_str(attr_extra, format("%s", comment), row, col + 42);
}
Example #5
0
/* Cas the specified spell */
bool spell_cast(int spell, int dir)
{
	int chance;

	/* Get the spell */
	const magic_type *s_ptr = &mp_ptr->info[spell];	

	/* Spell failure chance */
	chance = spell_chance(spell);

	/* Failed spell */
	if (randint0(100) < chance)
	{
		flush();
		msg("You failed to concentrate hard enough!");
	}

	/* Process spell */
	else
	{
		/* Cast the spell */
		if (!cast_spell(cp_ptr->spell_book, spell, dir)) return FALSE;

		/* A spell was cast */
		sound(MSG_SPELL);

		if (!(p_ptr->spell_flags[spell] & PY_SPELL_WORKED))
		{
			int e = s_ptr->sexp;

			/* The spell worked */
			p_ptr->spell_flags[spell] |= PY_SPELL_WORKED;

			/* Gain experience */
			gain_exp(e * s_ptr->slevel);

			/* Redraw object recall */
			p_ptr->redraw |= (PR_OBJECT);
		}
	}

	/* Sufficient mana */
	if (s_ptr->smana <= p_ptr->csp)
	{
		/* Use some mana */
		p_ptr->csp -= s_ptr->smana;
	}

	/* Over-exert the player */
	else
	{
		int oops = s_ptr->smana - p_ptr->csp;

		/* No mana left */
		p_ptr->csp = 0;
		p_ptr->csp_frac = 0;

		/* Message */
		msg("You faint from the effort!");

		/* Hack -- Bypass free action */
		(void)inc_timed(TMD_PARALYZED, randint1(5 * oops + 1), TRUE);

		/* Damage CON (possibly permanently) */
		if (randint0(100) < 50)
		{
			bool perm = (randint0(100) < 25);

			/* Message */
			msg("You have damaged your health!");

			/* Reduce constitution */
			player_stat_dec(p_ptr, A_CON, perm);
		}
	}

	/* Redraw mana */
	p_ptr->redraw |= (PR_MANA);

	return TRUE;
}