summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBardur Arantsson <bardur@scientician.net>2015-04-15 19:12:41 +0200
committerBardur Arantsson <bardur@scientician.net>2015-04-15 19:12:41 +0200
commit8b2be5adc24ffdecc7bb5d8ed08be12a7590bc46 (patch)
tree52f137bd6e83baa12ad60b50c4710d04a7559cb2
parentedede30a361f34d8c2f1d5de45adeac9392f41b9 (diff)
Rework object list filters to avoid global variables
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/bldg.cc36
-rw-r--r--src/cmd1.cc32
-rw-r--r--src/cmd1.hpp2
-rw-r--r--src/cmd2.cc93
-rw-r--r--src/cmd3.cc271
-rw-r--r--src/cmd5.cc173
-rw-r--r--src/cmd6.cc480
-rw-r--r--src/cmd7.cc348
-rw-r--r--src/defines.h1
-rw-r--r--src/files.cc6
-rw-r--r--src/object1.cc171
-rw-r--r--src/object1.hpp14
-rw-r--r--src/object2.cc6
-rw-r--r--src/object_filter.cc97
-rw-r--r--src/object_filter.hpp97
-rw-r--r--src/powers.cc9
-rw-r--r--src/q_bounty.cc15
-rw-r--r--src/q_fireprof.cc49
-rw-r--r--src/randart.cc24
-rw-r--r--src/spells2.cc275
-rw-r--r--src/spells2.hpp5
-rw-r--r--src/spells3.cc128
-rw-r--r--src/store.cc78
-rw-r--r--src/traps.cc79
-rw-r--r--src/variable.cc22
-rw-r--r--src/variable.hpp3
-rw-r--r--src/wizard2.cc33
28 files changed, 1237 insertions, 1311 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 346677b7..06257593 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -17,6 +17,7 @@ SET(SRCS_COMMON
q_troll.cc q_hobbit.cc q_thief.cc q_ultrae.cc q_ultrag.cc
q_one.cc q_main.cc q_rand.cc quest.cc
object1.cc object2.cc randart.cc squeltch.cc traps.cc
+ object_filter.cc
monster1.cc monster2.cc monster3.cc
xtra1.cc xtra2.cc skills.cc powers.cc gods.cc
spells1.cc spells2.cc spells3.cc spells4.cc spells5.cc spells6.cc
diff --git a/src/bldg.cc b/src/bldg.cc
index 0c62a826..640c04f5 100644
--- a/src/bldg.cc
+++ b/src/bldg.cc
@@ -887,7 +887,7 @@ static void list_weapon(object_type *o_ptr, int row, int col)
/*
* Select melee weapons
*/
-static bool_ item_tester_hook_melee_weapon(object_type *o_ptr)
+static bool item_tester_hook_melee_weapon(object_type const *o_ptr)
{
return (wield_slot(o_ptr) == INVEN_WIELD);
}
@@ -897,34 +897,28 @@ static bool_ item_tester_hook_melee_weapon(object_type *o_ptr)
*/
static bool_ compare_weapons(void)
{
- int item, item2, i;
+ int item, i;
object_type *o1_ptr, *o2_ptr, *orig_ptr;
- object_type *i_ptr;
-
- cptr q, s;
-
-
clear_bldg(6, 18);
o1_ptr = NULL;
o2_ptr = NULL;
- i_ptr = NULL;
/* Store copy of original wielded weapon in pack slot */
- i_ptr = &p_ptr->inventory[INVEN_WIELD];
+ object_type *i_ptr = &p_ptr->inventory[INVEN_WIELD];
orig_ptr = &p_ptr->inventory[INVEN_PACK];
object_copy(orig_ptr, i_ptr);
i = 6;
- /* Get first weapon */
- /* Restrict choices to meele weapons */
- item_tester_hook = item_tester_hook_melee_weapon;
- q = "What is your first melee weapon? ";
- s = "You have nothing to compare.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN)))
+ /* Get first weapon */
+ if (!get_item(&item,
+ "What is your first melee weapon? ",
+ "You have nothing to compare.",
+ (USE_EQUIP | USE_INVEN),
+ item_tester_hook_melee_weapon))
{
object_wipe(orig_ptr);
return (FALSE);
@@ -935,12 +929,12 @@ static bool_ compare_weapons(void)
o1_ptr = &p_ptr->inventory[item];
/* Get second weapon */
- /* Restrict choices to melee weapons */
- item_tester_hook = item_tester_hook_melee_weapon;
-
- q = "What is your second melee weapon? ";
- s = "You have nothing to compare.";
- if (!get_item(&item2, q, s, (USE_EQUIP | USE_INVEN)))
+ int item2;
+ if (!get_item(&item2,
+ "What is your second melee weapon? ",
+ "You have nothing to compare.",
+ (USE_EQUIP | USE_INVEN),
+ item_tester_hook_melee_weapon))
{
object_wipe(orig_ptr);
return (FALSE);
diff --git a/src/cmd1.cc b/src/cmd1.cc
index f387fc26..b7b7ef5c 100644
--- a/src/cmd1.cc
+++ b/src/cmd1.cc
@@ -4870,35 +4870,31 @@ void do_cmd_pet(void)
/*
* Incarnate into a body
*/
-bool_ do_cmd_integrate_body()
+void do_cmd_integrate_body()
{
- cptr q, s;
-
- int item;
-
- object_type *o_ptr;
-
-
if (!p_ptr->disembodied)
{
msg_print("You are already in a body.");
- return FALSE;
+ return;
}
- /* Restrict choices to monsters */
- item_tester_tval = TV_CORPSE;
-
/* Get an item */
- q = "Incarnate in which body? ";
- s = "You have no corpse to incarnate in.";
- if (!get_item(&item, q, s, (USE_FLOOR))) return FALSE;
+ int item;
+ if (!get_item(&item,
+ "Incarnate in which body? ",
+ "You have no corpse to incarnate in.",
+ (USE_FLOOR),
+ object_filter::TVal(TV_CORPSE)))
+ {
+ return;
+ }
- o_ptr = &o_list[0 - item];
+ object_type *o_ptr = &o_list[0 - item];
if (o_ptr->sval != SV_CORPSE_CORPSE)
{
msg_print("You must select a corpse.");
- return FALSE;
+ return;
}
p_ptr->body_monster = o_ptr->pval2;
@@ -4912,8 +4908,6 @@ bool_ do_cmd_integrate_body()
p_ptr->wraith_form = FALSE;
p_ptr->disembodied = FALSE;
do_cmd_redraw();
-
- return TRUE;
}
/*
diff --git a/src/cmd1.hpp b/src/cmd1.hpp
index 5ff58a75..0e530033 100644
--- a/src/cmd1.hpp
+++ b/src/cmd1.hpp
@@ -16,7 +16,7 @@ extern void move_player(int dir, int do_pickup, bool_ disarm);
extern void move_player_aux(int dir, int do_pickup, int run, bool_ disarm);
extern void run_step(int dir);
extern void do_cmd_pet(void);
-extern bool_ do_cmd_integrate_body(void);
+extern void do_cmd_integrate_body();
extern bool_ do_cmd_leave_body(bool_ drop_body);
extern bool_ execute_inscription(byte i, byte y, byte x);
extern void do_cmd_engrave(void);
diff --git a/src/cmd2.cc b/src/cmd2.cc
index 41b9f54c..b516fccc 100644
--- a/src/cmd2.cc
+++ b/src/cmd2.cc
@@ -3130,8 +3130,6 @@ void do_cmd_fire(void)
char o_name[80];
- cptr q, s;
-
int msec = delay_factor * delay_factor * delay_factor;
@@ -3160,14 +3158,15 @@ void do_cmd_fire(void)
/* If nothing correct try to choose from the backpack */
if ((p_ptr->tval_ammo != o_ptr->tval) || (!o_ptr->k_idx))
{
- /* Require proper missile */
- item_tester_tval = p_ptr->tval_ammo;
-
/* Get an item */
- q = "Your quiver is empty. Fire which item? ";
- s = "You have nothing to fire.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
-
+ if (!get_item(&item,
+ "Your quiver is empty. Fire which item? ",
+ "You have nothing to fire.",
+ (USE_INVEN | USE_FLOOR),
+ object_filter::TVal(p_ptr->tval_ammo)))
+ {
+ return;
+ }
/* Access the item */
o_ptr = get_object(item);
@@ -3539,7 +3538,7 @@ void do_cmd_fire(void)
*/
void do_cmd_throw(void)
{
- int dir, item;
+ int dir;
s32b special = 0;
@@ -3558,8 +3557,6 @@ void do_cmd_throw(void)
object_type *q_ptr;
- object_type *o_ptr;
-
bool_ hit_body = FALSE;
bool_ hit_wall = FALSE;
@@ -3572,20 +3569,20 @@ void do_cmd_throw(void)
int msec = delay_factor * delay_factor * delay_factor;
- cptr q, s;
-
- u32b f1, f2, f3, f4, f5, esp;
-
-
/* Get an item */
- q = "Throw which item? ";
- s = "You have nothing to throw.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Throw which item? ",
+ "You have nothing to throw.",
+ (USE_INVEN | USE_FLOOR)))
+ {
+ return;
+ }
/* Access the item */
- o_ptr = get_object(item);
-
+ object_type *o_ptr = get_object(item);
+ u32b f1, f2, f3, f4, f5, esp;
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
/* Hack - Cannot throw away 'no drop' cursed items */
@@ -4462,7 +4459,7 @@ void do_cmd_immovable_special(void)
}
/* Can we sacrifice it ? */
-static bool_ item_tester_hook_sacrifiable(object_type *o_ptr)
+static bool item_tester_hook_sacrificable(object_type const *o_ptr)
{
if (p_ptr->pgod == GOD_MELKOR)
{
@@ -4484,7 +4481,7 @@ static bool_ item_tester_hook_sacrifiable(object_type *o_ptr)
/*
* Is item eligible for sacrifice to Aule?
*/
-static bool_ item_tester_hook_sacrifice_aule(object_type *o_ptr)
+static bool item_tester_hook_sacrifice_aule(object_type const *o_ptr)
{
/* perhaps restrict this only to metal armour and weapons */
return (o_ptr->found == OBJ_FOUND_SELFMADE);
@@ -4497,11 +4494,11 @@ static void do_cmd_sacrifice_aule()
{
int item;
- item_tester_hook = item_tester_hook_sacrifice_aule;
if (!get_item(&item,
"Sacrifice which item? ",
"You have nothing to sacrifice.",
- USE_INVEN))
+ USE_INVEN,
+ item_tester_hook_sacrifice_aule))
{
return;
}
@@ -4583,15 +4580,18 @@ void do_cmd_sacrifice(void)
}
else
{
+ /* Get an item */
int item;
- object_type *o_ptr;
-
- /* Restrict choices to food */
- item_tester_hook = item_tester_hook_sacrifiable;
+ if (!get_item(&item,
+ "Sacrifice which item? ",
+ "You have nothing to sacrifice.",
+ (USE_INVEN),
+ item_tester_hook_sacrificable))
+ {
+ return;
+ }
- /* Get an item */
- if (!get_item(&item, "Sacrifice which item? ", "You have nothing to sacrifice.", (USE_INVEN))) return;
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Piety for corpses is based on monster level */
if (o_ptr->tval == TV_CORPSE)
@@ -4974,24 +4974,16 @@ void do_cmd_steal()
*/
void do_cmd_give()
{
- int dir, x, y;
-
- cave_type *c_ptr;
-
- cptr q, s;
-
- int item;
-
-
/* Get a "repeated" direction */
+ int dir;
if (!get_rep_dir(&dir)) return;
/* Get requested location */
- y = p_ptr->py + ddy[dir];
- x = p_ptr->px + ddx[dir];
+ int y = p_ptr->py + ddy[dir];
+ int x = p_ptr->px + ddx[dir];
/* Get requested grid */
- c_ptr = &cave[y][x];
+ cave_type *c_ptr = &cave[y][x];
/* No monster in the way */
if (c_ptr->m_idx == 0)
@@ -5001,9 +4993,14 @@ void do_cmd_give()
}
/* Get an item */
- q = "What item do you want to offer? ";
- s = "You have nothing to offer.";
- if (!get_item(&item, q, s, USE_INVEN)) return;
+ int item;
+ if (!get_item(&item,
+ "What item do you want to offer? ",
+ "You have nothing to offer.",
+ USE_INVEN))
+ {
+ return;
+ }
/* Process hooks if there are any */
hook_give_in in = { c_ptr->m_idx, item };
diff --git a/src/cmd3.cc b/src/cmd3.cc
index 2b69d288..529ec06b 100644
--- a/src/cmd3.cc
+++ b/src/cmd3.cc
@@ -47,16 +47,10 @@ void do_cmd_inven(void)
character_icky = TRUE;
Term_save();
- /* Hack -- show empty slots */
- item_tester_full = TRUE;
-
- /* Display the p_ptr->inventory */
- show_inven();
-
- /* Hack -- hide empty slots */
- item_tester_full = FALSE;
-
+ /* Show the inventory */
+ show_inven_full();
+ /* Show prompt */
{
s32b total_weight = calc_total_weight();
@@ -108,16 +102,10 @@ void do_cmd_equip(void)
character_icky = TRUE;
Term_save();
- /* Hack -- show empty slots */
- item_tester_full = TRUE;
-
/* Display the equipment */
- show_equip();
+ show_equip_full();
- /* Hack -- undo the hack above */
- item_tester_full = FALSE;
-
- /* Build a prompt */
+ /* Show prompt */
{
s32b total_weight = calc_total_weight();
@@ -158,7 +146,7 @@ void do_cmd_equip(void)
/*
* The "wearable" tester
*/
-static bool_ item_tester_hook_wear(object_type *o_ptr)
+static bool item_tester_hook_wear(object_type const *o_ptr)
{
u32b f1, f2, f3, f4, f5, esp;
int slot = wield_slot(o_ptr);
@@ -220,27 +208,27 @@ void do_cmd_wield(void)
object_type *q_ptr;
- object_type *o_ptr, *i_ptr;
+ object_type *i_ptr;
cptr act;
char o_name[80];
- cptr q, s;
-
u32b f1, f2, f3, f4, f5, esp;
- /* Restrict the choices */
- item_tester_hook = item_tester_hook_wear;
-
/* Get an item */
- q = "Wear/Wield which item? ";
- s = "You have nothing you can wear or wield.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Wear/Wield which item? ",
+ "You have nothing you can wear or wield.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_wear))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Check the slot */
slot = wield_slot(o_ptr);
@@ -464,20 +452,18 @@ void do_cmd_wield(void)
*/
void do_cmd_takeoff(void)
{
- int item;
-
- object_type *o_ptr;
-
- cptr q, s;
-
-
/* Get an item */
- q = "Take off which item? ";
- s = "You are not wearing anything to take off.";
- if (!get_item(&item, q, s, (USE_EQUIP))) return;
+ int item;
+ if (!get_item(&item,
+ "Take off which item? ",
+ "You are not wearing anything to take off.",
+ (USE_EQUIP)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Item is cursed */
if (cursed_p(o_ptr) && (!wizard))
@@ -508,23 +494,19 @@ void do_cmd_takeoff(void)
*/
void do_cmd_drop(void)
{
- int item, amt = 1;
-
- object_type *o_ptr;
-
- u32b f1, f2, f3, f4, f5, esp;
-
- cptr q, s;
-
-
/* Get an item */
- q = "Drop which item? ";
- s = "You have nothing to drop.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN))) return;
+ int item;
+ if (!get_item(&item,
+ "Drop which item? ",
+ "You have nothing to drop.",
+ (USE_EQUIP | USE_INVEN)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
-
+ object_type *o_ptr = get_object(item);
+ u32b f1, f2, f3, f4, f5, esp;
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
/* Can we drop */
@@ -555,8 +537,8 @@ void do_cmd_drop(void)
}
}
-
/* See how many items */
+ int amt = 1;
if (o_ptr->number > 1)
{
/* Get a quantity */
@@ -579,37 +561,33 @@ void do_cmd_drop(void)
*/
void do_cmd_destroy(void)
{
- int item, amt = 1;
-
int old_number;
bool_ force = FALSE;
- object_type *o_ptr;
-
char o_name[80];
char out_val[160];
- cptr q, s;
-
- u32b f1, f2, f3, f4, f5, esp;
-
-
/* Hack -- force destruction */
if (command_arg > 0) force = TRUE;
/* Get an item */
- q = "Destroy which item? ";
- s = "You have nothing to destroy.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_AUTO))) return;
+ int item;
+ if (!get_item(&item,
+ "Destroy which item? ",
+ "You have nothing to destroy.",
+ (USE_INVEN | USE_FLOOR | USE_AUTO)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
-
+ object_type *o_ptr = get_object(item);
/* See how many items */
+ int amt = 1;
if (o_ptr->number > 1)
{
/* Get a quantity */
@@ -637,6 +615,7 @@ void do_cmd_destroy(void)
/* Take no time, just like the automatizer */
energy_use = 0;
+ u32b f1, f2, f3, f4, f5, esp;
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
if ((f4 & TR4_CURSE_NO_DROP) && cursed_p(o_ptr))
@@ -712,24 +691,21 @@ void do_cmd_destroy(void)
*/
void do_cmd_observe(void)
{
- int item;
-
- object_type *o_ptr;
-
- char o_name[80];
-
- cptr q, s;
-
-
/* Get an item */
- q = "Examine which item? ";
- s = "You have nothing to examine.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Examine which item? ",
+ "You have nothing to examine.",
+ (USE_EQUIP | USE_INVEN | USE_FLOOR)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Description */
+ char o_name[80];
object_desc(o_name, o_ptr, TRUE, 3);
/* Describe */
@@ -747,20 +723,18 @@ void do_cmd_observe(void)
*/
void do_cmd_uninscribe(void)
{
- int item;
-
- object_type *o_ptr;
-
- cptr q, s;
-
-
/* Get an item */
- q = "Un-inscribe which item? ";
- s = "You have nothing to un-inscribe.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Un-inscribe which item? ",
+ "You have nothing to un-inscribe.",
+ (USE_EQUIP | USE_INVEN | USE_FLOOR)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Nothing to remove */
if (!o_ptr->note)
@@ -788,26 +762,21 @@ void do_cmd_uninscribe(void)
*/
void do_cmd_inscribe(void)
{
- int item;
-
- object_type *o_ptr;
-
- char o_name[80];
-
- char out_val[80];
-
- cptr q, s;
-
-
/* Get an item */
- q = "Inscribe which item? ";
- s = "You have nothing to inscribe.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Inscribe which item? ",
+ "You have nothing to inscribe.",
+ (USE_EQUIP | USE_INVEN | USE_FLOOR)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Describe the activity */
+ char o_name[80];
object_desc(o_name, o_ptr, TRUE, 3);
/* Message */
@@ -815,6 +784,7 @@ void do_cmd_inscribe(void)
msg_print(NULL);
/* Start with nothing */
+ char out_val[80];
strcpy(out_val, "");
/* Use old inscription */
@@ -843,17 +813,15 @@ void do_cmd_inscribe(void)
/*
* An "item_tester_hook" for refilling lanterns
*/
-static bool_ item_tester_refill_lantern(object_type *o_ptr)
+static object_filter_t const &item_tester_refill_lantern()
{
- /* Flasks of oil are okay */
- if (o_ptr->tval == TV_FLASK) return (TRUE);
-
- /* Lanterns are okay */
- if ((o_ptr->tval == TV_LITE) &&
- (o_ptr->sval == SV_LITE_LANTERN)) return (TRUE);
-
- /* Assume not okay */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance = Or(
+ TVal(TV_FLASK),
+ And(
+ TVal(TV_LITE),
+ SVal(SV_LITE_LANTERN)));
+ return instance;
}
@@ -862,30 +830,25 @@ static bool_ item_tester_refill_lantern(object_type *o_ptr)
*/
static void do_cmd_refill_lamp(void)
{
- int item;
-
- object_type *o_ptr;
- object_type *j_ptr;
-
- cptr q, s;
-
-
- /* Restrict the choices */
- item_tester_hook = item_tester_refill_lantern;
-
/* Get an item */
- q = "Refill with which flask? ";
- s = "You have no flasks of oil.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Refill with which flask? ",
+ "You have no flasks of oil.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_refill_lantern()))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Take a partial turn */
energy_use = 50;
/* Access the lantern */
- j_ptr = &p_ptr->inventory[INVEN_LITE];
+ object_type *j_ptr = &p_ptr->inventory[INVEN_LITE];
/* Refuel */
if (o_ptr->tval == TV_FLASK)
@@ -914,14 +877,14 @@ static void do_cmd_refill_lamp(void)
/*
* An "item_tester_hook" for refilling torches
*/
-static bool_ item_tester_refill_torch(object_type *o_ptr)
+static object_filter_t const &item_tester_refill_torch()
{
- /* Torches are okay */
- if ((o_ptr->tval == TV_LITE) &&
- (o_ptr->sval == SV_LITE_TORCH)) return (TRUE);
-
- /* Assume not okay */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance =
+ And(
+ TVal(TV_LITE),
+ SVal(SV_LITE_TORCH));
+ return instance;
}
@@ -930,31 +893,25 @@ static bool_ item_tester_refill_torch(object_type *o_ptr)
*/
static void do_cmd_refill_torch(void)
{
- int item;
-
- object_type *o_ptr;
-
- object_type *j_ptr;
-
- cptr q, s;
-
-
- /* Restrict the choices */
- item_tester_hook = item_tester_refill_torch;
-
/* Get an item */
- q = "Refuel with which torch? ";
- s = "You have no extra torches.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Refuel with which torch? ",
+ "You have no extra torches.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_refill_torch()))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Take a partial turn */
energy_use = 50;
/* Access the primary torch */
- j_ptr = &p_ptr->inventory[INVEN_LITE];
+ object_type *j_ptr = &p_ptr->inventory[INVEN_LITE];
/* Refuel */
j_ptr->timeout += o_ptr->timeout + 5;
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<int> 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;
diff --git a/src/cmd6.cc b/src/cmd6.cc
index c1d49c72..792dd9a6 100644
--- a/src/cmd6.cc
+++ b/src/cmd6.cc
@@ -37,8 +37,11 @@
#include "xtra1.hpp"
#include "xtra2.hpp"
+#include <boost/algorithm/string/predicate.hpp>
#include <cassert>
+using boost::algorithm::iequals;
+
/*
* Forward declare
*/
@@ -48,31 +51,41 @@ static bool_ activate_spell(object_type * o_ptr, byte choice);
/*
* General function to find an item by its name
*/
-cptr get_item_hook_find_obj_what;
-bool_ get_item_hook_find_obj(int *item)
+static select_by_name_t select_object_by_name(std::string const &prompt)
{
- int i;
- char buf[80];
- char buf2[100];
-
- strcpy(buf, "");
- if (!get_string(get_item_hook_find_obj_what, buf, 79))
- return FALSE;
-
- for (i = 0; i < INVEN_TOTAL; i++)
- {
- object_type *o_ptr = &p_ptr->inventory[i];
-
- if (!item_tester_okay(o_ptr)) continue;
-
- object_desc(buf2, o_ptr, -1, 0);
- if (!strcmp(buf, buf2))
+ return [=](object_filter_t const &filter) -> boost::optional<int> {
+ // Ask for the name of the object we want to select
+ char buf[80] = "";
+ if (!get_string(prompt.c_str(), buf, 79))
{
- *item = i;
- return TRUE;
+ return boost::none;
}
- }
- return FALSE;
+ // Named objects must be in the inventory
+ for (size_t i = 0; i < INVEN_TOTAL; i++)
+ {
+ object_type *o_ptr = get_object(i);
+ // Must have an actual item in the slot
+ if (!o_ptr->k_idx)
+ {
+ continue;
+ }
+ // Must pass the filter
+ if (!filter(o_ptr))
+ {
+ continue;
+ }
+ // Check against the name of the object
+ // ignoring case.
+ char buf2[100];
+ object_desc(buf2, o_ptr, -1, 0);
+ if (iequals(buf, buf2))
+ {
+ return i;
+ }
+ }
+ // No match
+ return boost::none;
+ };
}
@@ -933,13 +946,14 @@ static void corpse_effect(object_type *o_ptr, bool_ cutting)
/*
* Hook to determine if an object is eatable
*/
-static bool_ item_tester_hook_eatable(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_eatable()
{
- /* Foods and, well, corpses are edible */
- if ((o_ptr->tval == TV_FOOD) || (o_ptr->tval == TV_CORPSE)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance =
+ Or(
+ TVal(TV_FOOD),
+ TVal(TV_CORPSE));
+ return instance;
}
@@ -948,32 +962,28 @@ static bool_ item_tester_hook_eatable(object_type *o_ptr)
*/
void do_cmd_eat_food(void)
{
- int item, ident, lev, fval = 0;
+ int ident, lev, fval = 0;
- object_type *o_ptr;
object_type *q_ptr, forge;
monster_race *r_ptr;
- cptr q, s;
-
bool_ destroy = TRUE;
-
- /* Restrict choices to food */
- item_tester_hook = item_tester_hook_eatable;
-
- /* Set up the extra finder */
- get_item_hook_find_obj_what = "Food full name? ";
- get_item_extra_hook = get_item_hook_find_obj;
-
/* Get an item */
- q = "Eat which item? ";
- s = "You have nothing to eat.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return;
+ int item;
+ if (!get_item(&item,
+ "Eat which item? ",
+ "You have nothing to eat.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_eatable(),
+ select_object_by_name("Food full name? ")))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Sound */
sound(SOUND_EAT);
@@ -1517,29 +1527,20 @@ void do_cmd_cut_corpse(void)
{
int item, meat = 0, not_meat = 0;
- object_type *o_ptr;
-
- object_type *i_ptr;
-
- object_type object_type_body;
-
- monster_race *r_ptr;
-
- cptr q, s;
-
-
- /* Restrict choices to corpses */
- item_tester_tval = TV_CORPSE;
-
/* Get an item */
- q = "Hack up which corpse? ";
- s = "You have no corpses.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Hack up which corpse? ",
+ "You have no corpses.",
+ (USE_INVEN | USE_FLOOR),
+ object_filter::TVal(TV_CORPSE)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
- r_ptr = &r_info[o_ptr->pval2];
+ monster_race *r_ptr = &r_info[o_ptr->pval2];
if ((o_ptr->sval != SV_CORPSE_CORPSE) && (o_ptr->sval != SV_CORPSE_HEAD))
{
@@ -1593,7 +1594,8 @@ void do_cmd_cut_corpse(void)
corpse_effect(o_ptr, TRUE);
/* Get local object */
- i_ptr = &object_type_body;
+ object_type object_type_body;
+ object_type *i_ptr = &object_type_body;
/* Make some meat */
object_prep(i_ptr, lookup_kind(TV_CORPSE, SV_CORPSE_MEAT));
@@ -1624,32 +1626,27 @@ void do_cmd_cure_meat(void)
{
int item, num, cure;
- object_type *o_ptr;
-
object_type *i_ptr;
- cptr q, s;
-
-
- /* Restrict choices to corpses */
- item_tester_tval = TV_CORPSE;
- item_tester_hook = item_tester_hook_eatable;
-
/* Get some meat */
- q = "Cure which meat? ";
- s = "You have no meat to cure.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Cure which meat? ",
+ "You have no meat to cure.",
+ (USE_INVEN | USE_FLOOR),
+ object_filter::And(item_tester_hook_eatable(), object_filter::TVal(TV_CORPSE))))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
-
- /* Restrict choices to potions */
- item_tester_tval = TV_POTION;
+ object_type *o_ptr = get_object(item);
/* Get a potion */
- q = "Use which potion? ";
- s = "You have no potions to use.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Use which potion? ",
+ "You have no potions to use.",
+ (USE_INVEN | USE_FLOOR),
+ object_filter::TVal(TV_POTION))) return;
/* Get the item */
i_ptr = get_object(item);
@@ -1672,8 +1669,8 @@ void do_cmd_cure_meat(void)
/* Take a turn */
energy_use = 100;
- q = "You soak the meat.";
- s = "You soak the meat.";
+ cptr q = "You soak the meat.";
+ cptr s = "You soak the meat.";
switch (i_ptr->sval)
{
@@ -1735,8 +1732,14 @@ void do_cmd_cure_meat(void)
}
/* Message */
- if (object_known_p(i_ptr)) msg_print(q);
- else msg_print(s);
+ if (object_known_p(i_ptr))
+ {
+ msg_print(q);
+ }
+ else
+ {
+ msg_print(s);
+ }
/* The meat is already spoiling */
if (((o_ptr->sval == SV_CORPSE_MEAT) && (o_ptr->weight > o_ptr->pval)) ||
@@ -1758,12 +1761,13 @@ void do_cmd_cure_meat(void)
/*
* Hook to determine if an object is quaffable
*/
-static bool_ item_tester_hook_quaffable(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_quaffable()
{
- if ((o_ptr->tval == TV_POTION) || (o_ptr->tval == TV_POTION2)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance = Or(
+ TVal(TV_POTION),
+ TVal(TV_POTION2));
+ return instance;
}
@@ -2475,29 +2479,24 @@ static bool_ quaff_potion(int tval, int sval, int pval, int pval2)
*/
void do_cmd_quaff_potion(void)
{
- int item, ident, lev;
-
- object_type *o_ptr;
+ int ident, lev;
object_type *q_ptr, forge;
- cptr q, s;
-
-
- /* Restrict choices to potions */
- item_tester_hook = item_tester_hook_quaffable;
-
- /* Set up the extra finder */
- get_item_hook_find_obj_what = "Potion full name? ";
- get_item_extra_hook = get_item_hook_find_obj;
-
/* Get an item */
- q = "Quaff which potion? ";
- s = "You have no potions to quaff.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return;
+ int item;
+ if (!get_item(&item,
+ "Quaff which potion? ",
+ "You have no potions to quaff.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_quaffable(),
+ select_object_by_name("Potion full name? ")))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Sound */
@@ -2576,9 +2575,7 @@ static void do_cmd_fill_bottle(void)
int tval, sval, item, amt = 1;
- object_type *q_ptr, *o_ptr, forge;
-
- cptr q, s;
+ object_type *q_ptr, forge;
/* Is the fountain empty? */
/*
@@ -2604,14 +2601,17 @@ static void do_cmd_fill_bottle(void)
sval = c_ptr->special - SV_POTION_LAST;
}
- /* Restrict choices to bottles */
- item_tester_tval = TV_BOTTLE;
-
/* Get an item */
- q = "Fill which bottle? ";
- s = "You have no bottles to fill.";
- if (!get_item(&item, q, s, (USE_INVEN))) return;
- o_ptr = &p_ptr->inventory[item];
+ if (!get_item(&item,
+ "Fill which bottle? ",
+ "You have no bottles to fill.",
+ (USE_INVEN),
+ object_filter::TVal(TV_BOTTLE)))
+ {
+ return;
+ }
+
+ object_type *o_ptr = &p_ptr->inventory[item];
/* Find out how many the player wants */
if (o_ptr->number > 1)
@@ -2862,12 +2862,14 @@ bool_ curse_weapon(void)
/*
* Hook to determine if an object is readable
*/
-static bool_ item_tester_hook_readable(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_readable()
{
- if ((o_ptr->tval == TV_SCROLL) || (o_ptr->tval == TV_PARCHMENT)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance =
+ Or(
+ TVal(TV_SCROLL),
+ TVal(TV_PARCHMENT));
+ return instance;
}
@@ -2880,15 +2882,6 @@ static bool_ item_tester_hook_readable(object_type *o_ptr)
*/
void do_cmd_read_scroll(void)
{
- int item, k, used_up, ident, lev;
-
- object_type *o_ptr;
-
- object_type *q_ptr, forge;
-
- cptr q, s;
-
-
/* Check some conditions */
if (p_ptr->blind)
{
@@ -2908,33 +2901,32 @@ void do_cmd_read_scroll(void)
return;
}
-
- /* Restrict choices to scrolls */
- item_tester_hook = item_tester_hook_readable;
-
- /* Set up the extra finder */
- get_item_hook_find_obj_what = "Scroll full name? ";
- get_item_extra_hook = get_item_hook_find_obj;
-
/* Get an item */
- q = "Read which scroll? ";
- s = "You have no scrolls to read.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return;
+ int item;
+ if (!get_item(&item,
+ "Read which scroll? ",
+ "You have no scrolls to read.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_readable(),
+ select_object_by_name("Scroll full name? ")))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Take a turn */
energy_use = 100;
/* Not identified yet */
- ident = FALSE;
+ int ident = FALSE;
/* Object level */
- lev = k_info[o_ptr->k_idx].level;
+ int lev = k_info[o_ptr->k_idx].level;
/* Assume the scroll will get used up */
- used_up = TRUE;
+ int used_up = TRUE;
/* Corruption */
if (player_has_corruption(CORRUPT_BALROG_AURA) && magik(5))
@@ -2952,13 +2944,11 @@ void do_cmd_read_scroll(void)
{
case SV_SCROLL_MASS_RESURECTION:
{
- int k;
-
ident = TRUE;
msg_print("You feel the souls of the dead coming back "
"from the Halls of Mandos.");
- for (k = 0; k < max_r_idx; k++)
+ for (int k = 0; k < max_r_idx; k++)
{
monster_race *r_ptr = &r_info[k];
@@ -3075,7 +3065,7 @@ void do_cmd_read_scroll(void)
case SV_SCROLL_SUMMON_MONSTER:
{
- for (k = 0; k < randint(3); k++)
+ for (int k = 0; k < randint(3); k++)
{
if (summon_specific(p_ptr->py, p_ptr->px, dun_level, 0))
{
@@ -3098,7 +3088,7 @@ void do_cmd_read_scroll(void)
case SV_SCROLL_SUMMON_UNDEAD:
{
- for (k = 0; k < randint(3); k++)
+ for (int k = 0; k < randint(3); k++)
{
if (summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD))
{
@@ -3355,8 +3345,11 @@ void do_cmd_read_scroll(void)
case SV_SCROLL_PROTECTION_FROM_EVIL:
{
- k = 3 * p_ptr->lev;
- if (set_protevil(p_ptr->protevil + randint(25) + k)) ident = TRUE;
+ int k = 3 * p_ptr->lev;
+ if (set_protevil(p_ptr->protevil + randint(25) + k))
+ {
+ ident = TRUE;
+ }
break;
}
@@ -3596,7 +3589,7 @@ void do_cmd_read_scroll(void)
screen_save();
/* Get the filename */
- q = format("book-%d.txt", o_ptr->sval);
+ cptr q = format("book-%d.txt", o_ptr->sval);
/* Peruse the help file */
(void)show_file(q, NULL, 0, 0);
@@ -3639,10 +3632,13 @@ void do_cmd_read_scroll(void)
/* Destroy scroll */
inc_stack_size(item, -1);
+ /* Alchemists end up with a "drained" scroll instead */
if (get_skill(SKILL_ALCHEMY))
{
if (item >= 0)
{
+ object_type *q_ptr, forge;
+
q_ptr = &forge;
object_prep(q_ptr, lookup_kind(TV_SCROLL, SV_SCROLL_NOTHING));
object_aware(q_ptr);
@@ -3726,12 +3722,8 @@ void do_cmd_use_staff(void)
{
bool_ obvious, use_charge;
- object_type *o_ptr;
-
u32b f1, f2, f3, f4, f5, esp;
- cptr q, s;
-
/* No magic */
if (p_ptr->antimagic)
{
@@ -3739,21 +3731,20 @@ void do_cmd_use_staff(void)
return;
}
- /* Restrict choices to wands */
- item_tester_tval = TV_STAFF;
-
- /* Set up the extra finder */
- get_item_hook_find_obj_what = "Staff full name? ";
- get_item_extra_hook = get_item_hook_find_obj;
-
/* Get an item */
- q = "Use which staff? ";
- s = "You have no staff to use.";
int item;
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return;
+ if (!get_item(&item,
+ "Use which staff? ",
+ "You have no staff to use.",
+ (USE_INVEN | USE_FLOOR),
+ object_filter::TVal(TV_STAFF),
+ select_object_by_name("Staff full name? ")))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Mega-Hack -- refuse to use a pile from the ground */
if ((item < 0) && (o_ptr->number > 1))
@@ -3908,12 +3899,6 @@ void do_cmd_aim_wand(void)
{
bool_ obvious, use_charge;
- int item;
-
- object_type *o_ptr;
-
- cptr q, s;
-
u32b f1, f2, f3, f4, f5, esp;
@@ -3924,21 +3909,20 @@ void do_cmd_aim_wand(void)
return;
}
- /* Restrict choices to wands */
- item_tester_tval = TV_WAND;
-
- /* Set up the extra finder */
- get_item_hook_find_obj_what = "Wand full name? ";
- get_item_extra_hook = get_item_hook_find_obj;
-
/* Get an item */
- q = "Aim which wand? ";
- s = "You have no wand to aim.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return;
+ int item;
+ if (!get_item(&item,
+ "Aim which wand? ",
+ "You have no wand to aim.",
+ (USE_INVEN | USE_FLOOR),
+ object_filter::TVal(TV_WAND),
+ select_object_by_name("Wand full name? ")))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
-
+ object_type *o_ptr = get_object(item);
/* Mega-Hack -- refuse to aim a pile from the ground */
if ((item < 0) && (o_ptr->number > 1))
@@ -4052,25 +4036,24 @@ void do_cmd_aim_wand(void)
/*
* Hook to determine if an object is zapable
*/
-static bool_ item_tester_hook_zapable(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_zapable()
{
- if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_ROD_MAIN)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance =
+ Or(
+ TVal(TV_ROD),
+ TVal(TV_ROD_MAIN));
+ return instance;
}
/*
* Hook to determine if an object is attachable
*/
-static bool_ item_tester_hook_attachable(object_type *o_ptr)
+static bool item_tester_hook_attachable(object_type const *o_ptr)
{
- if ((o_ptr->tval == TV_ROD_MAIN) &&
- (o_ptr->pval == SV_ROD_NOTHING)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
+ return ((o_ptr->tval == TV_ROD_MAIN) &&
+ (o_ptr->pval == SV_ROD_NOTHING));
}
@@ -4081,10 +4064,6 @@ void zap_combine_rod_tip(object_type *q_ptr, int tip_item)
{
int item;
- object_type *o_ptr;
-
- cptr q, s;
-
u32b f1, f2, f3, f4, f5, esp;
s32b cost;
@@ -4096,16 +4075,18 @@ void zap_combine_rod_tip(object_type *q_ptr, int tip_item)
return;
}
- /* Restrict choices to rods */
- item_tester_hook = item_tester_hook_attachable;
-
/* Get an item */
- q = "Attach the rod tip with which rod? ";
- s = "You have no rod to attach to.";
- if (!get_item(&item, q, s, (USE_INVEN))) return;
+ if (!get_item(&item,
+ "Attach the rod tip with which rod? ",
+ "You have no rod to attach to.",
+ (USE_INVEN),
+ item_tester_hook_attachable))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Examine the rod */
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
@@ -4147,14 +4128,10 @@ void do_cmd_zap_rod(void)
bool_ require_dir;
- object_type *o_ptr;
-
object_kind *tip_ptr;
u32b f1, f2, f3, f4, f5, esp;
- cptr q, s;
-
/* Hack -- let perception get aborted */
bool_ use_charge = TRUE;
@@ -4166,21 +4143,19 @@ void do_cmd_zap_rod(void)
return;
}
-
- /* Restrict choices to rods */
- item_tester_hook = item_tester_hook_zapable;
-
- /* Set up the extra finder */
- get_item_hook_find_obj_what = "Rod full name? ";
- get_item_extra_hook = get_item_hook_find_obj;
-
/* Get an item */
- q = "Zap which rod? ";
- s = "You have no rod to zap.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return;
+ if (!get_item(&item,
+ "Zap which rod? ",
+ "You have no rod to zap.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_zapable(),
+ select_object_by_name("Rod full name? ")))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* "Zapping" a Rod Tip on rod of nothing will attach it */
@@ -4615,26 +4590,16 @@ void do_cmd_zap_rod(void)
/*
* Hook to determine if an object is activable
*/
-static bool_ item_tester_hook_activate(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_activate()
{
- u32b f1, f2, f3, f4, f5, esp;
-
-
- /* Not known */
- if (!object_known_p(o_ptr)) return (FALSE);
-
- /* Extract the flags */
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- /* Check activation flag */
- if (f3 & (TR3_ACTIVATE)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance = And(
+ IsKnown(),
+ HasFlag3(TR3_ACTIVATE));
+ return instance;
}
-
/*
* Hack -- activate the ring of power
*/
@@ -4784,7 +4749,7 @@ bool_ brand_bolts(void)
* Eternal flame activation
*/
-static int get_eternal_artifact_idx(object_type *o_ptr)
+static int get_eternal_artifact_idx(object_type const *o_ptr)
{
if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_LONG_SWORD)) {
return 147;
@@ -4821,7 +4786,7 @@ static int get_eternal_artifact_idx(object_type *o_ptr)
return -1;
}
-static bool_ eternal_flame_item_tester_hook(object_type *o_ptr)
+static bool eternal_flame_item_tester_hook(object_type const *o_ptr)
{
if ((o_ptr->name1 > 0) ||
(o_ptr->name2 > 0))
@@ -4837,11 +4802,11 @@ static bool activate_eternal_flame(int flame_item)
int item;
int artifact_idx = -1;
- item_tester_hook = eternal_flame_item_tester_hook;
if (!get_item(&item,
"Which object do you want to imbue?",
"You have no objects to imbue.",
- USE_INVEN))
+ USE_INVEN,
+ eternal_flame_item_tester_hook))
{
return false;
}
@@ -4943,24 +4908,21 @@ void do_cmd_activate(void)
char ch, spell_choice;
- object_type *o_ptr;
-
u32b f1, f2, f3, f4, f5, esp;
- cptr q, s;
-
-
- /* Prepare the hook */
- item_tester_hook = item_tester_hook_activate;
-
/* Get an item */
command_wrk = USE_EQUIP;
- q = "Activate which item? ";
- s = "You have nothing to activate.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN))) return;
+ if (!get_item(&item,
+ "Activate which item? ",
+ "You have nothing to activate.",
+ (USE_EQUIP | USE_INVEN),
+ item_tester_hook_activate()))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Extract object flags */
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
diff --git a/src/cmd7.cc b/src/cmd7.cc
index 81296411..71e46518 100644
--- a/src/cmd7.cc
+++ b/src/cmd7.cc
@@ -2376,19 +2376,24 @@ static bool_ alchemist_exists(int tval, int sval, int ego, int artifact)
/*
* Hook to determine if an object can have things extracted from it.
*/
-bool_ item_tester_hook_extractable(object_type *o_ptr)
+bool item_tester_hook_extractable(object_type const *o_ptr)
{
/* No artifacts */
- if (artifact_p(o_ptr)) return (FALSE);
+ if (artifact_p(o_ptr))
+ {
+ return false;
+ }
/* No cursed things */
- if (cursed_p(o_ptr)) return (FALSE);
+ if (cursed_p(o_ptr))
+ {
+ return false;
+ }
/* If we REALLY wanted to rebalance alchemists,
* we'd test for 'fully identified this object kind' here.
*/
-
return ((o_ptr->tval == TV_ROD_MAIN && o_ptr->pval != 0)
|| alchemist_exists(o_ptr->tval, o_ptr->sval, o_ptr->name2, o_ptr->name1));
}
@@ -2396,7 +2401,7 @@ bool_ item_tester_hook_extractable(object_type *o_ptr)
/*
* Hook to determine if an object is empowerable (NOT rechargeable)
*/
-bool_ item_tester_hook_empower(object_type *o_ptr)
+static bool item_tester_hook_empower(object_type const *o_ptr)
{
int sval = -1;
int lev = get_skill(SKILL_ALCHEMY);
@@ -2408,14 +2413,14 @@ bool_ item_tester_hook_empower(object_type *o_ptr)
/* Never Empower a cursed item */
if ( cursed_p(o_ptr))
{
- return FALSE;
+ return false;
}
/* Allow finalizing a self created artifact */
if (artifact_p(o_ptr)
&& (o_ptr->art_flags4 & TR4_ART_EXP)
&& !(o_ptr->art_flags4 & TR4_ULTIMATE))
- return TRUE;
+ return true;
switch ( o_ptr->tval)
{
@@ -2452,7 +2457,7 @@ bool_ item_tester_hook_empower(object_type *o_ptr)
/* Disallow ego dragon armour before you can create artifacts.*/
case TV_DRAG_ARMOR:
if ( lev < 25)
- return FALSE;
+ return false;
/* FALL THROUGH! no break here. */
/* weapons */
@@ -2488,24 +2493,24 @@ bool_ item_tester_hook_empower(object_type *o_ptr)
/* Disallow ANY creation of ego items below level 5*/
if ( lev < 5)
- return FALSE;
+ return false;
/* empowering an ego item creates an artifact or a
* double ego item, disallow below level 25 */
if ( lev < 25 && o_ptr->name2)
- return FALSE;
+ return false;
/* Disallow double-ego and artifact unless the character has
* the artifact creation ability. */
if (!has_ability(AB_CREATE_ART) &&
(artifact_p(o_ptr) || (o_ptr->name2 && o_ptr->name2b)))
- return FALSE;
+ return false;
/* Otherwise... */
- return TRUE;
+ return true;
default:
- return FALSE;
+ return false;
}
/* Return to the traditional alchemist objects.
@@ -2518,7 +2523,7 @@ bool_ item_tester_hook_empower(object_type *o_ptr)
if ((o_ptr->name2 || artifact_p(o_ptr)) &&
o_ptr->tval != TV_RING && o_ptr->tval != TV_AMULET)
- return FALSE;
+ return false;
/* return true if it's a 'of nothing' item;
* does nothing for TV_ROD_MAIN and TV_BOOK
@@ -3567,8 +3572,6 @@ void do_cmd_alchemist(void)
object_type forge, forge2;
byte carry_o_ptr = FALSE;
- cptr q, s;
-
/* With the new skill system, we can no longer depend on
* check_exp to handle the changes and learning involved in
* gaining levels.
@@ -3640,11 +3643,10 @@ void do_cmd_alchemist(void)
char o_name[200];
/* Get an item */
- q = "Empower which item? ";
- s = "You have no empowerable items.";
- item_tester_hook = item_tester_hook_empower;
-
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Empower which item? ",
+ "You have no empowerable items.",
+ (USE_INVEN | USE_FLOOR), item_tester_hook_empower)) return;
/* Get the item */
o_ptr = get_object(item);
@@ -3970,12 +3972,12 @@ void do_cmd_alchemist(void)
object_type *s_ptr = NULL;
bool_ carry_s_ptr = FALSE;
- item_tester_hook = item_tester_hook_extractable;
-
/* Get an item */
- q = "Extract from which item? ";
- s = "You have no item to extract power from.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Extract from which item? ",
+ "You have no item to extract power from.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_extractable)) return;
/* Get the item */
o_ptr = get_object(item);
@@ -4221,14 +4223,15 @@ void do_cmd_alchemist(void)
{
int item;
- cptr q, s;
-
- item_tester_hook = item_tester_hook_recharge;
-
/* Get an item */
- q = "Recharge which item? ";
- s = "You have no rechargable items.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR ))) return;
+ if (!get_item(&item,
+ "Recharge which item? ",
+ "You have no rechargable items.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_recharge()))
+ {
+ return;
+ }
/* Get the item */
o_ptr = get_object(item);
@@ -4971,12 +4974,14 @@ void do_cmd_possessor()
/*
* Hook to determine if an object is contertible in an arrow/bolt
*/
-static bool_ item_tester_hook_convertible(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_convertible()
{
- if ((o_ptr->tval == TV_JUNK) || (o_ptr->tval == TV_SKELETON)) return TRUE;
-
- /* Assume not */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance =
+ Or(
+ TVal(TV_JUNK),
+ TVal(TV_SKELETON));
+ return instance;
}
@@ -5091,14 +5096,12 @@ void do_cmd_archer(void)
{
int item;
- cptr q, s;
-
- item_tester_hook = item_tester_hook_convertible;
-
/* Get an item */
- q = "Convert which item? ";
- s = "You have no item to convert.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Convert which item? ",
+ "You have no item to convert.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_convertible())) return;
/* Get local object */
q_ptr = &forge;
@@ -5129,14 +5132,12 @@ void do_cmd_archer(void)
{
int item;
- cptr q, s;
-
- item_tester_hook = item_tester_hook_convertible;
-
/* Get an item */
- q = "Convert which item? ";
- s = "You have no item to convert.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Convert which item? ",
+ "You have no item to convert.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_convertible())) return;
/* Get local object */
q_ptr = &forge;
@@ -5535,66 +5536,23 @@ void do_cmd_necromancer(void)
p_ptr->window |= (PW_PLAYER);
}
-/* Runecrafters -- Move this into variable.c XXX XXX XXX */
-static s32b rune_combine = 0;
-
/*
* Hook to determine if an object is "runestone"
*/
-static bool_ item_tester_hook_runestone(object_type *o_ptr)
+static bool item_tester_hook_runestone(object_type const *o_ptr)
{
- if (o_ptr->tval != TV_RUNE2) return (FALSE);
-
- if (o_ptr->sval != RUNE_STONE) return (FALSE);
-
- if (o_ptr->pval != 0) return (FALSE);
-
- /* Assume yes */
- return (TRUE);
-}
-
-
-static bool_ item_tester_hook_runestone_full(object_type *o_ptr)
-{
- if (o_ptr->tval != TV_RUNE2) return (FALSE);
-
- if (o_ptr->sval != RUNE_STONE) return (FALSE);
-
- if (o_ptr->pval == 0) return (FALSE);
-
- /* Assume yes */
- return (TRUE);
+ return ((o_ptr->tval == TV_RUNE2) &&
+ (o_ptr->sval == RUNE_STONE) &&
+ (o_ptr->pval == 0));
}
-
-/*
- * Hook to determine if an object is "rune-able"
- */
-static bool_ item_tester_hook_runeable1(object_type *o_ptr)
+static bool item_tester_hook_runestone_full(object_type const *o_ptr)
{
- if (o_ptr->tval != TV_RUNE1) return (FALSE);
-
- /* Assume yes */
- return (TRUE);
+ return ((o_ptr->tval == TV_RUNE2) &&
+ (o_ptr->sval == RUNE_STONE) &&
+ (o_ptr->pval != 0));
}
-
-/*
- * Hook to determine if an object is "rune-able"
- */
-static bool_ item_tester_hook_runeable2(object_type *o_ptr)
-{
- if (o_ptr->tval != TV_RUNE2) return (FALSE);
-
- if (o_ptr->sval == RUNE_STONE) return (FALSE);
-
- if (rune_combine & BIT(o_ptr->sval)) return (FALSE);
-
- /* Assume yes */
- return (TRUE);
-}
-
-
/*
* math.h(sqrt) is banned of angband so ... :)
*/
@@ -5902,44 +5860,43 @@ bool_ test_runespell(rune_spell *spell)
*/
bool_ get_runespell(rune_spell *spell)
{
- int item, power_rune = 0, rune2 = 0, plev = get_skill(SKILL_RUNECRAFT);
-
- s32b power;
-
- int type = 0;
-
- object_type *o_ptr;
-
- cptr q, s;
-
- bool_ OK = FALSE;
+ s32b rune_combine = 0;
+ /* Lambda to use for selecting the secondary rune(s) */
+ auto rune2_filter = [&](object_type const *o_ptr) -> bool {
+ return ((o_ptr->tval == TV_RUNE2) &&
+ (o_ptr->sval != RUNE_STONE) &&
+ (!(rune_combine & BIT(o_ptr->sval))));
+ };
- rune_combine = 0;
+ /* Prompt */
+ const char *const q = "Use which rune? ";
+ const char *const s = "You have no rune to use.";
- /* Restrict choices to unused runes */
- item_tester_hook = item_tester_hook_runeable1;
-
- /* Get an item */
- q = "Use which rune? ";
- s = "You have no rune to use.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return FALSE;
+ /* Extract first rune for the base effect */
+ int type = 0;
+ {
+ int item;
+ if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR), object_filter::TVal(TV_RUNE1)))
+ {
+ return FALSE;
+ }
- /* Get the item */
- o_ptr = get_object(item);
- type = o_ptr->sval;
+ object_type *o_ptr = get_object(item);
+ type = o_ptr->sval;
+ }
+ /* Choose secondary rune(s) */
+ int rune2 = 0;
while (1)
{
- /* Restrict choices to unused secondary runes */
- item_tester_hook = item_tester_hook_runeable2;
-
- OK = !get_item(&item, q, s, (USE_INVEN | USE_FLOOR));
-
- if (OK) break;
+ int item;
+ if (!get_item(&item, q, nullptr, (USE_INVEN | USE_FLOOR), rune2_filter))
+ {
+ break;
+ }
- /* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
rune_combine |= 1 << o_ptr->sval;
rune2 |= 1 << o_ptr->sval;
@@ -5951,9 +5908,14 @@ bool_ get_runespell(rune_spell *spell)
return (FALSE);
}
- power = get_quantity("Which amount of Mana?",
- p_ptr->csp - (power_rune * (plev / 5)));
- if (power < 1) power = 1;
+ int power_rune = 0;
+ int plev = get_skill(SKILL_RUNECRAFT);
+ s32b power = get_quantity("Which amount of Mana? ",
+ p_ptr->csp - (power_rune * (plev / 5)));
+ if (power < 1)
+ {
+ power = 1;
+ }
spell->mana = power;
spell->type = type;
@@ -6274,10 +6236,6 @@ void do_cmd_runestone()
{
rune_spell s_ptr;
- object_type *o_ptr;
-
- cptr q, s;
-
int item;
@@ -6316,16 +6274,18 @@ void do_cmd_runestone()
return;
}
- /* Restrict choices to unused runes */
- item_tester_hook = item_tester_hook_runestone_full;
-
/* Get an item */
- q = "Cast from which runestone? ";
- s = "You have no runestone to cast from.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Cast from which runestone? ",
+ "You have no runestone to cast from.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_runestone_full))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
s_ptr.type = o_ptr->pval;
s_ptr.rune2 = o_ptr->pval2;
@@ -6397,10 +6357,6 @@ void do_cmd_rune_carve()
{
rune_spell s_ptr;
- object_type *o_ptr;
-
- cptr q, s;
-
int item, i;
char out_val[80];
@@ -6427,16 +6383,18 @@ void do_cmd_rune_carve()
if (!get_runespell(&s_ptr)) return;
- /* Restrict choices to unused runes */
- item_tester_hook = item_tester_hook_runestone;
-
/* Get an item */
- q = "Use which runestone? ";
- s = "You have no runestone to use.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Use which runestone? ",
+ "You have no runestone to use.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_runestone))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
o_ptr->pval = s_ptr.type;
o_ptr->pval2 = s_ptr.rune2;
@@ -6752,17 +6710,15 @@ void do_cmd_unbeliever()
/*
* Hook to determine if an object is totemable
*/
-static bool_ item_tester_hook_totemable(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_totemable()
{
- /* Only full corpse */
- if ((o_ptr->tval == TV_CORPSE) &&
- ((o_ptr->sval == SV_CORPSE_CORPSE) || (o_ptr->sval == SV_CORPSE_SKELETON)))
- {
- return (TRUE);
- }
-
- /* Assume not */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance = And(
+ TVal(TV_CORPSE),
+ Or(
+ SVal(SV_CORPSE_CORPSE),
+ SVal(SV_CORPSE_SKELETON)));
+ return instance;
}
@@ -6771,14 +6727,7 @@ static bool_ item_tester_hook_totemable(object_type *o_ptr)
*/
void do_cmd_summoner_extract()
{
- object_type *o_ptr, forge, *q_ptr;
-
- cptr q, s;
-
- int item, r;
-
- bool_ partial;
-
+ object_type forge, *q_ptr;
/* Not when confused */
if (p_ptr->confused)
@@ -6794,17 +6743,21 @@ void do_cmd_summoner_extract()
return;
}
- item_tester_hook = item_tester_hook_totemable;
-
/* Get an item */
- q = "Use which corpse? ";
- s = "You have no corpse to use.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Use which corpse? ",
+ "You have no corpse to use.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_totemable()))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
-
+ object_type *o_ptr = get_object(item);
+ bool_ partial;
if (r_info[o_ptr->pval2].flags1 & RF1_UNIQUE)
{
partial = FALSE;
@@ -6814,7 +6767,7 @@ void do_cmd_summoner_extract()
partial = get_check("Do you want to create a partial totem?");
}
- r = o_ptr->pval2;
+ int r = o_ptr->pval2;
inc_stack_size(item, -1);
@@ -6952,20 +6905,16 @@ void do_cmd_summoner_summon()
cptr q, s;
- object_type *o_ptr;
-
monster_type *m_ptr;
/* Which Totem? */
- item_tester_tval = TV_TOTEM;
-
q = "Summon from which Totem?";
s = "There are no totems to summon from!";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+ if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR), object_filter::TVal(TV_TOTEM))) return;
/* Access the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Take a turn */
energy_use = 100;
@@ -7307,19 +7256,18 @@ void do_cmd_symbiotic(void)
monster_type *m_ptr;
int m_idx;
int item, x, y, d;
- object_type *o_ptr;
-
- cptr q, s;
-
- /* Restrict choices to monsters */
- item_tester_tval = TV_HYPNOS;
/* Get an item */
- q = "Awaken which monster? ";
- s = "You have no monster to awaken.";
- if (!get_item(&item, q, s, (USE_FLOOR))) return;
+ if (!get_item(&item,
+ "Awaken which monster? ",
+ "You have no monster to awaken.",
+ (USE_FLOOR),
+ object_filter::TVal(TV_HYPNOS)))
+ {
+ return;
+ }
- o_ptr = &o_list[0 - item];
+ object_type *o_ptr = &o_list[0 - item];
d = 2;
while (d < 100)
diff --git a/src/defines.h b/src/defines.h
index a352e562..c2955e44 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -2135,7 +2135,6 @@
#define USE_EQUIP 0x01 /* Allow equip items */
#define USE_INVEN 0x02 /* Allow inven items */
#define USE_FLOOR 0x04 /* Allow floor items */
-#define USE_EXTRA 0x08 /* Allow extra items */
#define USE_AUTO 0x10 /* Allow creation of automatizer rule */
/*
* Bit flags for the "p_ptr->notice" variable
diff --git a/src/files.cc b/src/files.cc
index 25cadc05..2313b277 100644
--- a/src/files.cc
+++ b/src/files.cc
@@ -4668,8 +4668,7 @@ static void show_info(void)
if (equip_cnt)
{
Term_clear();
- item_tester_full = TRUE;
- show_equip();
+ show_equip_full();
prt("You are using: -more-", 0, 0);
if (inkey() == ESCAPE) return;
}
@@ -4678,8 +4677,7 @@ static void show_info(void)
if (inven_cnt)
{
Term_clear();
- item_tester_full = TRUE;
- show_inven();
+ show_inven_full();
prt("You are carrying: -more-", 0, 0);
if (inkey() == ESCAPE) return;
}
diff --git a/src/object1.cc b/src/object1.cc
index 25b848a0..fcbc35f8 100644
--- a/src/object1.cc
+++ b/src/object1.cc
@@ -49,6 +49,12 @@ static bool_ apply_flags_set(s16b a_idx, s16b set_idx,
#define TERM_MULTI TERM_VIOLET
+/**
+ * Show all equipment/inventory slots, even when empty?
+ */
+static bool item_tester_full;
+
+
/*
* Max sizes of the following arrays
*/
@@ -4327,45 +4333,42 @@ cptr describe_use(int i)
/*
* Check an item against the item tester info
*/
-bool_ item_tester_okay(object_type *o_ptr)
+static bool item_tester_okay(object_type const *o_ptr, object_filter_t const &filter)
{
/* Hack -- allow listing empty slots */
- if (item_tester_full) return (TRUE);
+ if (item_tester_full)
+ {
+ return true;
+ }
/* Require an item */
- if (!o_ptr->k_idx) return (FALSE);
-
- /* Hack -- ignore "gold" */
- if (o_ptr->tval == TV_GOLD) return (FALSE);
-
- /* Check the tval */
- if (item_tester_tval)
+ if (!o_ptr->k_idx)
{
- if (!(item_tester_tval == o_ptr->tval)) return (FALSE);
+ return false;
}
- /* Check the hook */
- if (item_tester_hook)
+ /* Hack -- ignore "gold" */
+ if (o_ptr->tval == TV_GOLD)
{
- if (!(*item_tester_hook)(o_ptr)) return (FALSE);
+ return false;
}
- /* Assume okay */
- return (TRUE);
+ /* Check against the filter */
+ return filter(o_ptr);
}
-void show_equip_aux(bool_ mirror, bool_ everything);
-void show_inven_aux(bool_ mirror, bool_ everything);
+static void show_equip_aux(bool_ mirror, bool_ everything, object_filter_t const &filter);
+static void show_inven_aux(bool_ mirror, bool_ everything, object_filter_t const &filter);
/*
* Choice window "shadow" of the "show_inven()" function
*/
void display_inven(void)
{
- show_inven_aux(TRUE, inventory_no_move);
+ show_inven_aux(TRUE, inventory_no_move, object_filter::True());
}
@@ -4375,7 +4378,7 @@ void display_inven(void)
*/
void display_equip(void)
{
- show_equip_aux(TRUE, inventory_no_move);
+ show_equip_aux(TRUE, inventory_no_move, object_filter::True());
}
@@ -4402,7 +4405,7 @@ byte get_item_letter_color(object_type *o_ptr)
*
* Hack -- do not display "trailing" empty slots
*/
-void show_inven_aux(bool_ mirror, bool_ everything)
+void show_inven_aux(bool_ mirror, bool_ everything, const object_filter_t &filter)
{
int i, j, k, l, z = 0;
int row, col, len, lim;
@@ -4454,7 +4457,7 @@ void show_inven_aux(bool_ mirror, bool_ everything)
o_ptr = &p_ptr->inventory[i];
/* Is this item acceptable? */
- if (!item_tester_okay(o_ptr))
+ if (!item_tester_okay(o_ptr, filter))
{
if ( !everything )
continue;
@@ -4562,20 +4565,34 @@ void show_inven_aux(bool_ mirror, bool_ everything)
}
-void show_inven()
+static void show_inven(object_filter_t const &filter)
{
- show_inven_aux(FALSE, FALSE);
+ show_inven_aux(FALSE, FALSE, filter);
}
-void show_equip()
+void show_inven_full()
{
- show_equip_aux(FALSE, FALSE);
+ item_tester_full = true;
+ show_inven(object_filter::True());
+ item_tester_full = false;
+}
+
+static void show_equip(object_filter_t const &filter)
+{
+ show_equip_aux(FALSE, FALSE, filter);
+}
+
+void show_equip_full()
+{
+ item_tester_full = true;
+ show_equip(object_filter::True());
+ item_tester_full = false;
}
/*
* Display the equipment.
*/
-void show_equip_aux(bool_ mirror, bool_ everything)
+void show_equip_aux(bool_ mirror, bool_ everything, object_filter_t const &filter)
{
int i, j, k, l;
int row, col, len, lim, idx;
@@ -4686,7 +4703,7 @@ void show_equip_aux(bool_ mirror, bool_ everything)
/* Truncate the description */
o_name[lim] = 0;
/* Is this item acceptable? */
- if (!item_tester_okay(o_ptr))
+ if (!item_tester_okay(o_ptr, filter))
{
if (!everything) continue;
out_index[k] = -1;
@@ -4911,16 +4928,16 @@ static bool_ get_item_allow(int item)
/*
* Auxiliary function for "get_item()" -- test an index
*/
-static bool_ get_item_okay(int i)
+static bool get_item_okay(int i, object_filter_t const &filter)
{
/* Illegal items */
- if ((i < 0) || (i >= INVEN_TOTAL)) return (FALSE);
+ if ((i < 0) || (i >= INVEN_TOTAL))
+ {
+ return (FALSE);
+ }
/* Verify the item */
- if (!item_tester_okay(&p_ptr->inventory[i])) return (FALSE);
-
- /* Assume okay */
- return (TRUE);
+ return item_tester_okay(&p_ptr->inventory[i], filter);
}
@@ -4992,7 +5009,7 @@ static int get_tag(int *cp, char tag)
* Return a list of o_list[] indexes of items at the given cave
* location.
*/
-static std::vector<int> scan_floor(int y, int x)
+static std::vector<int> scan_floor(int y, int x, object_filter_t const &filter)
{
int this_o_idx, next_o_idx;
std::vector<int> items;
@@ -5013,7 +5030,10 @@ static std::vector<int> scan_floor(int y, int x)
next_o_idx = o_ptr->next_o_idx;
/* Item tester */
- if (!item_tester_okay(o_ptr)) continue;
+ if (!item_tester_okay(o_ptr, filter))
+ {
+ continue;
+ }
/* Accept this item */
items.push_back(this_o_idx);
@@ -5029,7 +5049,7 @@ static std::vector<int> scan_floor(int y, int x)
/*
* Display a list of the items on the floor at the given location.
*/
-static void show_floor(int y, int x)
+static void show_floor(int y, int x, object_filter_t const &filter)
{
int i, j, k, l;
int col, len, lim;
@@ -5054,7 +5074,7 @@ static void show_floor(int y, int x)
lim -= 9;
/* Scan for objects in the grid, using item_tester_okay() */
- auto const floor_list = scan_floor(y, x);
+ auto const floor_list = scan_floor(y, x, filter);
assert(floor_list.size() <= 23);
int const floor_num = floor_list.size(); // "int" for warning avoidance
@@ -5131,8 +5151,7 @@ static void show_floor(int y, int x)
* This version of get_item() is called by get_item() when
* the easy_floor is on.
*/
-bool_ (*get_item_extra_hook)(int *cp);
-static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
+static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode, object_filter_t const &filter, select_by_name_t const &select_by_name)
{
char n1 = 0, n2 = 0, which = ' ';
@@ -5145,7 +5164,6 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
bool_ equip = FALSE;
bool_ inven = FALSE;
bool_ floor = FALSE;
- bool_ extra = FALSE;
bool_ automat = FALSE;
bool_ allow_equip = FALSE;
@@ -5176,28 +5194,16 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
o_ptr = &o_list[k];
/* Validate the item */
- if (item_tester_okay(o_ptr))
+ if (item_tester_okay(o_ptr, filter))
{
- /* Forget the item_tester_tval restriction */
- item_tester_tval = 0;
-
- /* Forget the item_tester_hook restriction */
- item_tester_hook = NULL;
-
/* Success */
return (TRUE);
}
}
/* Verify the item */
- else if (get_item_okay(*cp))
+ else if (get_item_okay(*cp, filter))
{
- /* Forget the item_tester_tval restriction */
- item_tester_tval = 0;
-
- /* Forget the item_tester_hook restriction */
- item_tester_hook = NULL;
-
/* Success */
return (TRUE);
}
@@ -5208,7 +5214,6 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
if (mode & (USE_EQUIP)) equip = TRUE;
if (mode & (USE_INVEN)) inven = TRUE;
if (mode & (USE_FLOOR)) floor = TRUE;
- if (mode & (USE_EXTRA)) extra = TRUE;
if (mode & (USE_AUTO)) automat = TRUE;
@@ -5231,8 +5236,8 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
if (!inven) i2 = -1;
/* Restrict inventory indexes */
- while ((i1 <= i2) && (!get_item_okay(i1))) i1++;
- while ((i1 <= i2) && (!get_item_okay(i2))) i2--;
+ while ((i1 <= i2) && (!get_item_okay(i1, filter))) i1++;
+ while ((i1 <= i2) && (!get_item_okay(i2, filter))) i2--;
/* Full equipment */
@@ -5243,13 +5248,13 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
if (!equip) e2 = -1;
/* Restrict equipment indexes */
- while ((e1 <= e2) && (!get_item_okay(e1))) e1++;
- while ((e1 <= e2) && (!get_item_okay(e2))) e2--;
+ while ((e1 <= e2) && (!get_item_okay(e1, filter))) e1++;
+ while ((e1 <= e2) && (!get_item_okay(e2, filter))) e2--;
/* Floor items? */
auto const floor_list =
- floor ? std::move(scan_floor(p_ptr->py, p_ptr->px))
+ floor ? std::move(scan_floor(p_ptr->py, p_ptr->px, filter))
: std::vector<int>();
assert(floor_list.size() <= 23);
int const floor_num = floor_list.size(); // "int" for warning avoidance
@@ -5351,7 +5356,7 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
n2 = I2A(i2);
/* Redraw */
- show_inven();
+ show_inven(filter);
}
/* Equipment screen */
@@ -5362,7 +5367,7 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
n2 = I2A(e2 - INVEN_WIELD);
/* Redraw */
- show_equip();
+ show_equip(filter);
}
/* Floor screen */
@@ -5376,7 +5381,7 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
n2 = I2A(k - floor_top);
/* Redraw */
- show_floor(p_ptr->py, p_ptr->px);
+ show_floor(p_ptr->py, p_ptr->px, filter);
}
/* Viewing inventory */
@@ -5442,8 +5447,8 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
}
}
- /* Extra? */
- if (extra)
+ /* Do we allow selection by name? */
+ if (select_by_name)
{
strcat(out_val, " @ for extra selection,");
}
@@ -5596,7 +5601,7 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
}
/* Validate the item */
- if (!get_item_okay(k))
+ if (!get_item_okay(k, filter))
{
bell();
break;
@@ -5655,7 +5660,7 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
}
/* Validate the item */
- if (!get_item_okay(k))
+ if (!get_item_okay(k, filter))
{
bell();
break;
@@ -5677,11 +5682,15 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
case '@':
{
- int i;
-
- if (extra && get_item_extra_hook(&i))
+ // Ignore if not "enabled"
+ if (!select_by_name)
{
- (*cp) = i;
+ break;
+ }
+ // Find by name
+ if (auto i = select_by_name(filter))
+ {
+ (*cp) = *i;
item = TRUE;
done = TRUE;
}
@@ -5738,7 +5747,7 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
}
/* Validate the item */
- if ((k >= 0) && !get_item_okay(k))
+ if ((k >= 0) && !get_item_okay(k, filter))
{
bell();
break;
@@ -5770,12 +5779,6 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
/* Fix the screen */
screen_load();
- /* Forget the item_tester_tval restriction */
- item_tester_tval = 0;
-
- /* Forget the item_tester_hook restriction */
- item_tester_hook = NULL;
-
/* Track */
if (item && done)
{
@@ -5863,17 +5866,16 @@ static bool_ get_item_floor(int *cp, cptr pmt, cptr str, int mode)
* We always erase the prompt when we are done, leaving a blank line,
* or a warning message, if appropriate, if no items are available.
*/
-bool_ get_item(int *cp, cptr pmt, cptr str, int mode)
+bool_ get_item(int *cp, cptr pmt, cptr str, int mode, object_filter_t const &filter, select_by_name_t const &select_by_name)
{
automatizer_create = FALSE;
-
- return get_item_floor(cp, pmt, str, mode);
+ return get_item_floor(cp, pmt, str, mode, filter, select_by_name);
}
/*
* Hook to determine if an object is getable
*/
-static bool_ item_tester_hook_getable(object_type *o_ptr)
+static bool item_tester_hook_getable(object_type const *o_ptr)
{
if (!inven_carry_okay(o_ptr)) return (FALSE);
@@ -6285,12 +6287,9 @@ void py_pickup_floor(int pickup)
int item;
/* Get an item */
-
- item_tester_hook = item_tester_hook_getable;
-
q = "Get which item? ";
s = "You have no room in your pack for any of the items here.";
- if (get_item(&item, q, s, (USE_FLOOR)))
+ if (get_item(&item, q, s, (USE_FLOOR), item_tester_hook_getable))
{
this_o_idx = 0 - item;
diff --git a/src/object1.hpp b/src/object1.hpp
index 01fc41d0..ba457619 100644
--- a/src/object1.hpp
+++ b/src/object1.hpp
@@ -1,6 +1,12 @@
#pragma once
#include "angband.h"
+#include "object_filter.hpp"
+
+#include <boost/optional.hpp>
+#include <functional>
+
+typedef std::function<boost::optional<int>(object_filter_t const &filter)> select_by_name_t;
extern byte get_item_letter_color(object_type *o_ptr);
extern void object_pickup(int this_o_idx);
@@ -21,14 +27,12 @@ extern char index_to_label(int i);
extern s16b wield_slot_ideal(object_type const *o_ptr, bool_ ideal);
extern s16b wield_slot(object_type const *o_ptr);
extern cptr describe_use(int i);
-extern bool_ item_tester_okay(object_type *o_ptr);
extern void display_inven(void);
extern void display_equip(void);
-extern void show_inven();
-extern void show_equip();
+extern void show_inven_full();
+extern void show_equip_full();
extern void toggle_inven_equip(void);
-extern bool_ (*get_item_extra_hook)(int *cp);
-extern bool_ get_item(int *cp, cptr pmt, cptr str, int mode);
+extern bool_ get_item(int *cp, cptr pmt, cptr str, int mode, object_filter_t const &filter = object_filter::True(), select_by_name_t const &select_by_name = select_by_name_t());
extern cptr item_activation(object_type *o_ptr,byte num);
extern void py_pickup_floor(int pickup);
extern void object_gain_level(object_type *o_ptr);
diff --git a/src/object2.cc b/src/object2.cc
index b8edb7ce..6b56d6dd 100644
--- a/src/object2.cc
+++ b/src/object2.cc
@@ -829,7 +829,7 @@ void object_known(object_type *o_ptr)
* Test One -- Check for special "known" tag
* Test Two -- Check for "Easy Know" + "Aware"
*/
-extern bool object_known_p(object_type const *o_ptr)
+bool object_known_p(object_type const *o_ptr)
{
return ((o_ptr->ident & (IDENT_KNOWN)) ||
(k_info[o_ptr->k_idx].easy_know && k_info[o_ptr->k_idx].aware));
@@ -6624,13 +6624,11 @@ void floor_decay(int item)
/* Return the item be it on the floor or in inven */
object_type *get_object(int item)
{
- /* Get the item (in the pack) */
if (item >= 0)
{
+ assert(item < INVEN_TOTAL);
return &p_ptr->inventory[item];
}
-
- /* Get the item (on the floor) */
else
{
return &o_list[0 - item];
diff --git a/src/object_filter.cc b/src/object_filter.cc
new file mode 100644
index 00000000..8d87213d
--- /dev/null
+++ b/src/object_filter.cc
@@ -0,0 +1,97 @@
+#include "object_filter.hpp"
+#include "object1.hpp"
+#include "object2.hpp"
+
+namespace object_filter {
+
+object_filter_t TVal(byte tval) {
+ return [=](object_type const *o_ptr) -> bool {
+ return o_ptr->tval == tval;
+ };
+}
+
+object_filter_t SVal(byte sval) {
+ return [=](object_type const *o_ptr) -> bool {
+ return o_ptr->sval == sval;
+ };
+}
+
+object_filter_t HasFlag3(u32b mask) {
+ return [=](object_type const *o_ptr) -> bool {
+ // Extract the flags
+ u32b f1, f2, f3, f4, f5, esp;
+ object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
+ // Does the item have the flag?
+ return (f3 & mask);
+ };
+}
+
+object_filter_t HasFlag4(u32b mask) {
+ return [=](object_type const *o_ptr) -> bool {
+ // Extract the flags
+ u32b f1, f2, f3, f4, f5, esp;
+ object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
+ // Does the item have the flag?
+ return (f4 & mask);
+ };
+}
+
+object_filter_t HasFlag5(u32b mask) {
+ return [=](object_type const *o_ptr) -> bool {
+ // Extract the flags
+ u32b f1, f2, f3, f4, f5, esp;
+ object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
+ // Does the item have the flag?
+ return (f5 & mask);
+ };
+}
+
+object_filter_t IsArtifact() {
+ return [](object_type const *o_ptr) -> bool {
+ return o_ptr->name1 > 0;
+ };
+}
+
+object_filter_t IsArtifactP() {
+ return [](object_type const *o_ptr) -> bool {
+ return artifact_p(o_ptr);
+ };
+}
+
+object_filter_t IsEgo() {
+ return [](object_type const *o_ptr) -> bool {
+ return ego_item_p(o_ptr);
+ };
+}
+
+object_filter_t IsKnown() {
+ return [](object_type const *o_ptr) -> bool {
+ return object_known_p(o_ptr);
+ };
+}
+
+object_filter_t True() {
+ return [](object_type const *o_ptr) -> bool {
+ return true;
+ };
+}
+
+object_filter_t Not(object_filter_t p) {
+ return [=](object_type const *o_ptr) -> bool {
+ return !p(o_ptr);
+ };
+}
+
+object_filter_t And() {
+ return [](object_type const *) -> bool {
+ return true;
+ };
+}
+
+object_filter_t Or() {
+ return [](object_type const *) -> bool {
+ return false;
+ };
+}
+
+}
diff --git a/src/object_filter.hpp b/src/object_filter.hpp
new file mode 100644
index 00000000..469b1fa6
--- /dev/null
+++ b/src/object_filter.hpp
@@ -0,0 +1,97 @@
+#pragma once
+
+#include "angband.h"
+#include <functional>
+#include <initializer_list>
+
+typedef std::function<bool (object_type const *)> object_filter_t;
+
+namespace object_filter {
+
+/**
+ * Is TVal equal to the given value?
+ */
+object_filter_t TVal(byte tval);
+
+/**
+ * Is SVal equal to the given value?
+ */
+object_filter_t SVal(byte sval);
+
+/**
+ * Has given bit mask in flag3 value.
+ */
+object_filter_t HasFlag3(u32b mask);
+
+/**
+ * Has given bit mask in flag4 value.
+ */
+object_filter_t HasFlag4(u32b mask);
+
+/**
+ * Has given bit mask in flag5 value.
+ */
+object_filter_t HasFlag5(u32b mask);
+
+/**
+ * Is the object an artifact?
+ */
+object_filter_t IsArtifact();
+
+/**
+ * Is the object an artifact as determined by artifact_p?
+ */
+object_filter_t IsArtifactP();
+
+/**
+ * Is the object an ego item?
+ */
+object_filter_t IsEgo();
+
+/**
+ * Is the object "known"?
+ */
+object_filter_t IsKnown();
+
+/**
+ * True always accepts all items.
+ */
+object_filter_t True();
+
+/**
+ * Invert an object filter.
+ */
+object_filter_t Not(object_filter_t p);
+
+/**
+ * Logical conjunction (AND)
+ */
+object_filter_t And();
+
+/**
+ * Logical conjunction (AND)
+ */
+template<typename Arg0, typename... Args> object_filter_t And(Arg0&& arg0, Args&&... args) {
+ auto argsFilter = And(args...);
+ return [=](object_type const *o_ptr) -> bool {
+ return arg0(o_ptr) && argsFilter(o_ptr);
+ };
+}
+
+/**
+ * Logical disjunction (OR)
+ */
+object_filter_t Or();
+
+/**
+ * Logical disjunction (OR)
+ */
+template<typename Arg0, typename... Args> object_filter_t Or(Arg0&& arg0, Args&&... args) {
+ auto argsFilter = Or(args...);
+ return [=](object_type const *o_ptr) -> bool {
+ auto x = arg0(o_ptr) || argsFilter(o_ptr);
+ return x;
+ };
+}
+
+}
diff --git a/src/powers.cc b/src/powers.cc
index 0b4f87bc..b5c3841f 100644
--- a/src/powers.cc
+++ b/src/powers.cc
@@ -587,13 +587,10 @@ static void power_activate(int power)
cptr q, s;
- /* Restrict choices to monsters */
- item_tester_tval = TV_HYPNOS;
-
/* Get an item */
q = "Awaken which monster? ";
s = "You have no monster to awaken.";
- if (!get_item(&item, q, s, (USE_FLOOR))) return;
+ if (!get_item(&item, q, s, (USE_FLOOR), object_filter::TVal(TV_HYPNOS))) return;
o_ptr = &o_list[0 - item];
@@ -878,12 +875,10 @@ static void power_activate(int power)
object_type * o_ptr;
int lev, item;
- item_tester_hook = item_tester_hook_recharge;
-
/* Get an item */
q = "Drain which item? ";
s = "You have nothing to drain.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) break;
+ if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR), item_tester_hook_recharge())) break;
o_ptr = get_object(item);
diff --git a/src/q_bounty.cc b/src/q_bounty.cc
index d8fc63e0..d8042557 100644
--- a/src/q_bounty.cc
+++ b/src/q_bounty.cc
@@ -65,16 +65,9 @@ static int get_new_bounty_monster(int lev)
return r_idx;
}
-static bool_ bounty_item_tester_hook(object_type *o_ptr)
+static bool bounty_item_tester_hook(object_type const *o_ptr)
{
- if ((o_ptr->tval == TV_CORPSE) && (o_ptr->pval2 == bounty_quest_monster))
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ return ((o_ptr->tval == TV_CORPSE) && (o_ptr->pval2 == bounty_quest_monster));
}
bool_ quest_bounty_init_hook(int dummy)
@@ -114,13 +107,13 @@ bool_ quest_bounty_get_item()
}
// Get the corpse.
- item_tester_hook = bounty_item_tester_hook;
int item = -1;
bool_ ret =
get_item(&item,
"What corpse to return?",
"You have no corpse to return.",
- USE_INVEN);
+ USE_INVEN,
+ bounty_item_tester_hook);
if (!ret) {
return FALSE;
}
diff --git a/src/q_fireprof.cc b/src/q_fireprof.cc
index dbf26c0b..d768ad8b 100644
--- a/src/q_fireprof.cc
+++ b/src/q_fireprof.cc
@@ -77,38 +77,27 @@ static int fireproof_get_sval()
return cquest.data[1];
}
-static bool_ item_tester_hook_eligible(object_type *o_ptr)
+static bool item_tester_hook_eligible(object_type const *o_ptr)
{
/* check it's the 'marked' item */
- if ((o_ptr->tval == fireproof_get_settings()->tval) &&
+ return ((o_ptr->tval == fireproof_get_settings()->tval) &&
(o_ptr->sval == fireproof_get_sval()) &&
- (o_ptr->pval2 == fireproof_get_sval()))
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ (o_ptr->pval2 == fireproof_get_sval()));
}
-static bool_ item_tester_hook_proofable(object_type *o_ptr)
+static object_filter_t const &item_tester_hook_proofable()
{
- u32b f1, f2, f3, f4, f5, esp;
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- /* is it a book/staff/scroll, is it already fireproof? */
- if (((o_ptr->tval == TV_BOOK) ||
- (o_ptr->tval == TV_SCROLL) ||
- (o_ptr->tval == TV_STAFF))
- && ((f3 & TR3_IGNORE_FIRE) == 0))
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ using namespace object_filter;
+ static auto instance = And(
+ // Must be the correct item base type
+ Or(
+ TVal(TV_BOOK),
+ TVal(TV_SCROLL),
+ TVal(TV_STAFF)),
+ // Must NOT already be fireproof
+ Not(
+ HasFlag3(TR3_IGNORE_FIRE)));
+ return instance;
}
/*
@@ -170,12 +159,11 @@ static bool_ fireproof_enough_points(object_type *o_ptr, int *stack)
static bool_ fireproof()
{
int item;
-
- item_tester_hook = item_tester_hook_proofable;
if (!get_item(&item,
"Which item shall I fireproof?",
"You have no more items I can fireproof, come back when you have some.",
- USE_INVEN))
+ USE_INVEN,
+ item_tester_hook_proofable()))
{
return FALSE;
}
@@ -288,8 +276,7 @@ void quest_fireproof_building(bool_ *paid, bool_ *recreate)
snprintf(pni, sizeof(pni), "You have no %s to return", settings->tval_name_plural);
/* ask for item */
- item_tester_hook = item_tester_hook_eligible;
- ret = get_item(&item_idx, p, pni, USE_INVEN);
+ ret = get_item(&item_idx, p, pni, USE_INVEN, item_tester_hook_eligible);
/* didn't get the item? */
if (!ret)
diff --git a/src/randart.cc b/src/randart.cc
index 69adecc4..df5bd806 100644
--- a/src/randart.cc
+++ b/src/randart.cc
@@ -405,26 +405,24 @@ bool_ create_artifact(object_type *o_ptr, bool_ a_scroll, bool_ get_name)
bool_ artifact_scroll(void)
{
- int item;
bool_ okay = FALSE;
- object_type *o_ptr;
- char o_name[80];
-
- cptr q, s;
-
-
- /* Enchant weapon/armour */
- item_tester_hook = item_tester_hook_artifactable;
/* Get an item */
- q = "Enchant which item? ";
- s = "You have nothing to enchant.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return (FALSE);
+ int item;
+ if (!get_item(&item,
+ "Enchant which item? ",
+ "You have nothing to enchant.",
+ (USE_EQUIP | USE_INVEN | USE_FLOOR),
+ item_tester_hook_artifactable()))
+ {
+ return (FALSE);
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Description */
+ char o_name[80];
object_desc(o_name, o_ptr, FALSE, 0);
/* Describe */
diff --git a/src/spells2.cc b/src/spells2.cc
index fe26a53f..cdf21755 100644
--- a/src/spells2.cc
+++ b/src/spells2.cc
@@ -672,23 +672,24 @@ bool_ alchemy(void) /* Turns an object into gold, gain some of its value in a sh
int old_number;
long price;
bool_ force = FALSE;
- object_type *o_ptr;
char o_name[80];
char out_val[160];
- cptr q, s;
-
/* Hack -- force destruction */
if (command_arg > 0) force = TRUE;
/* Get an item */
- q = "Turn which item to gold? ";
- s = "You have nothing to turn to gold.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return (FALSE);
+ if (!get_item(&item,
+ "Turn which item to gold? ",
+ "You have nothing to turn to gold.",
+ (USE_INVEN | USE_FLOOR),
+ object_filter::True()))
+ {
+ return (FALSE);
+ }
/* Get the item */
- o_ptr = get_object(item);
-
+ object_type *o_ptr = get_object(item);
/* See how many items */
if (o_ptr->number > 1)
@@ -2781,95 +2782,72 @@ void stair_creation(void)
/*
* Hook to specify "weapon"
*/
-static bool_ item_tester_hook_weapon(object_type *o_ptr)
-{
- switch (o_ptr->tval)
- {
- case TV_MSTAFF:
- case TV_BOOMERANG:
- case TV_SWORD:
- case TV_AXE:
- case TV_HAFTED:
- case TV_POLEARM:
- case TV_BOW:
- case TV_BOLT:
- case TV_ARROW:
- case TV_SHOT:
- {
- return (TRUE);
- }
- case TV_DAEMON_BOOK:
- {
- switch (o_ptr->sval)
- {
- case SV_DEMONBLADE:
- {
- return (TRUE);
- }
- }
- }
- }
-
- return (FALSE);
+static object_filter_t const &item_tester_hook_weapon()
+{
+ using namespace object_filter;
+ static auto instance =
+ Or(
+ TVal(TV_MSTAFF),
+ TVal(TV_BOOMERANG),
+ TVal(TV_SWORD),
+ TVal(TV_AXE),
+ TVal(TV_HAFTED),
+ TVal(TV_POLEARM),
+ TVal(TV_BOW),
+ TVal(TV_BOLT),
+ TVal(TV_ARROW),
+ TVal(TV_SHOT),
+ And(
+ TVal(TV_DAEMON_BOOK),
+ SVal(SV_DEMONBLADE)));
+ return instance;
}
/*
* Hook to specify "armour"
*/
-static bool_ item_tester_hook_armour(object_type *o_ptr)
-{
- switch (o_ptr->tval)
- {
- case TV_DRAG_ARMOR:
- case TV_HARD_ARMOR:
- case TV_SOFT_ARMOR:
- case TV_SHIELD:
- case TV_CLOAK:
- case TV_CROWN:
- case TV_HELM:
- case TV_BOOTS:
- case TV_GLOVES:
- {
- return (TRUE);
- }
- case TV_DAEMON_BOOK:
- {
- switch (o_ptr->sval)
- {
- case SV_DEMONHORN:
- case SV_DEMONSHIELD:
- {
- return (TRUE);
- }
- }
- }
- }
-
- return (FALSE);
+static object_filter_t const &item_tester_hook_armour()
+{
+ using namespace object_filter;
+ static auto instance =
+ Or(
+ TVal(TV_DRAG_ARMOR),
+ TVal(TV_HARD_ARMOR),
+ TVal(TV_SOFT_ARMOR),
+ TVal(TV_SHIELD),
+ TVal(TV_CLOAK),
+ TVal(TV_CROWN),
+ TVal(TV_HELM),
+ TVal(TV_BOOTS),
+ TVal(TV_GLOVES),
+ And(
+ TVal(TV_DAEMON_BOOK),
+ Or(
+ SVal(SV_DEMONHORN),
+ SVal(SV_DEMONSHIELD))));
+ return instance;
}
/*
- * Check if an object is weapon or armour (but not arrow, bolt, or shot)
- */
-bool_ item_tester_hook_weapon_armour(object_type *o_ptr)
-{
- return (item_tester_hook_weapon(o_ptr) ||
- item_tester_hook_armour(o_ptr));
-}
-
-/*
* Check if an object is artifactable
*/
-bool_ item_tester_hook_artifactable(object_type *o_ptr)
+object_filter_t const &item_tester_hook_artifactable()
{
- return ((item_tester_hook_weapon(o_ptr) ||
- item_tester_hook_armour(o_ptr) ||
- (o_ptr->tval == TV_DIGGING) ||
- (o_ptr->tval == TV_RING) || (o_ptr->tval == TV_AMULET))
- /* be nice: allow only normal items */
- && (!artifact_p(o_ptr)) && (!ego_item_p(o_ptr)));
+ using namespace object_filter;
+ static auto instance = And(
+ // Check base item family
+ Or(
+ item_tester_hook_weapon(),
+ item_tester_hook_armour(),
+ TVal(TV_DIGGING),
+ TVal(TV_RING),
+ TVal(TV_AMULET)),
+ // Only unenchanted items
+ Not(IsArtifactP()),
+ Not(IsEgo()));
+ return instance;
}
@@ -3069,24 +3047,26 @@ bool_ enchant_spell(int num_hit, int num_dam, int num_ac, int num_pval)
{
int item;
bool_ okay = FALSE;
- object_type *o_ptr;
char o_name[80];
cptr q, s;
/* Assume enchant weapon */
- item_tester_hook = item_tester_hook_weapon;
+ object_filter_t object_filter = item_tester_hook_weapon();
/* Enchant armor if requested */
- if (num_ac) item_tester_hook = item_tester_hook_armour;
+ if (num_ac)
+ {
+ object_filter = item_tester_hook_armour();
+ }
/* Get an item */
q = "Enchant which item? ";
s = "You have nothing to enchant.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return (FALSE);
+ if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR), object_filter)) return (FALSE);
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Description */
object_desc(o_name, o_ptr, FALSE, 0);
@@ -3441,17 +3421,6 @@ void random_resistance (object_type * o_ptr, bool_ is_scroll, int specific)
/*
- * Determines if an item is not identified
- */
-static bool_ item_tester_hook_unknown(object_type *o_ptr)
-{
- return (object_known_p(o_ptr) ? FALSE : TRUE);
-}
-
-
-
-
-/*
* Make note of found artifacts.
*/
static void note_found_object(object_type *o_ptr)
@@ -3479,22 +3448,16 @@ static void note_found_object(object_type *o_ptr)
*/
bool_ ident_spell(void)
{
- int item;
-
- object_type *o_ptr;
-
- char o_name[80];
-
- cptr q, s;
-
/* Get an item */
- item_tester_hook = item_tester_hook_unknown;
- q = "Identify which item? ";
- s = "You have nothing to identify.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return (FALSE);
+ int item;
+ if (!get_item(&item,
+ "Identify which item? ",
+ "You have nothing to identify.",
+ (USE_EQUIP | USE_INVEN | USE_FLOOR),
+ object_filter::Not(object_known_p))) return (FALSE);
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Identify it fully */
object_aware(o_ptr);
@@ -3510,6 +3473,7 @@ bool_ ident_spell(void)
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
/* Description */
+ char o_name[80];
object_desc(o_name, o_ptr, TRUE, 3);
/* Describe */
@@ -3573,9 +3537,9 @@ bool_ ident_all(void)
/*
* Determine if an object is not fully identified
*/
-static bool_ item_tester_hook_no_mental(object_type *o_ptr)
+static bool item_tester_hook_no_mental(object_type const *o_ptr)
{
- return ((o_ptr->ident & (IDENT_MENTAL)) ? FALSE : TRUE);
+ return ((o_ptr->ident & (IDENT_MENTAL)) ? false : true);
}
/*
@@ -3584,20 +3548,19 @@ static bool_ item_tester_hook_no_mental(object_type *o_ptr)
*/
bool_ identify_fully(void)
{
- int item;
- object_type *o_ptr;
- char o_name[80];
-
- cptr q, s;
-
/* Get an item */
- item_tester_hook = item_tester_hook_no_mental;
- q = "Identify which item? ";
- s = "You have nothing to identify.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return (FALSE);
+ int item;
+ if (!get_item(&item,
+ "Identify which item? ",
+ "You have nothing to identify.",
+ (USE_EQUIP | USE_INVEN | USE_FLOOR),
+ item_tester_hook_no_mental))
+ {
+ return (FALSE);
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Do the identification */
make_item_fully_identified(o_ptr);
@@ -3612,6 +3575,7 @@ bool_ identify_fully(void)
p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
/* Description */
+ char o_name[80];
object_desc(o_name, o_ptr, TRUE, 3);
/* Describe */
@@ -3650,27 +3614,19 @@ bool_ identify_fully(void)
/*
* Hook for "get_item()". Determine if something is rechargable.
*/
-bool_ item_tester_hook_recharge(object_type *o_ptr)
+object_filter_t const &item_tester_hook_recharge()
{
- u32b f1, f2, f3, f4, f5, esp;
-
- /* Extract the flags */
- object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
-
- /* Some objects cannot be recharged */
- if (f4 & TR4_NO_RECHARGE) return (FALSE);
-
- /* Recharge staffs */
- if (o_ptr->tval == TV_STAFF) return (TRUE);
-
- /* Recharge wands */
- if (o_ptr->tval == TV_WAND) return (TRUE);
-
- /* Hack -- Recharge rods */
- if (o_ptr->tval == TV_ROD_MAIN) return (TRUE);
-
- /* Nope */
- return (FALSE);
+ using namespace object_filter;
+ static auto instance =
+ And(
+ // Must NOT have NO_RECHARGE flag.
+ Not(HasFlag4(TR4_NO_RECHARGE)),
+ // ... and must be a device.
+ Or(
+ TVal(TV_STAFF),
+ TVal(TV_WAND),
+ TVal(TV_ROD_MAIN)));
+ return instance;
}
@@ -3697,31 +3653,28 @@ bool_ item_tester_hook_recharge(object_type *o_ptr)
bool_ recharge(int power)
{
int recharge_strength, recharge_amount;
- int item, lev;
-
+ int lev;
bool_ fail = FALSE;
byte fail_type = 1;
-
- cptr q, s;
-
- u32b f1, f2, f3, f4, f5, esp;
char o_name[80];
- object_type *o_ptr;
-
- /* Only accept legal items */
- item_tester_hook = item_tester_hook_recharge;
-
/* Get an item */
- q = "Recharge which item? ";
- s = "You have nothing to recharge.";
- if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return (FALSE);
+ int item;
+ if (!get_item(&item,
+ "Recharge which item? ",
+ "You have nothing to recharge.",
+ (USE_INVEN | USE_FLOOR),
+ item_tester_hook_recharge()))
+ {
+ return (FALSE);
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* Extract the flags */
+ u32b f1, f2, f3, f4, f5, esp;
object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
/* Extract the object "level" */
diff --git a/src/spells2.hpp b/src/spells2.hpp
index 515cf3c7..825391da 100644
--- a/src/spells2.hpp
+++ b/src/spells2.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "angband.h"
+#include "object_filter.hpp"
extern void curse_artifact(object_type * o_ptr);
extern void grow_things(s16b type, int rad);
@@ -98,10 +99,10 @@ extern void alter_reality(void);
extern void report_magics(void);
extern void teleport_swap(int dir);
extern void swap_position(int lty, int ltx);
-extern bool_ item_tester_hook_recharge(object_type *o_ptr);
+extern object_filter_t const &item_tester_hook_recharge();
extern bool_ project_hack(int typ, int dam);
extern void project_meteor(int radius, int typ, int dam, u32b flg);
-extern bool_ item_tester_hook_artifactable(object_type *o_ptr);
+extern object_filter_t const &item_tester_hook_artifactable();
extern bool_ passwall(int dir, bool_ safe);
extern bool_ project_hook(int typ, int dir, int dam, int flg);
extern bool_ reset_recall(bool_ no_trepas_max_depth);
diff --git a/src/spells3.cc b/src/spells3.cc
index 00cdfcc4..20701d0d 100644
--- a/src/spells3.cc
+++ b/src/spells3.cc
@@ -1384,11 +1384,15 @@ const char *fire_firewall_info()
return buf;
}
-bool_ item_tester_hook_fire_golem(object_type *o_ptr)
+object_filter_t const &item_tester_hook_fire_golem()
{
- return ((o_ptr->tval == TV_LITE) &&
- ((o_ptr->sval == SV_LITE_TORCH) ||
- (o_ptr->sval == SV_LITE_LANTERN)));
+ using namespace object_filter;
+ static auto instance = And(
+ TVal(TV_LITE),
+ Or(
+ SVal(SV_LITE_TORCH),
+ SVal(SV_LITE_LANTERN)));
+ return instance;
}
casting_result fire_golem()
@@ -1400,12 +1404,12 @@ casting_result fire_golem()
return NO_CAST;
}
- item_tester_hook = item_tester_hook_fire_golem;
int item;
if (!get_item(&item,
"Which light source do you want to use to create the golem?",
"You have no light source for the golem",
- USE_INVEN | USE_EQUIP))
+ USE_INVEN | USE_EQUIP,
+ item_tester_hook_fire_golem()))
{
return NO_CAST;
}
@@ -2949,32 +2953,31 @@ int levels_in_book(s32b sval, s32b pval)
return levels;
}
-static bool_ udun_object_is_drainable(object_type *o_ptr)
+static object_filter_t const &udun_object_is_drainable()
{
- return ((o_ptr->tval == TV_WAND) ||
- (o_ptr->tval == TV_ROD_MAIN) ||
- (o_ptr->tval == TV_STAFF));
+ using namespace object_filter;
+ static auto instance = Or(
+ TVal(TV_WAND),
+ TVal(TV_ROD_MAIN),
+ TVal(TV_STAFF));
+ return instance;
}
casting_result udun_drain()
{
- int item;
- object_type *o_ptr = NULL;
-
/* Ask for an item */
- item_tester_hook = udun_object_is_drainable;
+ int item;
if (!get_item(&item,
"What item to drain?",
"You have nothing you can drain",
- USE_INVEN))
+ USE_INVEN,
+ udun_object_is_drainable()))
{
return NO_CAST;
}
/* Drain */
-
- /* get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
switch (o_ptr->tval)
{
@@ -4038,34 +4041,27 @@ const char *aule_firebrand_info()
return buf;
}
-static bool_ aule_enchant_weapon_item_tester(object_type *o_ptr)
+static object_filter_t const &aule_enchant_weapon_item_tester()
{
- if (o_ptr->name1 > 0)
- {
- return FALSE;
- }
-
- switch (o_ptr->tval)
- {
- case TV_MSTAFF:
- case TV_BOW:
- case TV_HAFTED:
- case TV_POLEARM:
- case TV_SWORD:
- case TV_AXE:
- return TRUE;
-
- default:
- return FALSE;
- }
+ using namespace object_filter;
+ static auto instance = And(
+ // Cannot enchant artifacts, spell is probably already too overpowered.
+ Not(IsArtifact()),
+ // Only weapons which Aule likes
+ Or(
+ TVal(TV_MSTAFF),
+ TVal(TV_BOW),
+ TVal(TV_HAFTED),
+ TVal(TV_POLEARM),
+ TVal(TV_SWORD),
+ TVal(TV_AXE)));
+ return instance;
}
casting_result aule_enchant_weapon_spell()
{
s32b level = get_level_s(AULE_ENCHANT_WEAPON, 50);
s16b num_h, num_d, num_p;
- int item;
- object_type *o_ptr = NULL;
num_h = 1 + randint(level/12);
num_d = 0;
@@ -4080,16 +4076,17 @@ casting_result aule_enchant_weapon_spell()
num_p = 1;
}
- item_tester_hook = aule_enchant_weapon_item_tester;
+ int item;
if (!get_item(&item,
"Which object do you want to enchant?",
"You have no objects to enchant.",
- USE_INVEN))
+ USE_INVEN,
+ aule_enchant_weapon_item_tester()))
{
return NO_CAST;
}
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
o_ptr->to_h = o_ptr->to_h + num_h;
o_ptr->to_d = o_ptr->to_d + num_d;
@@ -4107,29 +4104,25 @@ const char *aule_enchant_weapon_info()
return buf;
}
-bool_ aule_enchant_armor_item_tester(object_type *o_ptr)
+static object_filter_t const &aule_enchant_armor_item_tester()
{
- if (o_ptr->name1 > 0)
- {
- return FALSE;
- }
-
- switch (o_ptr->tval)
- {
- case TV_BOOTS:
- case TV_GLOVES:
- case TV_HELM:
- case TV_CROWN:
- case TV_SHIELD:
- case TV_CLOAK:
- case TV_SOFT_ARMOR:
- case TV_HARD_ARMOR:
- case TV_DRAG_ARMOR:
- return TRUE;
-
- default:
- return FALSE;
- }
+ using namespace object_filter;
+ static auto instance = And(
+ // No enchanting artifacts; the spell is already horribly
+ // overpowered.
+ Not(IsArtifact()),
+ // Only armor-like things can be enchanted
+ Or(
+ TVal(TV_BOOTS),
+ TVal(TV_GLOVES),
+ TVal(TV_HELM),
+ TVal(TV_CROWN),
+ TVal(TV_SHIELD),
+ TVal(TV_CLOAK),
+ TVal(TV_SOFT_ARMOR),
+ TVal(TV_HARD_ARMOR),
+ TVal(TV_DRAG_ARMOR)));
+ return instance;
}
casting_result aule_enchant_armour_spell()
@@ -4137,7 +4130,6 @@ casting_result aule_enchant_armour_spell()
s32b level = get_level_s(AULE_ENCHANT_ARMOUR, 50);
s16b num_h, num_d, num_a, num_p;
int item;
- object_type *o_ptr = NULL;
num_a = 1 + randint(level/10);
num_h = 0;
@@ -4153,16 +4145,16 @@ casting_result aule_enchant_armour_spell()
num_p = 1;
}
- item_tester_hook = aule_enchant_armor_item_tester;
if (!get_item(&item,
"Which object do you want to enchant?",
"You have no objects to enchant.",
- USE_INVEN))
+ USE_INVEN,
+ aule_enchant_armor_item_tester()))
{
return NO_CAST;
}
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
o_ptr->to_h = o_ptr->to_h + num_h;
o_ptr->to_d = o_ptr->to_d + num_d;
diff --git a/src/store.cc b/src/store.cc
index 4a384b06..578343b6 100644
--- a/src/store.cc
+++ b/src/store.cc
@@ -627,17 +627,26 @@ static bool_ is_blessed(object_type const *o_ptr)
*
* Note that a shop-keeper must refuse to buy "worthless" items
*/
-static bool_ store_will_buy(object_type *o_ptr)
+static bool store_will_buy(object_type const *o_ptr)
{
cptr store_name = st_info[st_ptr->st_idx].name;
/* Hack -- The Home is simple */
- if (cur_store_num == 7) return (TRUE);
+ if (cur_store_num == 7)
+ {
+ return true;
+ }
- if (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM) return TRUE;
+ if (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM)
+ {
+ return true;
+ }
/* XXX XXX XXX Ignore "worthless" items */
- if (object_value(o_ptr) <= 0) return (FALSE);
+ if (object_value(o_ptr) <= 0)
+ {
+ return false;
+ }
/* What do stores buy? */
if (streq(store_name, STORE_GENERAL_STORE))
@@ -655,7 +664,7 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_DIGGING:
case TV_CLOAK:
case TV_BOTTLE:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_ARMOURY))
@@ -671,7 +680,7 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_SOFT_ARMOR:
case TV_HARD_ARMOR:
case TV_DRAG_ARMOR:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_WEAPONSMITH))
@@ -689,7 +698,7 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_SWORD:
case TV_AXE:
case TV_MSTAFF:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_TEMPLE))
@@ -701,34 +710,34 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_POTION2:
case TV_POTION:
case TV_HAFTED:
- return TRUE;
+ return true;
}
if ((o_ptr->tval == TV_BOOK) &&
(o_ptr->sval == BOOK_RANDOM) &&
(spell_type_random_type(spell_at(o_ptr->pval)) == SKILL_SPIRITUALITY))
{
- return TRUE;
+ return true;
}
else if ((o_ptr->tval == TV_POLEARM) &&
is_blessed(o_ptr))
{
- return TRUE;
+ return true;
}
else if ((o_ptr->tval == TV_SWORD) &&
is_blessed(o_ptr))
{
- return TRUE;
+ return true;
}
else if ((o_ptr->tval == TV_AXE) &&
is_blessed(o_ptr))
{
- return TRUE;
+ return true;
}
else if ((o_ptr->tval == TV_BOOMERANG) &&
is_blessed(o_ptr))
{
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_ALCHEMY))
@@ -740,7 +749,7 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_POTION:
case TV_BATERIE:
case TV_BOTTLE:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_MAGIC))
@@ -759,24 +768,24 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_POTION:
case TV_MSTAFF:
case TV_RANDART:
- return TRUE;
+ return true;
}
if ((o_ptr->tval == TV_BOOK) &&
(o_ptr->sval == BOOK_RANDOM) &&
(spell_type_random_type(spell_at(o_ptr->pval)) == SKILL_MAGIC))
{
- return TRUE;
+ return true;
}
else if ((o_ptr->tval == TV_BOOK) &&
(o_ptr->sval != BOOK_RANDOM))
{
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_BLACK_MARKET))
{
- return TRUE;
+ return true;
}
else if (streq(store_name, STORE_BOOKS))
{
@@ -787,7 +796,7 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_MUSIC_BOOK:
case TV_DAEMON_BOOK:
case TV_DRUID_BOOK:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_PETS))
@@ -805,7 +814,7 @@ static bool_ store_will_buy(object_type *o_ptr)
case TV_ARROW:
case TV_BOW:
case TV_POTION2:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_RUNIC_MAGIC))
@@ -814,7 +823,7 @@ static bool_ store_will_buy(object_type *o_ptr)
{
case TV_RUNE1:
case TV_RUNE2:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_CONSTRUCTION_SUPPLIES))
@@ -823,7 +832,7 @@ static bool_ store_will_buy(object_type *o_ptr)
{
case TV_LITE:
case TV_DIGGING:
- return TRUE;
+ return true;
}
}
else if (streq(store_name, STORE_MUSIC))
@@ -832,7 +841,7 @@ static bool_ store_will_buy(object_type *o_ptr)
}
/* Assume not okay */
- return (FALSE);
+ return false;
}
@@ -2435,36 +2444,35 @@ void store_sell(void)
object_type *o_ptr;
- cptr q, s;
-
char o_name[80];
u32b f1, f2, f3, f4, f5, esp;
bool_ museum = (st_info[st_ptr->st_idx].flags1 & SF1_MUSEUM) ? TRUE : FALSE;
- /* Prepare a prompt */
- if (cur_store_num == 7) q = "Drop which item? ";
- else if (museum) q = "Donate which item?";
- else q = "Sell which item? ";
-
- /* Only allow items the store will buy */
- item_tester_hook = store_will_buy;
-
- /* Get an item */
+ /* Prepare prompt */
+ cptr q, s;
if (cur_store_num == STORE_HOME)
{
+ q = "Drop which item? ";
s = "You have nothing to drop.";
}
else if (museum)
{
+ q = "Donate which item?";
s = "You have nothing to donate.";
}
else
{
+ q = "Sell which item? ";
s = "You have nothing that I want.";
}
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN))) return;
+
+ /* Get an item */
+ if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN), store_will_buy))
+ {
+ return;
+ }
/* Get the item */
o_ptr = get_object(item);
diff --git a/src/traps.cc b/src/traps.cc
index ad20e0aa..6883386e 100644
--- a/src/traps.cc
+++ b/src/traps.cc
@@ -2141,26 +2141,11 @@ void wiz_place_trap(int y, int x, int idx)
/*
* Hook to determine if an object is a device
*/
-static bool_ item_tester_hook_device(object_type *o_ptr)
+static bool item_tester_hook_device(object_type const *o_ptr)
{
- if (((o_ptr->tval == TV_ROD_MAIN) && (o_ptr->pval != 0)) ||
+ return (((o_ptr->tval == TV_ROD_MAIN) && (o_ptr->pval != 0)) ||
(o_ptr->tval == TV_STAFF) ||
- (o_ptr->tval == TV_WAND)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
-}
-
-/*
- * Hook to determine if an object is a potion
- */
-static bool_ item_tester_hook_potion(object_type *o_ptr)
-{
- if ((o_ptr->tval == TV_POTION) ||
- (o_ptr->tval == TV_POTION2)) return (TRUE);
-
- /* Assume not */
- return (FALSE);
+ (o_ptr->tval == TV_WAND));
}
/*
@@ -2205,46 +2190,46 @@ void do_cmd_set_trap(void)
return;
}
- /* Restrict choices to trapkits */
- item_tester_tval = TV_TRAPKIT;
-
/* Get an item */
q = "Use which trapping kit? ";
s = "You have no trapping kits.";
- if (!get_item(&item_kit, q, s, USE_INVEN)) return;
+ if (!get_item(&item_kit,
+ q, s,
+ USE_INVEN,
+ object_filter::TVal(TV_TRAPKIT)))
+ {
+ return;
+ }
o_ptr = &p_ptr->inventory[item_kit];
/* Trap kits need a second object */
- switch (o_ptr->sval)
- {
- case SV_TRAPKIT_BOW:
- item_tester_tval = TV_ARROW;
- break;
- case SV_TRAPKIT_XBOW:
- item_tester_tval = TV_BOLT;
- break;
- case SV_TRAPKIT_SLING:
- item_tester_tval = TV_SHOT;
- break;
- case SV_TRAPKIT_POTION:
- item_tester_hook = item_tester_hook_potion;
- break;
- case SV_TRAPKIT_SCROLL:
- item_tester_tval = TV_SCROLL;
- break;
- case SV_TRAPKIT_DEVICE:
- item_tester_hook = item_tester_hook_device;
- break;
- default:
- msg_print("Unknown trapping kit type!");
- break;
- }
+ object_filter_t object_filter = object_filter::Or(
+ object_filter::And(
+ object_filter::SVal(SV_TRAPKIT_BOW),
+ object_filter::TVal(TV_ARROW)),
+ object_filter::And(
+ object_filter::SVal(SV_TRAPKIT_XBOW),
+ object_filter::TVal(TV_BOLT)),
+ object_filter::And(
+ object_filter::SVal(SV_TRAPKIT_SLING),
+ object_filter::TVal(TV_SHOT)),
+ object_filter::And(
+ object_filter::SVal(SV_TRAPKIT_POTION),
+ object_filter::Or(
+ object_filter::TVal(TV_POTION),
+ object_filter::TVal(TV_POTION2))),
+ object_filter::And(
+ object_filter::SVal(SV_TRAPKIT_SCROLL),
+ object_filter::TVal(TV_SCROLL)),
+ object_filter::And(
+ object_filter::SVal(SV_TRAPKIT_DEVICE),
+ &item_tester_hook_device));
/* Get the second item */
q = "Load with what? ";
s = "You have nothing to load that trap with.";
- if (!get_item(&item_load, q, s, USE_INVEN)) return;
+ if (!get_item(&item_load, q, s, USE_INVEN, object_filter)) return;
/* Get the second object */
j_ptr = &p_ptr->inventory[item_load];
diff --git a/src/variable.cc b/src/variable.cc
index ca7696dd..9af43907 100644
--- a/src/variable.cc
+++ b/src/variable.cc
@@ -716,28 +716,6 @@ char *ANGBAND_DIR_XTRA;
/*
- * Total Hack -- allow all items to be listed (even empty ones)
- * This is only used by "do_cmd_inven_e()" and is cleared there.
- */
-bool_ item_tester_full;
-
-
-/*
- * Here is a "pseudo-hook" used during calls to "get_item()" and
- * "show_inven()" and "show_equip()", and the choice window routines.
- */
-byte item_tester_tval;
-
-
-/*
- * Here is a "hook" used during calls to "get_item()" and
- * "show_inven()" and "show_equip()", and the choice window routines.
- */
-bool_ (*item_tester_hook)(object_type*);
-
-
-
-/*
* Hack -- function hooks to restrict "get_mon_num_prep()" function
*/
bool_ (*get_mon_num_hook)(int r_idx);
diff --git a/src/variable.hpp b/src/variable.hpp
index d28f9757..586fdddc 100644
--- a/src/variable.hpp
+++ b/src/variable.hpp
@@ -179,9 +179,6 @@ extern cptr DEFAULT_FEAT_TUNNEL;
extern cptr DEFAULT_FEAT_BLOCK;
extern cptr ANGBAND_GRAF;
extern char *ANGBAND_DIR;
-extern bool_ item_tester_full;
-extern byte item_tester_tval;
-extern bool_ (*item_tester_hook)(object_type *o_ptr);
extern bool_ (*get_mon_num_hook)(int r_idx);
extern bool_ (*get_mon_num2_hook)(int r_idx);
extern bool_ (*get_obj_num_hook)(int k_idx);
diff --git a/src/wizard2.cc b/src/wizard2.cc
index 046a95bc..692bacb4 100644
--- a/src/wizard2.cc
+++ b/src/wizard2.cc
@@ -1067,30 +1067,22 @@ static void wiz_quantity_item(object_type *o_ptr)
*/
static void do_cmd_wiz_play(void)
{
- int item;
-
- object_type forge;
- object_type *q_ptr;
-
- object_type *o_ptr;
-
- char ch;
-
- bool_ changed;
-
- cptr q, s;
-
/* Get an item */
- q = "Play with which object? ";
- s = "You have nothing to play with.";
- if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;
+ int item;
+ if (!get_item(&item,
+ "Play with which object? ",
+ "You have nothing to play with.",
+ (USE_EQUIP | USE_INVEN | USE_FLOOR)))
+ {
+ return;
+ }
/* Get the item */
- o_ptr = get_object(item);
+ object_type *o_ptr = get_object(item);
/* The item was not changed */
- changed = FALSE;
+ bool_ changed = FALSE;
/* Icky */
@@ -1101,7 +1093,8 @@ static void do_cmd_wiz_play(void)
/* Get local object */
- q_ptr = &forge;
+ object_type forge;
+ object_type *q_ptr = &forge;
/* Copy object */
object_copy(q_ptr, o_ptr);
@@ -1110,6 +1103,8 @@ static void do_cmd_wiz_play(void)
/* The main loop */
while (TRUE)
{
+ char ch;
+
/* Display the item */
wiz_display_item(q_ptr);