/** * 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); }
/* 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; }
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); }
/** * 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); }
/* 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; }