From cbef37bd5bfb938a2303ee3887520c08be85d8e8 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Tue, 26 Mar 2013 17:10:10 +0100 Subject: Switch almost everything over to C++ --- src/cmd5.cc | 2471 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2471 insertions(+) create mode 100644 src/cmd5.cc (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc new file mode 100644 index 00000000..95ae0346 --- /dev/null +++ b/src/cmd5.cc @@ -0,0 +1,2471 @@ +/* File: cmd5.c */ + +/* Purpose: Class commands */ + +/* + * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke + * + * This software may be copied and distributed for educational, research, and + * not for profit purposes provided that this copyright and statement are + * included in all such copies. + */ + + +#include "angband.h" + +#include + +#include "spell_type.h" +#include "quark.h" + +/* Maximum number of tries for teleporting */ +#define MAX_TRIES 300 + +bool_ is_school_book(object_type *o_ptr) +{ + if (o_ptr->tval == TV_BOOK) + { + return TRUE; + } + else if (o_ptr->tval == TV_DAEMON_BOOK) + { + return TRUE; + } + else if (o_ptr->tval == TV_INSTRUMENT) + { + return TRUE; + } + else + { + return FALSE; + } +} + +/* Does it contains a schooled spell ? */ +static bool_ hook_school_spellable(object_type *o_ptr) +{ + if (is_school_book(o_ptr)) + return TRUE; + else + { + u32b f1, f2, f3, f4, f5, esp; + + /* Extract object flags */ + object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + + if ((f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 != -1)) + return TRUE; + } + return FALSE; +} + +/* Is it a book */ +bool_ item_tester_hook_browsable(object_type *o_ptr) +{ + if (hook_school_spellable(o_ptr)) return TRUE; + if (o_ptr->tval >= TV_BOOK) return TRUE; + return FALSE; +} + +/* + * Are we using a mage staff + */ +bool_ is_magestaff() +{ + int i; + + + i = 0; + + while (p_ptr->body_parts[i] == INVEN_WIELD) + { + object_type *o_ptr = &p_ptr->inventory[INVEN_WIELD + i]; + + /* Wielding a mage staff */ + if ((o_ptr->k_idx) && (o_ptr->tval == TV_MSTAFF)) return (TRUE); + + /* Next slot */ + i++; + + /* Paranoia */ + if (i >= (INVEN_TOTAL - INVEN_WIELD)) break; + } + + /* Not wielding a mage staff */ + return (FALSE); +} + +/* + * Peruse the spells/prayers in a book + * + * Note that *all* spells in the book are listed + * + * Note that browsing is allowed while confused or blind, + * and in the dark, primarily to allow browsing in stores. + */ + +extern 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); + + 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) + browse_school_spell(255, o_ptr->pval2, o_ptr); +} + +void do_cmd_browse(void) +{ + int item; + + cptr q, s; + + object_type *o_ptr; + + /* Restrict choices to "useful" books */ + item_tester_hook = item_tester_hook_browsable; + + /* Get an item */ + q = "Browse which book? "; + s = "You have no books that you can read."; + if (!get_item(&item, q, s, (USE_INVEN | USE_EQUIP | USE_FLOOR))) return; + + /* Get the item */ + o_ptr = get_object(item); + + do_cmd_browse_aux(o_ptr); +} + +void do_poly_wounds(void) +{ + /* Changed to always provide at least _some_ healing */ + s16b wounds = p_ptr->cut; + + s16b hit_p = (p_ptr->mhp - p_ptr->chp); + + s16b change = damroll(p_ptr->lev, 5); + + bool_ Nasty_effect = (randint(5) == 1); + + + if (!(wounds || hit_p || Nasty_effect)) return; + + msg_print("Your wounds are polymorphed into less serious ones."); + hp_player(change); + if (Nasty_effect) + { + msg_print("A new wound was created!"); + take_hit(change / 2, "a polymorphed wound"); + set_cut(change); + } + else + { + set_cut((p_ptr->cut) - (change / 2)); + } +} + +void do_poly_self(void) +{ + int power = p_ptr->lev; + int poly_power; + + msg_print("You feel a change coming over you..."); + + if ((power > rand_int(20)) && (rand_int(3) == 0)) + { + char effect_msg[80] = ""; + int new_race, expfact, goalexpfact; + + /* 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; + + /* Harmful deformity */ + power -= 15; + + while (tmp < 6) + { + if ( rand_int(2) == 0) + { + (void)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); + + if (effect_msg[0]) + { + char tmp_msg[10]; + strnfmt(tmp_msg, 10, "%s", effect_msg); + strnfmt(effect_msg, 80, "deformed %s", tmp_msg); + } + else + { + strcpy(effect_msg, "deformed"); + } + } + + while ((power > rand_int(20)) && (rand_int(10) == 0)) + { + /* Polymorph into a less corrupted form */ + power -= 10; + + lose_corruption(); + } + + /* + * I'm not sure 'power' is always positive, with *so* many minuses. + * Also, passing zero / negative numbers to randint/rand_int can + * cause a zero divide exception, IIRC, not to speak of its absurdity + * -- pelpel + */ + poly_power = (power > 1) ? power : 1; + + /* + * Restrict the race choices by exp penalty so weak polymorph + * always means weak race + */ + goalexpfact = 100 + 3 * rand_int(poly_power); + + /* Roll until an appropriate selection is made */ + while (1) + { + new_race = rand_int(max_rp_idx); + expfact = race_info[new_race].r_exp; + + if ((new_race != p_ptr->prace) && (expfact <= goalexpfact)) break; + } + + if (effect_msg[0]) + { + msg_format("You turn into a%s %s!", + ((is_a_vowel(rp_name[race_info[new_race].title])) ? "n" : ""), + race_info[new_race].title + rp_name); + } + else + { + msg_format("You turn into a %s %s!", effect_msg, + race_info[new_race].title); + } + + 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(); + + + check_experience(); + p_ptr->max_plv = p_ptr->lev; + + p_ptr->redraw |= (PR_BASIC); + + p_ptr->update |= (PU_BONUS); + + handle_stuff(); + lite_spot(p_ptr->py, p_ptr->px); + } + + if ((power > rand_int(30)) && (rand_int(6) == 0)) + { + int tmp = 0; + + /* Abomination! */ + power -= 20; + + msg_print("Your internal organs are rearranged!"); + while (tmp < 6) + { + (void)dec_stat(tmp, randint(6) + 6, (rand_int(3) == 0)); + tmp++; + } + if (rand_int(6) == 0) + { + msg_print("You find living difficult in your present form!"); + take_hit(damroll(randint(10), p_ptr->lev), "a lethal corruption"); + power -= 10; + } + } + + if ((power > rand_int(20)) && (rand_int(4) == 0)) + { + power -= 10; + + do_cmd_rerate(); + } + + while ((power > rand_int(15)) && (rand_int(3) == 0)) + { + power -= 7; + gain_random_corruption(); + } + + if (power > rand_int(5)) + { + power -= 5; + do_poly_wounds(); + } + + /* Note: earlier deductions may have left power < 0 already. */ + while (power > 0) + { + corrupt_player(); + power--; + } +} + + +/* + * Brand the current weapon + */ +void brand_weapon(int brand_type) +{ + object_type *o_ptr; + + cptr act = NULL; + + char o_name[80]; + + + o_ptr = &p_ptr->inventory[INVEN_WIELD]; + + /* + * You can never modify artifacts / ego-items + * You can never modify cursed items + * + * TY: You _can_ modify broken items (if you're silly enough) + */ + if (!o_ptr->k_idx || artifact_p(o_ptr) || ego_item_p(o_ptr) || + o_ptr->art_name || cursed_p(o_ptr)) + { + if (flush_failure) flush(); + + msg_print("The Branding failed."); + + return; + } + + + /* Save the old name */ + object_desc(o_name, o_ptr, FALSE, 0); + + switch (brand_type) + { + case 6: + { + act = "glows with godly power."; + o_ptr->name2 = EGO_BLESS_BLADE; + o_ptr->pval = randint(4); + + break; + } + case 5: + { + act = "seems very powerful."; + o_ptr->name2 = EGO_EARTHQUAKES; + o_ptr->pval = randint(3); + + break; + } + case 4: + { + act = "seems very unstable now."; + o_ptr->name2 = EGO_DRAGON; + o_ptr->pval = randint(2); + + break; + } + case 3: + { + act = "thirsts for blood!"; + o_ptr->name2 = EGO_VAMPIRIC; + + break; + } + case 2: + { + act = "is coated with poison."; + o_ptr->name2 = EGO_BRAND_POIS; + + break; + } + case 1: + { + act = "is engulfed in raw chaos!"; + o_ptr->name2 = EGO_CHAOTIC; + + break; + } + default: + { + if (rand_int(100) < 25) + { + act = "is covered in a fiery shield!"; + o_ptr->name2 = EGO_BRAND_FIRE; + } + else + { + act = "glows deep, icy blue!"; + o_ptr->name2 = EGO_BRAND_COLD; + } + } + } + + /* Apply the ego */ + apply_magic(o_ptr, dun_level, FALSE, FALSE, FALSE); + o_ptr->discount = 100; + + msg_format("Your %s %s", o_name, act); + + enchant(o_ptr, rand_int(3) + 4, ENCH_TOHIT | ENCH_TODAM); +} + +/* + * Fetch an item (teleport it right underneath the caster) + */ +void fetch(int dir, int wgt, bool_ require_los) +{ + int ty, tx, i; + + cave_type *c_ptr; + + object_type *o_ptr; + + char o_name[80]; + + + /* Check to see if an object is already there */ + if (cave[p_ptr->py][p_ptr->px].o_idx) + { + msg_print("You can't fetch when you're already standing on something."); + return; + } + + /* Use a target */ + if ((dir == 5) && target_okay()) + { + tx = target_col; + ty = target_row; + + if (distance(p_ptr->py, p_ptr->px, ty, tx) > MAX_RANGE) + { + msg_print("You can't fetch something that far away!"); + return; + } + + c_ptr = &cave[ty][tx]; + + if (!c_ptr->o_idx) + { + msg_print("There is no object at this place."); + return; + } + + if (require_los && (!player_has_los_bold(ty, tx))) + { + msg_print("You have no direct line of sight to that location."); + return; + } + } + else + { + /* Use a direction */ + ty = p_ptr->py; /* Where to drop the item */ + tx = p_ptr->px; + + while (1) + { + ty += ddy[dir]; + tx += ddx[dir]; + c_ptr = &cave[ty][tx]; + + if ((distance(p_ptr->py, p_ptr->px, ty, tx) > MAX_RANGE) || + !cave_floor_bold(ty, tx)) return; + + if (c_ptr->o_idx) break; + } + } + + o_ptr = &o_list[c_ptr->o_idx]; + + if (o_ptr->weight > wgt) + { + /* Too heavy to 'fetch' */ + msg_print("The object is too heavy."); + return; + } + + i = c_ptr->o_idx; + c_ptr->o_idx = o_ptr->next_o_idx; + cave[p_ptr->py][p_ptr->px].o_idx = i; /* 'move' it */ + o_ptr->next_o_idx = 0; + o_ptr->iy = p_ptr->py; + o_ptr->ix = p_ptr->px; + + object_desc(o_name, o_ptr, TRUE, 0); + msg_format("%^s flies through the air to your feet.", o_name); + + note_spot(p_ptr->py, p_ptr->px); + p_ptr->redraw |= PR_MAP; +} + + +/* + * 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; + } + } +} + + +/* + * Like all the random effect codes, this is *ugly*, + * and there is not a single line of comment, so I can't tell + * some fall throughs are really intended. Well, I know it's + * intended to be bizarre :) -- pelpel + */ +void wild_magic(int spell) +{ + int counter = 0; + int type = SUMMON_BIZARRE1 - 1 + randint(6); + + if (type < SUMMON_BIZARRE1) type = SUMMON_BIZARRE1; + else if (type > SUMMON_BIZARRE6) type = SUMMON_BIZARRE6; + + switch (randint(spell) + randint(8) + 1) + { + case 1: + case 2: + case 3: + { + teleport_player(10); + + break; + } + + case 4: + case 5: + case 6: + { + teleport_player(100); + + break; + } + + case 7: + case 8: + { + teleport_player(200); + + break; + } + + case 9: + case 10: + case 11: + { + unlite_area(10, 3); + + break; + } + + case 12: + case 13: + case 14: + { + lite_area(damroll(2, 3), 2); + + break; + } + + case 15: + { + destroy_doors_touch(); + + break; + } + + case 16: + case 17: + { + wall_breaker(); + + /* I don't think this is a fall through -- pelpel */ + break; + } + + case 18: + { + sleep_monsters_touch(); + + break; + } + + case 19: + case 20: + { + trap_creation(); + + break; + } + + case 21: + case 22: + { + door_creation(); + + break; + } + + case 23: + case 24: + case 25: + { + aggravate_monsters(1); + + break; + } + + case 26: + { + /* Prevent destruction of quest levels and town */ + if (!is_quest(dun_level) && dun_level) + earthquake(p_ptr->py, p_ptr->px, 5); + + break; + } + + case 27: + case 28: + { + break; + } + + case 29: + case 30: + { + apply_disenchant(0); + + break; + } + + case 31: + { + lose_all_info(); + + break; + } + + case 32: + { + fire_ball(GF_CHAOS, 0, spell + 5, 1 + (spell / 10)); + + break; + } + + case 33: + { + wall_stone(p_ptr->py, p_ptr->px); + + break; + } + + case 34: + case 35: + { + while (counter++ < 8) + { + (void) summon_specific(p_ptr->py, p_ptr->px, (dun_level * 3) / 2, type); + } + + break; + } + + case 36: + case 37: + { + activate_hi_summon(); + + break; + } + + case 38: + { + summon_cyber(); + + /* I don't think this is a fall through -- pelpel */ + break; + } + + default: + { + activate_ty_curse(); + } + } + + return; +} + + +/* + * Hack -- Determine if the player is wearing an artefact ring + * specified by art_type, that should be an index into a_info + */ +bool_ check_ring(int art_type) +{ + int i; + + + /* We are only interested in ring slots */ + i = INVEN_RING; + + /* Scan the list of rings until we reach the end */ + while (p_ptr->body_parts[i - INVEN_WIELD] == INVEN_RING) + { + /* Found the ring we were looking for */ + if (p_ptr->inventory[i].k_idx && (p_ptr->inventory[i].name1 == art_type)) + { + return (TRUE); + } + + /* Next item */ + i++; + } + + /* Found nothing */ + return (FALSE); +} + +/* + * Return the symbiote's name or description. + */ +cptr symbiote_name(bool_ capitalize) +{ + object_type *o_ptr = &p_ptr->inventory[INVEN_CARRY]; + static char buf[80]; + + /* Make sure there actually is a symbiote there... */ + if (!o_ptr->k_idx) + { + strcpy(buf, "A non-existent symbiote"); + } + else + { + monster_race *r_ptr = &r_info[o_ptr->pval]; + cptr s = NULL; + + if (r_ptr->flags1 & RF1_UNIQUE) + { + /* Unique monster; no preceding "your", and ignore our name. */ + strncpy(buf, r_name + r_ptr->name, sizeof(buf)); + } + else if (o_ptr->note && + (s = strstr(quark_str(o_ptr->note), "#named ")) != NULL) + { + /* We've named it. */ + strncpy(buf, s + 7, sizeof(buf)); + } + else + { + /* No special cases, just return "Your ". */ + strcpy(buf, "your "); + strncpy(buf + 5, r_name + r_ptr->name, sizeof(buf) - 5); + } + } + + /* Just in case... */ + buf[sizeof(buf) - 1] = '\0'; + if (capitalize) buf[0] = toupper(buf[0]); + return buf; +} + +/* + * Use a power of the monster in symbiosis + */ +int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost) +{ + 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++) + { + if (r_ptr->flags4 & BIT(i)) + { + if (monster_powers[i].great && (!great)) continue; + if (!monster_powers[i].power) continue; + powers[num++] = i; + } + } + + /* 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++) + { + if (r_ptr->flags6 & BIT(i)) + { + if (monster_powers[i + 64].great && (!great)) continue; + if (!monster_powers[i + 64].power) continue; + powers[num++] = i + 64; + } + } + + if (!num) + { + msg_print("You have no powers you can use."); + return (0); + } + + if (only_number) return (num); + + /* Nothing chosen yet */ + flag = FALSE; + + /* Get the last label */ + 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 */ + strnfmt(out_val, 78, + "(Powers a-%c, ESC=exit) Use which power of your %s? ", + label, (no_cost ? "symbiote" : "body")); + + /* Save the screen */ + character_icky = TRUE; + Term_save(); + + /* Get a spell from the user */ + while (!flag) + { + /* Show the list */ + { + 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; + + label = (ctr < 26) ? I2A(ctr) : I2D(ctr - 26); + + if (!no_cost) + { + strnfmt(dummy, 80, " %c) %2d %s", + label, mana, mp_ptr->name); + } + else + { + strnfmt(dummy, 80, " %c) %s", + label, mp_ptr->name); + } + + if (ctr < 17) + { + prt(dummy, y + ctr, x); + } + else + { + prt(dummy, y + ctr - 17, x + 40); + } + + ctr++; + } + + if (ctr < 17) + { + prt ("", y + ctr, x); + } + else + { + prt ("", y + 17, x); + } + } + + if (!get_com(out_val, &choice)) + { + flag = FALSE; + break; + } + + if (choice == '\r' && num == 1) + { + choice = 'a'; + } + + if (isalpha(choice)) + { + /* Note verify */ + ask = (isupper(choice)); + + /* Lowercase */ + if (ask) choice = tolower(choice); + + /* Extract request */ + i = (islower(choice) ? A2I(choice) : -1); + } + else + { + /* Can't uppercase digits XXX XXX XXX */ + ask = FALSE; + + i = choice - '0' + 26; + } + + /* Totally Illegal */ + if ((i < 0) || (i >= num)) + { + bell(); + continue; + } + + /* Save the spell index */ + power = powers[i]; + + /* Verify it */ + if (ask) + { + char tmp_val[160]; + + /* Prompt */ + strnfmt(tmp_val, 78, "Use %s? ", monster_powers[power].name); + + /* Belay that order */ + if (!get_check(tmp_val)) continue; + } + + /* Stop the loop */ + flag = TRUE; + } + + /* Restore the screen */ + Term_load(); + character_icky = FALSE; + + /* Abort if needed */ + if (!flag) + { + energy_use = 0; + return -1; + } + + /* 'Powerful' monsters have wider radii */ + if (r_ptr->flags2 & RF2_POWERFUL) + { + rad = 1 + (p_ptr->lev / 15); + } + else + { + rad = 1 + (p_ptr->lev / 20); + } + + + /* Analyse power */ + switch (power) + { + /**** RF4 (bit position) ****/ + + /* SHRIEK */ + case 0: + { + aggravate_monsters( -1); + + break; + } + + /* MULTIPLY */ + case 1: + { + do_cmd_wiz_named_friendly(p_ptr->body_monster, FALSE); + + break; + } + + /* S_ANIMAL */ + case 2: + { + summon_specific_friendly(y, x, rlev, SUMMON_ANIMAL, TRUE); + + break; + } + + /* ROCKET */ + case 3: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_ROCKET, dir, p_ptr->lev * 12, 1 + (p_ptr->lev / 20)); + + break; + } + + /* ARROW_1 */ + case 4: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_ARROW, dir, damroll(1, 6)); + + break; + } + + /* ARROW_2 */ + case 5: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_ARROW, dir, damroll(3, 6)); + + break; + } + + /* ARROW_3 */ + case 6: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_ARROW, dir, damroll(5, 6)); + + break; + } + + /* ARROW_4 */ + case 7: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_ARROW, dir, damroll(7, 6)); + + break; + } + + /* BR_ACID */ + case 8: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_ACID, dir, p_ptr->lev * 5, rad); + + break; + } + + /* BR_ELEC */ + case 9: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_ELEC, dir, p_ptr->lev * 5, rad); + + break; + } + + /* BR_FIRE */ + case 10: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_FIRE, dir, p_ptr->lev * 5, rad); + + break; + } + + /* BR_COLD */ + case 11: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_COLD, dir, p_ptr->lev * 5, rad); + + break; + } + + /* BR_POIS */ + case 12: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_POIS, dir, p_ptr->lev * 5, rad); + + break; + } + + /* BR_NETH */ + case 13: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_NETHER, dir, p_ptr->lev * 5, rad); + + break; + } + + /* BR_LITE */ + case 14: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_LITE, dir, p_ptr->lev * 8, rad); + + break; + } + + /* BR_DARK */ + case 15: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_DARK, dir, p_ptr->lev * 8, rad); + + break; + } + + /* BR_CONF */ + case 16: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_CONFUSION, dir, p_ptr->lev * 8, rad); + + break; + } + + /* BR_SOUN */ + case 17: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_SOUND, dir, p_ptr->lev * 8, rad); + + break; + } + + /* BR_CHAO */ + case 18: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_CHAOS, dir, p_ptr->lev * 7, rad); + + break; + } + + /* BR_DISE */ + case 19: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_DISENCHANT, dir, p_ptr->lev * 7, rad); + + break; + } + + /* BR_NEXU */ + case 20: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_NEXUS, dir, p_ptr->lev * 5, rad); + + break; + } + + /* BR_TIME */ + case 21: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_TIME, dir, p_ptr->lev * 3, rad); + + break; + } + + /* BR_INER */ + case 22: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_INERTIA, dir, p_ptr->lev * 4, rad); + + break; + } + + /* BR_GRAV */ + case 23: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_GRAVITY, dir, p_ptr->lev * 4, rad); + + break; + } + + /* BR_SHAR */ + case 24: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_SHARDS, dir, p_ptr->lev * 8, rad); + + break; + } + + /* BR_PLAS */ + case 25: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_PLASMA, dir, p_ptr->lev * 3, rad); + + break; + } + + /* BR_WALL */ + case 26: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_FORCE, dir, p_ptr->lev * 4, rad); + + break; + } + + /* BR_MANA */ + case 27: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_MANA, dir, p_ptr->lev * 5, rad); + + break; + } + + /* BA_NUKE */ + case 28: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_NUKE, dir, p_ptr->lev * 8, 1 + (p_ptr->lev / 20)); + + break; + } + + /* BR_NUKE */ + case 29: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_NUKE, dir, p_ptr->lev * 8, 1 + (p_ptr->lev / 20)); + + break; + } + + /* BA_CHAO */ + case 30: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_CHAOS, dir, p_ptr->lev * 4, 2); + + break; + } + + /* BR_DISI */ + case 31: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_DISINTEGRATE, dir, p_ptr->lev * 5, 1 + (p_ptr->lev / 20)); + + break; + } + + + /**** RF5 (bit position + 32) ****/ + + /* BA_ACID */ + case 32: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_ACID, dir, randint(p_ptr->lev * 6) + 20, 2); + + break; + } + + /* BA_ELEC */ + case 33: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_ELEC, dir, randint(p_ptr->lev * 3) + 20, 2); + + break; + } + + /* BA_FIRE */ + case 34: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_FIRE, dir, randint(p_ptr->lev * 7) + 20, 2); + + break; + } + + /* BA_COLD */ + case 35: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_COLD, dir, randint(p_ptr->lev * 3) + 20, 2); + + break; + } + + /* BA_POIS */ + case 36: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_POIS, dir, damroll(12, 2), 2); + + break; + } + + /* BA_NETH */ + case 37: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_NETHER, dir, randint(p_ptr->lev * 4) + 20, 2); + + break; + } + + /* BA_WATE */ + case 38: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_WATER, dir, randint(p_ptr->lev * 4) + 20, 2); + + break; + } + + /* BA_MANA */ + case 39: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_MANA, dir, randint(p_ptr->lev * 3) + 20, 2); + + break; + } + + /* BA_DARK */ + case 40: + { + if (!get_aim_dir(&dir)) break; + + fire_ball(GF_DARK, dir, randint(p_ptr->lev * 3) + 20, 2); + + break; + } + + /* 41 DRAIN_MANA -- Not available */ + + /* 42 MIND_BLAST -- Not available */ + + /* 43 BRAIN_SMASH -- Not available */ + + /* CAUSE_1 */ + case 44: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_MANA, dir, damroll(3, 8)); + + break; + } + + /* CAUSE_2 */ + case 45: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_MANA, dir, damroll(8, 8)); + + break; + } + + /* CAUSE_3 */ + case 46: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_MANA, dir, damroll(10, 15)); + + break; + } + + /* CAUSE_4 */ + case 47: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_MANA, dir, damroll(15, 15)); + + break; + } + + /* BO_ACID */ + case 48: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_ACID, dir, damroll(7, 8) + (p_ptr->lev / 3)); + + break; + } + + /* BO_ELEC */ + case 49: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_ELEC, dir, damroll(4, 8) + (p_ptr->lev / 3)); + + break; + } + + /* BO_FIRE */ + case 50: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_FIRE, dir, damroll(9, 8) + (p_ptr->lev / 3)); + + break; + } + + /* BO_COLD */ + case 51: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_COLD, dir, damroll(6, 8) + (p_ptr->lev / 3)); + + break; + } + + /* BO_POIS */ + case 52: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_POIS, dir, damroll(7, 8) + (p_ptr->lev / 3)); + + break; + } + + /* BO_NETH */ + case 53: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_NETHER, dir, damroll(5, 5) + (p_ptr->lev / 3)); + + break; + } + + /* BO_WATE */ + case 54: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_WATER, dir, damroll(10, 10) + (p_ptr->lev / 3)); + + break; + } + + /* BO_MANA */ + case 55: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_MANA, dir, damroll(3, 8) + (p_ptr->lev / 3)); + + break; + } + + /* BO_PLAS */ + case 56: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_PLASMA, dir, damroll(8, 8) + (p_ptr->lev / 3)); + + break; + } + + /* BO_ICEE */ + case 57: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_ICE, dir, damroll(6, 6) + (p_ptr->lev / 3)); + + break; + } + + /* MISSILE */ + case 58: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_MISSILE, dir, damroll(2, 6) + (p_ptr->lev / 3)); + + break; + } + + /* SCARE */ + case 59: + { + if (!get_aim_dir(&dir)) break; + + fear_monster(dir, plev); + + break; + } + + /* BLIND */ + case 60: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_CONFUSION, dir, damroll(1, 8) + (p_ptr->lev / 3)); + + break; + } + + /* CONF */ + case 61: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_CONFUSION, dir, damroll(7, 8) + (p_ptr->lev / 3)); + + break; + } + + /* SLOW */ + case 62: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_OLD_SLOW, dir, damroll(6, 8) + (p_ptr->lev / 3)); + + break; + } + + /* HOLD */ + case 63: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_OLD_SLEEP, dir, damroll(5, 8) + (p_ptr->lev / 3)); + + break; + } + + + /**** RF6 (bit position + 64) ****/ + + /* HASTE */ + case 64: + { + if (!p_ptr->fast) + { + (void)set_fast(randint(20 + (plev) ) + plev, 10); + } + else + { + (void)set_fast(p_ptr->fast + randint(5), 10); + } + + break; + } + + /* HAND_DOOM */ + case 65: + { + if (!get_aim_dir(&dir)) break; + + fire_bolt(GF_MANA, dir, damroll(10, 8) + (p_ptr->lev)); + + break; + } + + /* HEAL */ + case 66: + { + hp_player(damroll(8, 5)); + + break; + } + + /* S_ANIMALS */ + case 67: + { + for (k = 0; k < 4; k++) + { + summon_specific_friendly(y, x, rlev, SUMMON_ANIMAL, TRUE); + } + + break; + } + + /* BLINK */ + case 68: + { + if (dungeon_flags2 & DF2_NO_TELEPORT) + { + msg_print("No teleport on special levels..."); + break; + } + + teleport_player(10); + + break; + } + + /* TPORT */ + case 69: + { + if (dungeon_flags2 & DF2_NO_TELEPORT) + { + msg_print("No teleport on special levels..."); + break; + } + + teleport_player(plev * 5); + + break; + } + + /* TELE_TO */ + case 70: + { + int ii, ij; + + if (dungeon_flags2 & DF2_NO_TELEPORT) + { + msg_print("No teleport on special levels..."); + break; + } + + msg_print("You go between."); + + if (!tgt_pt(&ii, &ij)) break; + + 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)) + { + msg_print("You fail to show the destination correctly!"); + p_ptr->energy -= 100; + teleport_player(10); + } + else teleport_player_to(ij, ii); + + break; + } + + /* TELE_AWAY */ + case 71: + { + if (dungeon_flags2 & DF2_NO_TELEPORT) + { + msg_print("No teleport on special levels..."); + break; + } + + if (!get_aim_dir(&dir)) break; + + (void)fire_beam(GF_AWAY_ALL, dir, plev); + + break; + } + + /* TELE_LEVEL */ + case 72: + { + if (dungeon_flags2 & DF2_NO_TELEPORT) + { + msg_print("No teleport on special levels..."); + break; + } + + teleport_player_level(); + + break; + } + + /* DARKNESS */ + case 73: + { + (void)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); + + break; + } + + /* TRAPS */ + case 74: + { + 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++) + { + summon_specific_friendly(y, x, rlev, SUMMON_THUNDERLORD, TRUE); + } + + break; + } + + /* S_KIN -- Summon Kin, because we code bugs :) */ + case 80: + { + /* Big hack */ + summon_kin_type = r_ptr->d_char; + + for (k = 0; k < 6; k++) + { + summon_specific_friendly(y, x, rlev, SUMMON_KIN, TRUE); + } + + break; + } + + /* S_HI_DEMON */ + case 81: + { + for (k = 0; k < 1; k++) + { + summon_specific_friendly(y, x, rlev, SUMMON_HI_DEMON, TRUE); + } + + break; + } + + /* S_MONSTER */ + case 82: + { + for (k = 0; k < 1; k++) + { + summon_specific_friendly(y, x, rlev, 0, TRUE); + } + + break; + } + + /* S_MONSTERS */ + case 83: + { + for (k = 0; k < 6; k++) + { + summon_specific_friendly(y, x, rlev, 0, TRUE); + } + + break; + } + + /* S_ANT */ + case 84: + { + for (k = 0; k < 6; k++) + { + summon_specific_friendly(y, x, rlev, SUMMON_ANT, TRUE); + } + + break; + } + + /* S_SPIDER */ + case 85: + { + for (k = 0; k < 6; k++) + { + summon_specific_friendly(y, x, rlev, SUMMON_SPIDER, TRUE); + } + + break; + } + + /* S_HOUND */ + case 86: + { + for (k = 0; k < 6; k++) + { + summon_specific_friendly(y, x, rlev, SUMMON_HOUND, TRUE); + } + + break; + } + + /* S_HYDRA */ + case 87: + { + for (k = 0; k < 6; k++) + { + summon_specific_friendly(y, x, rlev, SUMMON_HYDRA, TRUE); + } + + break; + } + + /* S_ANGEL */ + case 88: + { + for (k = 0; k < 1; k++) + { + summon_specific_friendly(y, x, rlev, SUMMON_ANGEL, TRUE); + } + + break; + } + + /* S_DEMON */ + case 89: + { + for (k = 0; k < 1; k++) + { + summon_specific_friendly(y, x, rlev, SUMMON_DEMON, TRUE); + } + + break; + } + + /* S_UNDEAD */ + case 90: + { + for (k = 0; k < 1; k++) + { + summon_specific_friendly(y, x, rlev, SUMMON_UNDEAD, TRUE); + } + + break; + } + + /* S_DRAGON */ + case 91: + { + for (k = 0; k < 1; k++) + { + summon_specific_friendly(y, x, rlev, SUMMON_DRAGON, TRUE); + } + + break; + } + + /* S_HI_UNDEAD */ + case 92: + { + for (k = 0; k < 8; k++) + { + summon_specific_friendly(y, x, rlev, SUMMON_HI_UNDEAD_NO_UNIQUES, TRUE); + } + + break; + } + + /* S_HI_DRAGON */ + case 93: + { + for (k = 0; k < 8; k++) + { + summon_specific_friendly(y, x, rlev, SUMMON_HI_DRAGON_NO_UNIQUES, TRUE); + } + + break; + } + + /* S_WRAITH */ + case 94: + { + for (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; + + if (m > p_ptr->msp) m = p_ptr->msp; + if (!m) m = 1; + + p_ptr->csp -= m; + } + } + + /* Redraw mana */ + p_ptr->redraw |= (PR_MANA); + + /* Window stuff */ + p_ptr->window |= (PW_PLAYER); + + return (num); +} + +/* + * Schooled magic + */ + +/* + * Find a spell in any books/objects + */ +static int hack_force_spell = -1; +static object_type *hack_force_spell_obj = NULL; +bool_ get_item_hook_find_spell(int *item) +{ + int i, spell; + char buf[80]; + + strcpy(buf, "Manathrust"); + if (!get_string("Spell name? ", buf, 79)) + return FALSE; + + spell = find_spell(buf); + if (spell == -1) return FALSE; + + for (i = 0; i < INVEN_TOTAL; i++) + { + object_type *o_ptr = &p_ptr->inventory[i]; + u32b f1, f2, f3, f4, f5, esp; + + /* Must we wield it ? */ + object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + if ((wield_slot(o_ptr) != -1) && (i < INVEN_WIELD) && (f5 & TR5_WIELD_CAST)) continue; + + /* Is it a non-book? */ + if (!is_school_book(o_ptr)) + { + u32b f1, f2, f3, f4, f5, esp; + + /* Extract object flags */ + object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + + if ((f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 == spell)) + { + *item = i; + hack_force_spell = spell; + hack_force_spell_obj = o_ptr; + return TRUE; + } + } + /* A random book ? */ + else if (school_book_contains_spell(o_ptr->sval, spell)) + { + *item = i; + hack_force_spell = spell; + hack_force_spell_obj = o_ptr; + return TRUE; + } + } + return FALSE; +} + +/* + * Is the spell castable? + */ +bool_ is_ok_spell(s32b spell_idx, object_type *o_ptr) +{ + spell_type *spell = spell_at(spell_idx); + assert(o_ptr != NULL); + + if (get_level(spell_idx, 50, 0) == 0) + { + return FALSE; + } + + if (o_ptr->pval < spell_type_minimum_pval(spell)) + { + return FALSE; + } + + return TRUE; +} + + +/* + * Get a spell from a book + */ +s32b get_school_spell(cptr do_what, s16b force_book) +{ + int i, item; + s32b spell = -1; + int num = 0; + s32b where = 1; + int ask; + bool_ flag; + char out_val[160]; + char buf2[40]; + char buf3[40]; + object_type *o_ptr, forge; + int tmp; + int sval, pval; + u32b f1, f2, f3, f4, f5, esp; + + hack_force_spell = -1; + hack_force_spell_obj = NULL; + + /* Ok do we need to ask for a book ? */ + if (!force_book) + { + get_item_extra_hook = get_item_hook_find_spell; + item_tester_hook = hook_school_spellable; + sprintf(buf2, "You have no book to %s from", do_what); + sprintf(buf3, "%s from which book?", do_what); + if (!get_item(&item, buf3, buf2, USE_INVEN | USE_EQUIP | USE_EXTRA )) return -1; + + /* Get the item */ + o_ptr = get_object(item); + + object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + + /* If it can be wielded, it must */ + if ((wield_slot(o_ptr) != -1) && (item < INVEN_WIELD) && (f5 & TR5_WIELD_CAST)) + { + msg_format("You cannot %s from that object; it must be wielded first.", do_what); + return -1; + } + } + else + { + o_ptr = &forge; + o_ptr->tval = TV_BOOK; + o_ptr->sval = force_book; + o_ptr->pval = 0; + } + + if (repeat_pull(&tmp)) + { + return tmp; + } + + /* Nothing chosen yet */ + flag = FALSE; + + /* Show choices */ + window_stuff(); + + /* No spell to cast by default */ + spell = -1; + + /* Is it a random book, or something else ? */ + if (is_school_book(o_ptr)) + { + sval = o_ptr->sval; + pval = o_ptr->pval; + } + else + { + sval = 255; + pval = o_ptr->pval2; + } + + /* Save the screen */ + character_icky = TRUE; + Term_save(); + + /* Go */ + if (hack_force_spell == -1) + { + num = school_book_length(sval); + + /* Build a prompt (accept all spells) */ + strnfmt(out_val, 78, "(Spells %c-%c, Descs %c-%c, ESC=exit) %^s which spell? ", + I2A(0), I2A(num - 1), I2A(0) - 'a' + 'A', I2A(num - 1) - 'a' + 'A', do_what); + + /* Get a spell from the user */ + while (!flag) + { + char choice; + + /* Restore and save screen; this prevents + subprompt from leaving garbage when going + around the loop multiple times. */ + Term_load(); + Term_save(); + + /* Display a list of spells */ + where = print_book(sval, pval, o_ptr); + + /* Input */ + if (!get_com(out_val, &choice)) + { + flag = FALSE; + break; + } + + /* Note verify */ + ask = (isupper(choice)); + + /* Lowercase */ + if (ask) choice = tolower(choice); + + /* Extract request */ + i = (islower(choice) ? A2I(choice) : -1); + + /* Totally Illegal */ + if ((i < 0) || (i >= num)) + { + bell(); + continue; + } + + /* Verify it */ + if (ask) + { + /* Display a list of spells */ + where = print_book(sval, pval, o_ptr); + print_spell_desc(spell_x(sval, pval, i), where); + } + else + { + bool_ ok; + + /* Save the spell index */ + spell = spell_x(sval, pval, i); + + /* Do we need to do some pre test */ + ok = is_ok_spell(spell, o_ptr); + + /* Require "okay" spells */ + if (!ok) + { + bell(); + msg_format("You may not %s that spell.", do_what); + spell = -1; + continue; + } + + /* Stop the loop */ + flag = TRUE; + } + } + } + else + { + bool_ ok; + + /* Require "okay" spells */ + ok = is_ok_spell(hack_force_spell, hack_force_spell_obj); + if (ok) + { + flag = TRUE; + spell = hack_force_spell; + } + else + { + bell(); + msg_format("You may not %s that spell.", do_what); + spell = -1; + } + } + + + /* Restore the screen */ + Term_load(); + character_icky = FALSE; + + + /* Show choices */ + window_stuff(); + + + /* Abort if needed */ + if (!flag) return -1; + + tmp = spell; + repeat_push(tmp); + return spell; +} + +void cast_school_spell() +{ + int spell; + + /* No magic */ + if (p_ptr->antimagic) + { + 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; + } + + spell = get_school_spell("cast", 0); + + /* Actualy cast the choice */ + if (spell != -1) + { + lua_cast_school_spell(spell, FALSE); + } +} + +void browse_school_spell(int book, int pval, object_type *o_ptr) +{ + int i; + int num = 0, where = 1; + int ask; + char choice; + char out_val[160]; + + /* Show choices */ + window_stuff(); + + num = school_book_length(book); + + /* Build a prompt (accept all spells) */ + strnfmt(out_val, 78, "(Spells %c-%c, ESC=exit) cast which spell? ", + I2A(0), I2A(num - 1)); + + /* Save the screen */ + character_icky = TRUE; + Term_save(); + + /* Display a list of spells */ + where = print_book(book, pval, o_ptr); + + /* Get a spell from the user */ + while (get_com(out_val, &choice)) + { + /* Display a list of spells */ + where = print_book(book, pval, o_ptr); + + /* Note verify */ + ask = (isupper(choice)); + + /* Lowercase */ + if (ask) choice = tolower(choice); + + /* Extract request */ + i = (islower(choice) ? A2I(choice) : -1); + + /* Totally Illegal */ + if ((i < 0) || (i >= num)) + { + bell(); + continue; + } + + /* Restore the screen */ + Term_load(); + + /* Display a list of spells */ + where = print_book(book, pval, o_ptr); + print_spell_desc(spell_x(book, pval, i), where); + } + + + /* Restore the screen */ + Term_load(); + character_icky = FALSE; + + /* Show choices */ + window_stuff(); +} + +/* Can it contains a schooled spell ? */ +static bool_ hook_school_can_spellable(object_type *o_ptr) +{ + u32b f1, f2, f3, f4, f5, esp; + + /* Extract object flags */ + object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + + if ((f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 == -1)) + return TRUE; + return FALSE; +} + +/* + * Copy a spell from a bok to an object + */ +void do_cmd_copy_spell() +{ + int spell = get_school_spell("copy", 0); + int item; + object_type *o_ptr; + + if (spell == -1) return; + + /* Spells that cannot be randomly created cannot be copied */ + if (spell_type_random_type(spell_at(spell)) <= 0) + { + msg_print("This spell cannot be copied."); + return; + } + + item_tester_hook = hook_school_can_spellable; + if (!get_item(&item, "Copy to which object? ", "You have no object to copy to.", (USE_INVEN | USE_EQUIP))) return; + o_ptr = get_object(item); + + msg_print("You copy the spell!"); + o_ptr->pval2 = spell; + inven_item_describe(item); +} -- cgit v1.2.3 From ca71ccff098e4eec97480d2a08773a06629cc66e Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Thu, 26 Jun 2014 06:50:06 +0200 Subject: Simplify PR_* redraw code and remove direct references to Term members --- src/cmd5.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 95ae0346..d2a537df 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -287,7 +287,7 @@ void do_poly_self(void) check_experience(); p_ptr->max_plv = p_ptr->lev; - p_ptr->redraw |= (PR_BASIC); + p_ptr->redraw |= (PR_FRAME); p_ptr->update |= (PU_BONUS); @@ -2057,7 +2057,7 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost } /* Redraw mana */ - p_ptr->redraw |= (PR_MANA); + p_ptr->redraw |= (PR_FRAME); /* Window stuff */ p_ptr->window |= (PW_PLAYER); -- cgit v1.2.3 From 5db9e06833d5a98ab3e9fefc2eb2de6680d4c59b Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:11:55 +0100 Subject: Use get_level_school explicitly in is_ok_spell We are guaranteed that is_ok_spell is only ever called on "school spells", so this should be behavior-preserving. --- src/cmd5.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index d2a537df..60c51a1d 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -2130,17 +2130,21 @@ bool_ is_ok_spell(s32b spell_idx, object_type *o_ptr) { spell_type *spell = spell_at(spell_idx); assert(o_ptr != NULL); - - if (get_level(spell_idx, 50, 0) == 0) + // Calculate availability based on caster's skill level. + s32b level; + bool_ na; + get_level_school(spell_idx, 50, 0, &level, &na); + if (na || (level == 0)) { return FALSE; } - + // Are we permitted to cast based on item pval? Only music + // spells have non-zero minimum PVAL. if (o_ptr->pval < spell_type_minimum_pval(spell)) { return FALSE; } - + // OK, we're permitted to cast it. return TRUE; } -- cgit v1.2.3 From a53ffb9d26322296b64f23fe0ae72a245802a9b0 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:11:55 +0100 Subject: Change get_level_school() to use direct spell_type pointer instead of index --- src/cmd5.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 60c51a1d..f0c83133 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -2133,7 +2133,7 @@ bool_ is_ok_spell(s32b spell_idx, object_type *o_ptr) // Calculate availability based on caster's skill level. s32b level; bool_ na; - get_level_school(spell_idx, 50, 0, &level, &na); + get_level_school(spell, 50, 0, &level, &na); if (na || (level == 0)) { return FALSE; -- cgit v1.2.3 From 7d6273cfbbc9717c30792817824b5511f7aee05f Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:11:55 +0100 Subject: Consolide the two spell_type headers --- src/cmd5.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index f0c83133..0b0da5a4 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -15,7 +15,7 @@ #include -#include "spell_type.h" +#include "spell_type.hpp" #include "quark.h" /* Maximum number of tries for teleporting */ -- cgit v1.2.3 From ebb2771875ec2fffd7c63ee138024e6ebc47ebf8 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:11:55 +0100 Subject: Move school_spells array to spells5.cc --- src/cmd5.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 0b0da5a4..e03793be 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -17,6 +17,7 @@ #include "spell_type.hpp" #include "quark.h" +#include "spells5.hpp" /* Maximum number of tries for teleporting */ #define MAX_TRIES 300 -- cgit v1.2.3 From c4746c0f6d328baa429c96e54d86d2d7f97ccbcc Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:11:57 +0100 Subject: Remove r_name, r_text, r_head in favor of simple strings --- src/cmd5.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index e03793be..35d146e9 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -823,7 +823,7 @@ cptr symbiote_name(bool_ capitalize) if (r_ptr->flags1 & RF1_UNIQUE) { /* Unique monster; no preceding "your", and ignore our name. */ - strncpy(buf, r_name + r_ptr->name, sizeof(buf)); + strncpy(buf, r_ptr->name, sizeof(buf)); } else if (o_ptr->note && (s = strstr(quark_str(o_ptr->note), "#named ")) != NULL) @@ -835,7 +835,7 @@ cptr symbiote_name(bool_ capitalize) { /* No special cases, just return "Your ". */ strcpy(buf, "your "); - strncpy(buf + 5, r_name + r_ptr->name, sizeof(buf) - 5); + strncpy(buf + 5, r_ptr->name, sizeof(buf) - 5); } } -- cgit v1.2.3 From caa23251d8b279529330641032c62f8640ee13ff Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:11:58 +0100 Subject: Remove rp_head, rp_name, rp_text, rmp_head, rmp_name, rmp_text --- src/cmd5.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 35d146e9..8ecf67dc 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -266,8 +266,8 @@ void do_poly_self(void) if (effect_msg[0]) { msg_format("You turn into a%s %s!", - ((is_a_vowel(rp_name[race_info[new_race].title])) ? "n" : ""), - race_info[new_race].title + rp_name); + ((is_a_vowel(*race_info[new_race].title)) ? "n" : ""), + race_info[new_race].title); } else { -- cgit v1.2.3 From 3577729037709acd5d2105665134ec27a64bc4c3 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:11:59 +0100 Subject: Move corrupt.cc function declarations to separate header --- src/cmd5.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 8ecf67dc..25752331 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -12,12 +12,12 @@ #include "angband.h" - -#include - +#include "corrupt.hpp" #include "spell_type.hpp" -#include "quark.h" #include "spells5.hpp" +#include "quark.h" + +#include /* Maximum number of tries for teleporting */ #define MAX_TRIES 300 -- cgit v1.2.3 From dc4b789acb2e6737dd6ed5721b3efbde1a2be14f Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:11:59 +0100 Subject: Move skills.cc function declarations to skills.hpp --- src/cmd5.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 25752331..e2cdbd95 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -1,7 +1,3 @@ -/* File: cmd5.c */ - -/* Purpose: Class commands */ - /* * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke * @@ -10,9 +6,9 @@ * included in all such copies. */ - #include "angband.h" #include "corrupt.hpp" +#include "skills.hpp" #include "spell_type.hpp" #include "spells5.hpp" #include "quark.h" -- cgit v1.2.3 From 63fae54381d0898503c5dc7f4dcfabc125c04807 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:11:59 +0100 Subject: Move xtra1.cc function declarations to separate header Make a couple of functions private to the module while we're at it. --- src/cmd5.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index e2cdbd95..88939a67 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -12,6 +12,7 @@ #include "spell_type.hpp" #include "spells5.hpp" #include "quark.h" +#include "xtra1.hpp" #include -- cgit v1.2.3 From 5ef53fee463b7f93b8b890ed8e6ff0db778bd596 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:11:59 +0100 Subject: Move xtra2.cc functions to separate header Remove some functions and make others static while we're at it. --- src/cmd5.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 88939a67..aaedc465 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -13,6 +13,7 @@ #include "spells5.hpp" #include "quark.h" #include "xtra1.hpp" +#include "xtra2.hpp" #include @@ -135,7 +136,7 @@ void do_cmd_browse(void) do_cmd_browse_aux(o_ptr); } -void do_poly_wounds(void) +static void do_poly_wounds() { /* Changed to always provide at least _some_ healing */ s16b wounds = p_ptr->cut; -- cgit v1.2.3 From c98d4f1a479f1d4a5e74e8107e73949938c82709 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:12:00 +0100 Subject: Remove dead code --- src/cmd5.cc | 219 ------------------------------------------------------------ 1 file changed, 219 deletions(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index aaedc465..0f567a5b 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -581,225 +581,6 @@ void shriek_effect() } } - -/* - * Like all the random effect codes, this is *ugly*, - * and there is not a single line of comment, so I can't tell - * some fall throughs are really intended. Well, I know it's - * intended to be bizarre :) -- pelpel - */ -void wild_magic(int spell) -{ - int counter = 0; - int type = SUMMON_BIZARRE1 - 1 + randint(6); - - if (type < SUMMON_BIZARRE1) type = SUMMON_BIZARRE1; - else if (type > SUMMON_BIZARRE6) type = SUMMON_BIZARRE6; - - switch (randint(spell) + randint(8) + 1) - { - case 1: - case 2: - case 3: - { - teleport_player(10); - - break; - } - - case 4: - case 5: - case 6: - { - teleport_player(100); - - break; - } - - case 7: - case 8: - { - teleport_player(200); - - break; - } - - case 9: - case 10: - case 11: - { - unlite_area(10, 3); - - break; - } - - case 12: - case 13: - case 14: - { - lite_area(damroll(2, 3), 2); - - break; - } - - case 15: - { - destroy_doors_touch(); - - break; - } - - case 16: - case 17: - { - wall_breaker(); - - /* I don't think this is a fall through -- pelpel */ - break; - } - - case 18: - { - sleep_monsters_touch(); - - break; - } - - case 19: - case 20: - { - trap_creation(); - - break; - } - - case 21: - case 22: - { - door_creation(); - - break; - } - - case 23: - case 24: - case 25: - { - aggravate_monsters(1); - - break; - } - - case 26: - { - /* Prevent destruction of quest levels and town */ - if (!is_quest(dun_level) && dun_level) - earthquake(p_ptr->py, p_ptr->px, 5); - - break; - } - - case 27: - case 28: - { - break; - } - - case 29: - case 30: - { - apply_disenchant(0); - - break; - } - - case 31: - { - lose_all_info(); - - break; - } - - case 32: - { - fire_ball(GF_CHAOS, 0, spell + 5, 1 + (spell / 10)); - - break; - } - - case 33: - { - wall_stone(p_ptr->py, p_ptr->px); - - break; - } - - case 34: - case 35: - { - while (counter++ < 8) - { - (void) summon_specific(p_ptr->py, p_ptr->px, (dun_level * 3) / 2, type); - } - - break; - } - - case 36: - case 37: - { - activate_hi_summon(); - - break; - } - - case 38: - { - summon_cyber(); - - /* I don't think this is a fall through -- pelpel */ - break; - } - - default: - { - activate_ty_curse(); - } - } - - return; -} - - -/* - * Hack -- Determine if the player is wearing an artefact ring - * specified by art_type, that should be an index into a_info - */ -bool_ check_ring(int art_type) -{ - int i; - - - /* We are only interested in ring slots */ - i = INVEN_RING; - - /* Scan the list of rings until we reach the end */ - while (p_ptr->body_parts[i - INVEN_WIELD] == INVEN_RING) - { - /* Found the ring we were looking for */ - if (p_ptr->inventory[i].k_idx && (p_ptr->inventory[i].name1 == art_type)) - { - return (TRUE); - } - - /* Next item */ - i++; - } - - /* Found nothing */ - return (FALSE); -} - /* * Return the symbiote's name or description. */ -- cgit v1.2.3 From 21bbf94c159d161058282696630e0e0431917e92 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:12:00 +0100 Subject: Move birth.cc function declarations to separate header We leave the no_begin_screen variable because it needs to be accessed by non-C++ code. --- src/cmd5.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 0f567a5b..97e972d0 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -7,6 +7,7 @@ */ #include "angband.h" +#include "birth.hpp" #include "corrupt.hpp" #include "skills.hpp" #include "spell_type.hpp" -- cgit v1.2.3 From fe6ebd4af16244a02e16eb095181c0d8d5c56858 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:12:00 +0100 Subject: Move cave.cc function declarations to separate header --- src/cmd5.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 97e972d0..c5cbedc7 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -8,6 +8,7 @@ #include "angband.h" #include "birth.hpp" +#include "cave.hpp" #include "corrupt.hpp" #include "skills.hpp" #include "spell_type.hpp" -- cgit v1.2.3 From 6cffbd70646ee66c3b2a2a2fd7fd35c23d88b93e Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:12:00 +0100 Subject: Move cmd5.cc function declarations to separate header file Make a few of functions static, remove dead code and fix a few stray declarations while we're at it. --- src/cmd5.cc | 239 ++++++++++++++++++------------------------------------------ 1 file changed, 69 insertions(+), 170 deletions(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index c5cbedc7..2736aa5b 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -6,6 +6,8 @@ * included in all such copies. */ +#include "cmd5.hpp" + #include "angband.h" #include "birth.hpp" #include "cave.hpp" @@ -14,6 +16,7 @@ #include "spell_type.hpp" #include "spells5.hpp" #include "quark.h" +#include "wizard2.hpp" #include "xtra1.hpp" #include "xtra2.hpp" @@ -22,7 +25,7 @@ /* Maximum number of tries for teleporting */ #define MAX_TRIES 300 -bool_ is_school_book(object_type *o_ptr) +static bool_ is_school_book(object_type *o_ptr) { if (o_ptr->tval == TV_BOOK) { @@ -96,6 +99,71 @@ bool_ is_magestaff() return (FALSE); } + +static void browse_school_spell(int book, int pval, object_type *o_ptr) +{ + int i; + int num = 0, where = 1; + int ask; + char choice; + char out_val[160]; + + /* Show choices */ + window_stuff(); + + num = school_book_length(book); + + /* Build a prompt (accept all spells) */ + strnfmt(out_val, 78, "(Spells %c-%c, ESC=exit) cast which spell? ", + I2A(0), I2A(num - 1)); + + /* Save the screen */ + character_icky = TRUE; + Term_save(); + + /* Display a list of spells */ + where = print_book(book, pval, o_ptr); + + /* Get a spell from the user */ + while (get_com(out_val, &choice)) + { + /* Display a list of spells */ + where = print_book(book, pval, o_ptr); + + /* Note verify */ + ask = (isupper(choice)); + + /* Lowercase */ + if (ask) choice = tolower(choice); + + /* Extract request */ + i = (islower(choice) ? A2I(choice) : -1); + + /* Totally Illegal */ + if ((i < 0) || (i >= num)) + { + bell(); + continue; + } + + /* Restore the screen */ + Term_load(); + + /* Display a list of spells */ + where = print_book(book, pval, o_ptr); + print_spell_desc(spell_x(book, pval, i), where); + } + + + /* Restore the screen */ + Term_load(); + character_icky = FALSE; + + /* Show choices */ + window_stuff(); +} + + /* * Peruse the spells/prayers in a book * @@ -344,112 +412,6 @@ void do_poly_self(void) } } - -/* - * Brand the current weapon - */ -void brand_weapon(int brand_type) -{ - object_type *o_ptr; - - cptr act = NULL; - - char o_name[80]; - - - o_ptr = &p_ptr->inventory[INVEN_WIELD]; - - /* - * You can never modify artifacts / ego-items - * You can never modify cursed items - * - * TY: You _can_ modify broken items (if you're silly enough) - */ - if (!o_ptr->k_idx || artifact_p(o_ptr) || ego_item_p(o_ptr) || - o_ptr->art_name || cursed_p(o_ptr)) - { - if (flush_failure) flush(); - - msg_print("The Branding failed."); - - return; - } - - - /* Save the old name */ - object_desc(o_name, o_ptr, FALSE, 0); - - switch (brand_type) - { - case 6: - { - act = "glows with godly power."; - o_ptr->name2 = EGO_BLESS_BLADE; - o_ptr->pval = randint(4); - - break; - } - case 5: - { - act = "seems very powerful."; - o_ptr->name2 = EGO_EARTHQUAKES; - o_ptr->pval = randint(3); - - break; - } - case 4: - { - act = "seems very unstable now."; - o_ptr->name2 = EGO_DRAGON; - o_ptr->pval = randint(2); - - break; - } - case 3: - { - act = "thirsts for blood!"; - o_ptr->name2 = EGO_VAMPIRIC; - - break; - } - case 2: - { - act = "is coated with poison."; - o_ptr->name2 = EGO_BRAND_POIS; - - break; - } - case 1: - { - act = "is engulfed in raw chaos!"; - o_ptr->name2 = EGO_CHAOTIC; - - break; - } - default: - { - if (rand_int(100) < 25) - { - act = "is covered in a fiery shield!"; - o_ptr->name2 = EGO_BRAND_FIRE; - } - else - { - act = "glows deep, icy blue!"; - o_ptr->name2 = EGO_BRAND_COLD; - } - } - } - - /* Apply the ego */ - apply_magic(o_ptr, dun_level, FALSE, FALSE, FALSE); - o_ptr->discount = 100; - - msg_format("Your %s %s", o_name, act); - - enchant(o_ptr, rand_int(3) + 4, ENCH_TOHIT | ENCH_TODAM); -} - /* * Fetch an item (teleport it right underneath the caster) */ @@ -2153,69 +2115,6 @@ void cast_school_spell() } } -void browse_school_spell(int book, int pval, object_type *o_ptr) -{ - int i; - int num = 0, where = 1; - int ask; - char choice; - char out_val[160]; - - /* Show choices */ - window_stuff(); - - num = school_book_length(book); - - /* Build a prompt (accept all spells) */ - strnfmt(out_val, 78, "(Spells %c-%c, ESC=exit) cast which spell? ", - I2A(0), I2A(num - 1)); - - /* Save the screen */ - character_icky = TRUE; - Term_save(); - - /* Display a list of spells */ - where = print_book(book, pval, o_ptr); - - /* Get a spell from the user */ - while (get_com(out_val, &choice)) - { - /* Display a list of spells */ - where = print_book(book, pval, o_ptr); - - /* Note verify */ - ask = (isupper(choice)); - - /* Lowercase */ - if (ask) choice = tolower(choice); - - /* Extract request */ - i = (islower(choice) ? A2I(choice) : -1); - - /* Totally Illegal */ - if ((i < 0) || (i >= num)) - { - bell(); - continue; - } - - /* Restore the screen */ - Term_load(); - - /* Display a list of spells */ - where = print_book(book, pval, o_ptr); - print_spell_desc(spell_x(book, pval, i), where); - } - - - /* Restore the screen */ - Term_load(); - character_icky = FALSE; - - /* Show choices */ - window_stuff(); -} - /* Can it contains a schooled spell ? */ static bool_ hook_school_can_spellable(object_type *o_ptr) { -- cgit v1.2.3 From 901657b0c61ab16cceaef875d3ecd0b9f2bbbc5b Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:12:01 +0100 Subject: Split spells1.cc declarations to separate header file Make a couple of the functions static while we're at it --- src/cmd5.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 2736aa5b..c475fff3 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -14,6 +14,7 @@ #include "corrupt.hpp" #include "skills.hpp" #include "spell_type.hpp" +#include "spells1.hpp" #include "spells5.hpp" #include "quark.h" #include "wizard2.hpp" -- cgit v1.2.3 From 22d802ecbdbee5b06d32d1643af01744689c8b87 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:12:01 +0100 Subject: Split spells2.cc function declarations to separate header file --- src/cmd5.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index c475fff3..b58df8f0 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -15,6 +15,7 @@ #include "skills.hpp" #include "spell_type.hpp" #include "spells1.hpp" +#include "spells2.hpp" #include "spells5.hpp" #include "quark.h" #include "wizard2.hpp" -- cgit v1.2.3 From 0f610b77f2016ca80b18fdfb7a0bdd6eeb804743 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:12:01 +0100 Subject: Split spells4.cc declarations into separate header file --- src/cmd5.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index b58df8f0..93f29a99 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -16,6 +16,7 @@ #include "spell_type.hpp" #include "spells1.hpp" #include "spells2.hpp" +#include "spells4.hpp" #include "spells5.hpp" #include "quark.h" #include "wizard2.hpp" -- cgit v1.2.3 From 37ac44add61e4547507770017dcb85b53c20acb5 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Mon, 23 Feb 2015 09:12:01 +0100 Subject: Split util.cc function declarations into separate header files We need one .h file and one .hpp since some of the functions are being called from plain C code. --- src/cmd5.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 93f29a99..b61231e0 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -18,6 +18,8 @@ #include "spells2.hpp" #include "spells4.hpp" #include "spells5.hpp" +#include "util.hpp" +#include "util.h" #include "quark.h" #include "wizard2.hpp" #include "xtra1.hpp" -- cgit v1.2.3 From d379c47aaec011921c1d09140ee1098a7053b5b6 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Sat, 7 Mar 2015 16:55:40 +0100 Subject: Split monster2.cc declarations into separate header --- src/cmd5.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index b61231e0..15f80218 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -12,6 +12,7 @@ #include "birth.hpp" #include "cave.hpp" #include "corrupt.hpp" +#include "monster2.hpp" #include "skills.hpp" #include "spell_type.hpp" #include "spells1.hpp" -- cgit v1.2.3 From cfc0a04155eda35a4fe80ef72fd2b0f9eb10856b Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Sat, 7 Mar 2015 16:55:41 +0100 Subject: Split object*.cc declarations into separate header files --- src/cmd5.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 15f80218..ab103ff2 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -13,6 +13,8 @@ #include "cave.hpp" #include "corrupt.hpp" #include "monster2.hpp" +#include "object1.hpp" +#include "object2.hpp" #include "skills.hpp" #include "spell_type.hpp" #include "spells1.hpp" -- cgit v1.2.3 From 05f1835fd9ec10fa3dd3c9962605e889ec0fc698 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Sat, 7 Mar 2015 16:55:41 +0100 Subject: Move lua_bind.cc declarations to separate header file --- src/cmd5.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index ab103ff2..43357cef 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -12,6 +12,7 @@ #include "birth.hpp" #include "cave.hpp" #include "corrupt.hpp" +#include "lua_bind.hpp" #include "monster2.hpp" #include "object1.hpp" #include "object2.hpp" -- cgit v1.2.3 From f93c700dc8320da438ad46b59b2541e29d9b6d68 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Sat, 7 Mar 2015 16:55:42 +0100 Subject: Split tables.cc declarations into separate header files --- src/cmd5.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 43357cef..2725f4ea 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -22,6 +22,7 @@ #include "spells2.hpp" #include "spells4.hpp" #include "spells5.hpp" +#include "tables.hpp" #include "util.hpp" #include "util.h" #include "quark.h" -- cgit v1.2.3 From 6f612c6e6cf9b20c00fd2f515d3694d2b7f7f444 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Sat, 7 Mar 2015 16:55:42 +0100 Subject: Split variables.cc declarations to separate header files - Can now remove externs.h. Yay! - Put a stray option variable into its rightful place in options.hpp --- src/cmd5.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 2725f4ea..81e909f3 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -25,6 +25,8 @@ #include "tables.hpp" #include "util.hpp" #include "util.h" +#include "variable.h" +#include "variable.hpp" #include "quark.h" #include "wizard2.hpp" #include "xtra1.hpp" -- cgit v1.2.3 From c17c9486a22ce9f2160b2d2ad559d9a19e453f83 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Sun, 22 Mar 2015 15:22:02 +0100 Subject: Rename miscellaneous .h headers to .hpp --- src/cmd5.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 81e909f3..f57c6d62 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -27,7 +27,7 @@ #include "util.h" #include "variable.h" #include "variable.hpp" -#include "quark.h" +#include "quark.hpp" #include "wizard2.hpp" #include "xtra1.hpp" #include "xtra2.hpp" -- cgit v1.2.3 From 5d2af4a03a953e3891dae144076f8416faa5d8fd Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Sun, 22 Mar 2015 19:05:43 +0100 Subject: Limit is_spell_ok() parameter to pval instead of object_type --- src/cmd5.cc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index f57c6d62..aea592ab 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -1829,7 +1829,8 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost * Find a spell in any books/objects */ static int hack_force_spell = -1; -static object_type *hack_force_spell_obj = NULL; +static s32b hack_force_spell_pval = -1; + bool_ get_item_hook_find_spell(int *item) { int i, spell; @@ -1863,7 +1864,7 @@ bool_ get_item_hook_find_spell(int *item) { *item = i; hack_force_spell = spell; - hack_force_spell_obj = o_ptr; + hack_force_spell_pval = o_ptr->pval; return TRUE; } } @@ -1872,7 +1873,7 @@ bool_ get_item_hook_find_spell(int *item) { *item = i; hack_force_spell = spell; - hack_force_spell_obj = o_ptr; + hack_force_spell_pval = o_ptr->pval; return TRUE; } } @@ -1882,10 +1883,10 @@ bool_ get_item_hook_find_spell(int *item) /* * Is the spell castable? */ -bool_ is_ok_spell(s32b spell_idx, object_type *o_ptr) +bool_ is_ok_spell(s32b spell_idx, s32b pval) { spell_type *spell = spell_at(spell_idx); - assert(o_ptr != NULL); + // Calculate availability based on caster's skill level. s32b level; bool_ na; @@ -1896,7 +1897,7 @@ bool_ is_ok_spell(s32b spell_idx, object_type *o_ptr) } // Are we permitted to cast based on item pval? Only music // spells have non-zero minimum PVAL. - if (o_ptr->pval < spell_type_minimum_pval(spell)) + if (pval < spell_type_minimum_pval(spell)) { return FALSE; } @@ -1925,7 +1926,7 @@ s32b get_school_spell(cptr do_what, s16b force_book) u32b f1, f2, f3, f4, f5, esp; hack_force_spell = -1; - hack_force_spell_obj = NULL; + hack_force_spell_pval = -1; /* Ok do we need to ask for a book ? */ if (!force_book) @@ -2047,7 +2048,7 @@ s32b get_school_spell(cptr do_what, s16b force_book) spell = spell_x(sval, pval, i); /* Do we need to do some pre test */ - ok = is_ok_spell(spell, o_ptr); + ok = is_ok_spell(spell, o_ptr->pval); /* Require "okay" spells */ if (!ok) @@ -2068,7 +2069,7 @@ s32b get_school_spell(cptr do_what, s16b force_book) bool_ ok; /* Require "okay" spells */ - ok = is_ok_spell(hack_force_spell, hack_force_spell_obj); + ok = is_ok_spell(hack_force_spell, hack_force_spell_pval); if (ok) { flag = TRUE; -- cgit v1.2.3 From 9dc0b42341f8c7ffbf28c5c7386a19919cde5d47 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Tue, 14 Apr 2015 06:39:21 +0200 Subject: Rename "pval" parameter to "spell_idx" for clarity --- src/cmd5.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index aea592ab..4aaceda7 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -112,7 +112,7 @@ bool_ is_magestaff() } -static void browse_school_spell(int book, int pval, object_type *o_ptr) +static void browse_school_spell(int book, int spell_idx, object_type *o_ptr) { int i; int num = 0, where = 1; @@ -134,13 +134,13 @@ static void browse_school_spell(int book, int pval, object_type *o_ptr) Term_save(); /* Display a list of spells */ - where = print_book(book, pval, o_ptr); + where = print_book(book, spell_idx, o_ptr); /* Get a spell from the user */ while (get_com(out_val, &choice)) { /* Display a list of spells */ - where = print_book(book, pval, o_ptr); + where = print_book(book, spell_idx, o_ptr); /* Note verify */ ask = (isupper(choice)); @@ -162,8 +162,8 @@ static void browse_school_spell(int book, int pval, object_type *o_ptr) Term_load(); /* Display a list of spells */ - where = print_book(book, pval, o_ptr); - print_spell_desc(spell_x(book, pval, i), where); + where = print_book(book, spell_idx, o_ptr); + print_spell_desc(spell_x(book, spell_idx, i), where); } -- cgit v1.2.3 From 8b2be5adc24ffdecc7bb5d8ed08be12a7590bc46 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Wed, 15 Apr 2015 19:12:41 +0200 Subject: Rework object list filters to avoid global variables --- src/cmd5.cc | 173 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 86 insertions(+), 87 deletions(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 4aaceda7..3e45fe85 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -37,50 +37,40 @@ /* Maximum number of tries for teleporting */ #define MAX_TRIES 300 -static bool_ is_school_book(object_type *o_ptr) +static object_filter_t const &is_school_book() { - if (o_ptr->tval == TV_BOOK) - { - return TRUE; - } - else if (o_ptr->tval == TV_DAEMON_BOOK) - { - return TRUE; - } - else if (o_ptr->tval == TV_INSTRUMENT) - { - return TRUE; - } - else - { - return FALSE; - } + using namespace object_filter; + static auto instance = Or( + TVal(TV_BOOK), + TVal(TV_DAEMON_BOOK), + TVal(TV_INSTRUMENT)); + return instance; } /* Does it contains a schooled spell ? */ -static bool_ hook_school_spellable(object_type *o_ptr) +static object_filter_t const &hook_school_spellable() { - if (is_school_book(o_ptr)) - return TRUE; - else - { - u32b f1, f2, f3, f4, f5, esp; - - /* Extract object flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - if ((f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 != -1)) - return TRUE; - } - return FALSE; + using namespace object_filter; + static auto has_pval2 = + [=](object_type const *o_ptr) -> bool { + return (o_ptr->pval2 != -1); + }; + static auto instance = Or( + is_school_book(), + And( + HasFlag5(TR5_SPELL_CONTAIN), + has_pval2)); + return instance; } -/* Is it a book */ -bool_ item_tester_hook_browsable(object_type *o_ptr) +/* Is it a browsable for spells? */ +static object_filter_t const &item_tester_hook_browsable() { - if (hook_school_spellable(o_ptr)) return TRUE; - if (o_ptr->tval >= TV_BOOK) return TRUE; - return FALSE; + using namespace object_filter; + static auto instance = Or( + hook_school_spellable(), + TVal(TV_BOOK)); + return instance; } /* @@ -190,30 +180,31 @@ extern 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); - if (is_school_book(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) + { browse_school_spell(255, o_ptr->pval2, o_ptr); + } } void do_cmd_browse(void) { - int item; - - cptr q, s; - - object_type *o_ptr; - - /* Restrict choices to "useful" books */ - item_tester_hook = item_tester_hook_browsable; - /* Get an item */ - q = "Browse which book? "; - s = "You have no books that you can read."; - if (!get_item(&item, q, s, (USE_INVEN | USE_EQUIP | USE_FLOOR))) return; + int item; + if (!get_item(&item, + "Browse which book? ", + "You have no books that you can read.", + (USE_INVEN | USE_EQUIP | USE_FLOOR), + item_tester_hook_browsable())) + { + return; + } /* Get the item */ - o_ptr = get_object(item); + object_type *o_ptr = get_object(item); do_cmd_browse_aux(o_ptr); } @@ -1831,53 +1822,56 @@ int use_symbiotic_power(int r_idx, bool_ great, bool_ only_number, bool_ no_cost static int hack_force_spell = -1; static s32b hack_force_spell_pval = -1; -bool_ get_item_hook_find_spell(int *item) +boost::optional get_item_hook_find_spell(object_filter_t const &) { - int i, spell; char buf[80]; - strcpy(buf, "Manathrust"); if (!get_string("Spell name? ", buf, 79)) - return FALSE; + { + return boost::none; + } - spell = find_spell(buf); - if (spell == -1) return FALSE; + int const spell = find_spell(buf); + if (spell == -1) + { + return boost::none; + } - for (i = 0; i < INVEN_TOTAL; i++) + for (int i = 0; i < INVEN_TOTAL; i++) { object_type *o_ptr = &p_ptr->inventory[i]; - u32b f1, f2, f3, f4, f5, esp; - /* Must we wield it ? */ + /* Extract object flags */ + u32b f1, f2, f3, f4, f5, esp; object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if ((wield_slot(o_ptr) != -1) && (i < INVEN_WIELD) && (f5 & TR5_WIELD_CAST)) continue; - /* Is it a non-book? */ - if (!is_school_book(o_ptr)) + /* Must we wield it to cast from it? */ + if ((wield_slot(o_ptr) != -1) && (i < INVEN_WIELD) && (f5 & TR5_WIELD_CAST)) { - u32b f1, f2, f3, f4, f5, esp; - - /* Extract object flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); + continue; + } + /* Is it a non-book? */ + if (!is_school_book()(o_ptr)) + { + /* Does it contain the appropriate spell? */ if ((f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 == spell)) { - *item = i; hack_force_spell = spell; hack_force_spell_pval = o_ptr->pval; - return TRUE; + return i; } } /* A random book ? */ else if (school_book_contains_spell(o_ptr->sval, spell)) { - *item = i; hack_force_spell = spell; hack_force_spell_pval = o_ptr->pval; - return TRUE; + return i; } } - return FALSE; + + return boost::none; } /* @@ -1918,8 +1912,6 @@ s32b get_school_spell(cptr do_what, s16b force_book) int ask; bool_ flag; char out_val[160]; - char buf2[40]; - char buf3[40]; object_type *o_ptr, forge; int tmp; int sval, pval; @@ -1931,11 +1923,20 @@ s32b get_school_spell(cptr do_what, s16b force_book) /* Ok do we need to ask for a book ? */ if (!force_book) { - get_item_extra_hook = get_item_hook_find_spell; - item_tester_hook = hook_school_spellable; + char buf2[40]; + char buf3[40]; sprintf(buf2, "You have no book to %s from", do_what); sprintf(buf3, "%s from which book?", do_what); - if (!get_item(&item, buf3, buf2, USE_INVEN | USE_EQUIP | USE_EXTRA )) return -1; + + if (!get_item(&item, + buf3, + buf2, + USE_INVEN | USE_EQUIP, + hook_school_spellable(), + get_item_hook_find_spell)) + { + return -1; + } /* Get the item */ o_ptr = get_object(item); @@ -1972,7 +1973,7 @@ s32b get_school_spell(cptr do_what, s16b force_book) spell = -1; /* Is it a random book, or something else ? */ - if (is_school_book(o_ptr)) + if (is_school_book()(o_ptr)) { sval = o_ptr->sval; pval = o_ptr->pval; @@ -2129,16 +2130,12 @@ void cast_school_spell() } /* Can it contains a schooled spell ? */ -static bool_ hook_school_can_spellable(object_type *o_ptr) +static bool hook_school_can_spellable(object_type const *o_ptr) { u32b f1, f2, f3, f4, f5, esp; - - /* Extract object flags */ object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - if ((f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 == -1)) - return TRUE; - return FALSE; + return ((f5 & TR5_SPELL_CONTAIN) && (o_ptr->pval2 == -1)); } /* @@ -2148,7 +2145,6 @@ void do_cmd_copy_spell() { int spell = get_school_spell("copy", 0); int item; - object_type *o_ptr; if (spell == -1) return; @@ -2159,9 +2155,12 @@ void do_cmd_copy_spell() return; } - item_tester_hook = hook_school_can_spellable; - if (!get_item(&item, "Copy to which object? ", "You have no object to copy to.", (USE_INVEN | USE_EQUIP))) return; - o_ptr = get_object(item); + if (!get_item(&item, + "Copy to which object? ", + "You have no object to copy to.", + (USE_INVEN | USE_EQUIP), + hook_school_can_spellable)) return; + object_type *o_ptr = get_object(item); msg_print("You copy the spell!"); o_ptr->pval2 = spell; -- cgit v1.2.3 From c8a270e51dc22f39ed048ab1cc609e6e456df58f Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Sun, 7 Jun 2015 17:49:09 +0200 Subject: Split types.h into separate header for each type --- src/cmd5.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 3e45fe85..bb0349a4 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -8,20 +8,27 @@ #include "cmd5.hpp" -#include "angband.h" #include "birth.hpp" #include "cave.hpp" +#include "cave_type.hpp" #include "corrupt.hpp" #include "lua_bind.hpp" #include "monster2.hpp" +#include "monster_race.hpp" #include "object1.hpp" #include "object2.hpp" +#include "object_type.hpp" +#include "player_class.hpp" +#include "player_race.hpp" +#include "player_race_mod.hpp" +#include "player_type.hpp" #include "skills.hpp" #include "spell_type.hpp" #include "spells1.hpp" #include "spells2.hpp" #include "spells4.hpp" #include "spells5.hpp" +#include "stats.hpp" #include "tables.hpp" #include "util.hpp" #include "util.h" -- cgit v1.2.3 From 6fa2f3919907b1075532fa333ba92976f6cd5a1d Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Sun, 7 Jun 2015 17:49:09 +0200 Subject: Add missing includes for new Boost version --- src/cmd5.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index bb0349a4..3fcabb09 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -39,6 +39,8 @@ #include "xtra1.hpp" #include "xtra2.hpp" +#include +#include #include /* Maximum number of tries for teleporting */ -- cgit v1.2.3 From c6196b25d119a10e79deedef26a73e0d5a021b0e Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Fri, 12 Jun 2015 06:27:05 +0200 Subject: Refactor cave_type and monster_type to use non-intrusive lists We use vectors of object indexes instead of embedding the list within object_type itself. --- src/cmd5.cc | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 3fcabb09..05483b91 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -429,27 +429,19 @@ void do_poly_self(void) */ void fetch(int dir, int wgt, bool_ require_los) { - int ty, tx, i; - - cave_type *c_ptr; - - object_type *o_ptr; - - char o_name[80]; - - /* Check to see if an object is already there */ - if (cave[p_ptr->py][p_ptr->px].o_idx) + if (!cave[p_ptr->py][p_ptr->px].o_idxs.empty()) { msg_print("You can't fetch when you're already standing on something."); return; } /* Use a target */ + cave_type *c_ptr = nullptr; if ((dir == 5) && target_okay()) { - tx = target_col; - ty = target_row; + int tx = target_col; + int ty = target_row; if (distance(p_ptr->py, p_ptr->px, ty, tx) > MAX_RANGE) { @@ -459,7 +451,7 @@ void fetch(int dir, int wgt, bool_ require_los) c_ptr = &cave[ty][tx]; - if (!c_ptr->o_idx) + if (c_ptr->o_idxs.empty()) { msg_print("There is no object at this place."); return; @@ -474,8 +466,8 @@ void fetch(int dir, int wgt, bool_ require_los) else { /* Use a direction */ - ty = p_ptr->py; /* Where to drop the item */ - tx = p_ptr->px; + int ty = p_ptr->py; /* Where to drop the item */ + int tx = p_ptr->px; while (1) { @@ -486,12 +478,17 @@ void fetch(int dir, int wgt, bool_ require_los) if ((distance(p_ptr->py, p_ptr->px, ty, tx) > MAX_RANGE) || !cave_floor_bold(ty, tx)) return; - if (c_ptr->o_idx) break; + if (!c_ptr->o_idxs.empty()) break; } } - o_ptr = &o_list[c_ptr->o_idx]; + assert(c_ptr != nullptr); + assert(!c_ptr->o_idxs.empty()); + + /* Pick object from the list */ + auto o_idx = c_ptr->o_idxs.front(); + object_type *o_ptr = &o_list[o_idx]; if (o_ptr->weight > wgt) { /* Too heavy to 'fetch' */ @@ -499,13 +496,16 @@ void fetch(int dir, int wgt, bool_ require_los) return; } - i = c_ptr->o_idx; - c_ptr->o_idx = o_ptr->next_o_idx; - cave[p_ptr->py][p_ptr->px].o_idx = i; /* 'move' it */ - o_ptr->next_o_idx = 0; + /* Move the object between the lists */ + c_ptr->o_idxs.erase(c_ptr->o_idxs.begin()); // Remove + cave[p_ptr->py][p_ptr->px].o_idxs.push_back(o_idx); // Add + + /* Update object's location */ o_ptr->iy = p_ptr->py; o_ptr->ix = p_ptr->px; + /* Feedback */ + char o_name[80]; object_desc(o_name, o_ptr, TRUE, 0); msg_format("%^s flies through the air to your feet.", o_name); -- cgit v1.2.3 From 18e52d9a037ebb751312d6a2632383135321763f Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Fri, 11 Dec 2015 08:09:30 +0100 Subject: Remove redundant assignments to "where" in browse_school_spell() --- src/cmd5.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 05483b91..e12d62c5 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -114,7 +114,7 @@ bool_ is_magestaff() static void browse_school_spell(int book, int spell_idx, object_type *o_ptr) { int i; - int num = 0, where = 1; + int num = 0; int ask; char choice; char out_val[160]; @@ -133,13 +133,13 @@ static void browse_school_spell(int book, int spell_idx, object_type *o_ptr) Term_save(); /* Display a list of spells */ - where = print_book(book, spell_idx, o_ptr); + print_book(book, spell_idx, o_ptr); /* Get a spell from the user */ while (get_com(out_val, &choice)) { /* Display a list of spells */ - where = print_book(book, spell_idx, o_ptr); + print_book(book, spell_idx, o_ptr); /* Note verify */ ask = (isupper(choice)); @@ -161,7 +161,7 @@ static void browse_school_spell(int book, int spell_idx, object_type *o_ptr) Term_load(); /* Display a list of spells */ - where = print_book(book, spell_idx, o_ptr); + auto where = print_book(book, spell_idx, o_ptr); print_spell_desc(spell_x(book, spell_idx, i), where); } -- cgit v1.2.3 From 9f6f4a36d87c1334437debd9f48f3de27a747dce Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Fri, 11 Dec 2015 08:09:30 +0100 Subject: Move print_book() to cmd5.cc and make it static --- src/cmd5.cc | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index e12d62c5..2603b9a8 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -22,6 +22,7 @@ #include "player_race.hpp" #include "player_race_mod.hpp" #include "player_type.hpp" +#include "school_book.hpp" #include "skills.hpp" #include "spell_type.hpp" #include "spells1.hpp" @@ -111,6 +112,41 @@ bool_ is_magestaff() } +static int print_book(s16b sval, s32b spell_idx, object_type *obj) +{ + int y = 2; + int i; + + random_book_setup(sval, spell_idx); + + school_book *school_book = school_books_at(sval); + + /* Parse all spells */ + i = 0; + for (auto spell_idx : school_book->spell_idxs) + { + byte color = TERM_L_DARK; + bool_ is_ok; + char label[8]; + + is_ok = is_ok_spell(spell_idx, obj->pval); + 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; +} + + + static void browse_school_spell(int book, int spell_idx, object_type *o_ptr) { int i; -- cgit v1.2.3 From 97bcf1bc612d9920390c885b8dcea0b0cda6f246 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Fri, 11 Dec 2015 08:09:30 +0100 Subject: Migrate z-rand.c to C++ - Include explicitly instead of via angband.h - Change to regular functions instead of macros. --- src/cmd5.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/cmd5.cc') diff --git a/src/cmd5.cc b/src/cmd5.cc index 2603b9a8..a1dd5cbf 100644 --- a/src/cmd5.cc +++ b/src/cmd5.cc @@ -39,6 +39,7 @@ #include "wizard2.hpp" #include "xtra1.hpp" #include "xtra2.hpp" +#include "z-rand.hpp" #include #include -- cgit v1.2.3