summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBardur Arantsson <bardur@scientician.net>2015-04-14 06:39:21 +0200
committerBardur Arantsson <bardur@scientician.net>2015-04-14 06:39:21 +0200
commita029d18b62794a44dbaf3530d1d20663287f3ce2 (patch)
treed4ba5e6404728d8f67836578dc078900f2f5d7f2 /src
parent51b1e2dc27441812d7a3006b5d98834c95618e48 (diff)
Add pseudo-ID for items at player's feet
It's a bit silly and tedious play-wise to force player to actually pick things up for pseudo-ID to kick in.
Diffstat (limited to 'src')
-rw-r--r--src/dungeon.cc109
-rw-r--r--src/dungeon.hpp3
-rw-r--r--src/object1.cc58
3 files changed, 94 insertions, 76 deletions
diff --git a/src/dungeon.cc b/src/dungeon.cc
index abcc6cae..34dd781d 100644
--- a/src/dungeon.cc
+++ b/src/dungeon.cc
@@ -70,11 +70,15 @@
#define AUTO_CURSE_CHANCE 15
#define CHAINSWORD_NOISE 100
+/**
+ * Type of a "sense" function
+ */
+typedef byte (*sense_function_t)(object_type const *o_ptr);
/*
* Return a "feeling" (or NULL) about an item. Method 1 (Heavy).
*/
-static byte value_check_aux1(object_type *o_ptr)
+static byte value_check_aux1(object_type const *o_ptr)
{
/* Artifacts */
if (artifact_p(o_ptr))
@@ -109,7 +113,7 @@ static byte value_check_aux1(object_type *o_ptr)
return (SENSE_AVERAGE);
}
-static byte value_check_aux1_magic(object_type *o_ptr)
+static byte value_check_aux1_magic(object_type const *o_ptr)
{
object_kind *k_ptr = &k_info[o_ptr->k_idx];
@@ -176,7 +180,7 @@ static byte value_check_aux1_magic(object_type *o_ptr)
/*
* Return a "feeling" (or NULL) about an item. Method 2 (Light).
*/
-static byte value_check_aux2(object_type *o_ptr)
+static byte value_check_aux2(object_type const *o_ptr)
{
/* Cursed items (all of them) */
if (cursed_p(o_ptr)) return (SENSE_CURSED);
@@ -198,7 +202,7 @@ static byte value_check_aux2(object_type *o_ptr)
}
-static byte value_check_aux2_magic(object_type *o_ptr)
+static byte value_check_aux2_magic(object_type const *o_ptr)
{
object_kind *k_ptr = &k_info[o_ptr->k_idx];
@@ -278,9 +282,8 @@ static bool_ granted_resurrection(void)
return (FALSE);
}
-static byte select_sense(object_type *o_ptr)
+static sense_function_t select_sense(object_type *o_ptr, sense_function_t combat, sense_function_t magic)
{
- /* Valid "tval" codes */
switch (o_ptr->tval)
{
case TV_SHOT:
@@ -305,8 +308,7 @@ static byte select_sense(object_type *o_ptr)
case TV_BOOMERANG:
case TV_TRAPKIT:
{
- return 1;
- break;
+ return combat;
}
case TV_POTION:
@@ -317,22 +319,21 @@ static byte select_sense(object_type *o_ptr)
case TV_ROD:
case TV_ROD_MAIN:
{
- return 2;
- break;
+ return magic;
}
/* Dual use? */
case TV_DAEMON_BOOK:
{
- return 1;
- break;
+ return combat;
}
}
- return 0;
+
+ return nullptr;
}
/*
- * Sense the inventory
+ * Sense quality of specific list of objects.
*
* Combat items (weapons and armour) - Fast, weak if combat skill < 10, strong
* otherwise.
@@ -344,21 +345,8 @@ static byte select_sense(object_type *o_ptr)
* they learn one form of ID or another, and because most magic items are
* easy_know.
*/
-void sense_inventory(void)
+void sense_objects(std::vector<int> const &object_idxs)
{
- int i, combat_lev, magic_lev;
-
- bool_ heavy_combat, heavy_magic;
-
- byte feel;
-
- object_type *o_ptr;
-
- char o_name[80];
-
-
- /*** Check for "sensing" ***/
-
/* No sensing when confused */
if (p_ptr->confused) return;
@@ -388,24 +376,21 @@ void sense_inventory(void)
*/
/* The combat skill affects weapon/armour pseudo-ID */
- combat_lev = get_skill(SKILL_COMBAT);
+ int combat_lev = get_skill(SKILL_COMBAT);
/* The magic skill affects magic item pseudo-ID */
- magic_lev = get_skill(SKILL_MAGIC);
+ int magic_lev = get_skill(SKILL_MAGIC);
/* Higher skill levels give the player better sense of items */
- heavy_combat = (combat_lev > 10) ? TRUE : FALSE;
- heavy_magic = (magic_lev > 10) ? TRUE : FALSE;
-
+ auto feel_combat = (combat_lev > 10) ? value_check_aux1 : value_check_aux2;
+ auto feel_magic = (magic_lev > 10) ? value_check_aux1_magic : value_check_aux2_magic;
/*** Sense everything ***/
/* Check everything */
- for (i = 0; i < INVEN_TOTAL; i++)
+ for (auto i : object_idxs)
{
- byte okay = 0;
-
- o_ptr = &p_ptr->inventory[i];
+ object_type *o_ptr = get_object(i);
/* Skip empty slots */
if (!o_ptr->k_idx) continue;
@@ -416,37 +401,39 @@ void sense_inventory(void)
/* It is fully known, no information needed */
if (object_known_p(o_ptr)) continue;
- /* Valid "tval" codes */
- okay = select_sense(o_ptr);
+ /* Select appropriate sensing function, if any */
+ sense_function_t sense = select_sense(o_ptr, feel_combat, feel_magic);
- /* Skip non-sense machines */
- if (!okay) continue;
-
- /* Check for a feeling */
- if (okay == 1)
- {
- feel = (heavy_combat ? value_check_aux1(o_ptr) : value_check_aux2(o_ptr));
- }
- else
+ /* Skip non-sensed items */
+ if (!sense)
{
- feel = (heavy_magic ? value_check_aux1_magic(o_ptr) : value_check_aux2_magic(o_ptr));
+ continue;
}
+ /* Check for a feeling */
+ byte feel = sense(o_ptr);
+
/* Skip non-feelings */
- if (feel == SENSE_NONE) continue;
+ if (feel == SENSE_NONE)
+ {
+ continue;
+ }
/* Get an object description */
+ char o_name[80];
object_desc(o_name, o_ptr, FALSE, 0);
- /* Message (equipment) */
- if (i >= INVEN_WIELD)
+ /* Messages */
+ if (i < 0) {
+ // We get a message from the floor handling code, so
+ // it would be overkill to have a message here too.
+ }
+ else if (i >= INVEN_WIELD)
{
msg_format("You feel the %s (%c) you are %s %s %s...",
o_name, index_to_label(i), describe_use(i),
((o_ptr->number == 1) ? "is" : "are"), sense_desc[feel]);
}
-
- /* Message (inventory) */
else
{
msg_format("You feel the %s (%c) in your pack %s %s...",
@@ -471,6 +458,20 @@ void sense_inventory(void)
squeltch_inventory();
}
+void sense_inventory(void)
+{
+ static std::vector<int> idxs;
+ // Initialize static vector if necessary
+ if (idxs.empty())
+ {
+ idxs.reserve(INVEN_TOTAL);
+ for (int i = 0; i < INVEN_TOTAL; i++)
+ {
+ idxs.push_back(i);
+ }
+ }
+ sense_objects(idxs);
+}
/*
* Go to any level (ripped off from wiz_jump)
diff --git a/src/dungeon.hpp b/src/dungeon.hpp
index 37d54d39..bbe6da87 100644
--- a/src/dungeon.hpp
+++ b/src/dungeon.hpp
@@ -1,3 +1,6 @@
#pragma once
+#include <vector>
+
extern void sense_inventory();
+extern void sense_objects(std::vector<int> const &object_idxs);
diff --git a/src/object1.cc b/src/object1.cc
index cb1a6604..25b848a0 100644
--- a/src/object1.cc
+++ b/src/object1.cc
@@ -4229,7 +4229,7 @@ static cptr mention_use(int i)
*/
cptr describe_use(int i)
{
- cptr p;
+ cptr p = nullptr;
switch (i)
{
@@ -6113,48 +6113,57 @@ void object_pickup(int this_o_idx)
void py_pickup_floor(int pickup)
{
- s16b this_o_idx, next_o_idx = 0;
-
- char o_name[80] = "";
- object_type *o_ptr = 0;
-
- int floor_num = 0, floor_o_idx = 0;
-
- bool_ do_pickup = TRUE;
-
- bool_ do_ask = TRUE;
-
/* Hack -- ignore monster traps */
if (cave[p_ptr->py][p_ptr->px].feat == FEAT_MON_TRAP) return;
/* Try to grab ammo */
pickup_ammo();
+ /* Build a list of the floor objects. */
+ std::vector<int> floor_object_idxs;
+ {
+ s16b this_o_idx = cave[p_ptr->py][p_ptr->px].o_idx;
+ /* Reserve a number of slots if at least one is needed */
+ if (this_o_idx)
+ {
+ floor_object_idxs.reserve(16); // Avoid resizing in the common case
+ }
+ /* Fill in the indexes */
+ for (; this_o_idx; this_o_idx = o_list[this_o_idx].next_o_idx)
+ {
+ // Note the "-"! We need it for get_object()
+ // lookups to function correctly.
+ floor_object_idxs.push_back(0 - this_o_idx);
+ }
+ }
+
/* Mega Hack -- If we have auto-Id, do an ID sweep *before* squleching,
* so that we don't have to walk over things twice to get them
* squelched. --dsb */
if (p_ptr->auto_id)
{
- this_o_idx = cave[p_ptr->py][p_ptr->px].o_idx;
-
- for (; this_o_idx; this_o_idx = next_o_idx)
+ for (auto const o_idx : floor_object_idxs)
{
- /* Aquire the object */
- o_ptr = &o_list[this_o_idx];
-
- /* Acquire the next object index */
- next_o_idx = o_ptr->next_o_idx;
-
- /* Identify Object */
+ object_type *o_ptr = get_object(o_idx);
object_aware(o_ptr);
object_known(o_ptr);
}
}
+ /* Sense floor tile */
+ sense_objects(floor_object_idxs);
+
/* Squeltch the floor */
squeltch_grid();
/* Scan the pile of objects */
+ s16b next_o_idx = 0;
+ char o_name[80] = "";
+ object_type *o_ptr = 0;
+ int floor_num = 0;
+ int floor_o_idx = 0;
+
+ s16b this_o_idx;
for (this_o_idx = cave[p_ptr->py][p_ptr->px].o_idx; this_o_idx; this_o_idx = next_o_idx)
{
/* Acquire object */
@@ -6190,6 +6199,7 @@ void py_pickup_floor(int pickup)
continue;
}
+ /* Describe */
{
char testdesc[80];
@@ -6234,6 +6244,10 @@ void py_pickup_floor(int pickup)
return;
}
+ /* Are we actually going to pick up and/or ask about which item to pick up? */
+ bool_ do_pickup = TRUE;
+ bool_ do_ask = TRUE;
+
/* One item */
if (floor_num == 1)
{