#include "angband.h" #include "cave.hpp" #include "cmd5.hpp" #include "gods.hpp" #include "lua_bind.hpp" #include "spell_type.hpp" #include "spell_idx_list.hpp" #include "spells3.hpp" #include "spells5.hpp" #include #include #include school_book_type school_books[SCHOOL_BOOKS_SIZE]; s32b SCHOOL_AIR; s32b SCHOOL_AULE; s32b SCHOOL_CONVEYANCE; s32b SCHOOL_DEMON; s32b SCHOOL_DEVICE; s32b SCHOOL_DIVINATION; s32b SCHOOL_EARTH; s32b SCHOOL_ERU; s32b SCHOOL_FIRE; s32b SCHOOL_GEOMANCY; s32b SCHOOL_MANA; s32b SCHOOL_MANDOS; s32b SCHOOL_MANWE; s32b SCHOOL_MELKOR; s32b SCHOOL_META; s32b SCHOOL_MIND; s32b SCHOOL_MUSIC; s32b SCHOOL_NATURE; s32b SCHOOL_TEMPORAL; s32b SCHOOL_TULKAS; s32b SCHOOL_UDUN; s32b SCHOOL_ULMO; s32b SCHOOL_VARDA; s32b SCHOOL_WATER; s32b SCHOOL_YAVANNA; static bool_ uses_piety_to_cast(int s) { return spell_type_uses_piety_to_cast(spell_at(s)); } /** Describe what type of energy the spell uses for casting */ cptr get_power_name(s32b s) { return uses_piety_to_cast(s) ? "piety" : "mana"; } /* Changes the amount of power(mana, piety, whatever) for the spell */ void adjust_power(s32b s, s32b amount) { if (uses_piety_to_cast(s)) { inc_piety(GOD_ALL, amount); } else { increase_mana(amount); } } /* Return the amount of power available for casting spell */ s32b get_power(s32b s) { return uses_piety_to_cast(s) ? p_ptr->grace : p_ptr->csp; } /* Output the describtion when it is used as a spell */ void print_spell_desc(int s, int y) { spell_type *spell = spell_at(s); spell_type_description_foreach(spell, [&y] (std::string const &text) -> void { c_prt(TERM_L_BLUE, text.c_str(), y, 0); y += 1; }); if (spell_type_uses_piety_to_cast(spell)) { c_prt(TERM_L_WHITE, "It uses piety to cast.", y, 0); y++; } if (spell_type_castable_while_blind(spell)) { c_prt(TERM_ORANGE, "It is castable even while blinded.", y, 0); y++; } if (spell_type_castable_while_confused(spell)) { c_prt(TERM_ORANGE, "It is castable even while confused.", y, 0); y++; } } school_book_type *school_books_at(int i) { assert(i >= 0); assert(i < SCHOOL_BOOKS_SIZE); return &school_books[i]; } static void school_book_init(school_book_type *school_book) { school_book->spell_idx_list = new spell_idx_list(); } void school_book_add_spell(school_book_type *school_book, s32b spell_idx) { assert(school_book != nullptr); assert(school_book->spell_idx_list != nullptr); school_book->spell_idx_list->v.push_back(spell_idx); } int school_book_length(int sval) { school_book_type *school_book = school_books_at(sval); if (sval == BOOK_RANDOM) { return 1; } return school_book->spell_idx_list->v.size(); } int spell_x(int sval, int pval, int i) { assert(i >= 0); if (sval == BOOK_RANDOM) { return pval; } else { school_book_type *school_book = school_books_at(sval); return school_book->spell_idx_list->v.at(i); } } bool_ school_book_contains_spell(int sval, s32b spell_idx) { random_book_setup(sval, spell_idx); school_book_type *school_book = school_books_at(sval); return (school_book->spell_idx_list->v.end() != std::find(school_book->spell_idx_list->v.begin(), school_book->spell_idx_list->v.end(), spell_idx)); } void push_spell(int book_idx, s32b spell_idx) { school_book_type *school_book = school_books_at(book_idx); assert(school_book != NULL); school_book_add_spell(school_book, spell_idx); } void init_school_books() { int i; /* Initialize the new school books */ for (i = 0; ispell_idx_list->v.at(0) = spell_idx; } } static std::string spell_school_name(spell_type *spell) { std::ostringstream buf; bool first = true; for (s32b school_idx : spell_type_get_schools(spell)) { school_type *school = school_at(school_idx); // Add separator? if (first) { first = false; // Skip separator } else { buf << "/"; } // Put in the school's name buf << school->name; } return buf.str(); } int print_spell(cptr label_, byte color, int y, s32b s) { s32b level; bool_ na; spell_type *spell = spell_at(s); cptr spell_info = spell_type_info(spell); cptr label = (label_ == NULL) ? "" : label_; char level_str[8] = "n/a"; char buf[128]; get_level_school(spell, 50, -50, &level, &na); std::string sch_str(spell_school_name(spell)); if (!na) { sprintf(level_str, "%3d", (int) level); } sprintf(buf, "%s%-20s%-16s %s %4d %3d%% %s", label, spell_type_name(spell_at(s)), sch_str.c_str(), level_str, get_mana(s), (int) spell_chance_book(s), spell_info); c_prt(color, buf, y, 0); return y + 1; } int print_book(s16b sval, s32b pval, object_type *obj) { int y = 2; int i; school_book_type *school_book; random_book_setup(sval, pval); school_book = school_books_at(sval); /* Parse all spells */ i = 0; for (auto spell_idx : school_book->spell_idx_list->v) { byte color = TERM_L_DARK; bool_ is_ok; char label[8]; is_ok = is_ok_spell(spell_idx, obj); if (is_ok) { color = (get_mana(spell_idx) > get_power(spell_idx)) ? TERM_ORANGE : TERM_L_GREEN; } sprintf(label, "%c) ", 'a' + i); y = print_spell(label, color, y, spell_idx); i++; } prt(format(" %-20s%-16s Level Cost Fail Info", "Name", "School"), 1, 0); return y; } void lua_cast_school_spell(s32b s, bool_ no_cost) { bool_ use = FALSE; spell_type *spell = spell_at(s); /* No magic? */ if (p_ptr->antimagic > 0) { msg_print("Your anti-magic field disrupts any magic attempts."); return; } /* No magic? */ if (p_ptr->anti_magic) { msg_print("Your anti-magic shell disrupts any magic attempts."); return; } /* if it costs something then some condition must be met */ if (!no_cost) { /* Require lite */ if (!spell_type_castable_while_blind(spell) && ((p_ptr->blind > 0) || no_lite())) { msg_print("You cannot see!"); return; } /* Not when confused */ if (!spell_type_castable_while_confused(spell) && (p_ptr->confused > 0)) { msg_print("You are too confused!"); return; } /* Enough mana */ if (get_mana(s) > get_power(s)) { char buf[128]; sprintf(buf, "You do not have enough %s, do you want to try anyway?", get_power_name(s)); if (!get_check(buf)) { return; } } /* Invoke the spell effect */ if (!magik(spell_chance_book(s))) { use = (spell_type_produce_effect(spell) != NO_CAST); } else { use = TRUE; /* failures are dangerous; we'll flush the input buffer so it isn't missed. */ if (flush_failure) { flush(); } msg_print("You failed to get the spell off!"); } } else { spell_type_produce_effect(spell); } /* Use the mana/piety */ if (use == TRUE) { /* Reduce mana */ adjust_power(s, -get_mana(s)); /* Take a turn */ energy_use = is_magestaff() ? 80 : 100; } /* Refresh player */ p_ptr->redraw |= PR_FRAME; p_ptr->window |= PW_PLAYER; }