1 /**
2 * \file obj-ignore.c
3 * \brief Item ignoring
4 *
5 * Copyright (c) 2007 David T. Blackston, Iain McFall, DarkGod, Jeff Greene,
6 * David Vestal, Pete Mack, Andi Sidwell.
7 *
8 * This work is free software; you can redistribute it and/or modify it
9 * under the terms of either:
10 *
11 * a) the GNU General Public License as published by the Free Software
12 * Foundation, version 2, or
13 *
14 * b) the "Angband licence":
15 * This software may be copied and distributed for educational, research,
16 * and not for profit purposes provided that this copyright and statement
17 * are included in all such copies. Other copyrights may also apply.
18 */
19 #include "angband.h"
20 #include "cmds.h"
21 #include "init.h"
22 #include "obj-desc.h"
23 #include "obj-gear.h"
24 #include "obj-ignore.h"
25 #include "obj-knowledge.h"
26 #include "obj-pile.h"
27 #include "obj-tval.h"
28 #include "obj-util.h"
29 #include "object.h"
30 #include "player-calcs.h"
31
32
33 typedef struct
34 {
35 ignore_type_t ignore_type;
36 int tval;
37 const char *identifier;
38 } quality_ignore_struct;
39
40 /**
41 * Any entry here with an identifier should appear above the entry with the
42 * same tval and no identifier
43 */
44 static quality_ignore_struct quality_mapping[] =
45 {
46 { ITYPE_GREAT, TV_SWORD, "Chaos" },
47 { ITYPE_GREAT, TV_POLEARM, "Slicing" },
48 { ITYPE_GREAT, TV_HAFTED, "Disruption" },
49 { ITYPE_SHARP, TV_SWORD, "" },
50 { ITYPE_SHARP, TV_POLEARM, "" },
51 { ITYPE_BLUNT, TV_HAFTED, "" },
52 { ITYPE_SLING, TV_BOW, "Sling" },
53 { ITYPE_BOW, TV_BOW, "Bow" },
54 { ITYPE_CROSSBOW, TV_BOW, "Crossbow" },
55 { ITYPE_SHOT, TV_SHOT, "" },
56 { ITYPE_ARROW, TV_ARROW, "" },
57 { ITYPE_BOLT, TV_BOLT, "" },
58 { ITYPE_ROBE, TV_SOFT_ARMOR, "Robe" },
59 { ITYPE_BASIC_DRAGON_ARMOR, TV_DRAG_ARMOR, "Black" },
60 { ITYPE_BASIC_DRAGON_ARMOR, TV_DRAG_ARMOR, "Blue" },
61 { ITYPE_BASIC_DRAGON_ARMOR, TV_DRAG_ARMOR, "White" },
62 { ITYPE_BASIC_DRAGON_ARMOR, TV_DRAG_ARMOR, "Red" },
63 { ITYPE_BASIC_DRAGON_ARMOR, TV_DRAG_ARMOR, "Green" },
64 { ITYPE_MULTI_DRAGON_ARMOR, TV_DRAG_ARMOR, "Multi" },
65 { ITYPE_HIGH_DRAGON_ARMOR, TV_DRAG_ARMOR, "Shining" },
66 { ITYPE_HIGH_DRAGON_ARMOR, TV_DRAG_ARMOR, "Law" },
67 { ITYPE_HIGH_DRAGON_ARMOR, TV_DRAG_ARMOR, "Gold" },
68 { ITYPE_HIGH_DRAGON_ARMOR, TV_DRAG_ARMOR, "Chaos" },
69 { ITYPE_BALANCE_DRAGON_ARMOR, TV_DRAG_ARMOR, "Balance" },
70 { ITYPE_POWER_DRAGON_ARMOR, TV_DRAG_ARMOR, "Power" },
71 { ITYPE_BODY_ARMOR, TV_HARD_ARMOR, "" },
72 { ITYPE_BODY_ARMOR, TV_SOFT_ARMOR, "" },
73 { ITYPE_ELVEN_CLOAK, TV_CLOAK, "Elven" },
74 { ITYPE_CLOAK, TV_CLOAK, "" },
75 { ITYPE_SHIELD, TV_SHIELD, "" },
76 { ITYPE_HEADGEAR, TV_HELM, "" },
77 { ITYPE_HEADGEAR, TV_CROWN, "" },
78 { ITYPE_HANDGEAR, TV_GLOVES, "" },
79 { ITYPE_FEET, TV_BOOTS, "" },
80 { ITYPE_DIGGER, TV_DIGGING, "" },
81 { ITYPE_RING, TV_RING, "" },
82 { ITYPE_AMULET, TV_AMULET, "" },
83 { ITYPE_LIGHT, TV_LIGHT, "" },
84 };
85
86
87
88 quality_name_struct quality_choices[] =
89 {
90 #define ITYPE(a, b) { ITYPE_##a, b },
91 #include "list-ignore-types.h"
92 #undef ITYPE
93 };
94
95 /**
96 * The names for the various kinds of quality
97 */
98 quality_name_struct quality_values[IGNORE_MAX] =
99 {
100 { IGNORE_NONE, "no ignore" },
101 { IGNORE_BAD, "bad" },
102 { IGNORE_AVERAGE, "average" },
103 { IGNORE_GOOD, "good" },
104 { IGNORE_ALL, "non-artifact" },
105 };
106
107 byte ignore_level[ITYPE_MAX];
108 const size_t ignore_size = ITYPE_MAX;
109 bool **ego_ignore_types;
110 /* Hackish - ego_ignore_types should be initialised with arrays */
111 static int num_ego_types;
112
113
114 /**
115 * Initialise the ignore package
116 */
init_ignore(void)117 void init_ignore(void)
118 {
119 int i;
120
121 num_ego_types = z_info->e_max;
122 ego_ignore_types = mem_zalloc(z_info->e_max * sizeof(bool*));
123 for (i = 0; i < z_info->e_max; i++)
124 ego_ignore_types[i] = mem_zalloc(ITYPE_MAX * sizeof(bool));
125 }
126
127
128 /**
129 * Clean up the ignore package
130 */
cleanup_ignore(void)131 void cleanup_ignore(void)
132 {
133 int i;
134 for (i = 0; i < num_ego_types; i++)
135 mem_free(ego_ignore_types[i]);
136 mem_free(ego_ignore_types);
137 }
138
139
140 /**
141 * Reset the player's ignore choices for a new game.
142 */
ignore_birth_init(void)143 void ignore_birth_init(void)
144 {
145 int i, j;
146
147 /* Reset ignore bits */
148 for (i = 0; i < z_info->k_max; i++)
149 k_info[i].ignore = false;
150
151 /* Clear the ignore bytes */
152 for (i = ITYPE_NONE; i < ITYPE_MAX; i++)
153 ignore_level[i] = IGNORE_NONE;
154
155 /* Clear ego ignore */
156 for (i = 0; i < z_info->e_max; i++)
157 for (j = ITYPE_NONE; j < ITYPE_MAX; j++)
158 ego_ignore_types[i][j] = 0;
159 }
160
161
162
163 /**
164 * ------------------------------------------------------------------------
165 * Autoinscription stuff
166 * ------------------------------------------------------------------------ */
167
168
169 /**
170 * Make or extend a rune autoinscription
171 */
rune_add_autoinscription(struct object * obj,int i)172 static void rune_add_autoinscription(struct object *obj, int i)
173 {
174 char current_note[80] = "";
175
176 /* No autoinscription, or already there, don't bother */
177 if (!rune_note(i)) return;
178 if (obj->note && strstr(quark_str(obj->note), quark_str(rune_note(i))))
179 return;
180
181 /* Extend any current note */
182 if (obj->note)
183 my_strcpy(current_note, quark_str(obj->note), sizeof(current_note));
184 my_strcat(current_note, quark_str(rune_note(i)), sizeof(current_note));
185
186 /* Add the inscription */
187 obj->note = quark_add(current_note);
188 }
189
190 /**
191 * Put a rune autoinscription on all available objects
192 */
rune_autoinscribe(int i)193 void rune_autoinscribe(int i)
194 {
195 struct object *obj;
196
197 /* Check the player knows the rune */
198 if (!player_knows_rune(player, i)) {
199 return;
200 }
201
202 /* Autoinscribe each object on the ground */
203 if (cave)
204 for (obj = square_object(cave, player->grid); obj; obj = obj->next)
205 if (object_has_rune(obj, i))
206 rune_add_autoinscription(obj, i);
207
208 /* Autoinscribe each object in the inventory */
209 for (obj = player->gear; obj; obj = obj->next)
210 if (object_has_rune(obj, i))
211 rune_add_autoinscription(obj, i);
212 }
213
214 /**
215 * Put all appropriate rune autoinscriptions on an object
216 */
runes_autoinscribe(struct object * obj)217 static void runes_autoinscribe(struct object *obj)
218 {
219 int i, rune_max = max_runes();
220
221 for (i = 0; i < rune_max; i++)
222 if (object_has_rune(obj, i) && player_knows_rune(player, i))
223 rune_add_autoinscription(obj, i);
224 }
225
226 /**
227 * Return an object kind autoinscription
228 */
get_autoinscription(struct object_kind * kind,bool aware)229 const char *get_autoinscription(struct object_kind *kind, bool aware)
230 {
231 if (!kind)
232 return NULL;
233 else if (aware)
234 return quark_str(kind->note_aware);
235 else
236 return quark_str(kind->note_unaware);
237 }
238
239 /**
240 * Put an autoinscription on an object
241 */
apply_autoinscription(struct object * obj)242 int apply_autoinscription(struct object *obj)
243 {
244 char o_name[80];
245 bool aware = obj->kind->aware;
246 const char *note = obj ? get_autoinscription(obj->kind, aware) : NULL;
247
248 /* Remove unaware inscription if aware */
249 if (aware && quark_str(obj->note) && quark_str(obj->kind->note_unaware) &&
250 streq(quark_str(obj->note), quark_str(obj->kind->note_unaware)))
251 obj->note = 0;
252
253 /* Make rune autoinscription go first, for now */
254 runes_autoinscribe(obj);
255
256 /* No note - don't inscribe */
257 if (!note)
258 return 0;
259
260 /* Don't re-inscribe if it's already inscribed */
261 if (obj->note)
262 return 0;
263
264 /* Don't inscribe unless the player is carrying it */
265 if (!object_is_carried(player, obj))
266 return 0;
267
268 /* Don't inscribe if ignored */
269 if (ignore_item_ok(obj))
270 return 0;
271
272 /* Get an object description */
273 object_desc(o_name, sizeof(o_name), obj, ODESC_PREFIX | ODESC_FULL);
274
275 if (note[0] != 0)
276 obj->note = quark_add(note);
277 else
278 obj->note = 0;
279
280 msg("You autoinscribe %s.", o_name);
281
282 return 1;
283 }
284
285
286 /**
287 * Deregister an object kind autoinscription
288 */
remove_autoinscription(s16b kind)289 int remove_autoinscription(s16b kind)
290 {
291 struct object_kind *k = objkind_byid(kind);
292 if (!k)
293 return 0;
294
295 /* Unaware */
296 if (!k->aware) {
297 if (!k->note_unaware) {
298 return 0;
299 } else {
300 k->note_unaware = 0;
301 return 1;
302 }
303 }
304
305 /* Aware */
306 if (!k->note_aware)
307 return 0;
308
309 k->note_aware = 0;
310 return 1;
311 }
312
313
314 /**
315 * Register an object kind autoinscription
316 */
add_autoinscription(s16b kind,const char * inscription,bool aware)317 int add_autoinscription(s16b kind, const char *inscription, bool aware)
318 {
319 struct object_kind *k = objkind_byid(kind);
320 if (!k)
321 return 0;
322 if (!inscription)
323 return remove_autoinscription(kind);
324 if (aware)
325 k->note_aware = quark_add(inscription);
326 else
327 k->note_unaware = quark_add(inscription);
328 return 1;
329 }
330
331
332 /**
333 * Put an autoinscription on all objects on the floor beneath the player
334 */
autoinscribe_ground(void)335 void autoinscribe_ground(void)
336 {
337 struct object *obj;
338
339 /* Autoinscribe each object in the pile */
340 for (obj = square_object(cave, player->grid); obj; obj = obj->next)
341 apply_autoinscription(obj);
342 }
343
344 /**
345 * Put an autoinscription on all the player's carried objects
346 */
autoinscribe_pack(void)347 void autoinscribe_pack(void)
348 {
349 struct object *obj;
350
351 /* Autoinscribe each object in the inventory */
352 for (obj = player->gear; obj; obj = obj->next)
353 apply_autoinscription(obj);
354 }
355
356 /**
357 * ------------------------------------------------------------------------
358 * Ignore code
359 * ------------------------------------------------------------------------ */
360
361
362 /**
363 * Ignore the flavor of an object
364 */
object_ignore_flavor_of(const struct object * obj)365 void object_ignore_flavor_of(const struct object *obj)
366 {
367 if (object_flavor_is_aware(obj))
368 obj->kind->ignore |= IGNORE_IF_AWARE;
369 else
370 obj->kind->ignore |= IGNORE_IF_UNAWARE;
371 }
372
373
374 /**
375 * Find the ignore type of the object, or ITYPE_MAX if none
376 */
ignore_type_of(const struct object * obj)377 ignore_type_t ignore_type_of(const struct object *obj)
378 {
379 size_t i;
380
381 /* Find the appropriate ignore group */
382 for (i = 0; i < N_ELEMENTS(quality_mapping); i++) {
383 if (quality_mapping[i].tval == obj->tval) {
384 /* If there's an identifier, it must match */
385 if (quality_mapping[i].identifier[0]) {
386 if (!strstr(obj->kind->name, quality_mapping[i].identifier))
387 continue;
388 }
389 /* Otherwise we're fine */
390 return quality_mapping[i].ignore_type;
391 }
392 }
393
394 return ITYPE_MAX;
395 }
396
397 /**
398 * Find whether an ignore type is valid for a given ego item
399 */
ego_has_ignore_type(struct ego_item * ego,ignore_type_t itype)400 bool ego_has_ignore_type(struct ego_item *ego, ignore_type_t itype)
401 {
402 struct poss_item *poss;
403
404 /* Go through all the possible items */
405 for (poss = ego->poss_items; poss; poss = poss->next) {
406 size_t i;
407 struct object_kind *kind = &k_info[poss->kidx];
408
409 /* Check the appropriate ignore group */
410 for (i = 0; i < N_ELEMENTS(quality_mapping); i++)
411 if ((quality_mapping[i].tval == kind->tval) &&
412 (quality_mapping[i].ignore_type == itype) &&
413 strstr(kind->name, quality_mapping[i].identifier))
414 return true;
415 }
416
417 return false;
418 }
419
420
421 /**
422 * Small helper function to see how an object trait compares to the one
423 * in its base type.
424 *
425 * If the base type provides a positive bonus, we'll use that. Otherwise, we'll
426 * use zero (players don't consider an item with a positive bonus to be bad
427 * even if the base kind has a higher positive bonus).
428 */
cmp_object_trait(int bonus,random_value base)429 static int cmp_object_trait(int bonus, random_value base)
430 {
431 int amt = randcalc(base, 0, MINIMISE);
432 if (amt > 0) amt = 0;
433 return CMP(bonus, amt);
434 }
435
436 /**
437 * Small helper function to see if an item seems good, bad or average based on
438 * to_h, to_d and to_a.
439 *
440 * The sign of the return value announces if the object is bad (negative),
441 * good (positive) or average (zero).
442 */
is_object_good(const struct object * obj)443 static int is_object_good(const struct object *obj)
444 {
445 int good = 0;
446 good += 4 * cmp_object_trait(obj->to_d, obj->kind->to_d);
447 good += 2 * cmp_object_trait(obj->to_h, obj->kind->to_h);
448 good += 1 * cmp_object_trait(obj->to_a, obj->kind->to_a);
449 return good;
450 }
451
452
453 /**
454 * Determine the ignore level of an object
455 *
456 * The main point is when the value is undetermined given current info,
457 * return the maximum possible value.
458 */
ignore_level_of(const struct object * obj)459 byte ignore_level_of(const struct object *obj)
460 {
461 byte value = 0;
462 int i;
463
464 if (!obj->known) return IGNORE_MAX;
465
466 /* Deal with jewelry specially - only bad or average */
467 if (tval_is_jewelry(obj)) {
468 /* One positive modifier means not bad*/
469 for (i = 0; i < OBJ_MOD_MAX; i++)
470 if (obj->known->modifiers[i] > 0)
471 return IGNORE_AVERAGE;
472
473 /* One positive combat value means not bad, one negative means bad */
474 if ((obj->known->to_h > 0) || (obj->known->to_d > 0) ||
475 (obj->known->to_a > 0))
476 return IGNORE_AVERAGE;
477 if ((obj->known->to_h < 0) || (obj->known->to_d < 0) ||
478 (obj->known->to_a < 0))
479 return IGNORE_BAD;
480
481 return IGNORE_AVERAGE;
482 }
483
484 /* Now just do bad, average, good, ego */
485 if (object_fully_known(obj)) {
486 int isgood = is_object_good(obj);
487
488 /* Values for items not egos or artifacts, may be updated */
489 if (isgood > 0) {
490 value = IGNORE_GOOD;
491 } else if (isgood < 0) {
492 value = IGNORE_BAD;
493 } else {
494 value = IGNORE_AVERAGE;
495 }
496
497 if (obj->ego)
498 value = IGNORE_ALL;
499 else if (obj->artifact)
500 value = IGNORE_MAX;
501 } else {
502 if ((obj->known->notice & OBJ_NOTICE_ASSESSED) && !obj->artifact)
503 value = IGNORE_ALL;
504 else
505 value = IGNORE_MAX;
506 }
507
508 return value;
509 }
510
511 /**
512 * Remove any ignoring of a particular flavor
513 */
kind_ignore_clear(struct object_kind * kind)514 void kind_ignore_clear(struct object_kind *kind)
515 {
516 kind->ignore = 0;
517 player->upkeep->notice |= PN_IGNORE;
518 }
519
ego_ignore(struct object * obj)520 void ego_ignore(struct object *obj)
521 {
522 assert(obj->ego);
523 ego_ignore_types[obj->ego->eidx][ignore_type_of(obj)] = true;
524 player->upkeep->notice |= PN_IGNORE;
525 }
526
ego_ignore_clear(struct object * obj)527 void ego_ignore_clear(struct object *obj)
528 {
529 assert(obj->ego);
530 ego_ignore_types[obj->ego->eidx][ignore_type_of(obj)] = false;
531 player->upkeep->notice |= PN_IGNORE;
532 }
533
ego_ignore_toggle(int e_idx,int itype)534 void ego_ignore_toggle(int e_idx, int itype)
535 {
536 ego_ignore_types[e_idx][itype] = !ego_ignore_types[e_idx][itype];
537 player->upkeep->notice |= PN_IGNORE;
538 }
539
ego_is_ignored(int e_idx,int itype)540 bool ego_is_ignored(int e_idx, int itype)
541 {
542 return ego_ignore_types[e_idx][itype];
543 }
544
kind_is_ignored_aware(const struct object_kind * kind)545 bool kind_is_ignored_aware(const struct object_kind *kind)
546 {
547 return (kind->ignore & IGNORE_IF_AWARE) ? true : false;
548 }
549
kind_is_ignored_unaware(const struct object_kind * kind)550 bool kind_is_ignored_unaware(const struct object_kind *kind)
551 {
552 return (kind->ignore & IGNORE_IF_UNAWARE) ? true : false;
553 }
554
kind_ignore_when_aware(struct object_kind * kind)555 void kind_ignore_when_aware(struct object_kind *kind)
556 {
557 kind->ignore |= IGNORE_IF_AWARE;
558 player->upkeep->notice |= PN_IGNORE;
559 }
560
kind_ignore_when_unaware(struct object_kind * kind)561 void kind_ignore_when_unaware(struct object_kind *kind)
562 {
563 kind->ignore |= IGNORE_IF_UNAWARE;
564 player->upkeep->notice |= PN_IGNORE;
565 }
566
567
568 /**
569 * Determines if an object is already ignored.
570 */
object_is_ignored(const struct object * obj)571 bool object_is_ignored(const struct object *obj)
572 {
573 byte type;
574
575 /* Objects that aren't yet known can't be ignored */
576 if (!obj->known)
577 return false;
578
579 /* Do ignore individual objects that marked ignore */
580 if (obj->known->notice & OBJ_NOTICE_IGNORE)
581 return true;
582
583 /* Don't ignore artifacts unless marked to be ignored */
584 if (obj->artifact ||
585 check_for_inscrip(obj, "!k") || check_for_inscrip(obj, "!*"))
586 return false;
587
588 /* Do ignoring by kind */
589 if (object_flavor_is_aware(obj) ?
590 kind_is_ignored_aware(obj->kind) :
591 kind_is_ignored_unaware(obj->kind))
592 return true;
593
594 /* Ignore ego items if known */
595 if (obj->known->ego && ego_is_ignored(obj->ego->eidx, ignore_type_of(obj)))
596 return true;
597
598 type = ignore_type_of(obj);
599 if (type == ITYPE_MAX)
600 return false;
601
602 /* Ignore items known not to be artifacts */
603 if ((obj->known->notice & OBJ_NOTICE_ASSESSED) && !obj->artifact &&
604 ignore_level[type] == IGNORE_ALL)
605 return true;
606
607 /* Get result based on the feeling and the ignore_level */
608 if (ignore_level_of(obj) <= ignore_level[type])
609 return true;
610 else
611 return false;
612 }
613
614 /**
615 * Determines if an object is eligible for ignoring.
616 */
ignore_item_ok(const struct object * obj)617 bool ignore_item_ok(const struct object *obj)
618 {
619 if (player->unignoring)
620 return false;
621
622 return object_is_ignored(obj);
623 }
624
625 /**
626 * Determines if the known version of an object is eligible for ignoring.
627 *
628 * This function should only be called on known version of items which have a
629 * (real or imaginary) listed base item in the current level
630 */
ignore_known_item_ok(const struct object * obj)631 bool ignore_known_item_ok(const struct object *obj)
632 {
633 struct object *base_obj = cave->objects[obj->oidx];
634
635 if (player->unignoring)
636 return false;
637
638 /* Get the real object and check its ignore properties */
639 assert(base_obj);
640 return object_is_ignored(base_obj);
641 }
642
643 /**
644 * Drop all {ignore}able items.
645 */
ignore_drop(void)646 void ignore_drop(void)
647 {
648 struct object *obj;
649
650 /* Scan through the slots backwards */
651 for (obj = gear_last_item(); obj; obj = obj->prev) {
652 /* Skip non-objects and unignoreable objects */
653 assert(obj->kind);
654 if (!ignore_item_ok(obj)) continue;
655
656 /* Check for !d (no drop) inscription */
657 if (!check_for_inscrip(obj, "!d") && !check_for_inscrip(obj, "!*")) {
658 /* Confirm the drop if the item is equipped. */
659 if (object_is_equipped(player->body, obj)) {
660 if (!verify_object("Really take off and drop", obj)) {
661 /* Hack - inscribe the item with !d to prevent repeated
662 * confirmations. */
663 const char *inscription = quark_str(obj->note);
664
665 if (inscription == NULL) {
666 obj->note = quark_add("!d");
667 } else {
668 char buffer[1024];
669 my_strcpy(buffer, inscription, sizeof(buffer));
670 my_strcat(buffer, "!d", sizeof(buffer));
671 obj->note = quark_add(buffer);
672 }
673
674 continue;
675 }
676 }
677
678 /* We're allowed to drop it. */
679 if (!square_isshop(cave, player->grid)) {
680 player->upkeep->dropping = true;
681 cmdq_push(CMD_DROP);
682 cmd_set_arg_item(cmdq_peek(), "item", obj);
683 cmd_set_arg_number(cmdq_peek(), "quantity", obj->number);
684 }
685 }
686 }
687
688 /* Update the gear */
689 player->upkeep->update |= (PU_INVEN);
690
691 /* Combine/reorder the pack */
692 player->upkeep->notice |= (PN_COMBINE);
693 }
694
695 /**
696 * Return the name of an ignore type.
697 */
ignore_name_for_type(ignore_type_t type)698 const char *ignore_name_for_type(ignore_type_t type)
699 {
700 size_t i;
701
702 for (i = ITYPE_NONE + 1; i < ITYPE_MAX; i++) {
703 if (quality_choices[i].enum_val == type)
704 return quality_choices[i].name;
705 }
706
707 return "unknown";
708 }
709
710 struct init_module ignore_module = {
711 .name = "ignore",
712 .init = init_ignore,
713 .cleanup = cleanup_ignore
714 };
715