The master and develop branches track hengband.
OS X development happens on the macos-1-6-2, macos-2-2-1, and macos-develop branches.
修订版 | 19c1095adfb20fe9b69f02105ee80ebc0c3c10ae (tree) |
---|---|
时间 | 2022-11-26 05:05:32 |
作者 | Eric Branlund <ebranlund@fast...> |
Commiter | Eric Branlund |
Merge branch 'develop' into macos-develop
@@ -419,7 +419,7 @@ static void generate_unnatural_random_artifact( | ||
419 | 419 | msg_format_wizard(player_ptr, CHEAT_OBJECT, |
420 | 420 | _("パワー %d で 価値%ld のランダムアーティファクト生成 バイアスは「%s」", "Random artifact generated - Power:%d Value:%d Bias:%s."), max_powers, |
421 | 421 | total_flags, artifact_bias_name[o_ptr->artifact_bias]); |
422 | - set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_FLOOR_ITEM_LIST); | |
422 | + set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
423 | 423 | } |
424 | 424 | |
425 | 425 | /*! |
@@ -156,7 +156,7 @@ void random_plus(ItemEntity *o_ptr) | ||
156 | 156 | return; |
157 | 157 | } |
158 | 158 | |
159 | - int this_type = o_ptr->is_weapon_ammo() ? 23 : 19; | |
159 | + const auto this_type = o_ptr->is_weapon_ammo() ? 23 : 19; | |
160 | 160 | switch (randint1(this_type)) { |
161 | 161 | case 1: |
162 | 162 | case 2: |
@@ -204,7 +204,7 @@ bool exe_eat_charge_of_magic_device(PlayerType *player_ptr, ItemEntity *o_ptr, I | ||
204 | 204 | } |
205 | 205 | |
206 | 206 | if (item >= 0) { |
207 | - inven_item_charges(player_ptr, item); | |
207 | + inven_item_charges(player_ptr->inventory_list[item]); | |
208 | 208 | } else { |
209 | 209 | floor_item_charges(player_ptr->current_floor_ptr, 0 - item); |
210 | 210 | } |
@@ -195,7 +195,7 @@ void do_cmd_uninscribe(PlayerType *player_ptr) | ||
195 | 195 | msg_print(_("銘を消した。", "Inscription removed.")); |
196 | 196 | o_ptr->inscription = 0; |
197 | 197 | set_bits(player_ptr->update, PU_COMBINE); |
198 | - set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_FLOOR_ITEM_LIST); | |
198 | + set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
199 | 199 | set_bits(player_ptr->update, PU_BONUS); |
200 | 200 | } |
201 | 201 |
@@ -227,7 +227,7 @@ void do_cmd_inscribe(PlayerType *player_ptr) | ||
227 | 227 | if (get_string(_("銘: ", "Inscription: "), out_val, MAX_INSCRIPTION)) { |
228 | 228 | o_ptr->inscription = quark_add(out_val); |
229 | 229 | set_bits(player_ptr->update, PU_COMBINE); |
230 | - set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_FLOOR_ITEM_LIST); | |
230 | + set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
231 | 231 | set_bits(player_ptr->update, PU_BONUS); |
232 | 232 | } |
233 | 233 | } |
@@ -298,4 +298,9 @@ void window_stuff(PlayerType *player_ptr) | ||
298 | 298 | // ウィンドウサイズ変更に対応できず。カーソル位置を取る必要がある。 |
299 | 299 | fix_floor_item_list(player_ptr, player_ptr->y, player_ptr->x); |
300 | 300 | } |
301 | + | |
302 | + if (any_bits(window_flags, PW_FOUND_ITEM_LIST)) { | |
303 | + reset_bits(player_ptr->window_flags, PW_FOUND_ITEM_LIST); | |
304 | + fix_found_item_list(player_ptr); | |
305 | + } | |
301 | 306 | } |
@@ -18,9 +18,10 @@ enum window_redraw_type { | ||
18 | 18 | PW_OBJECT = 1U << 9, /*!<サブウィンドウ描画フラグ: アイテムの知識 / Display object recall */ |
19 | 19 | PW_DUNGEON = 1U << 10, /*!<サブウィンドウ描画フラグ: ダンジョンの地形 / Display dungeon view */ |
20 | 20 | PW_SNAPSHOT = 1U << 11, /*!<サブウィンドウ描画フラグ: 記念写真 / Display snap-shot */ |
21 | - PW_FLOOR_ITEM_LIST = 1U << 12, /*!<サブウィンドウ描画フラグ: 床上のアイテム一覧 / Display items at feet */ | |
21 | + PW_FLOOR_ITEM_LIST = 1U << 12, /*!<サブウィンドウ描画フラグ: 床上のアイテム一覧 / Display items on grid */ | |
22 | + PW_FOUND_ITEM_LIST = 1U << 13, /*!<サブウィンドウ描画フラグ: 発見済みのアイテム一覧 / Display found items*/ | |
22 | 23 | |
23 | - PW_ALL = (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER | PW_MONSTER_LIST | PW_MESSAGE | PW_OVERHEAD | PW_MONSTER | PW_OBJECT | PW_DUNGEON | PW_SNAPSHOT | PW_FLOOR_ITEM_LIST), | |
24 | + PW_ALL = (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER | PW_MONSTER_LIST | PW_MESSAGE | PW_OVERHEAD | PW_MONSTER | PW_OBJECT | PW_DUNGEON | PW_SNAPSHOT | PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST), | |
24 | 25 | }; |
25 | 26 | |
26 | 27 | // clang-format on |
@@ -234,7 +234,7 @@ void floor_item_increase(PlayerType *player_ptr, INVENTORY_IDX item, ITEM_NUMBER | ||
234 | 234 | num -= o_ptr->number; |
235 | 235 | o_ptr->number += num; |
236 | 236 | |
237 | - set_bits(player_ptr->window_flags, PW_FLOOR_ITEM_LIST); | |
237 | + set_bits(player_ptr->window_flags, PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
238 | 238 | } |
239 | 239 | |
240 | 240 | /*! |
@@ -255,7 +255,7 @@ void floor_item_optimize(PlayerType *player_ptr, INVENTORY_IDX item) | ||
255 | 255 | |
256 | 256 | delete_object_idx(player_ptr, item); |
257 | 257 | |
258 | - set_bits(player_ptr->window_flags, PW_FLOOR_ITEM_LIST); | |
258 | + set_bits(player_ptr->window_flags, PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
259 | 259 | } |
260 | 260 | |
261 | 261 | /*! |
@@ -282,7 +282,7 @@ void delete_object_idx(PlayerType *player_ptr, OBJECT_IDX o_idx) | ||
282 | 282 | j_ptr->wipe(); |
283 | 283 | floor_ptr->o_cnt--; |
284 | 284 | |
285 | - set_bits(player_ptr->window_flags, PW_FLOOR_ITEM_LIST); | |
285 | + set_bits(player_ptr->window_flags, PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
286 | 286 | } |
287 | 287 | |
288 | 288 | /*! |
@@ -559,7 +559,7 @@ OBJECT_IDX drop_near(PlayerType *player_ptr, ItemEntity *j_ptr, PERCENTAGE chanc | ||
559 | 559 | sound(SOUND_DROP); |
560 | 560 | |
561 | 561 | if (player_bold(player_ptr, by, bx)) { |
562 | - set_bits(player_ptr->window_flags, PW_FLOOR_ITEM_LIST); | |
562 | + set_bits(player_ptr->window_flags, PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
563 | 563 | } |
564 | 564 | |
565 | 565 | if (chance && player_bold(player_ptr, by, bx)) { |
@@ -359,6 +359,7 @@ void note_spot(PlayerType *player_ptr, POSITION y, POSITION x) | ||
359 | 359 | |
360 | 360 | /* Memorize objects */ |
361 | 361 | o_ptr->marked.set(OmType::FOUND); |
362 | + player_ptr->window_flags |= PW_FOUND_ITEM_LIST; | |
362 | 363 | } |
363 | 364 | |
364 | 365 | /* Hack -- memorize grids */ |
@@ -87,7 +87,7 @@ bool psychometry(PlayerType *player_ptr) | ||
87 | 87 | o_ptr->marked.set(OmType::TOUCHED); |
88 | 88 | |
89 | 89 | set_bits(player_ptr->update, PU_COMBINE | PU_REORDER); |
90 | - set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST); | |
90 | + set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
91 | 91 | |
92 | 92 | bool okay = false; |
93 | 93 | switch (o_ptr->tval) { |
@@ -58,7 +58,7 @@ bool bless_weapon(PlayerType *player_ptr) | ||
58 | 58 | set_bits(o_ptr->ident, IDENT_SENSE); |
59 | 59 | o_ptr->feeling = FEEL_NONE; |
60 | 60 | set_bits(player_ptr->update, PU_BONUS); |
61 | - set_bits(player_ptr->window_flags, PW_EQUIP | PW_FLOOR_ITEM_LIST); | |
61 | + set_bits(player_ptr->window_flags, PW_EQUIP | PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
62 | 62 | } |
63 | 63 | |
64 | 64 | /* |
@@ -132,7 +132,7 @@ bool bless_weapon(PlayerType *player_ptr) | ||
132 | 132 | } |
133 | 133 | |
134 | 134 | set_bits(player_ptr->update, PU_BONUS); |
135 | - set_bits(player_ptr->window_flags, PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST); | |
135 | + set_bits(player_ptr->window_flags, PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
136 | 136 | calc_android_exp(player_ptr); |
137 | 137 | return true; |
138 | 138 | } |
@@ -30,6 +30,7 @@ | ||
30 | 30 | #include "system/player-type-definition.h" |
31 | 31 | #include "util/bit-flags-calculator.h" |
32 | 32 | #include "view/display-messages.h" |
33 | +#include <core/window-redrawer.h> | |
33 | 34 | |
34 | 35 | /*! |
35 | 36 | * @brief オブジェクトのフラグを更新する |
@@ -154,6 +155,7 @@ static void monster_pickup_object(PlayerType *player_ptr, turn_flags *turn_flags | ||
154 | 155 | o_ptr->iy = o_ptr->ix = 0; |
155 | 156 | o_ptr->held_m_idx = m_idx; |
156 | 157 | m_ptr->hold_o_idx_list.add(player_ptr->current_floor_ptr, this_o_idx); |
158 | + player_ptr->window_flags |= PW_FOUND_ITEM_LIST; | |
157 | 159 | return; |
158 | 160 | } |
159 | 161 |
@@ -32,7 +32,7 @@ void AbstractWeaponEnchanter::give_killing_bonus() | ||
32 | 32 | auto tohit2 = static_cast<short>(m_bonus(10, this->level)); |
33 | 33 | auto todam2 = static_cast<short>(m_bonus(10, this->level)); |
34 | 34 | |
35 | - if ((this->o_ptr->tval == ItemKindType::BOLT) || (this->o_ptr->tval == ItemKindType::ARROW) || (this->o_ptr->tval == ItemKindType::SHOT)) { | |
35 | + if (this->o_ptr->is_ammo()) { | |
36 | 36 | tohit2 = (tohit2 + 1) / 2; |
37 | 37 | todam2 = (todam2 + 1) / 2; |
38 | 38 | } |
@@ -16,8 +16,7 @@ | ||
16 | 16 | */ |
17 | 17 | bool object_is_favorite(PlayerType *player_ptr, const ItemEntity *o_ptr) |
18 | 18 | { |
19 | - /* Only melee weapons match */ | |
20 | - if (!(o_ptr->tval == ItemKindType::POLEARM || o_ptr->tval == ItemKindType::SWORD || o_ptr->tval == ItemKindType::DIGGING || o_ptr->tval == ItemKindType::HAFTED)) { | |
19 | + if (!o_ptr->is_melee_weapon()) { | |
21 | 20 | return false; |
22 | 21 | } |
23 | 22 |
@@ -117,7 +117,7 @@ void ObjectUseEntity::execute() | ||
117 | 117 | gain_exp(this->player_ptr, (lev + (this->player_ptr->lev >> 1)) / this->player_ptr->lev); |
118 | 118 | } |
119 | 119 | |
120 | - set_bits(this->player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST); | |
120 | + set_bits(this->player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
121 | 121 | set_bits(this->player_ptr->update, inventory_flags); |
122 | 122 | if (!use_charge) { |
123 | 123 | return; |
@@ -136,7 +136,7 @@ void ObjectUseEntity::execute() | ||
136 | 136 | } |
137 | 137 | |
138 | 138 | if (this->item >= 0) { |
139 | - inven_item_charges(this->player_ptr, this->item); | |
139 | + inven_item_charges(this->player_ptr->inventory_list[this->item]); | |
140 | 140 | } else { |
141 | 141 | floor_item_charges(this->player_ptr->current_floor_ptr, 0 - this->item); |
142 | 142 | } |
@@ -140,7 +140,7 @@ void ObjectZapRodEntity::execute(INVENTORY_IDX item) | ||
140 | 140 | gain_exp(this->player_ptr, (lev + (this->player_ptr->lev >> 1)) / this->player_ptr->lev); |
141 | 141 | } |
142 | 142 | |
143 | - set_bits(this->player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST); | |
143 | + set_bits(this->player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
144 | 144 | } |
145 | 145 | |
146 | 146 | bool ObjectZapRodEntity::check_can_zap() |
@@ -121,11 +121,11 @@ void ObjectZapWandEntity::execute(INVENTORY_IDX item) | ||
121 | 121 | gain_exp(this->player_ptr, (lev + (this->player_ptr->lev >> 1)) / this->player_ptr->lev); |
122 | 122 | } |
123 | 123 | |
124 | - set_bits(this->player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST); | |
124 | + set_bits(this->player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
125 | 125 | set_bits(this->player_ptr->update, inventory_flags); |
126 | 126 | o_ptr->pval--; |
127 | 127 | if (item >= 0) { |
128 | - inven_item_charges(this->player_ptr, item); | |
128 | + inven_item_charges(this->player_ptr->inventory_list[item]); | |
129 | 129 | return; |
130 | 130 | } |
131 | 131 |
@@ -76,8 +76,6 @@ enum class ItemKindType : short { | ||
76 | 76 | |
77 | 77 | #define TV_EQUIP_BEGIN ItemKindType::SHOT |
78 | 78 | #define TV_EQUIP_END ItemKindType::CARD |
79 | -#define TV_MISSILE_BEGIN ItemKindType::SHOT | |
80 | -#define TV_MISSILE_END ItemKindType::BOLT | |
81 | 79 | #define TV_WEARABLE_BEGIN ItemKindType::BOW |
82 | 80 | #define TV_WEARABLE_END ItemKindType::CARD |
83 | 81 | #define TV_WEAPON_BEGIN ItemKindType::BOW |
@@ -62,8 +62,7 @@ void object_aware(PlayerType *player_ptr, const ItemEntity *o_ptr) | ||
62 | 62 | return; |
63 | 63 | } |
64 | 64 | |
65 | - // 未鑑定名の無いアイテムは記録しない | |
66 | - if (!((o_ptr->tval >= ItemKindType::AMULET && o_ptr->tval <= ItemKindType::POTION) || o_ptr->tval == ItemKindType::FOOD)) { | |
65 | + if (!o_ptr->has_unidentified_name()) { | |
67 | 66 | return; |
68 | 67 | } |
69 | 68 |
@@ -234,7 +234,7 @@ bool move_player_effect(PlayerType *player_ptr, POSITION ny, POSITION nx, BIT_FL | ||
234 | 234 | |
235 | 235 | if (!player_ptr->running) { |
236 | 236 | // 自動拾い/自動破壊により床上のアイテムリストが変化した可能性があるので表示を更新 |
237 | - set_bits(player_ptr->window_flags, PW_FLOOR_ITEM_LIST); | |
237 | + set_bits(player_ptr->window_flags, PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
238 | 238 | window_stuff(player_ptr); |
239 | 239 | } |
240 | 240 |
@@ -333,8 +333,7 @@ static void update_bonuses(PlayerType *player_ptr) | ||
333 | 333 | update_ability_scores(player_ptr); |
334 | 334 | o_ptr = &player_ptr->inventory_list[INVEN_BOW]; |
335 | 335 | if (o_ptr->bi_id) { |
336 | - const BaseitemKey key(o_ptr->tval, o_ptr->sval); | |
337 | - player_ptr->tval_ammo = key.get_arrow_kind(); | |
336 | + player_ptr->tval_ammo = o_ptr->get_arrow_kind(); | |
338 | 337 | player_ptr->num_fire = calc_num_fire(player_ptr, o_ptr); |
339 | 338 | } |
340 | 339 |
@@ -1048,8 +1047,7 @@ int16_t calc_num_fire(PlayerType *player_ptr, ItemEntity *o_ptr) | ||
1048 | 1047 | return (int16_t)num; |
1049 | 1048 | } |
1050 | 1049 | |
1051 | - const BaseitemKey key(o_ptr->tval, o_ptr->sval); | |
1052 | - const auto tval_ammo = key.get_arrow_kind(); | |
1050 | + const auto tval_ammo = o_ptr->get_arrow_kind(); | |
1053 | 1051 | PlayerClass pc(player_ptr); |
1054 | 1052 | if (pc.equals(PlayerClassType::RANGER) && (tval_ammo == ItemKindType::ARROW)) { |
1055 | 1053 | num += (player_ptr->lev * 4); |
@@ -167,7 +167,7 @@ int Smith::get_essence_consumption(SmithEffectType effect, const ItemEntity *o_p | ||
167 | 167 | return consumption; |
168 | 168 | } |
169 | 169 | |
170 | - if ((o_ptr->tval >= ItemKindType::SHOT) && (o_ptr->tval <= ItemKindType::BOLT)) { | |
170 | + if (o_ptr->is_ammo()) { | |
171 | 171 | consumption = (consumption + 9) / 10; |
172 | 172 | } |
173 | 173 |
@@ -262,6 +262,7 @@ bool detect_objects_normal(PlayerType *player_ptr, POSITION range) | ||
262 | 262 | detect = false; |
263 | 263 | } |
264 | 264 | if (detect) { |
265 | + player_ptr->window_flags |= PW_FOUND_ITEM_LIST; | |
265 | 266 | msg_print(_("アイテムの存在を感じとった!", "You sense the presence of objects!")); |
266 | 267 | } |
267 | 268 |
@@ -272,19 +273,28 @@ bool detect_objects_normal(PlayerType *player_ptr, POSITION range) | ||
272 | 273 | return detect; |
273 | 274 | } |
274 | 275 | |
276 | +static bool is_object_magically(const ItemKindType tval) | |
277 | +{ | |
278 | + switch (tval) { | |
279 | + case ItemKindType::WHISTLE: | |
280 | + case ItemKindType::AMULET: | |
281 | + case ItemKindType::RING: | |
282 | + case ItemKindType::STAFF: | |
283 | + case ItemKindType::WAND: | |
284 | + case ItemKindType::ROD: | |
285 | + case ItemKindType::SCROLL: | |
286 | + case ItemKindType::POTION: | |
287 | + return true; | |
288 | + default: | |
289 | + return false; | |
290 | + } | |
291 | +} | |
292 | + | |
275 | 293 | /*! |
276 | - * @brief 魔法効果のあるのアイテムオブジェクトを感知する / Detect all "magic" objects on the current panel. | |
294 | + * @brief 魔法効果のあるのアイテムオブジェクトを感知する | |
277 | 295 | * @param player_ptr プレイヤーへの参照ポインタ |
278 | 296 | * @param range 効果範囲 |
279 | - * @return 効力があった場合TRUEを返す | |
280 | - * @details | |
281 | - * <pre> | |
282 | - * This will light up all spaces with "magic" items, including artifacts, | |
283 | - * ego-items, potions, scrolls, books, rods, wands, staffs, amulets, rings, | |
284 | - * and "enchanted" items of the "good" variety. | |
285 | - * | |
286 | - * It can probably be argued that this function is now too powerful. | |
287 | - * </pre> | |
297 | + * @return 1つ以上感知したか否か | |
288 | 298 | */ |
289 | 299 | bool detect_objects_magic(PlayerType *player_ptr, POSITION range) |
290 | 300 | { |
@@ -292,27 +302,22 @@ bool detect_objects_magic(PlayerType *player_ptr, POSITION range) | ||
292 | 302 | range /= 3; |
293 | 303 | } |
294 | 304 | |
295 | - ItemKindType tv; | |
296 | - bool detect = false; | |
305 | + auto detect = false; | |
297 | 306 | for (OBJECT_IDX i = 1; i < player_ptr->current_floor_ptr->o_max; i++) { |
298 | 307 | auto *o_ptr = &player_ptr->current_floor_ptr->o_list[i]; |
299 | - | |
300 | - if (!o_ptr->is_valid()) { | |
301 | - continue; | |
302 | - } | |
303 | - if (o_ptr->is_held_by_monster()) { | |
308 | + if (!o_ptr->is_valid() || o_ptr->is_held_by_monster()) { | |
304 | 309 | continue; |
305 | 310 | } |
306 | 311 | |
307 | - POSITION y = o_ptr->iy; | |
308 | - POSITION x = o_ptr->ix; | |
309 | - | |
312 | + auto y = o_ptr->iy; | |
313 | + auto x = o_ptr->ix; | |
310 | 314 | if (distance(player_ptr->y, player_ptr->x, y, x) > range) { |
311 | 315 | continue; |
312 | 316 | } |
313 | 317 | |
314 | - tv = o_ptr->tval; | |
315 | - if (o_ptr->is_artifact() || o_ptr->is_ego() || (tv == ItemKindType::WHISTLE) || (tv == ItemKindType::AMULET) || (tv == ItemKindType::RING) || (tv == ItemKindType::STAFF) || (tv == ItemKindType::WAND) || (tv == ItemKindType::ROD) || (tv == ItemKindType::SCROLL) || (tv == ItemKindType::POTION) || (tv == ItemKindType::LIFE_BOOK) || (tv == ItemKindType::SORCERY_BOOK) || (tv == ItemKindType::NATURE_BOOK) || (tv == ItemKindType::CHAOS_BOOK) || (tv == ItemKindType::DEATH_BOOK) || (tv == ItemKindType::TRUMP_BOOK) || (tv == ItemKindType::ARCANE_BOOK) || (tv == ItemKindType::CRAFT_BOOK) || (tv == ItemKindType::DEMON_BOOK) || (tv == ItemKindType::CRUSADE_BOOK) || (tv == ItemKindType::MUSIC_BOOK) || (tv == ItemKindType::HISSATSU_BOOK) || (tv == ItemKindType::HEX_BOOK) || ((o_ptr->to_a > 0) || (o_ptr->to_h + o_ptr->to_d > 0))) { | |
318 | + auto has_bonus = o_ptr->to_a > 0; | |
319 | + has_bonus |= o_ptr->to_h + o_ptr->to_d > 0; | |
320 | + if (o_ptr->is_artifact() || o_ptr->is_ego() || is_object_magically(o_ptr->tval) || o_ptr->is_spell_book() || has_bonus) { | |
316 | 321 | o_ptr->marked.set(OmType::FOUND); |
317 | 322 | lite_spot(player_ptr, y, x); |
318 | 323 | detect = true; |
@@ -320,6 +325,7 @@ bool detect_objects_magic(PlayerType *player_ptr, POSITION range) | ||
320 | 325 | } |
321 | 326 | |
322 | 327 | if (detect) { |
328 | + player_ptr->window_flags |= PW_FOUND_ITEM_LIST; | |
323 | 329 | msg_print(_("魔法のアイテムの存在を感じとった!", "You sense the presence of magic objects!")); |
324 | 330 | } |
325 | 331 |
@@ -123,7 +123,7 @@ void wiz_lite(PlayerType *player_ptr, bool ninja) | ||
123 | 123 | |
124 | 124 | player_ptr->update |= (PU_MONSTERS); |
125 | 125 | player_ptr->redraw |= (PR_MAP); |
126 | - player_ptr->window_flags |= (PW_OVERHEAD | PW_DUNGEON); | |
126 | + player_ptr->window_flags |= (PW_OVERHEAD | PW_DUNGEON | PW_FOUND_ITEM_LIST); | |
127 | 127 | |
128 | 128 | if (player_ptr->current_floor_ptr->grid_array[player_ptr->y][player_ptr->x].info & CAVE_GLOW) { |
129 | 129 | set_superstealth(player_ptr, false); |
@@ -181,7 +181,7 @@ void wiz_dark(PlayerType *player_ptr) | ||
181 | 181 | player_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE); |
182 | 182 | player_ptr->update |= (PU_MONSTERS); |
183 | 183 | player_ptr->redraw |= (PR_MAP); |
184 | - player_ptr->window_flags |= (PW_OVERHEAD | PW_DUNGEON); | |
184 | + player_ptr->window_flags |= (PW_OVERHEAD | PW_DUNGEON | PW_FOUND_ITEM_LIST); | |
185 | 185 | } |
186 | 186 | |
187 | 187 | /* |
@@ -76,7 +76,7 @@ bool identify_item(PlayerType *player_ptr, ItemEntity *o_ptr) | ||
76 | 76 | o_ptr->marked.set(OmType::TOUCHED); |
77 | 77 | |
78 | 78 | set_bits(player_ptr->update, PU_BONUS | PU_COMBINE | PU_REORDER); |
79 | - set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST); | |
79 | + set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
80 | 80 | |
81 | 81 | strcpy(record_o_name, o_name); |
82 | 82 | record_turn = w_ptr->game_turn; |
@@ -509,7 +509,7 @@ bool enchant_equipment(PlayerType *player_ptr, ItemEntity *o_ptr, int n, int efl | ||
509 | 509 | return false; |
510 | 510 | } |
511 | 511 | set_bits(player_ptr->update, PU_BONUS | PU_COMBINE | PU_REORDER); |
512 | - set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST); | |
512 | + set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
513 | 513 | |
514 | 514 | /* Success */ |
515 | 515 | return true; |
@@ -304,7 +304,7 @@ bool lose_all_info(PlayerType *player_ptr) | ||
304 | 304 | } |
305 | 305 | |
306 | 306 | set_bits(player_ptr->update, PU_BONUS | PU_COMBINE | PU_REORDER); |
307 | - set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST); | |
307 | + set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
308 | 308 | wiz_dark(player_ptr); |
309 | 309 | return true; |
310 | 310 | } |
@@ -10,6 +10,7 @@ | ||
10 | 10 | #include "system/baseitem-info.h" |
11 | 11 | #include "object/tval-types.h" |
12 | 12 | #include "sv-definition/sv-bow-types.h" |
13 | +#include "sv-definition/sv-food-types.h" | |
13 | 14 | |
14 | 15 | BaseitemKey::BaseitemKey(const ItemKindType type_value, const std::optional<int> &subtype_value) |
15 | 16 | : type_value(type_value) |
@@ -113,6 +114,86 @@ bool BaseitemKey::is_high_level_book() const | ||
113 | 114 | return this->subtype_value >= 2; |
114 | 115 | } |
115 | 116 | |
117 | +bool BaseitemKey::is_melee_weapon() const | |
118 | +{ | |
119 | + switch (this->type_value) { | |
120 | + case ItemKindType::POLEARM: | |
121 | + case ItemKindType::SWORD: | |
122 | + case ItemKindType::DIGGING: | |
123 | + case ItemKindType::HAFTED: | |
124 | + return true; | |
125 | + default: | |
126 | + return false; | |
127 | + } | |
128 | +} | |
129 | + | |
130 | +bool BaseitemKey::is_ammo() const | |
131 | +{ | |
132 | + switch (this->type_value) { | |
133 | + case ItemKindType::SHOT: | |
134 | + case ItemKindType::ARROW: | |
135 | + case ItemKindType::BOLT: | |
136 | + return true; | |
137 | + default: | |
138 | + return false; | |
139 | + } | |
140 | +} | |
141 | + | |
142 | +/* | |
143 | + * @brief 未鑑定名を持つか否かの判定 | |
144 | + * @details FOODはキノコが該当する | |
145 | + */ | |
146 | +bool BaseitemKey::has_unidentified_name() const | |
147 | +{ | |
148 | + switch (this->type_value) { | |
149 | + case ItemKindType::AMULET: | |
150 | + case ItemKindType::RING: | |
151 | + case ItemKindType::STAFF: | |
152 | + case ItemKindType::WAND: | |
153 | + case ItemKindType::ROD: | |
154 | + case ItemKindType::SCROLL: | |
155 | + case ItemKindType::POTION: | |
156 | + return true; | |
157 | + case ItemKindType::FOOD: | |
158 | + return this->is_mushrooms(); | |
159 | + default: | |
160 | + return false; | |
161 | + } | |
162 | +} | |
163 | + | |
164 | +bool BaseitemKey::is_mushrooms() const | |
165 | +{ | |
166 | + if (!this->subtype_value.has_value()) { | |
167 | + return false; | |
168 | + } | |
169 | + | |
170 | + switch (this->subtype_value.value()) { | |
171 | + case SV_FOOD_POISON: | |
172 | + case SV_FOOD_BLINDNESS: | |
173 | + case SV_FOOD_PARANOIA: | |
174 | + case SV_FOOD_CONFUSION: | |
175 | + case SV_FOOD_HALLUCINATION: | |
176 | + case SV_FOOD_PARALYSIS: | |
177 | + case SV_FOOD_WEAKNESS: | |
178 | + case SV_FOOD_SICKNESS: | |
179 | + case SV_FOOD_STUPIDITY: | |
180 | + case SV_FOOD_NAIVETY: | |
181 | + case SV_FOOD_UNHEALTH: | |
182 | + case SV_FOOD_DISEASE: | |
183 | + case SV_FOOD_CURE_POISON: | |
184 | + case SV_FOOD_CURE_BLINDNESS: | |
185 | + case SV_FOOD_CURE_PARANOIA: | |
186 | + case SV_FOOD_CURE_CONFUSION: | |
187 | + case SV_FOOD_CURE_SERIOUS: | |
188 | + case SV_FOOD_RESTORE_STR: | |
189 | + case SV_FOOD_RESTORE_CON: | |
190 | + case SV_FOOD_RESTORING: | |
191 | + return true; | |
192 | + default: | |
193 | + return false; | |
194 | + } | |
195 | +} | |
196 | + | |
116 | 197 | BaseitemInfo::BaseitemInfo() |
117 | 198 | : bi_key(ItemKindType::NONE) |
118 | 199 | { |
@@ -40,10 +40,15 @@ public: | ||
40 | 40 | ItemKindType get_arrow_kind() const; |
41 | 41 | bool is_spell_book() const; |
42 | 42 | bool is_high_level_book() const; |
43 | + bool is_melee_weapon() const; | |
44 | + bool is_ammo() const; | |
45 | + bool has_unidentified_name() const; | |
43 | 46 | |
44 | 47 | private: |
45 | 48 | ItemKindType type_value; |
46 | 49 | std::optional<int> subtype_value; |
50 | + | |
51 | + bool is_mushrooms() const; | |
47 | 52 | }; |
48 | 53 | |
49 | 54 | enum class ItemKindType : short; |
@@ -117,13 +117,12 @@ bool ItemEntity::is_weapon() const | ||
117 | 117 | } |
118 | 118 | |
119 | 119 | /*! |
120 | - * @brief アイテムが武器や矢弾として使用できるかを返す / Check if an object is weapon (including bows and ammo) | |
121 | - * Rare weapons/aromors including Blade of Chaos, Dragon armors, etc. | |
120 | + * @brief アイテムが武器や矢弾として使用できるかを返す | |
122 | 121 | * @return 武器や矢弾として使えるならばtrueを返す |
123 | 122 | */ |
124 | 123 | bool ItemEntity::is_weapon_ammo() const |
125 | 124 | { |
126 | - return (TV_MISSILE_BEGIN <= this->tval) && (this->tval <= TV_WEAPON_END); | |
125 | + return this->is_weapon() || this->is_ammo(); | |
127 | 126 | } |
128 | 127 | |
129 | 128 | /*! |
@@ -141,7 +140,7 @@ bool ItemEntity::is_weapon_armour_ammo() const | ||
141 | 140 | */ |
142 | 141 | bool ItemEntity::is_melee_weapon() const |
143 | 142 | { |
144 | - return (ItemKindType::DIGGING <= this->tval) && (this->tval <= ItemKindType::SWORD); | |
143 | + return BaseitemKey(this->tval).is_melee_weapon(); | |
145 | 144 | } |
146 | 145 | |
147 | 146 | /*! |
@@ -302,7 +301,7 @@ bool ItemEntity::allow_two_hands_wielding() const | ||
302 | 301 | */ |
303 | 302 | bool ItemEntity::is_ammo() const |
304 | 303 | { |
305 | - return (TV_MISSILE_BEGIN <= this->tval) && (this->tval <= TV_MISSILE_END); | |
304 | + return BaseitemKey(this->tval).is_ammo(); | |
306 | 305 | } |
307 | 306 | |
308 | 307 | /*! |
@@ -808,3 +807,13 @@ bool ItemEntity::is_specific_artifact(FixedArtifactId id) const | ||
808 | 807 | { |
809 | 808 | return this->fixed_artifact_idx == id; |
810 | 809 | } |
810 | + | |
811 | +bool ItemEntity::has_unidentified_name() const | |
812 | +{ | |
813 | + return BaseitemKey(this->tval).has_unidentified_name(); | |
814 | +} | |
815 | + | |
816 | +ItemKindType ItemEntity::get_arrow_kind() const | |
817 | +{ | |
818 | + return BaseitemKey(this->tval, this->sval).get_arrow_kind(); | |
819 | +} |
@@ -121,6 +121,8 @@ public: | ||
121 | 121 | char get_symbol() const; |
122 | 122 | int get_price() const; |
123 | 123 | bool is_specific_artifact(FixedArtifactId id) const; |
124 | + bool has_unidentified_name() const; | |
125 | + ItemKindType get_arrow_kind() const; | |
124 | 126 | |
125 | 127 | private: |
126 | 128 | int get_baseitem_price() const; |
@@ -118,8 +118,8 @@ const concptr window_flag_desc[32] = { | ||
118 | 118 | _("アイテムの詳細", "Display object recall"), |
119 | 119 | _("自分の周囲を表示", "Display dungeon view"), |
120 | 120 | _("記念撮影", "Display snap-shot"), |
121 | - _("足元/床上のアイテム一覧", "Display items on floor"), | |
122 | - nullptr, | |
121 | + _("足元/床上のアイテム一覧", "Display items on grid"), | |
122 | + _("発見済みのアイテム一覧", "Display found items"), | |
123 | 123 | nullptr, |
124 | 124 | nullptr, |
125 | 125 | nullptr, |
@@ -14,6 +14,23 @@ | ||
14 | 14 | #include "system/monster-race-info.h" |
15 | 15 | #include "system/player-type-definition.h" |
16 | 16 | |
17 | +static int get_item_sort_rank(const ItemEntity &item) | |
18 | +{ | |
19 | + if (item.is_fixed_artifact()) { | |
20 | + return 3; | |
21 | + } | |
22 | + | |
23 | + if (item.art_name) { | |
24 | + return 2; | |
25 | + } | |
26 | + | |
27 | + if (item.is_ego()) { | |
28 | + return 1; | |
29 | + } | |
30 | + | |
31 | + return 0; | |
32 | +} | |
33 | + | |
17 | 34 | /*! |
18 | 35 | * @brief オブジェクトを定義された基準に従いソートするための関数 / |
19 | 36 | * Check if we have space for an item in the pack without overflow |
@@ -24,81 +41,73 @@ | ||
24 | 41 | */ |
25 | 42 | bool object_sort_comp(PlayerType *player_ptr, ItemEntity *o_ptr, int32_t o_value, ItemEntity *j_ptr) |
26 | 43 | { |
27 | - int o_type, j_type; | |
28 | - if (!j_ptr->bi_id) { | |
44 | + if (j_ptr->bi_id == 0) { | |
29 | 45 | return true; |
30 | 46 | } |
31 | 47 | |
32 | - if ((o_ptr->tval == get_realm1_book(player_ptr)) && (j_ptr->tval != get_realm1_book(player_ptr))) { | |
48 | + const auto o_tval = o_ptr->tval; | |
49 | + const auto j_tval = j_ptr->tval; | |
50 | + if ((o_tval == get_realm1_book(player_ptr)) && (j_tval != get_realm1_book(player_ptr))) { | |
33 | 51 | return true; |
34 | 52 | } |
35 | - if ((j_ptr->tval == get_realm1_book(player_ptr)) && (o_ptr->tval != get_realm1_book(player_ptr))) { | |
53 | + | |
54 | + if ((j_tval == get_realm1_book(player_ptr)) && (o_tval != get_realm1_book(player_ptr))) { | |
36 | 55 | return false; |
37 | 56 | } |
38 | 57 | |
39 | - if ((o_ptr->tval == get_realm2_book(player_ptr)) && (j_ptr->tval != get_realm2_book(player_ptr))) { | |
58 | + if ((o_tval == get_realm2_book(player_ptr)) && (j_tval != get_realm2_book(player_ptr))) { | |
40 | 59 | return true; |
41 | 60 | } |
42 | - if ((j_ptr->tval == get_realm2_book(player_ptr)) && (o_ptr->tval != get_realm2_book(player_ptr))) { | |
61 | + | |
62 | + if ((j_tval == get_realm2_book(player_ptr)) && (o_tval != get_realm2_book(player_ptr))) { | |
43 | 63 | return false; |
44 | 64 | } |
45 | 65 | |
46 | - if (o_ptr->tval > j_ptr->tval) { | |
66 | + if (o_tval > j_tval) { | |
47 | 67 | return true; |
48 | 68 | } |
49 | - if (o_ptr->tval < j_ptr->tval) { | |
69 | + | |
70 | + if (o_tval < j_tval) { | |
50 | 71 | return false; |
51 | 72 | } |
52 | 73 | |
53 | 74 | if (!o_ptr->is_aware()) { |
54 | 75 | return false; |
55 | 76 | } |
77 | + | |
56 | 78 | if (!j_ptr->is_aware()) { |
57 | 79 | return true; |
58 | 80 | } |
59 | 81 | |
60 | - if (o_ptr->sval < j_ptr->sval) { | |
82 | + const auto o_sval = o_ptr->sval; | |
83 | + const auto j_sval = j_ptr->sval; | |
84 | + if (o_sval < j_sval) { | |
61 | 85 | return true; |
62 | 86 | } |
63 | - if (o_ptr->sval > j_ptr->sval) { | |
87 | + | |
88 | + if (o_sval > j_sval) { | |
64 | 89 | return false; |
65 | 90 | } |
66 | 91 | |
67 | 92 | if (!o_ptr->is_known()) { |
68 | 93 | return false; |
69 | 94 | } |
95 | + | |
70 | 96 | if (!j_ptr->is_known()) { |
71 | 97 | return true; |
72 | 98 | } |
73 | 99 | |
74 | - if (o_ptr->is_fixed_artifact()) { | |
75 | - o_type = 3; | |
76 | - } else if (o_ptr->art_name) { | |
77 | - o_type = 2; | |
78 | - } else if (o_ptr->is_ego()) { | |
79 | - o_type = 1; | |
80 | - } else { | |
81 | - o_type = 0; | |
82 | - } | |
83 | - | |
84 | - if (j_ptr->is_fixed_artifact()) { | |
85 | - j_type = 3; | |
86 | - } else if (j_ptr->art_name) { | |
87 | - j_type = 2; | |
88 | - } else if (j_ptr->is_ego()) { | |
89 | - j_type = 1; | |
90 | - } else { | |
91 | - j_type = 0; | |
92 | - } | |
93 | - | |
94 | - if (o_type < j_type) { | |
100 | + const auto o_rank = get_item_sort_rank(*o_ptr); | |
101 | + const auto j_rank = get_item_sort_rank(*j_ptr); | |
102 | + if (o_rank < j_rank) { | |
95 | 103 | return true; |
96 | 104 | } |
97 | - if (o_type > j_type) { | |
105 | + | |
106 | + if (o_rank > j_rank) { | |
98 | 107 | return false; |
99 | 108 | } |
100 | 109 | |
101 | - switch (o_ptr->tval) { | |
110 | + switch (o_tval) { | |
102 | 111 | case ItemKindType::FIGURINE: |
103 | 112 | case ItemKindType::STATUE: |
104 | 113 | case ItemKindType::CORPSE: |
@@ -108,32 +117,35 @@ bool object_sort_comp(PlayerType *player_ptr, ItemEntity *o_ptr, int32_t o_value | ||
108 | 117 | if (monraces_info[o_r_idx].level < monraces_info[j_r_idx].level) { |
109 | 118 | return true; |
110 | 119 | } |
120 | + | |
111 | 121 | if ((monraces_info[o_r_idx].level == monraces_info[j_r_idx].level) && (o_ptr->pval < j_ptr->pval)) { |
112 | 122 | return true; |
113 | 123 | } |
124 | + | |
114 | 125 | return false; |
115 | 126 | } |
116 | - | |
117 | 127 | case ItemKindType::SHOT: |
118 | 128 | case ItemKindType::ARROW: |
119 | 129 | case ItemKindType::BOLT: |
120 | 130 | if (o_ptr->to_h + o_ptr->to_d < j_ptr->to_h + j_ptr->to_d) { |
121 | 131 | return true; |
122 | 132 | } |
133 | + | |
123 | 134 | if (o_ptr->to_h + o_ptr->to_d > j_ptr->to_h + j_ptr->to_d) { |
124 | 135 | return false; |
125 | 136 | } |
126 | - break; | |
127 | 137 | |
138 | + break; | |
128 | 139 | case ItemKindType::ROD: |
129 | 140 | if (o_ptr->pval < j_ptr->pval) { |
130 | 141 | return true; |
131 | 142 | } |
143 | + | |
132 | 144 | if (o_ptr->pval > j_ptr->pval) { |
133 | 145 | return false; |
134 | 146 | } |
135 | - break; | |
136 | 147 | |
148 | + break; | |
137 | 149 | default: |
138 | 150 | break; |
139 | 151 | } |
@@ -14,34 +14,31 @@ | ||
14 | 14 | #include "view/display-messages.h" |
15 | 15 | |
16 | 16 | /*! |
17 | - * @brief 魔道具の使用回数の残量を示すメッセージを表示する / | |
18 | - * Describe the charges on an item in the inventory. | |
19 | - * @param player_ptr プレイヤーへの参照ポインタ | |
20 | - * @param item 残量を表示したいプレイヤーのアイテム所持スロット | |
17 | + * @brief 魔道具の使用回数の残量を示すメッセージを表示する | |
18 | + * @param item 残量を表示したいインベントリ内のアイテム | |
21 | 19 | */ |
22 | -void inven_item_charges(PlayerType *player_ptr, INVENTORY_IDX item) | |
20 | +void inven_item_charges(const ItemEntity &item) | |
23 | 21 | { |
24 | - auto *o_ptr = &player_ptr->inventory_list[item]; | |
25 | - if ((o_ptr->tval != ItemKindType::STAFF) && (o_ptr->tval != ItemKindType::WAND)) { | |
22 | + const auto tval = item.tval; | |
23 | + if ((tval != ItemKindType::STAFF) && (tval != ItemKindType::WAND)) { | |
26 | 24 | return; |
27 | 25 | } |
28 | - if (!o_ptr->is_known()) { | |
26 | + | |
27 | + if (!item.is_known()) { | |
29 | 28 | return; |
30 | 29 | } |
31 | 30 | |
32 | 31 | #ifdef JP |
33 | - if (o_ptr->pval <= 0) { | |
32 | + if (item.pval <= 0) { | |
34 | 33 | msg_print("もう魔力が残っていない。"); |
35 | 34 | } else { |
36 | - msg_format("あと %d 回分の魔力が残っている。", o_ptr->pval); | |
35 | + msg_format("あと %d 回分の魔力が残っている。", item.pval); | |
37 | 36 | } |
38 | 37 | #else |
39 | - if (o_ptr->pval != 1) { | |
40 | - msg_format("You have %d charges remaining.", o_ptr->pval); | |
41 | - } | |
42 | - | |
43 | - else { | |
44 | - msg_format("You have %d charge remaining.", o_ptr->pval); | |
38 | + if (item.pval != 1) { | |
39 | + msg_format("You have %d charges remaining.", item.pval); | |
40 | + } else { | |
41 | + msg_format("You have %d charge remaining.", item.pval); | |
45 | 42 | } |
46 | 43 | #endif |
47 | 44 | } |
@@ -52,7 +49,7 @@ void inven_item_charges(PlayerType *player_ptr, INVENTORY_IDX item) | ||
52 | 49 | * @param player_ptr プレイヤーへの参照ポインタ |
53 | 50 | * @param item 残量を表示したいプレイヤーのアイテム所持スロット |
54 | 51 | */ |
55 | -void inven_item_describe(PlayerType *player_ptr, INVENTORY_IDX item) | |
52 | +void inven_item_describe(PlayerType *player_ptr, short item) | |
56 | 53 | { |
57 | 54 | auto *o_ptr = &player_ptr->inventory_list[item]; |
58 | 55 | GAME_TEXT o_name[MAX_NLEN]; |
@@ -1,8 +1,7 @@ | ||
1 | 1 | #pragma once |
2 | 2 | |
3 | -#include "system/angband.h" | |
4 | - | |
3 | +class ItemEntity; | |
5 | 4 | class PlayerType; |
6 | -void inven_item_charges(PlayerType *player_ptr, INVENTORY_IDX item); | |
7 | -void inven_item_describe(PlayerType *player_ptr, INVENTORY_IDX item); | |
5 | +void inven_item_charges(const ItemEntity &item); | |
6 | +void inven_item_describe(PlayerType *player_ptr, short item); | |
8 | 7 | void display_koff(PlayerType *player_ptr, short bi_id); |
@@ -51,6 +51,7 @@ | ||
51 | 51 | #include <mutex> |
52 | 52 | #include <sstream> |
53 | 53 | #include <string> |
54 | +#include <util/object-sort.h> | |
54 | 55 | |
55 | 56 | /*! サブウィンドウ表示用の ItemTester オブジェクト */ |
56 | 57 | static std::unique_ptr<ItemTester> fix_item_tester = std::make_unique<AllMatchItemTester>(); |
@@ -670,6 +671,105 @@ void fix_floor_item_list(PlayerType *player_ptr, const int y, const int x) | ||
670 | 671 | } |
671 | 672 | |
672 | 673 | /*! |
674 | + * @brief 発見済みのアイテム一覧を作成し、表示する | |
675 | + * @param プレイヤー情報への参照ポインタ | |
676 | + */ | |
677 | +static void display_found_item_list(PlayerType *player_ptr) | |
678 | +{ | |
679 | + // Term の行数を取得。 | |
680 | + TERM_LEN term_h; | |
681 | + TERM_LEN term_w; | |
682 | + term_get_size(&term_w, &term_h); | |
683 | + | |
684 | + if (term_h <= 0) { | |
685 | + return; | |
686 | + } | |
687 | + | |
688 | + auto *floor_ptr = player_ptr->current_floor_ptr; | |
689 | + | |
690 | + // 所持品一覧と同じ順にソートする | |
691 | + // あらかじめfloor_ptr->o_list から↓項目を取り除く | |
692 | + // bi_idが0 | |
693 | + // OM_FOUNDフラグが立っていない | |
694 | + // ItemKindTypeがGOLD | |
695 | + std::vector<ItemEntity *> found_item_list; | |
696 | + for (auto &item : floor_ptr->o_list) { | |
697 | + auto item_entity_ptr = &item; | |
698 | + if (item_entity_ptr->bi_id > 0 && item_entity_ptr->marked.has(OmType::FOUND) && item_entity_ptr->tval != ItemKindType::GOLD) { | |
699 | + found_item_list.push_back(item_entity_ptr); | |
700 | + } | |
701 | + } | |
702 | + | |
703 | + std::sort( | |
704 | + found_item_list.begin(), found_item_list.end(), | |
705 | + [player_ptr](ItemEntity *left, ItemEntity *right) -> bool { | |
706 | + return object_sort_comp(player_ptr, left, left->get_price(), right); | |
707 | + }); | |
708 | + | |
709 | + term_clear(); | |
710 | + term_gotoxy(0, 0); | |
711 | + | |
712 | + // 先頭行を書く。 | |
713 | + term_addstr(-1, TERM_WHITE, _("発見済みのアイテム一覧", "Found items")); | |
714 | + | |
715 | + // 発見済みのアイテムを表示 | |
716 | + TERM_LEN term_y = 1; | |
717 | + for (auto item : found_item_list) { | |
718 | + // 途中で行数が足りなくなったら終了。 | |
719 | + if (term_y >= term_h) { | |
720 | + break; | |
721 | + } | |
722 | + | |
723 | + term_gotoxy(0, term_y); | |
724 | + | |
725 | + // アイテムシンボル表示 | |
726 | + const auto symbol_code = item->get_symbol(); | |
727 | + const std::string symbol = format(" %c ", symbol_code); | |
728 | + const auto color_code_for_symbol = item->get_color(); | |
729 | + term_addstr(-1, color_code_for_symbol, symbol.data()); | |
730 | + | |
731 | + // アイテム名表示 | |
732 | + char temp[512]; | |
733 | + describe_flavor(player_ptr, temp, item, 0); | |
734 | + const std::string item_description(temp); | |
735 | + const auto color_code_for_item = tval_to_attr[enum2i(item->tval) % 128]; | |
736 | + term_addstr(-1, color_code_for_item, item_description.data()); | |
737 | + | |
738 | + // アイテム座標表示 | |
739 | + const std::string item_location = format("(X:%3d Y:%3d)", item->ix, item->iy); | |
740 | + prt(item_location.data(), term_y, term_w - item_location.length() - 1); | |
741 | + | |
742 | + ++term_y; | |
743 | + } | |
744 | +} | |
745 | + | |
746 | +/*! | |
747 | + * @brief 発見済みのアイテム一覧をサブウィンドウに表示する | |
748 | + */ | |
749 | +void fix_found_item_list(PlayerType *player_ptr) | |
750 | +{ | |
751 | + for (int j = 0; j < 8; j++) { | |
752 | + if (!angband_term[j]) { | |
753 | + continue; | |
754 | + } | |
755 | + if (angband_term[j]->never_fresh) { | |
756 | + continue; | |
757 | + } | |
758 | + if (none_bits(window_flag[j], PW_FOUND_ITEM_LIST)) { | |
759 | + continue; | |
760 | + } | |
761 | + | |
762 | + term_type *old = game_term; | |
763 | + term_activate(angband_term[j]); | |
764 | + | |
765 | + display_found_item_list(player_ptr); | |
766 | + term_fresh(); | |
767 | + | |
768 | + term_activate(old); | |
769 | + } | |
770 | +} | |
771 | + | |
772 | +/*! | |
673 | 773 | * @brief サブウィンドウに所持品、装備品リストの表示を行う / |
674 | 774 | * Flip "inven" and "equip" in any sub-windows |
675 | 775 | */ |
@@ -18,6 +18,7 @@ void fix_dungeon(PlayerType *player_ptr); | ||
18 | 18 | void fix_monster(PlayerType *player_ptr); |
19 | 19 | void fix_object(PlayerType *player_ptr); |
20 | 20 | void fix_floor_item_list(PlayerType *player_ptr, const int y, const int x); |
21 | +void fix_found_item_list(PlayerType *player_ptr); | |
21 | 22 | void toggle_inventory_equipment(PlayerType *player_ptr); |
22 | 23 | |
23 | 24 | /*! |
@@ -579,7 +579,7 @@ static void wiz_reroll_item(PlayerType *player_ptr, ItemEntity *o_ptr) | ||
579 | 579 | |
580 | 580 | o_ptr->copy_from(q_ptr); |
581 | 581 | set_bits(player_ptr->update, PU_BONUS | PU_COMBINE | PU_REORDER); |
582 | - set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER | PW_FLOOR_ITEM_LIST); | |
582 | + set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER | PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
583 | 583 | } |
584 | 584 | |
585 | 585 | /*! |
@@ -724,7 +724,7 @@ void wiz_modify_item(PlayerType *player_ptr) | ||
724 | 724 | |
725 | 725 | o_ptr->copy_from(q_ptr); |
726 | 726 | set_bits(player_ptr->update, PU_BONUS | PU_COMBINE | PU_REORDER); |
727 | - set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER | PW_FLOOR_ITEM_LIST); | |
727 | + set_bits(player_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER | PW_FLOOR_ITEM_LIST | PW_FOUND_ITEM_LIST); | |
728 | 728 | } else { |
729 | 729 | msg_print("Changes ignored."); |
730 | 730 | } |