diff options
Diffstat (limited to 'src/cmd5.cc')
-rw-r--r-- | src/cmd5.cc | 847 |
1 files changed, 394 insertions, 453 deletions
diff --git a/src/cmd5.cc b/src/cmd5.cc index a1dd5cbf..a93759b0 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -12,11 +12,16 @@ #include "cave.hpp" #include "cave_type.hpp" #include "corrupt.hpp" +#include "dungeon_flag.hpp" +#include "game.hpp" #include "lua_bind.hpp" #include "monster2.hpp" #include "monster_race.hpp" +#include "monster_race_flag.hpp" +#include "monster_spell_flag.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_flag.hpp" #include "object_type.hpp" #include "player_class.hpp" #include "player_race.hpp" @@ -35,7 +40,6 @@ #include "util.h" #include "variable.h" #include "variable.hpp" -#include "quark.hpp" #include "wizard2.hpp" #include "xtra1.hpp" #include "xtra2.hpp" @@ -69,7 +73,7 @@ static object_filter_t const &hook_school_spellable() static auto instance = Or( is_school_book(), And( - HasFlag5(TR5_SPELL_CONTAIN), + HasFlags(TR_SPELL_CONTAIN), has_pval2)); return instance; } @@ -221,22 +225,21 @@ static void browse_school_spell(int book, int spell_idx, object_type *o_ptr) * and in the dark, primarily to allow browsing in stores. */ -extern void do_cmd_browse_aux(object_type *o_ptr) +void do_cmd_browse_aux(object_type *o_ptr) { - u32b f1, f2, f3, f4, f5, esp; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); if (is_school_book()(o_ptr)) { browse_school_spell(o_ptr->sval, o_ptr->pval, o_ptr); } - else if (f5 & TR5_SPELL_CONTAIN && o_ptr->pval2 != -1) + else if ((flags & TR_SPELL_CONTAIN) && (o_ptr->pval2 != -1)) { browse_school_spell(255, o_ptr->pval2, o_ptr); } } -void do_cmd_browse(void) +void do_cmd_browse() { /* Get an item */ int item; @@ -283,8 +286,10 @@ static void do_poly_wounds() } } -void do_poly_self(void) +void do_poly_self() { + auto const &race_info = game->edit_data.race_info; + int power = p_ptr->lev; int poly_power; @@ -298,25 +303,6 @@ void do_poly_self(void) /* Some form of racial polymorph... */ power -= 10; - if ((power > rand_int(5)) && (rand_int(4) == 0)) - { - /* sex change */ - power -= 2; - - if (p_ptr->psex == SEX_MALE) - { - p_ptr->psex = SEX_FEMALE; - sp_ptr = &sex_info[p_ptr->psex]; - strcpy(effect_msg, "female"); - } - else - { - p_ptr->psex = SEX_MALE; - sp_ptr = &sex_info[p_ptr->psex]; - strcpy(effect_msg, "male"); - } - } - if ((power > rand_int(30)) && (rand_int(5) == 0)) { int tmp = 0; @@ -328,14 +314,14 @@ void do_poly_self(void) { if ( rand_int(2) == 0) { - (void)dec_stat(tmp, randint(6) + 6, (rand_int(3) == 0)); + dec_stat(tmp, randint(6) + 6, (rand_int(3) == 0)); power -= 1; } tmp++; } /* Deformities are discriminated against! */ - (void)dec_stat(A_CHR, randint(6), TRUE); + dec_stat(A_CHR, randint(6), TRUE); if (effect_msg[0]) { @@ -374,34 +360,34 @@ void do_poly_self(void) /* Roll until an appropriate selection is made */ while (1) { - new_race = rand_int(max_rp_idx); - expfact = race_info[new_race].r_exp; + new_race = rand_int(race_info.size()); + expfact = race_info[new_race].ps.exp; - if ((new_race != p_ptr->prace) && (expfact <= goalexpfact)) break; + if ((new_race != p_ptr->prace) && (expfact <= goalexpfact)) + { + break; + } } if (effect_msg[0]) { msg_format("You turn into a%s %s!", - ((is_a_vowel(*race_info[new_race].title)) ? "n" : ""), - race_info[new_race].title); + (is_a_vowel(race_info[new_race].title[0]) ? "n" : ""), + race_info[new_race].title.c_str()); } else { msg_format("You turn into a %s %s!", effect_msg, - race_info[new_race].title); + race_info[new_race].title.c_str()); } p_ptr->prace = new_race; rp_ptr = &race_info[p_ptr->prace]; /* Experience factor */ - p_ptr->expfact = rp_ptr->r_exp + rmp_ptr->r_exp + cp_ptr->c_exp; - - /* Calculate the height/weight */ - get_height_weight(); - + p_ptr->expfact = rp_ptr->ps.exp + rmp_ptr->ps.exp + cp_ptr->ps.exp; + /* Level up if necessary */ check_experience(); p_ptr->max_plv = p_ptr->lev; @@ -423,7 +409,7 @@ void do_poly_self(void) msg_print("Your internal organs are rearranged!"); while (tmp < 6) { - (void)dec_stat(tmp, randint(6) + 6, (rand_int(3) == 0)); + dec_stat(tmp, randint(6) + 6, (rand_int(3) == 0)); tmp++; } if (rand_int(6) == 0) @@ -552,179 +538,141 @@ void fetch(int dir, int wgt, bool_ require_los) /* - * Handle random effects of player shrieking - */ -void shriek_effect() -{ - switch (randint(9)) - { - case 1: - case 5: - case 8: - case 9: - { - msg_print("You make a high-pitched shriek!"); - aggravate_monsters(1); - - break; - } - case 2: - case 6: - { - msg_print("Oops! You call a monster."); - summon_specific(p_ptr->py, p_ptr->px, max_dlv[dungeon_type], 0); - - break; - } - case 3: - case 7: - { - msg_print("The dungeon collapses!"); - earthquake(p_ptr->py, p_ptr->px, 5); - - break; - } - case 4: - { - msg_print("Your shriek is so horrible that you damage your health!"); - take_hit(damroll(p_ptr->lev / 5, 8), "inner hemorrhaging"); - - break; - } - } -} - -/* * Return the symbiote's name or description. */ -cptr symbiote_name(bool_ capitalize) +std::string symbiote_name(bool capitalize) { + auto const &r_info = game->edit_data.r_info; + object_type *o_ptr = &p_ptr->inventory[INVEN_CARRY]; - static char buf[80]; - /* Make sure there actually is a symbiote there... */ + std::string buf; + buf.reserve(32); + + // Fallback; shouldn't ever be necessary if (!o_ptr->k_idx) { - strcpy(buf, "A non-existent symbiote"); + buf += "A non-existent symbiote"; } else { - monster_race *r_ptr = &r_info[o_ptr->pval]; - cptr s = NULL; + auto r_ptr = &r_info[o_ptr->pval]; + std::size_t i = 0; - if (r_ptr->flags1 & RF1_UNIQUE) + if (r_ptr->flags & RF_UNIQUE) { - /* Unique monster; no preceding "your", and ignore our name. */ - strncpy(buf, r_ptr->name, sizeof(buf)); + // Unique monster; no preceding "your" and ignore name + buf += r_ptr->name; } - else if (o_ptr->note && - (s = strstr(quark_str(o_ptr->note), "#named ")) != NULL) + else if ((i = o_ptr->inscription.find("#named ")) != std::string::npos) { - /* We've named it. */ - strncpy(buf, s + 7, sizeof(buf)); + // We've named it; extract the name */ + buf += o_ptr->inscription.substr(i); } else { - /* No special cases, just return "Your <monster type>". */ - strcpy(buf, "your "); - strncpy(buf + 5, r_ptr->name, sizeof(buf) - 5); + // No special cases; just return "Your <monster type>". + buf += "your "; + buf += r_ptr->name; } } - /* Just in case... */ - buf[sizeof(buf) - 1] = '\0'; - if (capitalize) buf[0] = toupper(buf[0]); + // Capitalize? + if (capitalize) + { + buf[0] = toupper(buf[0]); + } + + // Done return buf; } + /* - * Use a power of the monster in symbiosis + * Find monster power */ -int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost) +monster_power const *lookup_monster_power(std::size_t idx) { - int power = -1; - - int num = 0, dir = 0 , i; - - int powers[96]; - - bool_ flag; - - int ask, plev = p_ptr->lev; - - char choice; - - char out_val[160]; - - monster_race *r_ptr = &r_info[r_idx]; - - int rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1); - - int x = p_ptr->px, y = p_ptr->py, k; - - int rad; - - int label; - - - /* List the monster powers -- RF4_* */ - for (i = 0; i < 32; i++) + for (auto const &p: monster_powers) { - if (r_ptr->flags4 & BIT(i)) + if (p.monster_spell_index == idx) { - if (monster_powers[i].great && (!great)) continue; - if (!monster_powers[i].power) continue; - powers[num++] = i; + return &p; } } + return nullptr; +} - /* List the monster powers -- RF5_* */ - for (i = 0; i < 32; i++) - { - if (r_ptr->flags5 & BIT(i)) - { - if (monster_powers[i + 32].great && (!great)) continue; - if (!monster_powers[i + 32].power) continue; - powers[num++] = i + 32; - } - } - /* List the monster powers -- RF6_* */ - for (i = 0; i < 32; i++) +/* + * Extract powers + */ +std::vector<monster_power const *> extract_monster_powers(monster_race const *r_ptr, bool great) +{ + std::vector<monster_power const *> powers; + powers.reserve(MONSTER_POWERS_MAX); + + for (std::size_t i = 0; i < monster_spell_flag_set::nbits; i++) { - if (r_ptr->flags6 & BIT(i)) + if (r_ptr->spells.bit(i)) { - if (monster_powers[i + 64].great && (!great)) continue; - if (!monster_powers[i + 64].power) continue; - powers[num++] = i + 64; + if (auto power = lookup_monster_power(i)) + { + if (power->great && (!great)) + { + continue; + } + powers.push_back(power); + } } } + return powers; +} + +/** + * Calculate mana required for a given monster power. + */ +static int calc_monster_spell_mana(monster_power const *mp_ptr) +{ + int mana = mp_ptr->mana / 10; + if (mana > p_ptr->msp) mana = p_ptr->msp; + if (!mana) mana = 1; + return mana; +} + +/** + * Choose a monster power + */ +static std::tuple<int, int> choose_monster_power(monster_race const *r_ptr, bool great, bool symbiosis) +{ + /* Extract available monster powers */ + auto powers = extract_monster_powers(r_ptr, great); + int const num = powers.size(); // Avoid signed/unsigned warnings + if (!num) { msg_print("You have no powers you can use."); - return (0); + return std::make_tuple(0, num); } - if (only_number) return (num); - - /* Nothing chosen yet */ - flag = FALSE; - /* Get the last label */ - label = (num <= 26) ? I2A(num - 1) : I2D(num - 1 - 26); + int label = (num <= 26) ? I2A(num - 1) : I2D(num - 1 - 26); /* Build a prompt (accept all spells) */ /* Mega Hack -- if no_cost is false, we're actually a Possessor -dsb */ + char out_val[160]; strnfmt(out_val, 78, "(Powers a-%c, ESC=exit) Use which power of your %s? ", - label, (no_cost ? "symbiote" : "body")); + label, (symbiosis ? "symbiote" : "body")); /* Save the screen */ character_icky = TRUE; Term_save(); /* Get a spell from the user */ + monster_power const *power = nullptr; + bool_ flag = FALSE; // Nothing chosen yet while (!flag) { /* Show the list */ @@ -732,26 +680,26 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost byte y = 1, x = 0; int ctr = 0; char dummy[80]; - strcpy(dummy, ""); prt ("", y++, x); while (ctr < num) { - monster_power *mp_ptr = &monster_powers[powers[ctr]]; - int mana = mp_ptr->mana / 10; - - if (mana > p_ptr->msp) mana = p_ptr->msp; - - if (!mana) mana = 1; + monster_power const *mp_ptr = powers[ctr]; label = (ctr < 26) ? I2A(ctr) : I2D(ctr - 26); - if (!no_cost) + byte color = TERM_L_GREEN; + if (!symbiosis) { + int mana = calc_monster_spell_mana(mp_ptr); strnfmt(dummy, 80, " %c) %2d %s", label, mana, mp_ptr->name); + // Gray out if player doesn't have enough mana to cast. + if (mana > p_ptr->csp) { + color = TERM_L_DARK; + } } else { @@ -761,11 +709,11 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost if (ctr < 17) { - prt(dummy, y + ctr, x); + c_prt(color, dummy, y + ctr, x); } else { - prt(dummy, y + ctr - 17, x + 40); + c_prt(color, dummy, y + ctr - 17, x + 40); } ctr++; @@ -781,6 +729,7 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost } } + char choice; if (!get_com(out_val, &choice)) { flag = FALSE; @@ -792,6 +741,8 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost choice = 'a'; } + int i; + int ask; if (isalpha(choice)) { /* Note verify */ @@ -818,16 +769,26 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost continue; } - /* Save the spell index */ + /* Save the spell */ power = powers[i]; + /* Make sure it's actually possible for the player to cast */ + if (!symbiosis) + { + if (p_ptr->csp < calc_monster_spell_mana(power)) + { + bell(); + continue; + } + } + /* Verify it */ if (ask) { char tmp_val[160]; /* Prompt */ - strnfmt(tmp_val, 78, "Use %s? ", monster_powers[power].name); + strnfmt(tmp_val, 78, "Use %s? ", power->name); /* Belay that order */ if (!get_check(tmp_val)) continue; @@ -842,55 +803,60 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost character_icky = FALSE; /* Abort if needed */ - if (!flag) + if (!flag || (power == nullptr)) { - energy_use = 0; - return -1; + return std::make_tuple(-1, num); } - /* 'Powerful' monsters have wider radii */ - if (r_ptr->flags2 & RF2_POWERFUL) - { - rad = 1 + (p_ptr->lev / 15); - } - else - { - rad = 1 + (p_ptr->lev / 20); - } + return std::make_tuple(power->monster_spell_index, num); +} + +/* + * Apply the effect of a monster power + */ +static void apply_monster_power(monster_race const *r_ptr, std::size_t monster_spell_idx) +{ + assert(monster_spell_idx < monster_spell_flag_set::nbits); + + /* Shorthand */ + int const x = p_ptr->px; + int const y = p_ptr->py; + int const plev = p_ptr->lev; + int const rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1); + + /* 'Powerful' monsters have wider radii */ + int rad = (r_ptr->flags & RF_POWERFUL) + ? 1 + (p_ptr->lev / 15) + : 1 + (p_ptr->lev / 20); /* Analyse power */ - switch (power) + switch (monster_spell_idx) { - /**** RF4 (bit position) ****/ - - /* SHRIEK */ - case 0: + case SF_SHRIEK_IDX: { aggravate_monsters( -1); break; } - /* MULTIPLY */ - case 1: + case SF_MULTIPLY_IDX: { do_cmd_wiz_named_friendly(p_ptr->body_monster, FALSE); break; } - /* S_ANIMAL */ - case 2: + case SF_S_ANIMAL_IDX: { summon_specific_friendly(y, x, rlev, SUMMON_ANIMAL, TRUE); break; } - /* ROCKET */ - case 3: + case SF_ROCKET_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_ROCKET, dir, p_ptr->lev * 12, 1 + (p_ptr->lev / 20)); @@ -898,9 +864,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* ARROW_1 */ - case 4: + case SF_ARROW_1_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_ARROW, dir, damroll(1, 6)); @@ -908,9 +874,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* ARROW_2 */ - case 5: + case SF_ARROW_2_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_ARROW, dir, damroll(3, 6)); @@ -918,9 +884,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* ARROW_3 */ - case 6: + case SF_ARROW_3_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_ARROW, dir, damroll(5, 6)); @@ -928,9 +894,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* ARROW_4 */ - case 7: + case SF_ARROW_4_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_ARROW, dir, damroll(7, 6)); @@ -938,9 +904,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_ACID */ - case 8: + case SF_BR_ACID_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_ACID, dir, p_ptr->lev * 5, rad); @@ -948,9 +914,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_ELEC */ - case 9: + case SF_BR_ELEC_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_ELEC, dir, p_ptr->lev * 5, rad); @@ -958,9 +924,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_FIRE */ - case 10: + case SF_BR_FIRE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_FIRE, dir, p_ptr->lev * 5, rad); @@ -968,9 +934,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_COLD */ - case 11: + case SF_BR_COLD_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_COLD, dir, p_ptr->lev * 5, rad); @@ -978,9 +944,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_POIS */ - case 12: + case SF_BR_POIS_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_POIS, dir, p_ptr->lev * 5, rad); @@ -988,9 +954,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_NETH */ - case 13: + case SF_BR_NETH_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_NETHER, dir, p_ptr->lev * 5, rad); @@ -998,9 +964,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_LITE */ - case 14: + case SF_BR_LITE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_LITE, dir, p_ptr->lev * 8, rad); @@ -1008,9 +974,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_DARK */ - case 15: + case SF_BR_DARK_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_DARK, dir, p_ptr->lev * 8, rad); @@ -1018,9 +984,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_CONF */ - case 16: + case SF_BR_CONF_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_CONFUSION, dir, p_ptr->lev * 8, rad); @@ -1028,9 +994,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_SOUN */ - case 17: + case SF_BR_SOUN_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_SOUND, dir, p_ptr->lev * 8, rad); @@ -1038,9 +1004,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_CHAO */ - case 18: + case SF_BR_CHAO_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_CHAOS, dir, p_ptr->lev * 7, rad); @@ -1048,9 +1014,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_DISE */ - case 19: + case SF_BR_DISE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_DISENCHANT, dir, p_ptr->lev * 7, rad); @@ -1058,9 +1024,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_NEXU */ - case 20: + case SF_BR_NEXU_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_NEXUS, dir, p_ptr->lev * 5, rad); @@ -1068,9 +1034,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_TIME */ - case 21: + case SF_BR_TIME_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_TIME, dir, p_ptr->lev * 3, rad); @@ -1078,9 +1044,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_INER */ - case 22: + case SF_BR_INER_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_INERTIA, dir, p_ptr->lev * 4, rad); @@ -1088,9 +1054,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_GRAV */ - case 23: + case SF_BR_GRAV_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_GRAVITY, dir, p_ptr->lev * 4, rad); @@ -1098,9 +1064,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_SHAR */ - case 24: + case SF_BR_SHAR_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_SHARDS, dir, p_ptr->lev * 8, rad); @@ -1108,9 +1074,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_PLAS */ - case 25: + case SF_BR_PLAS_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_PLASMA, dir, p_ptr->lev * 3, rad); @@ -1118,9 +1084,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_WALL */ - case 26: + case SF_BR_WALL_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_FORCE, dir, p_ptr->lev * 4, rad); @@ -1128,9 +1094,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_MANA */ - case 27: + case SF_BR_MANA_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_MANA, dir, p_ptr->lev * 5, rad); @@ -1138,9 +1104,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_NUKE */ - case 28: + case SF_BA_NUKE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_NUKE, dir, p_ptr->lev * 8, 1 + (p_ptr->lev / 20)); @@ -1148,9 +1114,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_NUKE */ - case 29: + case SF_BR_NUKE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_NUKE, dir, p_ptr->lev * 8, 1 + (p_ptr->lev / 20)); @@ -1158,9 +1124,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_CHAO */ - case 30: + case SF_BA_CHAO_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_CHAOS, dir, p_ptr->lev * 4, 2); @@ -1168,9 +1134,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BR_DISI */ - case 31: + case SF_BR_DISI_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_DISINTEGRATE, dir, p_ptr->lev * 5, 1 + (p_ptr->lev / 20)); @@ -1178,12 +1144,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - - /**** RF5 (bit position + 32) ****/ - - /* BA_ACID */ - case 32: + case SF_BA_ACID_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_ACID, dir, randint(p_ptr->lev * 6) + 20, 2); @@ -1191,9 +1154,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_ELEC */ - case 33: + case SF_BA_ELEC_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_ELEC, dir, randint(p_ptr->lev * 3) + 20, 2); @@ -1201,9 +1164,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_FIRE */ - case 34: + case SF_BA_FIRE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_FIRE, dir, randint(p_ptr->lev * 7) + 20, 2); @@ -1211,9 +1174,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_COLD */ - case 35: + case SF_BA_COLD_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_COLD, dir, randint(p_ptr->lev * 3) + 20, 2); @@ -1221,9 +1184,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_POIS */ - case 36: + case SF_BA_POIS_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_POIS, dir, damroll(12, 2), 2); @@ -1231,9 +1194,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_NETH */ - case 37: + case SF_BA_NETH_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_NETHER, dir, randint(p_ptr->lev * 4) + 20, 2); @@ -1241,9 +1204,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_WATE */ - case 38: + case SF_BA_WATE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_WATER, dir, randint(p_ptr->lev * 4) + 20, 2); @@ -1251,9 +1214,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_MANA */ - case 39: + case SF_BA_MANA_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_MANA, dir, randint(p_ptr->lev * 3) + 20, 2); @@ -1261,9 +1224,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BA_DARK */ - case 40: + case SF_BA_DARK_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_ball(GF_DARK, dir, randint(p_ptr->lev * 3) + 20, 2); @@ -1271,15 +1234,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* 41 DRAIN_MANA -- Not available */ - - /* 42 MIND_BLAST -- Not available */ - - /* 43 BRAIN_SMASH -- Not available */ - - /* CAUSE_1 */ - case 44: + case SF_CAUSE_1_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_MANA, dir, damroll(3, 8)); @@ -1287,9 +1244,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* CAUSE_2 */ - case 45: + case SF_CAUSE_2_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_MANA, dir, damroll(8, 8)); @@ -1297,9 +1254,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* CAUSE_3 */ - case 46: + case SF_CAUSE_3_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_MANA, dir, damroll(10, 15)); @@ -1307,9 +1264,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* CAUSE_4 */ - case 47: + case SF_CAUSE_4_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_MANA, dir, damroll(15, 15)); @@ -1317,9 +1274,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_ACID */ - case 48: + case SF_BO_ACID_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_ACID, dir, damroll(7, 8) + (p_ptr->lev / 3)); @@ -1327,9 +1284,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_ELEC */ - case 49: + case SF_BO_ELEC_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_ELEC, dir, damroll(4, 8) + (p_ptr->lev / 3)); @@ -1337,9 +1294,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_FIRE */ - case 50: + case SF_BO_FIRE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_FIRE, dir, damroll(9, 8) + (p_ptr->lev / 3)); @@ -1347,9 +1304,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_COLD */ - case 51: + case SF_BO_COLD_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_COLD, dir, damroll(6, 8) + (p_ptr->lev / 3)); @@ -1357,9 +1314,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_POIS */ - case 52: + case SF_BO_POIS_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_POIS, dir, damroll(7, 8) + (p_ptr->lev / 3)); @@ -1367,9 +1324,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_NETH */ - case 53: + case SF_BO_NETH_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_NETHER, dir, damroll(5, 5) + (p_ptr->lev / 3)); @@ -1377,9 +1334,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_WATE */ - case 54: + case SF_BO_WATE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_WATER, dir, damroll(10, 10) + (p_ptr->lev / 3)); @@ -1387,9 +1344,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_MANA */ - case 55: + case SF_BO_MANA_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_MANA, dir, damroll(3, 8) + (p_ptr->lev / 3)); @@ -1397,9 +1354,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_PLAS */ - case 56: + case SF_BO_PLAS_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_PLASMA, dir, damroll(8, 8) + (p_ptr->lev / 3)); @@ -1407,9 +1364,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BO_ICEE */ - case 57: + case SF_BO_ICEE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_ICE, dir, damroll(6, 6) + (p_ptr->lev / 3)); @@ -1417,9 +1374,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* MISSILE */ - case 58: + case SF_MISSILE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_MISSILE, dir, damroll(2, 6) + (p_ptr->lev / 3)); @@ -1427,9 +1384,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* SCARE */ - case 59: + case SF_SCARE_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fear_monster(dir, plev); @@ -1437,9 +1394,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BLIND */ - case 60: + case SF_BLIND_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_CONFUSION, dir, damroll(1, 8) + (p_ptr->lev / 3)); @@ -1447,9 +1404,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* CONF */ - case 61: + case SF_CONF_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_CONFUSION, dir, damroll(7, 8) + (p_ptr->lev / 3)); @@ -1457,9 +1414,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* SLOW */ - case 62: + case SF_SLOW_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_OLD_SLOW, dir, damroll(6, 8) + (p_ptr->lev / 3)); @@ -1467,9 +1424,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* HOLD */ - case 63: + case SF_HOLD_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_OLD_SLEEP, dir, damroll(5, 8) + (p_ptr->lev / 3)); @@ -1477,27 +1434,23 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - - /**** RF6 (bit position + 64) ****/ - - /* HASTE */ - case 64: + case SF_HASTE_IDX: { if (!p_ptr->fast) { - (void)set_fast(randint(20 + (plev) ) + plev, 10); + set_fast(randint(20 + (plev) ) + plev, 10); } else { - (void)set_fast(p_ptr->fast + randint(5), 10); + set_fast(p_ptr->fast + randint(5), 10); } break; } - /* HAND_DOOM */ - case 65: + case SF_HAND_DOOM_IDX: { + int dir; if (!get_aim_dir(&dir)) break; fire_bolt(GF_MANA, dir, damroll(10, 8) + (p_ptr->lev)); @@ -1505,18 +1458,16 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* HEAL */ - case 66: + case SF_HEAL_IDX: { hp_player(damroll(8, 5)); break; } - /* S_ANIMALS */ - case 67: + case SF_S_ANIMALS_IDX: { - for (k = 0; k < 4; k++) + for (int k = 0; k < 4; k++) { summon_specific_friendly(y, x, rlev, SUMMON_ANIMAL, TRUE); } @@ -1524,10 +1475,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* BLINK */ - case 68: + case SF_BLINK_IDX: { - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("No teleport on special levels..."); break; @@ -1538,10 +1488,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* TPORT */ - case 69: + case SF_TPORT_IDX: { - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("No teleport on special levels..."); break; @@ -1552,12 +1501,11 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* TELE_TO */ - case 70: + case SF_TELE_TO_IDX: { int ii, ij; - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("No teleport on special levels..."); break; @@ -1570,8 +1518,8 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost p_ptr->energy -= 60 - plev; if (!cave_empty_bold(ij, ii) || - (cave[ij][ii].info & CAVE_ICKY) || - (distance(ij, ii, p_ptr->py, p_ptr->px) > plev * 20 + 2)) + (cave[ij][ii].info & CAVE_ICKY) || + (distance(ij, ii, p_ptr->py, p_ptr->px) > plev * 20 + 2)) { msg_print("You fail to show the destination correctly!"); p_ptr->energy -= 100; @@ -1582,26 +1530,25 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* TELE_AWAY */ - case 71: + case SF_TELE_AWAY_IDX: { - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("No teleport on special levels..."); break; } + int dir; if (!get_aim_dir(&dir)) break; - (void)fire_beam(GF_AWAY_ALL, dir, plev); + fire_beam(GF_AWAY_ALL, dir, plev); break; } - /* TELE_LEVEL */ - case 72: + case SF_TELE_LEVEL_IDX: { - if (dungeon_flags2 & DF2_NO_TELEPORT) + if (dungeon_flags & DF_NO_TELEPORT) { msg_print("No teleport on special levels..."); break; @@ -1612,11 +1559,10 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* DARKNESS */ - case 73: + case SF_DARKNESS_IDX: { - (void)project( -1, 3, p_ptr->py, p_ptr->px, 0, GF_DARK_WEAK, - PROJECT_GRID | PROJECT_KILL); + project( -1, 3, p_ptr->py, p_ptr->px, 0, GF_DARK_WEAK, + PROJECT_GRID | PROJECT_KILL); /* Unlite the room */ unlite_room(p_ptr->py, p_ptr->px); @@ -1624,34 +1570,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* TRAPS */ - case 74: + case SF_S_THUNDERLORD_IDX: { - trap_creation(); - - break; - } - - /* 75 FORGET -- Not available */ - - /* ANIM_DEAD -- Use the same code as the nether spell */ - case 76: - { - if (!get_aim_dir(&dir)) break; - - fire_ball(GF_RAISE, dir, 1, 0); - - break; - } - - /* 77 S_BUG -- Not available, well we do that anyway ;) */ - - /* 78 S_RNG -- Not available, who dares? */ - - /* S_THUNDERLORD */ - case 79: - { - for (k = 0; k < 1; k++) + for (int k = 0; k < 1; k++) { summon_specific_friendly(y, x, rlev, SUMMON_THUNDERLORD, TRUE); } @@ -1659,13 +1580,12 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_KIN -- Summon Kin, because we code bugs :) */ - case 80: + case SF_S_KIN_IDX: { /* Big hack */ summon_kin_type = r_ptr->d_char; - for (k = 0; k < 6; k++) + for (int k = 0; k < 6; k++) { summon_specific_friendly(y, x, rlev, SUMMON_KIN, TRUE); } @@ -1673,10 +1593,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_HI_DEMON */ - case 81: + case SF_S_HI_DEMON_IDX: { - for (k = 0; k < 1; k++) + for (int k = 0; k < 1; k++) { summon_specific_friendly(y, x, rlev, SUMMON_HI_DEMON, TRUE); } @@ -1684,10 +1603,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_MONSTER */ - case 82: + case SF_S_MONSTER_IDX: { - for (k = 0; k < 1; k++) + for (int k = 0; k < 1; k++) { summon_specific_friendly(y, x, rlev, 0, TRUE); } @@ -1695,10 +1613,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_MONSTERS */ - case 83: + case SF_S_MONSTERS_IDX: { - for (k = 0; k < 6; k++) + for (int k = 0; k < 6; k++) { summon_specific_friendly(y, x, rlev, 0, TRUE); } @@ -1706,10 +1623,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_ANT */ - case 84: + case SF_S_ANT_IDX: { - for (k = 0; k < 6; k++) + for (int k = 0; k < 6; k++) { summon_specific_friendly(y, x, rlev, SUMMON_ANT, TRUE); } @@ -1717,10 +1633,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_SPIDER */ - case 85: + case SF_S_SPIDER_IDX: { - for (k = 0; k < 6; k++) + for (int k = 0; k < 6; k++) { summon_specific_friendly(y, x, rlev, SUMMON_SPIDER, TRUE); } @@ -1728,10 +1643,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_HOUND */ - case 86: + case SF_S_HOUND_IDX: { - for (k = 0; k < 6; k++) + for (int k = 0; k < 6; k++) { summon_specific_friendly(y, x, rlev, SUMMON_HOUND, TRUE); } @@ -1739,10 +1653,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_HYDRA */ - case 87: + case SF_S_HYDRA_IDX: { - for (k = 0; k < 6; k++) + for (int k = 0; k < 6; k++) { summon_specific_friendly(y, x, rlev, SUMMON_HYDRA, TRUE); } @@ -1750,10 +1663,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_ANGEL */ - case 88: + case SF_S_ANGEL_IDX: { - for (k = 0; k < 1; k++) + for (int k = 0; k < 1; k++) { summon_specific_friendly(y, x, rlev, SUMMON_ANGEL, TRUE); } @@ -1761,10 +1673,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_DEMON */ - case 89: + case SF_S_DEMON_IDX: { - for (k = 0; k < 1; k++) + for (int k = 0; k < 1; k++) { summon_specific_friendly(y, x, rlev, SUMMON_DEMON, TRUE); } @@ -1772,10 +1683,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_UNDEAD */ - case 90: + case SF_S_UNDEAD_IDX: { - for (k = 0; k < 1; k++) + for (int k = 0; k < 1; k++) { summon_specific_friendly(y, x, rlev, SUMMON_UNDEAD, TRUE); } @@ -1783,10 +1693,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_DRAGON */ - case 91: + case SF_S_DRAGON_IDX: { - for (k = 0; k < 1; k++) + for (int k = 0; k < 1; k++) { summon_specific_friendly(y, x, rlev, SUMMON_DRAGON, TRUE); } @@ -1794,10 +1703,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_HI_UNDEAD */ - case 92: + case SF_S_HI_UNDEAD_IDX: { - for (k = 0; k < 8; k++) + for (int k = 0; k < 8; k++) { summon_specific_friendly(y, x, rlev, SUMMON_HI_UNDEAD_NO_UNIQUES, TRUE); } @@ -1805,10 +1713,9 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_HI_DRAGON */ - case 93: + case SF_S_HI_DRAGON_IDX: { - for (k = 0; k < 8; k++) + for (int k = 0; k < 8; k++) { summon_specific_friendly(y, x, rlev, SUMMON_HI_DRAGON_NO_UNIQUES, TRUE); } @@ -1816,38 +1723,43 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost break; } - /* S_WRAITH */ - case 94: + case SF_S_WRAITH_IDX: { - for (k = 0; k < 8; k++) + for (int k = 0; k < 8; k++) { summon_specific_friendly(y, x, rlev, SUMMON_WRAITH, TRUE); } break; } - - /* 95 S_UNIQUE -- Not available */ } +} - /* Take some SP */ - if (!no_cost) - { - int chance, pchance; - - chance = (monster_powers[power].mana + r_ptr->level); - pchance = adj_str_wgt[p_ptr->stat_ind[A_WIS]] / 2 + get_skill(SKILL_POSSESSION); - if (rand_int(chance) >= pchance) - { - int m = monster_powers[power].mana / 10; +/* + * Use a monster power and call the given callback. + */ +static int use_monster_power_aux(monster_race const *r_ptr, bool great, bool symbiosis, std::function<void(monster_power const *power)> f) +{ + int power; + int num; + std::tie(power, num) = choose_monster_power(r_ptr, great, symbiosis); + + // Early exit? + if (power == 0) { + // No powers available + return 0; + } else if (power < 0) { + // Canceled by user + energy_use = 0; + return -1; + } - if (m > p_ptr->msp) m = p_ptr->msp; - if (!m) m = 1; + // Apply the effect + apply_monster_power(r_ptr, power); - p_ptr->csp -= m; - } - } + // Post-processing + f(&monster_powers[power]); /* Redraw mana */ p_ptr->redraw |= (PR_FRAME); @@ -1858,6 +1770,38 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost return (num); } +/** + * Use a power of the monster in symbiosis + */ +int use_symbiotic_power(int r_idx, bool great) +{ + auto const &r_info = game->edit_data.r_info; + + monster_race const *r_ptr = &r_info[r_idx]; + return use_monster_power_aux(r_ptr, great, true, [](monster_power const *) { + // Don't need to do anything post-cast. + }); +} + +/** + * Use a power of a possessed body. + */ +void use_monster_power(int r_idx, bool great) +{ + auto const &r_info = game->edit_data.r_info; + + monster_race const *r_ptr = &r_info[r_idx]; + use_monster_power_aux(r_ptr, great, false, [r_ptr](monster_power const *power) { + // Sometimes give a free cast. + int chance = (power->mana + r_ptr->level); + int pchance = adj_str_wgt[p_ptr->stat_ind[A_WIS]] / 2 + get_skill(SKILL_POSSESSION); + if (rand_int(chance) >= pchance) + { + p_ptr->csp -= calc_monster_spell_mana(power); + } + }); +} + /* * Schooled magic */ @@ -1888,11 +1832,10 @@ boost::optional<int> get_item_hook_find_spell(object_filter_t const &) object_type *o_ptr = &p_ptr->inventory[i]; /* Extract object flags */ - u32b f1, f2, f3, f4, f5, esp; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const flags = object_flags(o_ptr); /* Must we wield it to cast from it? */ - if ((wield_slot(o_ptr) != -1) && (i < INVEN_WIELD) && (f5 & TR5_WIELD_CAST)) + if ((wield_slot(o_ptr) != -1) && (i < INVEN_WIELD) && (flags & TR_WIELD_CAST)) { continue; } @@ -1901,7 +1844,7 @@ boost::optional<int> get_item_hook_find_spell(object_filter_t const &) if (!is_school_book()(o_ptr)) { /* Does it contain the appropriate spell? */ - if ((f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 == spell)) + if ((flags & TR_SPELL_CONTAIN) && (o_ptr->pval2 == spell)) { hack_force_spell = spell; hack_force_spell_pval = o_ptr->pval; @@ -1961,7 +1904,6 @@ s32b get_school_spell(cptr do_what, s16b force_book) object_type *o_ptr, forge; int tmp; int sval, pval; - u32b f1, f2, f3, f4, f5, esp; hack_force_spell = -1; hack_force_spell_pval = -1; @@ -1987,10 +1929,10 @@ s32b get_school_spell(cptr do_what, s16b force_book) /* Get the item */ o_ptr = get_object(item); - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const f = object_flags(o_ptr); /* If it can be wielded, it must */ - if ((wield_slot(o_ptr) != -1) && (item < INVEN_WIELD) && (f5 & TR5_WIELD_CAST)) + if ((wield_slot(o_ptr) != -1) && (item < INVEN_WIELD) && (f & TR_WIELD_CAST)) { msg_format("You cannot %s from that object; it must be wielded first.", do_what); return -1; @@ -2178,10 +2120,9 @@ void cast_school_spell() /* Can it contains a schooled spell ? */ static bool hook_school_can_spellable(object_type const *o_ptr) { - u32b f1, f2, f3, f4, f5, esp; - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + auto const f = object_flags(o_ptr); - return ((f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 == -1)); + return ((f & TR_SPELL_CONTAIN) && (o_ptr->pval2 == -1)); } /* |