void gray_mage_cast_spell(void) { _slot_info_ptr slot_ptr; /* Blind is OK!!! */ if (p_ptr->confused) { msg_print("You are too confused!"); return; } slot_ptr = _choose("Cast", _ALLOW_EXCHANGE | _SHOW_INFO); if (slot_ptr) { magic_type *spell_ptr = _get_spell_info(slot_ptr->realm, slot_ptr->spell); int cost = calculate_cost(spell_ptr->smana); int fail = calculate_fail_rate(spell_ptr->slevel, spell_ptr->sfail, p_ptr->stat_ind[A_INT]); if (spell_ptr->slevel > p_ptr->lev) /* Experience Drain? */ { msg_format("You need to be level %d to use that spell.", spell_ptr->slevel); return; } if (cost > p_ptr->csp) { msg_print("You do not have enough mana to cast this spell."); return; } p_ptr->csp -= cost; energy_use = 100; if (randint0(100) < fail) { if (flush_failure) flush(); cmsg_format(TERM_VIOLET, "You failed to cast %s!", do_spell(slot_ptr->realm, slot_ptr->spell, SPELL_NAME)); if (demigod_is_(DEMIGOD_ATHENA)) p_ptr->csp += cost/2; spell_stats_on_fail_old(slot_ptr->realm, slot_ptr->spell); sound(SOUND_FAIL); do_spell(slot_ptr->realm, slot_ptr->spell, SPELL_FAIL); } else { if (!do_spell(slot_ptr->realm, slot_ptr->spell, SPELL_CAST)) { /* Canceled */ p_ptr->csp += cost; energy_use = 0; return; } sound(SOUND_ZAP); spell_stats_on_cast_old(slot_ptr->realm, slot_ptr->spell); } } p_ptr->redraw |= PR_MANA; p_ptr->window |= PW_SPELL; }
/*! * @brief 一定ゲームターン毎に復讐処理の残り期間の判定を行う * @return なし */ void revenge_spell(void) { if (p_ptr->realm1 != REALM_HEX) return; if (p_ptr->magic_num2[2] <= 0) return; switch(p_ptr->magic_num2[1]) { case 1: do_spell(REALM_HEX, HEX_PATIENCE, SPELL_CONT); break; case 2: do_spell(REALM_HEX, HEX_REVENGE, SPELL_CONT); break; } }
static void _list_spell(doc_ptr doc, int realm, int spell, int choice, int options) { magic_type *spell_ptr = _get_spell_info(realm, spell); int cost = calculate_cost(spell_ptr->smana); int fail = calculate_fail_rate(spell_ptr->slevel, spell_ptr->sfail, p_ptr->stat_ind[A_INT]); if (cost > p_ptr->csp) doc_insert(doc, "<color:D>"); else if (choice == _browse_choice) doc_insert(doc, "<color:B>"); else if (spell_ptr->slevel > p_ptr->lev) { if (options & _FROM_BOOK) doc_insert(doc, "<color:D>"); else doc_insert(doc, "<color:y>"); } else doc_insert(doc, "<color:w>"); if (spell_ptr->slevel > p_ptr->lev) doc_printf(doc, " <color:D>%c)</color> ", I2A(choice)); else doc_printf(doc, " %c) ", I2A(choice)); doc_printf(doc, "%-20.20s ", do_spell(realm, spell, SPELL_NAME)); doc_printf(doc, "%3d %3d %3d%% ", spell_ptr->slevel, cost, fail); if (spell_ptr->slevel > p_ptr->lev) { if (options & _FROM_BOOK) doc_printf(doc, "%-15.15s", ""); else doc_printf(doc, "%-15.15s", "Forgotten"); } else if (options & _SHOW_INFO) doc_printf(doc, "%-15.15s", do_spell(realm, spell, SPELL_INFO)); if (options & _SHOW_STATS) { spell_stats_ptr stats = spell_stats_old(realm, spell); if (stats->ct_cast + stats->ct_fail) { doc_printf(doc, " %5d %4d %3d%%", stats->ct_cast, stats->ct_fail, spell_stats_fail(stats) ); } } doc_insert(doc, "</color>\n"); }
static void _list_spells(doc_ptr doc, int options) { int i; doc_insert(doc, "<style:table>"); doc_printf(doc, "<color:G> %-20.20s Lvl SP Fail %-15.15s", "Name", "Desc"); if (options & _SHOW_STATS) doc_insert(doc, " Cast Fail"); doc_insert(doc, "</color>\n"); for (i = 0; i < _MAX_SLOTS; i++) { if (_spells[i].realm != REALM_NONE) _list_spell(doc, _spells[i].realm, _spells[i].spell, i, options); else { if (options & _ALLOW_EMPTY) doc_printf(doc, " %c) <color:D>(Empty)</color>\n", I2A(i)); else doc_printf(doc, " <color:D>%c) (Empty)</color>\n", I2A(i)); } } doc_insert(doc, "</style>"); if (_browse_choice != -1 && _spells[_browse_choice].realm != REALM_NONE) { doc_newline(doc); doc_printf(doc, " <indent>%s</indent>\n\n", do_spell(_spells[_browse_choice].realm, _spells[_browse_choice].spell, SPELL_DESC)); } }
static void _spoil_spell_book2(doc_ptr doc, int class1_idx, int class2_idx, int realm_idx, int book_idx) { int spell_idx; int k_idx = lookup_kind(realm2tval(realm_idx), book_idx); player_magic *magic1_ptr = &m_info[class1_idx]; player_magic *magic2_ptr = &m_info[class2_idx]; doc_printf(doc, "%-25.25s <color:G>%-12.12s</color> <color:R>%-12.12s</color>\n", "", get_class_aux(class1_idx, 0)->name, get_class_aux(class2_idx, 0)->name); doc_printf(doc, "<color:o>%-25.25s</color><color:G> Lvl Cst Fail</color> <color:R>Lvl Cst Fail</color>\n", k_name + k_info[k_idx].name); for (spell_idx = book_idx*8; spell_idx < (book_idx+1)*8; spell_idx++) { magic_type *spell1_ptr = &magic1_ptr->info[realm_idx - 1][spell_idx]; magic_type *spell2_ptr = &magic2_ptr->info[realm_idx - 1][spell_idx]; doc_printf(doc, "%-25.25s ", do_spell(realm_idx, spell_idx, SPELL_NAME)); if (1 <= spell1_ptr->slevel && spell1_ptr->slevel <= PY_MAX_LEVEL) doc_printf(doc, "%3d %3d %3d%% ", spell1_ptr->slevel, spell1_ptr->smana, spell1_ptr->sfail); else doc_insert(doc, "<color:D>Illegible</color> "); if (1 <= spell2_ptr->slevel && spell2_ptr->slevel <= PY_MAX_LEVEL) doc_printf(doc, "%3d %3d %3d%% ", spell2_ptr->slevel, spell2_ptr->smana, spell2_ptr->sfail); else doc_insert(doc, "<color:D>Illegible</color> "); doc_newline(doc); } doc_newline(doc); }
static void _spoil_spell_book(doc_ptr doc, int class_idx, int realm_idx, int book_idx) { int spell_idx; int k_idx = lookup_kind(realm2tval(realm_idx), book_idx); player_magic *magic_ptr = &m_info[class_idx]; doc_printf(doc, "<color:o>%-25.25s</color><color:G> Lvl Cst Fail </color>\n", k_name + k_info[k_idx].name); for (spell_idx = book_idx*8; spell_idx < (book_idx+1)*8; spell_idx++) { magic_type *spell_ptr = NULL; if (is_magic(realm_idx)) spell_ptr = &magic_ptr->info[realm_idx - 1][spell_idx]; else spell_ptr = &technic_info[realm_idx - MIN_TECHNIC][spell_idx]; if (0 < spell_ptr->slevel && spell_ptr->slevel <= PY_MAX_LEVEL) { doc_printf(doc, "%-25.25s %3d %3d %3d%%\n", do_spell(realm_idx, spell_idx, SPELL_NAME), spell_ptr->slevel, spell_ptr->smana, spell_ptr->sfail ); } else { doc_printf(doc, "<color:D>%-26.26s</color>\n", "Illegible"); } } doc_newline(doc); }
/* * Stop singing if the player is a Bard */ void bard_stop_singing(void) { if (p_ptr->pclass != CLASS_BARD) return; /* Are there interupted song? */ if (p_ptr->magic_num1[1]) { /* Forget interupted song */ p_ptr->magic_num1[1] = 0; return; } /* The player is singing? */ if (!p_ptr->magic_num1[0]) return; /* Hack -- if called from set_action(), avoid recursive loop */ if (p_ptr->action == ACTION_SING) set_action(ACTION_NONE); /* Message text of each song or etc. */ do_spell(REALM_MUSIC, p_ptr->magic_num2[0], SPELL_STOP); p_ptr->magic_num1[0] = MUSIC_NONE; p_ptr->magic_num2[0] = 0; /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); /* Redraw status bar */ p_ptr->redraw |= (PR_STATUS); }
bool stop_hex_spell_all(void) { int i; for (i = 0; i < 32; i++) { if (hex_spelling(i)) do_spell(REALM_HEX, i, SPELL_STOP); } p_ptr->magic_num1[0] = 0; p_ptr->magic_num2[0] = 0; /* Print message */ if (p_ptr->action == ACTION_SPELL) set_action(ACTION_NONE); /* Redraw status */ p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS); p_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA); return TRUE; }
/*! * @brief プレイヤーが詠唱中の呪術から一つを選んで停止する * @return なし */ bool stop_hex_spell(void) { int spell; char choice; char out_val[160]; bool flag = FALSE; int y = 1; int x = 20; int sp[MAX_KEEP]; if (!hex_spelling_any()) { #ifdef JP msg_print("呪文を詠唱していません。"); #else msg_print("You are casting no spell."); #endif return FALSE; } /* Stop all spells */ else if ((p_ptr->magic_num2[0] == 1) || (p_ptr->lev < 35)) { return stop_hex_spell_all(); } else { #ifdef JP strnfmt(out_val, 78, "どの呪文の詠唱を中断しますか?(呪文 %c-%c, 'l'全て, ESC)", I2A(0), I2A(p_ptr->magic_num2[0] - 1)); #else strnfmt(out_val, 78, "Which spell do you stop casting? (Spell %c-%c, 'l' to all, ESC)", I2A(0), I2A(p_ptr->magic_num2[0] - 1)); #endif screen_save(); while (!flag) { int n = 0; Term_erase(x, y, 255); prt(" 名前", y, x + 5); for (spell = 0; spell < 32; spell++) { if (hex_spelling(spell)) { Term_erase(x, y + n + 1, 255); put_str(format("%c) %s", I2A(n), do_spell(REALM_HEX, spell, SPELL_NAME)), y + n + 1, x + 2); sp[n++] = spell; } } if (!get_com(out_val, &choice, TRUE)) break; if (isupper(choice)) choice = tolower(choice); if (choice == 'l') /* All */ { screen_load(); return stop_hex_spell_all(); } if ((choice < I2A(0)) || (choice > I2A(p_ptr->magic_num2[0] - 1))) continue; flag = TRUE; } } screen_load(); if (flag) { int n = sp[A2I(choice)]; do_spell(REALM_HEX, n, SPELL_STOP); p_ptr->magic_num1[0] &= ~(1L << n); p_ptr->magic_num2[0]--; } /* Redraw status */ p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS); p_ptr->redraw |= (PR_EXTRA | PR_HP | PR_MANA); return flag; }
/*! * @brief 一定時間毎に呪術で消費するMPを処理する / * Upkeeping hex spells Called from dungeon.c * @return なし */ void check_hex(void) { int spell; s32b need_mana; u32b need_mana_frac; bool res = FALSE; /* Spells spelled by player */ if (p_ptr->realm1 != REALM_HEX) return; if (!p_ptr->magic_num1[0] && !p_ptr->magic_num1[1]) return; if (p_ptr->magic_num1[1]) { p_ptr->magic_num1[0] = p_ptr->magic_num1[1]; p_ptr->magic_num1[1] = 0; res = TRUE; } /* Stop all spells when anti-magic ability is given */ if (p_ptr->anti_magic) { stop_hex_spell_all(); return; } need_mana = 0; for (spell = 0; spell < 32; spell++) { if (hex_spelling(spell)) { const magic_type *s_ptr; s_ptr = &technic_info[REALM_HEX - MIN_TECHNIC][spell]; need_mana += mod_need_mana(s_ptr->smana, spell, REALM_HEX); } } /* Culcurates final mana cost */ need_mana_frac = 0; s64b_div(&need_mana, &need_mana_frac, 0, 3); /* Divide by 3 */ need_mana += (p_ptr->magic_num2[0] - 1); /* Not enough mana */ if (s64b_cmp(p_ptr->csp, p_ptr->csp_frac, need_mana, need_mana_frac) < 0) { stop_hex_spell_all(); return; } /* Enough mana */ else { s64b_sub(&(p_ptr->csp), &(p_ptr->csp_frac), need_mana, need_mana_frac); p_ptr->redraw |= PR_MANA; if (res) { #ifdef JP msg_print("詠唱を再開した。"); #else msg_print("You restart spelling."); #endif p_ptr->action = ACTION_SPELL; /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS | PU_HP); /* Redraw map and status bar */ p_ptr->redraw |= (PR_MAP | PR_STATUS | PR_STATE); /* Update monsters */ p_ptr->update |= (PU_MONSTERS); /* Window stuff */ p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON); } } /* Gain experiences of spelling spells */ for (spell = 0; spell < 32; spell++) { const magic_type *s_ptr; if (!hex_spelling(spell)) continue; s_ptr = &technic_info[REALM_HEX - MIN_TECHNIC][spell]; if (p_ptr->spell_exp[spell] < SPELL_EXP_BEGINNER) p_ptr->spell_exp[spell] += 5; else if(p_ptr->spell_exp[spell] < SPELL_EXP_SKILLED) { if (one_in_(2) && (dun_level > 4) && ((dun_level + 10) > p_ptr->lev)) p_ptr->spell_exp[spell] += 1; } else if(p_ptr->spell_exp[spell] < SPELL_EXP_EXPERT) { if (one_in_(5) && ((dun_level + 5) > p_ptr->lev) && ((dun_level + 5) > s_ptr->slevel)) p_ptr->spell_exp[spell] += 1; } else if(p_ptr->spell_exp[spell] < SPELL_EXP_MASTER) { if (one_in_(5) && ((dun_level + 5) > p_ptr->lev) && (dun_level > s_ptr->slevel)) p_ptr->spell_exp[spell] += 1; } } /* Do any effects of continual spells */ for (spell = 0; spell < 32; spell++) { if (hex_spelling(spell)) { do_spell(REALM_HEX, spell, SPELL_CONT); } } }
/* Legacy Spell System */ spell_stats_ptr spell_stats_old(int realm, int spell) { cptr name = do_spell(realm, spell, SPELL_NAME); return spell_stats_aux(name); }
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); }
void gray_mage_gain_spell(void) { int item; if (p_ptr->blind || no_lite()) { msg_print("You cannot see!"); return; } if (p_ptr->confused) { msg_print("You are too confused!"); return; } if (!p_ptr->new_spells) { msg_print("You cannot learn any new spells!"); return; } item_tester_hook = _spell_book_p; if (get_item(&item, "Study which book?", "You have no books that you can read.", USE_INVEN)) { object_type *o_ptr = &inventory[item]; int spell_idx; _slot_info_ptr slot_ptr; /* Pick a spell to learn */ spell_idx = _choose_spell_to_gain(o_ptr); if (spell_idx == -1) return; /* Pick a slot for storage (possibly replacing an already learned spell) */ slot_ptr = _choose("Replace", _ALLOW_EMPTY | _SHOW_INFO); if (!slot_ptr) return; if (slot_ptr->realm != REALM_NONE) { string_ptr prompt = string_alloc_format( "Really replace %s? <color:y>[y/N]</color>", do_spell(slot_ptr->realm, slot_ptr->spell, SPELL_NAME)); if (msg_prompt(string_buffer(prompt), "ny", PROMPT_DEFAULT) == 'n') { string_free(prompt); return; } string_free(prompt); } /* Learn the spell: Note, we don't bother with spell_learned# and spell_order[], since these are hard coded for 2 spell realms. Hopefully, ticking up learned_spells is enough? */ p_ptr->learned_spells++; slot_ptr->realm = tval2realm(o_ptr->tval); slot_ptr->spell = spell_idx; msg_format("You have learned the spell '%s'.", do_spell(slot_ptr->realm, slot_ptr->spell, SPELL_NAME)); p_ptr->update |= PU_SPELLS; p_ptr->redraw |= PR_EFFECTS; energy_use = 100; } }