1 /**
2 * \file obj-knowledge.c
3 * \brief Object knowledge
4 *
5 * Copyright (c) 2016 Nick McConnell
6 *
7 * This work is free software; you can redistribute it and/or modify it
8 * under the terms of either:
9 *
10 * a) the GNU General Public License as published by the Free Software
11 * Foundation, version 2, or
12 *
13 * b) the "Angband licence":
14 * This software may be copied and distributed for educational, research,
15 * and not for profit purposes provided that this copyright and statement
16 * are included in all such copies. Other copyrights may also apply.
17 */
18
19 #include "angband.h"
20 #include "cave.h"
21 #include "init.h"
22 #include "obj-curse.h"
23 #include "obj-desc.h"
24 #include "obj-gear.h"
25 #include "obj-ignore.h"
26 #include "obj-knowledge.h"
27 #include "obj-pile.h"
28 #include "obj-properties.h"
29 #include "obj-slays.h"
30 #include "obj-tval.h"
31 #include "obj-util.h"
32 #include "player.h"
33 #include "player-calcs.h"
34 #include "player-history.h"
35 #include "player-util.h"
36 #include "project.h"
37 #include "store.h"
38
39 /**
40 * Overview
41 * ========
42 * This file deals with the new "rune-based ID" system. This system operates
43 * as follows:
44 * - struct player has an object struct attached to it (obj_k) which contains
45 * the player's knowledge of object properties (runes)
46 * - whenever the player learns a rune,
47 * - if it's an object flag, that flag is set in obj_k
48 * - if it's an integer value, that value in obj_k is set to 1
49 * - if it's element info, the res_level value is set to 1
50 * - if it's a brand, a brand is added to obj_k with the relevant element
51 * - if it's a slay, a slay is added to obj_k with the right race flag or name
52 * - every object has a known version which is filled in with details as the
53 * player learns them
54 * - whenever the player learns a rune, that knowledge is applied to the known
55 * version of every object that the player has picked up or walked over
56 * or seen in a shop
57 */
58
59 /**
60 * ------------------------------------------------------------------------
61 * Object knowledge data
62 * This section covers initialisation, access and cleanup of rune data
63 * ------------------------------------------------------------------------ */
64 static size_t rune_max;
65 static struct rune *rune_list;
66 static char *c_rune[] = {
67 "enchantment to armor",
68 "enchantment to hit",
69 "enchantment to damage"
70 };
71
72 /**
73 * Initialise the rune module
74 */
init_rune(void)75 static void init_rune(void)
76 {
77 int i, j, count;
78
79 /* Count runes (combat runes are fixed) */
80 count = COMBAT_RUNE_MAX;
81 for (i = 1; i < OF_MAX; i++) {
82 struct obj_property *prop = lookup_obj_property(OBJ_PROPERTY_FLAG, i);
83 if (prop->subtype == OFT_NONE) continue;
84 if (prop->subtype == OFT_LIGHT) continue;
85 if (prop->subtype == OFT_DIG) continue;
86 if (prop->subtype == OFT_THROW) continue;
87 count++;
88 }
89 for (i = 0; i < OBJ_MOD_MAX; i++) {
90 count++;
91 }
92 for (i = 0; i < ELEM_HIGH_MAX; i++) {
93 count++;
94 }
95 /* Note brand runes cover all brands with the same name */
96 for (i = 1; i < z_info->brand_max; i++) {
97 bool counted = false;
98 if (brands[i].name) {
99 for (j = 1; j < i; j++) {
100 if (streq(brands[i].name, brands[j].name)) {
101 counted = true;
102 }
103 }
104 if (!counted) {
105 count++;
106 }
107 }
108 }
109 /* Note slay runes cover all slays with the same flag/base */
110 for (i = 1; i < z_info->slay_max; i++) {
111 bool counted = false;
112 if (slays[i].name) {
113 for (j = 1; j < i; j++) {
114 if (same_monsters_slain(i, j)) {
115 counted = true;
116 }
117 }
118 if (!counted) {
119 count++;
120 }
121 }
122 }
123 for (i = 1; i < z_info->curse_max; i++) {
124 if (curses[i].name) {
125 count++;
126 }
127 }
128
129 /* Now allocate and fill the rune list */
130 rune_max = count;
131 rune_list = mem_zalloc(rune_max * sizeof(struct rune));
132 count = 0;
133 for (i = 0; i < COMBAT_RUNE_MAX; i++) {
134 rune_list[count++] = (struct rune) { RUNE_VAR_COMBAT, i, 0, c_rune[i] };
135 }
136 for (i = 0; i < OBJ_MOD_MAX; i++) {
137 struct obj_property *prop = lookup_obj_property(OBJ_PROPERTY_MOD, i);
138 rune_list[count++] = (struct rune) { RUNE_VAR_MOD, i, 0, prop->name };
139 }
140 for (i = 0; i < ELEM_HIGH_MAX; i++) {
141 rune_list[count++] = (struct rune) { RUNE_VAR_RESIST, i, 0, projections[i].name };
142 }
143 for (i = 1; i < z_info->brand_max; i++) {
144 bool counted = false;
145 if (brands[i].name) {
146 for (j = 1; j < i; j++) {
147 if (streq(brands[i].name, brands[j].name)) {
148 counted = true;
149 }
150 }
151 if (!counted) {
152 rune_list[count++] =
153 (struct rune) { RUNE_VAR_BRAND, i, 0, brands[i].name };
154 }
155 }
156 }
157 for (i = 1; i < z_info->slay_max; i++) {
158 bool counted = false;
159 if (slays[i].name) {
160 for (j = 1; j < i; j++) {
161 if (same_monsters_slain(i, j)) {
162 counted = true;
163 }
164 }
165 if (!counted) {
166 rune_list[count++] =
167 (struct rune) { RUNE_VAR_SLAY, i, 0, slays[i].name };
168 }
169 }
170 }
171 for (i = 1; i < z_info->curse_max; i++) {
172 if (curses[i].name) {
173 rune_list[count++] =
174 (struct rune) { RUNE_VAR_CURSE, i, 0, curses[i].name };
175 }
176 }
177 for (i = 1; i < OF_MAX; i++) {
178 struct obj_property *prop = lookup_obj_property(OBJ_PROPERTY_FLAG, i);
179 if (prop->subtype == OFT_NONE) continue;
180 if (prop->subtype == OFT_LIGHT) continue;
181 if (prop->subtype == OFT_DIG) continue;
182 if (prop->subtype == OFT_THROW) continue;
183
184 rune_list[count++] = (struct rune)
185 { RUNE_VAR_FLAG, i, 0, prop->name };
186 }
187 }
188
189 /**
190 * Get a rune by variety and index
191 */
rune_index(size_t variety,int index)192 static int rune_index(size_t variety, int index)
193 {
194 size_t i;
195
196 /* Look for the rune */
197 for (i = 0; i < rune_max; i++)
198 if ((rune_list[i].variety == variety) && (rune_list[i].index == index))
199 return i;
200
201 /* Can't find it */
202 return -1;
203 }
204
205 /**
206 * Cleanup the rune module
207 */
cleanup_rune(void)208 static void cleanup_rune(void)
209 {
210 mem_free(rune_list);
211 }
212
213 struct init_module rune_module = {
214 .name = "rune",
215 .init = init_rune,
216 .cleanup = cleanup_rune
217 };
218
219 /**
220 * ------------------------------------------------------------------------
221 * Rune knowledge functions
222 * These functions provide details about the rune list for use in
223 * player knowledge screens
224 * ------------------------------------------------------------------------ */
225 /**
226 * The number of runes
227 */
max_runes(void)228 int max_runes(void)
229 {
230 return rune_max;
231 }
232
233 /**
234 * The variety of a rune
235 */
rune_variety(size_t i)236 enum rune_variety rune_variety(size_t i)
237 {
238 return rune_list[i].variety;
239 }
240
241 /**
242 * Reports if the player knows a given rune
243 *
244 * \param p is the player
245 * \param i is the rune's number in the rune list
246 */
player_knows_rune(struct player * p,size_t i)247 bool player_knows_rune(struct player *p, size_t i)
248 {
249 struct rune *r = &rune_list[i];
250
251 switch (r->variety) {
252 /* Combat runes */
253 case RUNE_VAR_COMBAT: {
254 if (r->index == COMBAT_RUNE_TO_A) {
255 if (p->obj_k->to_a)
256 return true;
257 } else if (r->index == COMBAT_RUNE_TO_H) {
258 if (p->obj_k->to_h)
259 return true;
260 } else if (r->index == COMBAT_RUNE_TO_D) {
261 if (p->obj_k->to_d)
262 return true;
263 }
264 break;
265 }
266 /* Mod runes */
267 case RUNE_VAR_MOD: {
268 if (p->obj_k->modifiers[r->index])
269 return true;
270 break;
271 }
272 /* Element runes */
273 case RUNE_VAR_RESIST: {
274 if (p->obj_k->el_info[r->index].res_level)
275 return true;
276 break;
277 }
278 /* Brand runes */
279 case RUNE_VAR_BRAND: {
280 assert(r->index < z_info->brand_max);
281 if (p->obj_k->brands[r->index]) {
282 return true;
283 }
284 break;
285 }
286 /* Slay runes */
287 case RUNE_VAR_SLAY: {
288 assert(r->index < z_info->slay_max);
289 if (p->obj_k->slays[r->index]) {
290 return true;
291 }
292 break;
293 }
294 /* Curse runes */
295 case RUNE_VAR_CURSE: {
296 assert(r->index < z_info->curse_max);
297 if (p->obj_k->curses[r->index].power) {
298 return true;
299 }
300 break;
301 }
302 /* Flag runes */
303 case RUNE_VAR_FLAG: {
304 if (of_has(p->obj_k->flags, r->index))
305 return true;
306 break;
307 }
308 default: {
309 break;
310 }
311 }
312
313 return false;
314 }
315
316 /**
317 * The name of a rune
318 */
rune_name(size_t i)319 char *rune_name(size_t i)
320 {
321 struct rune *r = &rune_list[i];
322
323 if (r->variety == RUNE_VAR_BRAND)
324 return format("%s brand", r->name);
325 else if (r->variety == RUNE_VAR_SLAY)
326 return format("slay %s", r->name);
327 else if (r->variety == RUNE_VAR_CURSE)
328 return format("%s curse", r->name);
329 else if (r->variety == RUNE_VAR_RESIST)
330 return format("resist %s", r->name);
331 else
332 return format("%s", r->name);
333
334 return NULL;
335 }
336
337 /**
338 * The description of a rune
339 */
rune_desc(size_t i)340 char *rune_desc(size_t i)
341 {
342 struct rune *r = &rune_list[i];
343
344 switch (r->variety) {
345 /* Combat runes */
346 case RUNE_VAR_COMBAT: {
347 if (r->index == COMBAT_RUNE_TO_A)
348 return "Object magically increases the player's armor class";
349 else if (r->index == COMBAT_RUNE_TO_H)
350 return "Object magically increases the player's chance to hit";
351 else if (r->index == COMBAT_RUNE_TO_D)
352 return "Object magically increases the player's damage";
353 break;
354 }
355 /* Mod runes */
356 case RUNE_VAR_MOD: {
357 return format("Object gives the player a magical bonus to %s.",
358 r->name);
359 break;
360 }
361 /* Element runes */
362 case RUNE_VAR_RESIST: {
363 return format("Object affects the player's resistance to %s.",
364 r->name);
365 break;
366 }
367 /* Brand runes */
368 case RUNE_VAR_BRAND: {
369 return format("Object brands the player's attacks with %s.",
370 r->name);
371 break;
372 }
373 /* Slay runes */
374 case RUNE_VAR_SLAY: {
375 return format("Object makes the player's attacks against %s more powerful.", r->name);
376 break;
377 }
378 /* Curse runes */
379 case RUNE_VAR_CURSE: {
380 return format("Object %s.", curses[r->index].desc);
381 break;
382 }
383 /* Flag runes */
384 case RUNE_VAR_FLAG: {
385 return format("Object gives the player the property of %s.",
386 r->name);
387 break;
388 }
389 default: {
390 break;
391 }
392 }
393
394 return NULL;
395 }
396
397 /**
398 * The autoinscription index (if any) of a rune
399 */
rune_note(size_t i)400 quark_t rune_note(size_t i)
401 {
402 return rune_list[i].note;
403 }
404
405 /**
406 * Set an autoinscription on a rune
407 */
rune_set_note(size_t i,const char * inscription)408 void rune_set_note(size_t i, const char *inscription)
409 {
410 struct rune *r = &rune_list[i];
411
412 if (!inscription)
413 r->note = 0;
414 else
415 r->note = quark_add(inscription);
416 }
417
418 /**
419 * ------------------------------------------------------------------------
420 * Object knowledge predicates
421 * These functions tell how much the player knows about an object
422 * ------------------------------------------------------------------------ */
423
424 /**
425 * Check if a brand is known to the player
426 *
427 * \param p is the player
428 * \param b is the brand
429 */
player_knows_brand(struct player * p,int i)430 bool player_knows_brand(struct player *p, int i)
431 {
432 return p->obj_k->brands[i];
433 }
434
435 /**
436 * Check if a slay is known to the player
437 *
438 * \param p is the player
439 * \param s is the slay
440 */
player_knows_slay(struct player * p,int i)441 bool player_knows_slay(struct player *p, int i)
442 {
443 return p->obj_k->slays[i];
444 }
445
446 /**
447 * Check if a curse is known to the player
448 *
449 * \param p is the player
450 * \param c is the curse
451 */
player_knows_curse(struct player * p,int index)452 bool player_knows_curse(struct player *p, int index)
453 {
454 return p->obj_k->curses[index].power == 1;
455 }
456
457 /**
458 * Check if an ego item type is known to the player
459 *
460 * \param p is the player
461 * \param ego is the ego item type
462 * \param obj may be NULL to test whether the player knows the ego in general;
463 * if obj is not NULL, the test is for whether the ego is know for that
464 * specific object (allows for the ego to be known for the object in the
465 * case where an ego has range of at least two values, including zero, for
466 * a modifier, the player doesn't know that modifier, and the object has
467 * zero for that modifier)
468 */
player_knows_ego(struct player * p,struct ego_item * ego,const struct object * obj)469 bool player_knows_ego(struct player *p, struct ego_item *ego,
470 const struct object *obj)
471 {
472 int i;
473
474 if (!ego) return false;
475
476 /* All flags known */
477 if (!of_is_subset(p->obj_k->flags, ego->flags)) return false;
478
479 /* All modifiers known */
480 for (i = 0; i < OBJ_MOD_MAX; i++) {
481 int modmax =
482 randcalc(ego->modifiers[i], MAX_RAND_DEPTH, MAXIMISE);
483 int modmin =
484 randcalc(ego->modifiers[i], MAX_RAND_DEPTH, MINIMISE);
485
486 if ((modmax > 0 || modmin < 0) && !p->obj_k->modifiers[i]) {
487 /*
488 * If testing a specific object, can possibly know if
489 * the range includes zero (i.e. product of bounds is
490 * not positive) and the object has zero for that
491 * modifier.
492 */
493 if (!obj || modmax * modmin > 0 ||
494 obj->modifiers[i] != 0) {
495 return false;
496 }
497 }
498 }
499
500 /* All elements known */
501 for (i = 0; i < ELEM_MAX; i++)
502 if (ego->el_info[i].res_level && !p->obj_k->el_info[i].res_level)
503 return false;
504
505 /* All brands known */
506 for (i = 1; i < z_info->brand_max; i++) {
507 if (ego->brands && ego->brands[i] && !player_knows_brand(p, i)) {
508 return false;
509 }
510 }
511
512 /* All slays known */
513 for (i = 1; i < z_info->slay_max; i++) {
514 if (ego->slays && ego->slays[i] && !player_knows_slay(p, i)) {
515 return false;
516 }
517 }
518
519 /* All curses known */
520 for (i = 1; i < z_info->curse_max; i++) {
521 if (ego->curses && ego->curses[i] && !player_knows_curse(p, i)) {
522 return false;
523 }
524 }
525
526 return true;
527 }
528
529 /**
530 * Checks whether the player is aware of the object's effect when used
531 *
532 * \param obj is the object
533 */
object_effect_is_known(const struct object * obj)534 bool object_effect_is_known(const struct object *obj)
535 {
536 if (obj->effect == obj->known->effect) return true;
537
538 return false;
539 }
540
541 /**
542 * Checks whether the object is known to be an artifact
543 *
544 * \param obj is the object
545 */
object_is_known_artifact(const struct object * obj)546 bool object_is_known_artifact(const struct object *obj)
547 {
548 if (!obj->known) return false;
549 return obj->known->artifact ? true : false;
550 }
551
552 /**
553 * Checks whether the object is in a store (not the home)
554 *
555 * \param obj is the object
556 */
object_is_in_store(const struct object * obj)557 bool object_is_in_store(const struct object *obj)
558 {
559 int i;
560 struct object *obj1;
561
562 /* Check all the store objects */
563 for (i = 0; i < MAX_STORES; i++) {
564 struct store *s = &stores[i];
565 if (s->sidx == STORE_HOME) continue;
566 for (obj1 = s->stock; obj1; obj1 = obj1->next)
567 if (obj1 == obj) return true;
568 }
569
570 return false;
571 }
572
573 /**
574 * Checks whether the object has the usual to-hit value
575 *
576 * \param obj is the object
577 */
object_has_standard_to_h(const struct object * obj)578 bool object_has_standard_to_h(const struct object *obj)
579 {
580 /* Hack for curse object structures */
581 if (!obj->kind) {
582 return true;
583 }
584 if (tval_is_body_armor(obj) && !randcalc_varies(obj->kind->to_h)) {
585 return (obj->to_h == obj->kind->to_h.base);
586 } else {
587 return (obj->to_h == 0);
588 }
589 }
590
591 /**
592 * Check if an object has a rune
593 *
594 * \param obj is the object
595 * \param rune_no is the rune's number in the rune list
596 */
object_has_rune(const struct object * obj,int rune_no)597 bool object_has_rune(const struct object *obj, int rune_no)
598 {
599 struct rune *r = &rune_list[rune_no];
600
601 switch (r->variety) {
602 /* Combat runes - just check them all */
603 case RUNE_VAR_COMBAT: {
604 if ((r->index == COMBAT_RUNE_TO_A) && (obj->to_a))
605 return true;
606 else if ((r->index == COMBAT_RUNE_TO_H) &&
607 !object_has_standard_to_h(obj))
608 return true;
609 else if ((r->index == COMBAT_RUNE_TO_D) && (obj->to_d))
610 return true;
611 break;
612 }
613 /* Mod runes */
614 case RUNE_VAR_MOD: {
615 if (obj->modifiers[r->index] != 0)
616 return true;
617 break;
618 }
619 /* Element runes */
620 case RUNE_VAR_RESIST: {
621 if (obj->el_info[r->index].res_level != 0)
622 return true;
623 break;
624 }
625 /* Brand runes */
626 case RUNE_VAR_BRAND: {
627 if (obj->brands) {
628 int i;
629 for (i = 0; i < z_info->brand_max; i++) {
630 if (obj->brands[i] && streq(brands[i].name, r->name)) {
631 return true;
632 }
633 }
634 }
635 break;
636 }
637 /* Slay runes */
638 case RUNE_VAR_SLAY: {
639 if (obj->slays) {
640 int i;
641 for (i = 0; i < z_info->slay_max; i++) {
642 if (obj->slays[i] && same_monsters_slain(r->index, i)) {
643 return true;
644 }
645 }
646 }
647 break;
648 }
649 /* Curse runes */
650 case RUNE_VAR_CURSE: {
651 if (obj->curses && obj->curses[r->index].power)
652 return true;
653 break;
654 }
655 /* Flag runes */
656 case RUNE_VAR_FLAG: {
657 if (of_has(obj->flags, r->index))
658 return true;
659 break;
660 }
661 default: break;
662 }
663
664 return false;
665 }
666
667 /**
668 * Check if all non-curse runes on an object are known to the player
669 *
670 * \param obj is the object
671 */
object_non_curse_runes_known(const struct object * obj)672 static bool object_non_curse_runes_known(const struct object *obj)
673 {
674 int i;
675
676 /* No known object */
677 if (!obj->known) return false;
678
679 /* Not all combat details known */
680 if (obj->known->to_a != obj->to_a) return false;
681 if (obj->known->to_h != obj->to_h) return false;
682 if (obj->known->to_d != obj->to_d) return false;
683
684 /* Not all modifiers known */
685 for (i = 0; i < OBJ_MOD_MAX; i++)
686 if (obj->modifiers[i] != obj->known->modifiers[i])
687 return false;
688
689 /* Not all elements known */
690 for (i = 0; i < ELEM_MAX; i++)
691 if ((obj->el_info[i].res_level != 0) &&
692 (obj->known->el_info[i].res_level == 0))
693 return false;
694
695 /* Not all brands known */
696 if (obj->brands) {
697 if (!obj->known->brands)
698 return false;
699 for (i = 0; i < z_info->brand_max; i++) {
700 if (obj->brands[i] && !obj->known->brands[i]) {
701 return false;
702 }
703 }
704 }
705
706 /* Not all slays known */
707 if (obj->slays) {
708 if (!obj->known->slays)
709 return false;
710 for (i = 0; i < z_info->slay_max; i++) {
711 if (obj->slays[i] && !obj->known->slays[i]) {
712 return false;
713 }
714 }
715 }
716
717 /* Not all flags known */
718 if (!of_is_subset(obj->known->flags, obj->flags)) return false;
719
720 return true;
721 }
722
723 /**
724 * Check if all the runes on an object are known to the player
725 *
726 * \param obj is the object
727 */
object_runes_known(const struct object * obj)728 bool object_runes_known(const struct object *obj)
729 {
730 /* No known object */
731 if (!obj->known) return false;
732
733 /* Not all curses known */
734 if (!curses_are_equal(obj, obj->known)) {
735 return false;
736 }
737
738 /* Answer is now the same as for non-curse runes */
739 return object_non_curse_runes_known(obj);
740 }
741
742
743 /**
744 * Check if an object is fully known to the player
745 *
746 * \param obj is the object
747 */
object_fully_known(const struct object * obj)748 bool object_fully_known(const struct object *obj)
749 {
750 /* Not all runes known */
751 if (!object_runes_known(obj)) return false;
752
753 /* Effect not known */
754 if (!object_effect_is_known(obj)) return false;
755
756 return true;
757 }
758
759
760 /**
761 * Checks whether the player knows whether an object has a given flag
762 *
763 * \param obj is the object
764 * \param flag is the flag
765 */
object_flag_is_known(const struct object * obj,int flag)766 bool object_flag_is_known(const struct object *obj, int flag)
767 {
768 /* Object fully known means OK */
769 if (object_fully_known(obj)) return true;
770
771 /* Player knows the flag means OK */
772 if (of_has(player->obj_k->flags, flag)) return true;
773
774 /* Object has had a chance to display the flag means OK */
775 if (of_has(obj->known->flags, flag)) return true;
776
777 return false;
778 }
779
780 /**
781 * Checks whether the player knows the given element properties of an object
782 *
783 * \param obj is the object
784 * \param element is the element
785 */
object_element_is_known(const struct object * obj,int element)786 bool object_element_is_known(const struct object *obj, int element)
787 {
788 if (element < 0 || element >= ELEM_MAX) return false;
789
790 /* Object fully known means OK */
791 if (object_fully_known(obj)) return true;
792
793 /* Player knows the element means OK */
794 if (player->obj_k->el_info[element].res_level) return true;
795
796 /* Object has been exposed to the element means OK */
797 if (obj->known->el_info[element].res_level) return true;
798
799 return false;
800 }
801
802 /**
803 * ------------------------------------------------------------------------
804 * Object knowledge propagators
805 * These functions transfer player knowledge to objects
806 * ------------------------------------------------------------------------ */
807 /**
808 * Sets the basic details on a known object
809 */
object_set_base_known(struct object * obj)810 void object_set_base_known(struct object *obj)
811 {
812 assert(obj->known);
813 obj->known->kind = obj->kind;
814 obj->known->tval = obj->tval;
815 obj->known->sval = obj->sval;
816 obj->known->weight = obj->weight;
817 obj->known->number = obj->number;
818
819 /* Generic dice and ac, to_h for armor, and launcher multipliers */
820 if (!obj->known->dd) {
821 obj->known->dd = obj->kind->dd * player->obj_k->dd;
822 }
823 if (!obj->known->ds) {
824 obj->known->ds = obj->kind->ds * player->obj_k->ds;
825 }
826 if (!obj->known->ac) {
827 obj->known->ac = obj->kind->ac * player->obj_k->ac;
828 }
829 if (object_has_standard_to_h(obj)) {
830 obj->known->to_h = obj->kind->to_h.base;
831 }
832 if (tval_is_launcher(obj)) {
833 obj->known->pval = obj->pval;
834 }
835
836 /* Aware flavours and unflavored non-wearables get info now */
837 if ((obj->kind->aware && obj->kind->flavor) ||
838 (!tval_is_wearable(obj) && !obj->kind->flavor)) {
839 obj->known->pval = obj->pval;
840 obj->known->effect = obj->effect;
841 }
842
843 /* Know standard activations for wearables */
844 if (tval_is_wearable(obj) && obj->kind->effect && obj->kind->aware) {
845 obj->known->effect = obj->effect;
846 }
847 }
848
849 /**
850 * Gain knowledge based on sensing an object on the floor
851 */
object_sense(struct player * p,struct object * obj)852 void object_sense(struct player *p, struct object *obj)
853 {
854 struct object *known_obj = p->cave->objects[obj->oidx];
855 struct loc grid = obj->grid;
856 int none = tval_find_idx("none");
857
858 /* Make new sensed objects where necessary or move them */
859 if (known_obj == NULL ||
860 !square_holds_object(p->cave, grid, known_obj)) {
861 struct object *new_obj;
862
863 /* Check whether we need to make a new one */
864 if (obj->known) {
865 assert(known_obj == obj->known);
866 new_obj = obj->known;
867 } else {
868 new_obj = object_new();
869 obj->known = new_obj;
870 p->cave->objects[obj->oidx] = new_obj;
871 new_obj->oidx = obj->oidx;
872 }
873
874 /* Give it a fake kind and number. */
875 new_obj->number = 1;
876 if (tval_is_money(obj)) {
877 new_obj->kind = unknown_gold_kind;
878 new_obj->sval = lookup_sval(none, "<unknown treasure>");
879 } else {
880 new_obj->kind = unknown_item_kind;
881 new_obj->sval = lookup_sval(none, "<unknown item>");
882 }
883
884 /* Attach it to the current floor pile */
885 new_obj->grid = grid;
886 pile_insert_end(&p->cave->squares[grid.y][grid.x].obj, new_obj);
887 }
888 }
889
890 /**
891 * Gain knowledge based on seeing an object on the floor
892 */
object_see(struct player * p,struct object * obj)893 void object_see(struct player *p, struct object *obj)
894 {
895 struct object *known_obj = p->cave->objects[obj->oidx];
896 struct loc grid = obj->grid;
897
898 /* Make new known objects, fully know sensed ones, relocate old ones */
899 if (known_obj == NULL) {
900 /* Make a new one */
901 struct object *new_obj;
902
903 assert(! obj->known);
904 new_obj = object_new();
905 obj->known = new_obj;
906 object_set_base_known(obj);
907
908 /* List the known object */
909 p->cave->objects[obj->oidx] = new_obj;
910 new_obj->oidx = obj->oidx;
911
912 /* If monster held, we're done */
913 if (obj->held_m_idx) return;
914
915 /* Attach it to the current floor pile */
916 new_obj->grid = grid;
917 pile_insert_end(&p->cave->squares[grid.y][grid.x].obj, new_obj);
918 } else {
919 struct loc old = known_obj->grid;
920
921 /* Make sure knowledge is correct */
922 assert(known_obj == obj->known);
923
924 if (known_obj->kind != obj->kind) {
925 /* Copy over actual details */
926 object_set_base_known(obj);
927 } else {
928 known_obj->number = obj->number;
929 }
930
931 /* If monster held, we're done */
932 if (obj->held_m_idx) return;
933
934 /* Attach it to the current floor pile if necessary */
935 if (! square_holds_object(p->cave, grid, known_obj)) {
936 /* Detach from any old pile */
937 if (!loc_is_zero(old) && square_holds_object(p->cave, old, known_obj)) {
938 square_excise_object(p->cave, old, known_obj);
939 }
940
941 known_obj->grid = grid;
942 pile_insert_end(&p->cave->squares[grid.y][grid.x].obj, known_obj);
943 }
944 }
945 }
946
947 /**
948 * Gain knowledge based on being an the same square as an object
949 */
object_touch(struct player * p,struct object * obj)950 void object_touch(struct player *p, struct object *obj)
951 {
952 /* Automatically notice artifacts, mark as assessed */
953 obj->known->artifact = obj->artifact;
954 obj->known->notice |= OBJ_NOTICE_ASSESSED;
955
956 /* Apply known properties to the object */
957 player_know_object(p, obj);
958
959 /* Log artifacts if found */
960 if (obj->artifact)
961 history_find_artifact(p, obj->artifact);
962 }
963
964
965 /**
966 * Gain knowledge based on grabbing an object from a monster
967 */
object_grab(struct player * p,struct object * obj)968 void object_grab(struct player *p, struct object *obj)
969 {
970 struct object *known_obj = p->cave->objects[obj->oidx];
971
972 /* Make new known objects, fully know sensed ones, relocate old ones */
973 if (known_obj == NULL) {
974 /* Make a new one */
975 struct object *new_obj;
976
977 assert(! obj->known);
978 new_obj = object_new();
979 obj->known = new_obj;
980 object_set_base_known(obj);
981 p->cave->objects[obj->oidx] = new_obj;
982 new_obj->oidx = obj->oidx;
983 } else {
984 struct loc old = known_obj->grid;
985
986 /* Make sure knowledge is correct */
987 assert(known_obj == obj->known);
988
989 /* Detach from any old (incorrect) floor pile
990 * This will be dead code once compatibility with old savefiles
991 * isn't needed. It (and the declaration of old above) can be
992 * removed in 4.3.0. */
993 if (!loc_is_zero(old) && square_holds_object(p->cave, old, known_obj)) {
994 square_excise_object(p->cave, old, known_obj);
995 }
996
997 /* Copy over actual details */
998 object_set_base_known(obj);
999 }
1000
1001 /* Touch the object */
1002 object_touch(p, obj);
1003 }
1004
1005
1006 /**
1007 * Transfer player object knowledge to an object
1008 *
1009 * \param p is the player
1010 * \param obj is the object
1011 */
player_know_object(struct player * p,struct object * obj)1012 void player_know_object(struct player *p, struct object *obj)
1013 {
1014 int i, flag;
1015 bool seen = true;
1016
1017 /* Unseen or only sensed objects don't get any ID */
1018 if (!obj) return;
1019 if (!obj->known) return;
1020 if (obj->kind != obj->known->kind) return;
1021
1022 /* Distant objects just get base properties */
1023 if (obj->kind && !(obj->known->notice & OBJ_NOTICE_ASSESSED)) {
1024 object_set_base_known(obj);
1025 return;
1026 }
1027
1028 /* Get the dice, and the pval for anything but chests */
1029 obj->known->dd = obj->dd * p->obj_k->dd;
1030 obj->known->ds = obj->ds * p->obj_k->ds;
1031 obj->known->ac = obj->ac * p->obj_k->ac;
1032 if (!tval_is_chest(obj))
1033 obj->known->pval = obj->pval;
1034
1035 /* Set combat details */
1036 obj->known->to_a = p->obj_k->to_a * obj->to_a;
1037 if (!object_has_standard_to_h(obj))
1038 obj->known->to_h = p->obj_k->to_h * obj->to_h;
1039 obj->known->to_d = p->obj_k->to_d * obj->to_d;
1040
1041 /* Set modifiers */
1042 for (i = 0; i < OBJ_MOD_MAX; i++)
1043 if (p->obj_k->modifiers[i])
1044 obj->known->modifiers[i] = obj->modifiers[i];
1045
1046 /* Set elements */
1047 for (i = 0; i < ELEM_MAX; i++)
1048 if (p->obj_k->el_info[i].res_level == 1) {
1049 obj->known->el_info[i].res_level = obj->el_info[i].res_level;
1050 obj->known->el_info[i].flags = obj->el_info[i].flags;
1051 }
1052
1053 /* Set object flags */
1054 for (flag = of_next(p->obj_k->flags, FLAG_START); flag != FLAG_END;
1055 flag = of_next(p->obj_k->flags, flag + 1)) {
1056 if (of_has(obj->flags, flag))
1057 of_on(obj->known->flags, flag);
1058 }
1059
1060 /* Curse object structures are finished now */
1061 if (!obj->kind) {
1062 return;
1063 }
1064
1065 /* Set brands */
1066 if (obj->brands) {
1067 for (i = 1; i < z_info->brand_max; i++) {
1068 if (player_knows_brand(p, i) && obj->brands[i]) {
1069 if (!obj->known->brands) {
1070 obj->known->brands = mem_zalloc(z_info->brand_max *
1071 sizeof(bool));
1072 }
1073 obj->known->brands[i] = true;
1074 }
1075 }
1076 }
1077
1078 /* Set slays */
1079 if (obj->slays) {
1080 for (i = 1; i < z_info->slay_max; i++) {
1081 if (player_knows_slay(p, i) && obj->slays[i]) {
1082 if (!obj->known->slays) {
1083 obj->known->slays = mem_zalloc(z_info->slay_max *
1084 sizeof(bool));
1085 }
1086 obj->known->slays[i] = true;
1087 }
1088 }
1089 }
1090
1091 /* Set curses - be very careful to keep knowledge aligned */
1092 if (obj->curses) {
1093 bool known_cursed = false;
1094 for (i = 1; i < z_info->curse_max; i++) {
1095 if (p->obj_k->curses[i].power && obj->curses[i].power) {
1096 if (!obj->known->curses) {
1097 obj->known->curses = mem_zalloc(z_info->curse_max *
1098 sizeof(struct curse_data));
1099 }
1100 obj->known->curses[i].power = obj->curses[i].power;
1101 known_cursed = true;
1102 } else if (obj->known->curses) {
1103 obj->known->curses[i].power = 0;
1104 }
1105 }
1106 if (!known_cursed) {
1107 mem_free(obj->known->curses);
1108 obj->known->curses = NULL;
1109 }
1110 } else if (obj->known->curses) {
1111 mem_free(obj->known->curses);
1112 obj->known->curses = NULL;
1113 }
1114
1115 /* Set ego type, jewellery type if known */
1116 if (player_knows_ego(p, obj->ego, obj)) {
1117 seen = obj->ego->everseen;
1118 obj->known->ego = obj->ego;
1119 }
1120
1121 if (object_non_curse_runes_known(obj) && tval_is_jewelry(obj)) {
1122 seen = obj->kind->everseen;
1123 object_flavor_aware(obj);
1124 }
1125
1126 /* Ensure effect is known as if object_set_base_known() had been called. */
1127 if ((obj->kind->aware && obj->kind->flavor) ||
1128 (!tval_is_wearable(obj) && !obj->kind->flavor) ||
1129 (tval_is_wearable(obj) && obj->kind->effect && obj->kind->aware)) {
1130 obj->known->effect = obj->effect;
1131 }
1132
1133 /* Report on new stuff */
1134 if (!seen) {
1135 char o_name[80];
1136
1137 /* Describe the object if it's available */
1138 if (object_is_carried(p, obj)) {
1139 object_desc(o_name, sizeof(o_name), obj, ODESC_PREFIX | ODESC_FULL);
1140 msg("You have %s (%c).", o_name, gear_to_label(obj));
1141 } else if (cave && square_holds_object(cave, p->grid, obj)) {
1142 object_desc(o_name, sizeof(o_name), obj, ODESC_PREFIX | ODESC_FULL);
1143 msg("On the ground: %s.", o_name);
1144 }
1145 }
1146
1147 /* Fully known objects have their known element and flag info set to
1148 * match the actual info, rather than showing what elements and flags
1149 * the would be displaying if they had them */
1150 if (object_fully_known(obj)) {
1151 for (i = 0; i < ELEM_MAX; i++) {
1152 obj->known->el_info[i].res_level = obj->el_info[i].res_level;
1153 obj->known->el_info[i].flags = obj->el_info[i].flags;
1154 }
1155 of_wipe(obj->known->flags);
1156 of_copy(obj->known->flags, obj->flags);
1157 }
1158 }
1159
1160 /**
1161 * Propagate player knowledge of objects to all objects
1162 *
1163 * \param p is the player
1164 */
update_player_object_knowledge(struct player * p)1165 void update_player_object_knowledge(struct player *p)
1166 {
1167 int i;
1168 struct object *obj;
1169
1170 /* Level objects */
1171 if (cave)
1172 for (i = 0; i < cave->obj_max; i++)
1173 player_know_object(p, cave->objects[i]);
1174
1175 /* Player objects */
1176 for (obj = p->gear; obj; obj = obj->next)
1177 player_know_object(p, obj);
1178
1179 /* Store objects */
1180 for (i = 0; i < MAX_STORES; i++) {
1181 struct store *s = &stores[i];
1182 for (obj = s->stock; obj; obj = obj->next)
1183 player_know_object(p, obj);
1184 }
1185
1186 /* Curse objects */
1187 for (i = 1; i < z_info->curse_max; i++) {
1188 player_know_object(player, curses[i].obj);
1189 }
1190
1191 /* Update */
1192 if (cave)
1193 autoinscribe_ground();
1194 autoinscribe_pack();
1195 event_signal(EVENT_INVENTORY);
1196 event_signal(EVENT_EQUIPMENT);
1197 }
1198
1199 /**
1200 * ------------------------------------------------------------------------
1201 * Object knowledge learners
1202 * These functions are for increasing player knowledge of object properties
1203 * ------------------------------------------------------------------------ */
1204 /**
1205 * Learn a given rune
1206 *
1207 * \param p is the player
1208 * \param i is the rune index
1209 * \param message is whether or not to print a message
1210 */
player_learn_rune(struct player * p,size_t i,bool message)1211 static void player_learn_rune(struct player *p, size_t i, bool message)
1212 {
1213 struct rune *r = &rune_list[i];
1214 bool learned = false;
1215
1216 switch (r->variety) {
1217 /* Combat runes */
1218 case RUNE_VAR_COMBAT: {
1219 if (r->index == COMBAT_RUNE_TO_A) {
1220 if (!p->obj_k->to_a) {
1221 p->obj_k->to_a = 1;
1222 learned = true;
1223 }
1224 } else if (r->index == COMBAT_RUNE_TO_H) {
1225 if (!p->obj_k->to_h) {
1226 p->obj_k->to_h = 1;
1227 learned = true;
1228 }
1229 } else if (r->index == COMBAT_RUNE_TO_D) {
1230 if (!p->obj_k->to_d) {
1231 p->obj_k->to_d = 1;
1232 learned = true;
1233 }
1234 }
1235 break;
1236 }
1237 /* Mod runes */
1238 case RUNE_VAR_MOD: {
1239 if (!p->obj_k->modifiers[r->index]) {
1240 p->obj_k->modifiers[r->index] = 1;
1241 learned = true;
1242 }
1243 break;
1244 }
1245 /* Element runes */
1246 case RUNE_VAR_RESIST: {
1247 if (!p->obj_k->el_info[r->index].res_level) {
1248 p->obj_k->el_info[r->index].res_level = 1;
1249 learned = true;
1250 }
1251 break;
1252 }
1253 /* Brand runes */
1254 case RUNE_VAR_BRAND: {
1255 assert(r->index < z_info->brand_max);
1256
1257 /* If the brand was unknown, add it to known brands */
1258 if (!player_knows_brand(p, r->index)) {
1259 int i;
1260 for (i = 1; i < z_info->brand_max; i++) {
1261 /* Check base and race flag */
1262 if (streq(brands[r->index].name, brands[i].name)) {
1263 p->obj_k->brands[i] = true;
1264 learned = true;
1265 }
1266 }
1267 }
1268 break;
1269 }
1270 /* Slay runes */
1271 case RUNE_VAR_SLAY: {
1272 assert(r->index < z_info->slay_max);
1273
1274 /* If the slay was unknown, add it to known slays */
1275 if (!player_knows_slay(p, r->index)) {
1276 int i;
1277 for (i = 1; i < z_info->slay_max; i++) {
1278 /* Check base and race flag */
1279 if (same_monsters_slain(r->index, i)) {
1280 p->obj_k->slays[i] = true;
1281 learned = true;
1282 }
1283 }
1284 }
1285 break;
1286 }
1287
1288 /* Curse runes */
1289 case RUNE_VAR_CURSE: {
1290 int i = r->index;
1291 assert(i < z_info->curse_max);
1292
1293 /* If the curse was unknown, add it to known curses */
1294 if (!player_knows_curse(p, i)) {
1295 p->obj_k->curses[i].power = 1;
1296 learned = true;
1297 }
1298 break;
1299 }
1300 /* Flag runes */
1301 case RUNE_VAR_FLAG: {
1302 if (of_on(p->obj_k->flags, r->index))
1303 learned = true;
1304 break;
1305 }
1306 default: {
1307 learned = false;
1308 break;
1309 }
1310 }
1311
1312 /* Nothing learned */
1313 if (!learned) return;
1314
1315 /* Give a message */
1316 if (message)
1317 msgt(MSG_RUNE, "You have learned the rune of %s.", rune_name(i));
1318
1319 /* Update knowledge */
1320 update_player_object_knowledge(p);
1321 }
1322
1323 /**
1324 * Learn a flag
1325 */
player_learn_flag(struct player * p,int flag)1326 void player_learn_flag(struct player *p, int flag)
1327 {
1328 player_learn_rune(p, rune_index(RUNE_VAR_FLAG, flag), true);
1329 update_player_object_knowledge(p);
1330 }
1331
1332 /**
1333 * Learn a curse
1334 */
player_learn_curse(struct player * p,struct curse * curse)1335 void player_learn_curse(struct player *p, struct curse *curse)
1336 {
1337 int index = rune_index(RUNE_VAR_CURSE, lookup_curse(curse->name));
1338 if (index >= 0) {
1339 player_learn_rune(p, index, true);
1340 }
1341 update_player_object_knowledge(p);
1342 }
1343
1344 /**
1345 * Learn all innate runes
1346 *
1347 * \param p is the player
1348 */
player_learn_innate(struct player * p)1349 void player_learn_innate(struct player *p)
1350 {
1351 int element, flag;
1352
1353 /* Elements */
1354 for (element = 0; element < ELEM_MAX; element++) {
1355 if (p->race->el_info[element].res_level != 0) {
1356 player_learn_rune(p, rune_index(RUNE_VAR_RESIST, element), false);
1357 }
1358 }
1359
1360 /* Flags */
1361 for (flag = of_next(p->race->flags, FLAG_START); flag != FLAG_END;
1362 flag = of_next(p->race->flags, flag + 1)) {
1363 player_learn_rune(p, rune_index(RUNE_VAR_FLAG, flag), false);
1364 }
1365
1366 update_player_object_knowledge(p);
1367 }
1368
1369 /**
1370 * Learn absolutely everything
1371 *
1372 * \param p is the player
1373 */
player_learn_all_runes(struct player * p)1374 void player_learn_all_runes(struct player *p)
1375 {
1376 size_t i;
1377
1378 for (i = 0; i < rune_max; i++)
1379 player_learn_rune(p, i, false);
1380 }
1381
1382 /**
1383 * ------------------------------------------------------------------------
1384 * Functions for learning from the behaviour of indvidual objects or shapes
1385 * ------------------------------------------------------------------------ */
1386 /**
1387 * Print a message when an object modifier is identified by use.
1388 *
1389 * \param obj is the object
1390 * \param mod is the modifier being noticed
1391 */
mod_message(struct object * obj,int mod)1392 void mod_message(struct object *obj, int mod)
1393 {
1394 /* Special messages for individual properties */
1395 switch (mod) {
1396 case OBJ_MOD_STR:
1397 if (obj->modifiers[OBJ_MOD_STR] > 0)
1398 msg("You feel stronger!");
1399 else if (obj->modifiers[OBJ_MOD_STR] < 0)
1400 msg("You feel weaker!");
1401 break;
1402 case OBJ_MOD_INT:
1403 if (obj->modifiers[OBJ_MOD_INT] > 0)
1404 msg("You feel smarter!");
1405 else if (obj->modifiers[OBJ_MOD_INT] < 0)
1406 msg("You feel more stupid!");
1407 break;
1408 case OBJ_MOD_WIS:
1409 if (obj->modifiers[OBJ_MOD_WIS] > 0)
1410 msg("You feel wiser!");
1411 else if (obj->modifiers[OBJ_MOD_WIS] < 0)
1412 msg("You feel more naive!");
1413 break;
1414 case OBJ_MOD_DEX:
1415 if (obj->modifiers[OBJ_MOD_DEX] > 0)
1416 msg("You feel more dextrous!");
1417 else if (obj->modifiers[OBJ_MOD_DEX] < 0)
1418 msg("You feel clumsier!");
1419 break;
1420 case OBJ_MOD_CON:
1421 if (obj->modifiers[OBJ_MOD_CON] > 0)
1422 msg("You feel healthier!");
1423 else if (obj->modifiers[OBJ_MOD_CON] < 0)
1424 msg("You feel sicklier!");
1425 break;
1426 case OBJ_MOD_STEALTH:
1427 if (obj->modifiers[OBJ_MOD_STEALTH] > 0)
1428 msg("You feel stealthier.");
1429 else if (obj->modifiers[OBJ_MOD_STEALTH] < 0)
1430 msg("You feel noisier.");
1431 break;
1432 case OBJ_MOD_SPEED:
1433 if (obj->modifiers[OBJ_MOD_SPEED] > 0)
1434 msg("You feel strangely quick.");
1435 else if (obj->modifiers[OBJ_MOD_SPEED] < 0)
1436 msg("You feel strangely sluggish.");
1437 break;
1438 case OBJ_MOD_BLOWS:
1439 if (obj->modifiers[OBJ_MOD_BLOWS] > 0)
1440 msg("Your weapon tingles in your hands.");
1441 else if (obj->modifiers[OBJ_MOD_BLOWS] < 0)
1442 msg("Your weapon aches in your hands.");
1443 break;
1444 case OBJ_MOD_SHOTS:
1445 if (obj->modifiers[OBJ_MOD_SHOTS] > 0)
1446 msg("Your missile weapon tingles in your hands.");
1447 else if (obj->modifiers[OBJ_MOD_SHOTS] < 0)
1448 msg("Your missile weapon aches in your hands.");
1449 break;
1450 case OBJ_MOD_INFRA:
1451 msg("Your eyes tingle.");
1452 break;
1453 case OBJ_MOD_LIGHT:
1454 msg("It glows!");
1455 break;
1456 default:
1457 break;
1458 }
1459 }
1460
object_curses_find_to_a(struct player * p,struct object * obj)1461 void object_curses_find_to_a(struct player *p, struct object *obj)
1462 {
1463 int index = rune_index(RUNE_VAR_COMBAT, COMBAT_RUNE_TO_A);
1464 if (obj->curses) {
1465 int i;
1466
1467 for (i = 1; i < z_info->curse_max; i++) {
1468 if (!obj->curses[i].power || !curses[i].obj)
1469 continue;
1470
1471 if (curses[i].obj->to_a != 0) {
1472 player_learn_rune(p, index, true);
1473
1474 /* Learn the curse */
1475 index = rune_index(RUNE_VAR_CURSE, i);
1476 if (index >= 0) {
1477 player_learn_rune(p, index, true);
1478 }
1479 }
1480 }
1481 }
1482 }
1483
object_curses_find_to_h(struct player * p,struct object * obj)1484 void object_curses_find_to_h(struct player *p, struct object *obj)
1485 {
1486 int index = rune_index(RUNE_VAR_COMBAT, COMBAT_RUNE_TO_H);
1487 if (obj->curses) {
1488 int i;
1489
1490 for (i = 1; i < z_info->curse_max; i++) {
1491 if (!obj->curses[i].power || !curses[i].obj)
1492 continue;
1493
1494 if (curses[i].obj->to_h != 0) {
1495 player_learn_rune(p, index, true);
1496
1497 /* Learn the curse */
1498 index = rune_index(RUNE_VAR_CURSE, i);
1499 if (index >= 0) {
1500 player_learn_rune(p, index, true);
1501 }
1502 }
1503 }
1504 }
1505 }
1506
object_curses_find_to_d(struct player * p,struct object * obj)1507 void object_curses_find_to_d(struct player *p, struct object *obj)
1508 {
1509 int index = rune_index(RUNE_VAR_COMBAT, COMBAT_RUNE_TO_D);
1510 if (obj->curses) {
1511 int i;
1512
1513 for (i = 1; i < z_info->curse_max; i++) {
1514 if (!obj->curses[i].power || !curses[i].obj)
1515 continue;
1516
1517 if (curses[i].obj->to_d != 0) {
1518 player_learn_rune(p, index, true);
1519
1520 /* Learn the curse */
1521 index = rune_index(RUNE_VAR_CURSE, i);
1522 if (index >= 0) {
1523 player_learn_rune(p, index, true);
1524 }
1525 }
1526 }
1527 }
1528 }
1529
1530 /**
1531 * Find flags caused by curses
1532 *
1533 * \param p is the player
1534 * \param obj is the object
1535 * \param test_flags is the set of flags to check for
1536 * \return whether a flag was found
1537 */
object_curses_find_flags(struct player * p,struct object * obj,bitflag * test_flags)1538 bool object_curses_find_flags(struct player *p, struct object *obj,
1539 bitflag *test_flags)
1540 {
1541 char o_name[80];
1542 bool new = false;
1543
1544 object_desc(o_name, sizeof(o_name), obj, ODESC_BASE);
1545 if (obj->curses) {
1546 int i;
1547 int index;
1548 bitflag f[OF_SIZE];
1549 int flag;
1550
1551 for (i = 1; i < z_info->curse_max; i++) {
1552 if (!obj->curses[i].power || !curses[i].obj)
1553 continue;
1554
1555 /* Get all the relevant flags */
1556 object_flags(curses[i].obj, f);
1557 of_inter(f, test_flags);
1558 for (flag = of_next(f, FLAG_START); flag != FLAG_END;
1559 flag = of_next(f, flag + 1)) {
1560 /* Learn any new flags */
1561 if (!of_has(p->obj_k->flags, flag)) {
1562 new = true;
1563 player_learn_rune(p, rune_index(RUNE_VAR_FLAG, flag), true);
1564 if (p->upkeep->playing) {
1565 flag_message(flag, o_name);
1566 }
1567 }
1568
1569 /* Learn the curse */
1570 index = rune_index(RUNE_VAR_CURSE, i);
1571 if (index >= 0) {
1572 player_learn_rune(p, index, true);
1573 }
1574 }
1575 }
1576 }
1577
1578 return new;
1579 }
1580
1581 /**
1582 * Find a modifiers caused by curses
1583 *
1584 * \param p is the player
1585 * \param obj is the object
1586 */
object_curses_find_modifiers(struct player * p,struct object * obj)1587 void object_curses_find_modifiers(struct player *p, struct object *obj)
1588 {
1589 int i;
1590
1591 if (obj->curses) {
1592 for (i = 1; i < z_info->curse_max; i++) {
1593 int index = rune_index(RUNE_VAR_CURSE, i);
1594 int j;
1595
1596 if (!obj->curses[i].power || !curses[i].obj)
1597 continue;
1598
1599 /* Learn all modifiers */
1600 for (j = 0; j < OBJ_MOD_MAX; j++) {
1601 if (curses[i].obj->modifiers[j]) {
1602 if (!p->obj_k->modifiers[j]) {
1603 player_learn_rune(p, rune_index(RUNE_VAR_MOD, j), true);
1604 if (p->upkeep->playing) {
1605 mod_message(obj, j);
1606 }
1607 }
1608
1609 /* Learn the curse */
1610 if (index >= 0) {
1611 player_learn_rune(p, index, true);
1612 }
1613 }
1614 }
1615 }
1616 }
1617 }
1618
1619 /**
1620 * Find an elemental property caused by curses
1621 *
1622 * \param p is the player
1623 * \param obj is the object
1624 * \param elem the element
1625 * \return whether the element appeared in a curse
1626 */
object_curses_find_element(struct player * p,struct object * obj,int elem)1627 bool object_curses_find_element(struct player *p, struct object *obj, int elem)
1628 {
1629 char o_name[80];
1630 bool new = false;
1631
1632 object_desc(o_name, sizeof(o_name), obj, ODESC_BASE);
1633 if (obj->curses) {
1634 int i;
1635
1636 for (i = 1; i < z_info->curse_max; i++) {
1637 int index = rune_index(RUNE_VAR_CURSE, i);
1638
1639 if (!obj->curses[i].power || !curses[i].obj)
1640 continue;
1641
1642 /* Does the object affect the player's resistance to the element? */
1643 if (curses[i].obj->el_info[elem].res_level != 0) {
1644 /* Learn the element properties if we don't know yet */
1645 if (!p->obj_k->el_info[elem].res_level) {
1646 msg("Your %s glows.", o_name);
1647
1648 player_learn_rune(p, rune_index(RUNE_VAR_RESIST, elem),
1649 true);
1650 }
1651
1652 /* Learn the curse */
1653 if (index >= 0) {
1654 player_learn_rune(p, index, true);
1655 }
1656 new = true;
1657 }
1658 }
1659 }
1660 return new;
1661 }
1662
1663 /**
1664 * Get a random unknown rune from an object
1665 *
1666 * \param p is the player
1667 * \param obj is the object
1668 * \return the index into the rune list, or -1 for no unknown runes
1669 */
object_find_unknown_rune(struct player * p,struct object * obj)1670 int object_find_unknown_rune(struct player *p, struct object *obj)
1671 {
1672 size_t i, num = 0;
1673 int *poss_runes;
1674 int chosen = -1;
1675
1676 if (object_runes_known(obj)) return -1;
1677
1678 poss_runes = mem_zalloc(rune_max * sizeof(int));
1679 for (i = 0; i < rune_max; i++)
1680 if (object_has_rune(obj, i) && !player_knows_rune(p, i))
1681 poss_runes[num++] = i;
1682
1683 /* Grab a random rune from among the unknowns */
1684 if (num) {
1685 chosen = poss_runes[randint0(num)];
1686 }
1687
1688 mem_free(poss_runes);
1689 return chosen;
1690 }
1691
1692 /**
1693 * Learn a random unknown rune from an object
1694 *
1695 * \param p is the player
1696 * \param obj is the object
1697 */
object_learn_unknown_rune(struct player * p,struct object * obj)1698 void object_learn_unknown_rune(struct player *p, struct object *obj)
1699 {
1700 /* Get a random unknown rune from the object */
1701 int i = object_find_unknown_rune(p, obj);
1702
1703 /* No unknown runes */
1704 if (i < 0) return;
1705
1706 /* Learn the rune */
1707 player_learn_rune(p, i, true);
1708 }
1709
1710 /**
1711 * Learn object properties that become obvious on wielding or wearing
1712 *
1713 * \param p is the player
1714 * \param obj is the wielded object
1715 */
object_learn_on_wield(struct player * p,struct object * obj)1716 void object_learn_on_wield(struct player *p, struct object *obj)
1717 {
1718 bitflag f[OF_SIZE], obvious_mask[OF_SIZE];
1719 int i, flag;
1720 char o_name[80];
1721
1722 assert(obj->known);
1723 object_desc(o_name, sizeof(o_name), obj, ODESC_BASE);
1724
1725 /* Check the worn flag */
1726 if (obj->known->notice & OBJ_NOTICE_WORN) {
1727 return;
1728 } else {
1729 obj->known->notice |= OBJ_NOTICE_WORN;
1730 }
1731
1732 /* Worn means tried (for flavored wearables) */
1733 object_flavor_tried(obj);
1734
1735 /* Get the obvious object flags */
1736 create_obj_flag_mask(obvious_mask, true, OFID_WIELD, OFT_MAX);
1737
1738 /* Make sustains obvious for items with that stat bonus */
1739 for (i = 0; i < STAT_MAX; i++) {
1740 int sust = sustain_flag(i);
1741 if (obj->modifiers[i]) {
1742 of_on(obvious_mask, sust);
1743 }
1744 }
1745
1746 /* Learn about obvious, previously unknown flags */
1747 object_flags(obj, f);
1748 of_inter(f, obvious_mask);
1749 for (flag = of_next(f, FLAG_START); flag != FLAG_END;
1750 flag = of_next(f, flag + 1)) {
1751 if (!of_has(p->obj_k->flags, flag)) {
1752 player_learn_rune(p, rune_index(RUNE_VAR_FLAG, flag), true);
1753 if (p->upkeep->playing) {
1754 flag_message(flag, o_name);
1755 }
1756 }
1757 }
1758
1759 /* Learn all modifiers */
1760 for (i = 0; i < OBJ_MOD_MAX; i++) {
1761 if (obj->modifiers[i] && !p->obj_k->modifiers[i]) {
1762 player_learn_rune(p, rune_index(RUNE_VAR_MOD, i), true);
1763 if (p->upkeep->playing) {
1764 mod_message(obj, i);
1765 }
1766 }
1767 }
1768
1769 /* Learn curses */
1770 object_curses_find_to_a(p, obj);
1771 object_curses_find_to_h(p, obj);
1772 object_curses_find_to_d(p, obj);
1773 object_curses_find_flags(p, obj, obvious_mask);
1774 object_curses_find_modifiers(p, obj);
1775 for (i = 0; i < ELEM_MAX; i++) {
1776 if (p->obj_k->el_info[i].res_level) {
1777 (void) object_curses_find_element(p, obj, i);
1778 }
1779 }
1780 }
1781
1782 /**
1783 * Learn object properties that become obvious on making a shapechange
1784 *
1785 * \param p is the player
1786 * \param name is the name of the assumed shape
1787 */
shape_learn_on_assume(struct player * p,const char * name)1788 void shape_learn_on_assume(struct player *p, const char *name)
1789 {
1790 bitflag f[OF_SIZE], obvious_mask[OF_SIZE];
1791 int flag, element;
1792 struct player_shape *shape = lookup_player_shape(name);
1793
1794 /* Get the shape's obvious flags */
1795 create_obj_flag_mask(obvious_mask, true, OFID_WIELD, OFT_MAX);
1796 of_copy(f, shape->flags);
1797 of_inter(f, obvious_mask);
1798
1799 /* Learn flags */
1800 for (flag = of_next(f, FLAG_START); flag != FLAG_END;
1801 flag = of_next(f, flag + 1)) {
1802 equip_learn_flag(p, flag);
1803 }
1804
1805 /* Learn elements */
1806 for (element = 0; element < ELEM_MAX; element++) {
1807 if (shape->el_info[element].res_level &&
1808 !p->obj_k->el_info[element].res_level) {
1809 equip_learn_element(p, element);
1810 }
1811 }
1812 }
1813
1814 /**
1815 * Learn object properties that become obvious on use, mark it as
1816 * aware and reward the player with some experience.
1817 *
1818 * \param p is the player
1819 * \param obj is the used object
1820 */
object_learn_on_use(struct player * p,struct object * obj)1821 void object_learn_on_use(struct player *p, struct object *obj)
1822 {
1823 /* Object level */
1824 int lev = obj->kind->level;
1825
1826 object_flavor_aware(obj);
1827 obj->known->effect = obj->effect;
1828 update_player_object_knowledge(p);
1829 player_exp_gain(p, (lev + (p->lev / 2)) / p->lev);
1830
1831 p->upkeep->notice |= PN_IGNORE;
1832 }
1833
1834 /**
1835 * Notice any slays on a particular object which affect a particular monster.
1836 *
1837 * \param obj is the object on which we are noticing slays
1838 * \param mon the monster we are trying to slay
1839 */
object_learn_slay(struct player * p,struct object * obj,int index)1840 void object_learn_slay(struct player *p, struct object *obj, int index)
1841 {
1842 /* Learn about the slay */
1843 if (!player_knows_slay(p, index)) {
1844 int i;
1845
1846 /* Find the rune index */
1847 for (i = 1; i < z_info->slay_max; i++) {
1848 if (same_monsters_slain(i, index)) {
1849 break;
1850 }
1851 }
1852 assert(i < z_info->slay_max);
1853
1854 /* Learn the rune */
1855 player_learn_rune(p, rune_index(RUNE_VAR_SLAY, i), true);
1856 update_player_object_knowledge(p);
1857 }
1858 }
1859
1860 /**
1861 * Notice any brands on a particular object which affect a particular monster.
1862 *
1863 * \param obj is the object on which we are noticing brands
1864 * \param mon the monster we are trying to brand
1865 */
object_learn_brand(struct player * p,struct object * obj,int index)1866 void object_learn_brand(struct player *p, struct object *obj, int index)
1867 {
1868 /* Learn about the brand */
1869 if (!player_knows_brand(p, index)) {
1870 int i;
1871
1872 /* Find the rune index */
1873 for (i = 1; i < z_info->brand_max; i++) {
1874 if (streq(brands[i].name, brands[index].name)) {
1875 break;
1876 }
1877 }
1878 assert(i < z_info->brand_max);
1879
1880 /* Learn the rune */
1881 player_learn_rune(p, rune_index(RUNE_VAR_BRAND, i), true);
1882 update_player_object_knowledge(p);
1883 }
1884 }
1885
1886
1887 /**
1888 * Learn attack bonus on making a ranged attack.
1889 * Can be applied to the missile or the missile launcher
1890 *
1891 * \param p is the player
1892 * \param obj is the missile or launcher
1893 */
missile_learn_on_ranged_attack(struct player * p,struct object * obj)1894 void missile_learn_on_ranged_attack(struct player *p, struct object *obj)
1895 {
1896 if (p->obj_k->to_h && p->obj_k->to_d)
1897 return;
1898
1899 assert(obj->known);
1900 if (!object_has_standard_to_h(obj)) {
1901 int index = rune_index(RUNE_VAR_COMBAT, COMBAT_RUNE_TO_H);
1902 player_learn_rune(p, index, true);
1903 }
1904 if (obj->to_d) {
1905 int index = rune_index(RUNE_VAR_COMBAT, COMBAT_RUNE_TO_D);
1906 player_learn_rune(p, index, true);
1907 }
1908 object_curses_find_to_h(p, obj);
1909 object_curses_find_to_d(p, obj);
1910 }
1911
1912 /**
1913 * ------------------------------------------------------------------------
1914 * Functions for learning about equipment properties
1915 * These functions are for gaining object knowledge from the behaviour of
1916 * the player's equipment or shape
1917 * ------------------------------------------------------------------------ */
1918 /**
1919 * Learn things which happen on defending.
1920 *
1921 * \param p is the player
1922 */
equip_learn_on_defend(struct player * p)1923 void equip_learn_on_defend(struct player *p)
1924 {
1925 int i;
1926
1927 if (p->obj_k->to_a) return;
1928
1929 for (i = 0; i < p->body.count; i++) {
1930 struct object *obj = slot_object(p, i);
1931 if (obj) {
1932 assert(obj->known);
1933 if (obj->to_a) {
1934 int index = rune_index(RUNE_VAR_COMBAT, COMBAT_RUNE_TO_A);
1935 player_learn_rune(p, index, true);
1936 }
1937 object_curses_find_to_a(p, obj);
1938 if (p->obj_k->to_a) return;
1939 }
1940 }
1941 if (p->shape) {
1942 struct player_shape *shape = lookup_player_shape(p->shape->name);
1943 if (shape->to_a != 0) {
1944 int index = rune_index(RUNE_VAR_COMBAT, COMBAT_RUNE_TO_A);
1945 player_learn_rune(p, index, true);
1946 }
1947 }
1948 }
1949
1950 /**
1951 * Learn to-hit bonus on making a ranged attack.
1952 * Does not apply to weapon or bow
1953 *
1954 * \param p is the player
1955 */
equip_learn_on_ranged_attack(struct player * p)1956 void equip_learn_on_ranged_attack(struct player *p)
1957 {
1958 int i;
1959
1960 if (p->obj_k->to_h) return;
1961
1962 for (i = 0; i < p->body.count; i++) {
1963 struct object *obj = slot_object(p, i);
1964 if (i == slot_by_name(p, "weapon")) continue;
1965 if (i == slot_by_name(p, "shooting")) continue;
1966 if (obj) {
1967 assert(obj->known);
1968 if (!object_has_standard_to_h(obj)) {
1969 int index = rune_index(RUNE_VAR_COMBAT, COMBAT_RUNE_TO_H);
1970 player_learn_rune(p, index, true);
1971 }
1972 object_curses_find_to_h(p, obj);
1973 if (p->obj_k->to_h) return;
1974 }
1975 }
1976 if (p->shape) {
1977 struct player_shape *shape = lookup_player_shape(p->shape->name);
1978 if (shape->to_h != 0) {
1979 int index = rune_index(RUNE_VAR_COMBAT, COMBAT_RUNE_TO_H);
1980 player_learn_rune(p, index, true);
1981 }
1982 }
1983 }
1984
1985
1986 /**
1987 * Learn things which happen on making a melee attack.
1988 * Does not apply to bow
1989 *
1990 * \param p is the player
1991 */
equip_learn_on_melee_attack(struct player * p)1992 void equip_learn_on_melee_attack(struct player *p)
1993 {
1994 int i;
1995
1996 if (p->obj_k->to_h && p->obj_k->to_d)
1997 return;
1998
1999 for (i = 0; i < p->body.count; i++) {
2000 struct object *obj = slot_object(p, i);
2001 if (i == slot_by_name(p, "shooting")) continue;
2002 if (obj) {
2003 assert(obj->known);
2004 if (!object_has_standard_to_h(obj)) {
2005 int index = rune_index(RUNE_VAR_COMBAT, COMBAT_RUNE_TO_H);
2006 player_learn_rune(p, index, true);
2007 }
2008 if (obj->to_d) {
2009 int index = rune_index(RUNE_VAR_COMBAT, COMBAT_RUNE_TO_D);
2010 player_learn_rune(p, index, true);
2011 }
2012 object_curses_find_to_h(p, obj);
2013 object_curses_find_to_d(p, obj);
2014 if (p->obj_k->to_h && p->obj_k->to_d) return;
2015 }
2016 }
2017 if (p->shape) {
2018 struct player_shape *shape = lookup_player_shape(p->shape->name);
2019 if (shape->to_h != 0) {
2020 int index = rune_index(RUNE_VAR_COMBAT, COMBAT_RUNE_TO_H);
2021 player_learn_rune(p, index, true);
2022 }
2023 if (shape->to_d != 0) {
2024 int index = rune_index(RUNE_VAR_COMBAT, COMBAT_RUNE_TO_D);
2025 player_learn_rune(p, index, true);
2026 }
2027 }
2028 }
2029
2030
2031 /**
2032 * Learn a given object flag on wielded items.
2033 *
2034 * \param p is the player
2035 * \param flag is the flag to notice
2036 */
equip_learn_flag(struct player * p,int flag)2037 void equip_learn_flag(struct player *p, int flag)
2038 {
2039 int i;
2040 bitflag f[OF_SIZE];
2041 of_wipe(f);
2042 of_on(f, flag);
2043
2044 /* No flag */
2045 if (!flag) return;
2046
2047 /* All wielded items eligible */
2048 for (i = 0; i < p->body.count; i++) {
2049 struct object *obj = slot_object(p, i);
2050 if (!obj) continue;
2051 assert(obj->known);
2052
2053 /* Does the object have the flag? */
2054 if (of_has(obj->flags, flag)) {
2055 if (!of_has(p->obj_k->flags, flag)) {
2056 char o_name[80];
2057 object_desc(o_name, sizeof(o_name), obj, ODESC_BASE);
2058 flag_message(flag, o_name);
2059 player_learn_rune(p, rune_index(RUNE_VAR_FLAG, flag), true);
2060 }
2061 } else if (!object_fully_known(obj)) {
2062 /* Objects not fully known yet get marked as having had a chance
2063 * to display the flag */
2064 of_on(obj->known->flags, flag);
2065 }
2066
2067 /* Flag may be on a curse */
2068 object_curses_find_flags(p, obj, f);
2069 }
2070 }
2071
2072 /**
2073 * Learn the elemental resistance properties on wielded items.
2074 *
2075 * \param p is the player
2076 * \param element is the element to notice
2077 */
equip_learn_element(struct player * p,int element)2078 void equip_learn_element(struct player *p, int element)
2079 {
2080 int i;
2081
2082 /* Invalid element or element already known */
2083 if (element < 0 || element >= ELEM_MAX) return;
2084 if (p->obj_k->el_info[element].res_level == 1) return;
2085
2086 /* All wielded items eligible */
2087 for (i = 0; i < p->body.count; i++) {
2088 struct object *obj = slot_object(p, i);
2089 if (!obj) continue;
2090 assert(obj->known);
2091
2092 /* Does the object affect the player's resistance to the element? */
2093 if (obj->el_info[element].res_level != 0) {
2094 char o_name[80];
2095 object_desc(o_name, sizeof(o_name), obj, ODESC_BASE);
2096
2097 /* Message */
2098 msg("Your %s glows.", o_name);
2099
2100 /* Learn the element properties */
2101 player_learn_rune(p, rune_index(RUNE_VAR_RESIST, element), true);
2102 } else if (!object_fully_known(obj)) {
2103 /* Objects not fully known yet get marked as having had a chance
2104 * to display the element */
2105 obj->known->el_info[element].res_level = 1;
2106 obj->known->el_info[element].flags = obj->el_info[element].flags;
2107 }
2108
2109 /* Element may be on a curse */
2110 object_curses_find_element(p, obj, element);
2111 }
2112 }
2113
2114 /**
2115 * Learn things that would be noticed in time.
2116 *
2117 * \param p is the player
2118 */
equip_learn_after_time(struct player * p)2119 void equip_learn_after_time(struct player *p)
2120 {
2121 int i, flag;
2122 bitflag f[OF_SIZE], timed_mask[OF_SIZE];
2123
2124 /* Get the timed flags */
2125 create_obj_flag_mask(timed_mask, true, OFID_TIMED, OFT_MAX);
2126
2127 /* Get the unknown timed flags, and return if there are none */
2128 object_flags(p->obj_k, f);
2129 of_negate(f);
2130 of_inter(timed_mask, f);
2131 if (of_is_empty(timed_mask)) return;
2132
2133 /* All wielded items eligible */
2134 for (i = 0; i < p->body.count; i++) {
2135 char o_name[80];
2136 struct object *obj = slot_object(p, i);
2137
2138 if (!obj) continue;
2139 assert(obj->known);
2140 object_desc(o_name, sizeof(o_name), obj, ODESC_BASE);
2141
2142 /* Get the unknown timed flags for this object */
2143 object_flags(obj, f);
2144 of_inter(f, timed_mask);
2145
2146 /* Attempt to learn every flag */
2147 for (flag = of_next(f, FLAG_START); flag != FLAG_END;
2148 flag = of_next(f, flag + 1)) {
2149 if (!of_has(p->obj_k->flags, flag)) {
2150 flag_message(flag, o_name);
2151 }
2152 player_learn_rune(p, rune_index(RUNE_VAR_FLAG, flag), true);
2153 }
2154
2155 /* Learn curses */
2156 object_curses_find_flags(p, obj, timed_mask);
2157
2158 if (!object_fully_known(obj)) {
2159 /* Objects not fully known yet get marked as having had a chance
2160 * to display all the timed flags */
2161 of_union(obj->known->flags, timed_mask);
2162 }
2163 }
2164 }
2165
2166 /**
2167 * ------------------------------------------------------------------------
2168 * Object kind functions
2169 * These deal with knowledge of an object's kind
2170 * ------------------------------------------------------------------------ */
2171
2172 /**
2173 * Checks whether an object counts as "known" due to EASY_KNOW status
2174 *
2175 * \param obj is the object
2176 */
easy_know(const struct object * obj)2177 bool easy_know(const struct object *obj)
2178 {
2179 assert(obj->kind);
2180 if (obj->kind->aware && kf_has(obj->kind->kind_flags, KF_EASY_KNOW))
2181 return true;
2182 else
2183 return false;
2184 }
2185
2186 /**
2187 * Checks whether the player is aware of the object's flavour
2188 *
2189 * \param obj is the object
2190 */
object_flavor_is_aware(const struct object * obj)2191 bool object_flavor_is_aware(const struct object *obj)
2192 {
2193 assert(obj->kind);
2194 return obj->kind->aware;
2195 }
2196
2197 /**
2198 * Checks whether the player has tried to use other objects of the same kind
2199 *
2200 * \param obj is the object
2201 */
object_flavor_was_tried(const struct object * obj)2202 bool object_flavor_was_tried(const struct object *obj)
2203 {
2204 assert(obj->kind);
2205 return obj->kind->tried;
2206 }
2207
2208 /**
2209 * Mark an object's flavour as as one the player is aware of.
2210 *
2211 * \param obj is the object whose flavour should be marked as aware
2212 */
object_flavor_aware(struct object * obj)2213 void object_flavor_aware(struct object *obj)
2214 {
2215 int y, x, i;
2216 struct object *obj1;
2217
2218 assert(obj->known);
2219 if (obj->kind->aware) return;
2220 obj->kind->aware = true;
2221 obj->known->effect = obj->effect;
2222
2223 /* Fix ignore/autoinscribe */
2224 if (kind_is_ignored_unaware(obj->kind))
2225 kind_ignore_when_aware(obj->kind);
2226 player->upkeep->notice |= PN_IGNORE;
2227
2228 /* Update player objects */
2229 for (obj1 = player->gear; obj1; obj1 = obj1->next)
2230 object_set_base_known(obj1);
2231
2232 /* Store objects */
2233 for (i = 0; i < MAX_STORES; i++) {
2234 struct store *s = &stores[i];
2235 for (obj1 = s->stock; obj1; obj1 = obj1->next)
2236 object_set_base_known(obj1);
2237 }
2238
2239 /* Quit if no dungeon yet */
2240 if (!cave) return;
2241
2242 /* Some objects change tile on awareness, so update display for all
2243 * floor objects of this kind */
2244 for (y = 1; y < cave->height; y++) {
2245 for (x = 1; x < cave->width; x++) {
2246 bool light = false;
2247 const struct object *floor_obj;
2248 struct loc grid = loc(x, y);
2249
2250 for (floor_obj = square_object(cave, grid); floor_obj;
2251 floor_obj = floor_obj->next)
2252 if (floor_obj->kind == obj->kind) {
2253 light = true;
2254 break;
2255 }
2256
2257 if (light) square_light_spot(cave, grid);
2258 }
2259 }
2260 }
2261
2262 /**
2263 * Mark an object's flavour as tried.
2264 *
2265 * \param obj is the object whose flavour should be marked
2266 */
object_flavor_tried(struct object * obj)2267 void object_flavor_tried(struct object *obj)
2268 {
2269 assert(obj);
2270 assert(obj->kind);
2271 obj->kind->tried = true;
2272 }
2273