1 /* File: object.c */
2
3 /* Purpose: misc code for objects */
4
5 /*
6 * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
7 *
8 * This software may be copied and distributed for educational, research, and
9 * not for profit purposes provided that this copyright and statement are
10 * included in all such copies.
11 */
12
13 #include "mangband.h"
14
15
16
17
delete_object_ptr(object_type * o_ptr)18 void delete_object_ptr(object_type * o_ptr)
19 {
20 /* special function to deal with inventory items being destoryed, instead of just wiping them */
21 /*
22 int i,j;
23
24 int y = o_ptr->iy;
25 int x = o_ptr->ix;
26 int Depth = o_ptr->dun_depth;
27 */
28 /* Wipe the object */
29 WIPE(o_ptr, object_type);
30
31 }
32
33 /*
34 * Excise a dungeon object from any stacks
35 */
excise_object_idx(int o_idx)36 static void excise_object_idx(int o_idx)
37 {
38 object_type *j_ptr;
39 s16b this_o_idx, next_o_idx = 0;
40 s16b prev_o_idx = 0;
41
42 /* Object */
43 j_ptr = &o_list[o_idx];
44
45 /* Monster */
46 if (j_ptr->held_m_idx)
47 {
48 monster_type *m_ptr;
49
50 /* Monster */
51 m_ptr = &m_list[j_ptr->held_m_idx];
52
53 /* Scan all objects in the grid */
54 for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
55 {
56 object_type *o_ptr;
57
58 /* Get the object */
59 o_ptr = &o_list[this_o_idx];
60
61 /* Get the next object */
62 next_o_idx = o_ptr->next_o_idx;
63
64 /* Done */
65 if (this_o_idx == o_idx)
66 {
67 /* No previous */
68 if (prev_o_idx == 0)
69 {
70 /* Remove from list */
71 m_ptr->hold_o_idx = next_o_idx;
72 }
73
74 /* Real previous */
75 else
76 {
77 object_type *i_ptr;
78
79 /* Previous object */
80 i_ptr = &o_list[prev_o_idx];
81
82 /* Remove from list */
83 i_ptr->next_o_idx = next_o_idx;
84 }
85
86 /* Forget next pointer */
87 o_ptr->next_o_idx = 0;
88
89 /* Done */
90 break;
91 }
92
93 /* Save prev_o_idx */
94 prev_o_idx = this_o_idx;
95 }
96 }
97
98 /* Dungeon */
99 else
100 {
101 int y = j_ptr->iy;
102 int x = j_ptr->ix;
103 int Depth = j_ptr->dun_depth;
104 cave_type *c_ptr = &cave[Depth][y][x];
105 int i;
106
107 /* Object is gone */
108 c_ptr->o_idx = 0;
109
110 /* No one can see it anymore */
111 for (i = 1; i <= NumPlayers; i++)
112 {
113 if (Players[i]->obj_vis[o_idx]) Players[i]->window |= (PW_ITEMLIST);
114 Players[i]->obj_vis[o_idx] = FALSE;
115 }
116 }
117 }
118
119
object_wipe(object_type * o_ptr)120 static void object_wipe(object_type* o_ptr)
121 {
122 /* Wipe the object */
123 WIPE(o_ptr, object_type);
124 }
125
126 /*
127 * Prepare an object based on an object kind.
128 */
object_prep(object_type * o_ptr,int k_idx)129 void object_prep(object_type *o_ptr, int k_idx)
130 {
131 object_kind *k_ptr = &k_info[k_idx];
132
133 /* Clear the record */
134 (void)WIPE(o_ptr, object_type);
135
136 /* Save the kind index */
137 o_ptr->k_idx = k_idx;
138
139 /* Efficiency -- tval/sval */
140 o_ptr->tval = k_ptr->tval;
141 o_ptr->sval = k_ptr->sval;
142
143 /* Default "pval" */
144 o_ptr->pval = k_ptr->pval;
145
146 /* Default number */
147 o_ptr->number = 1;
148
149 /* Default weight */
150 o_ptr->weight = k_ptr->weight;
151
152 /* Default magic */
153 o_ptr->to_h = k_ptr->to_h;
154 o_ptr->to_d = k_ptr->to_d;
155 o_ptr->to_a = k_ptr->to_a;
156
157 /* Default power */
158 o_ptr->ac = k_ptr->ac;
159 o_ptr->dd = k_ptr->dd;
160 o_ptr->ds = k_ptr->ds;
161
162 /* Default owner (none) */
163 o_ptr->owner_id = 0;
164 o_ptr->owner_name = 0;
165
166 /* Hack -- worthless items are always "broken" */
167 if (k_ptr->cost <= 0) o_ptr->ident |= (ID_BROKEN);
168
169 /* Hack -- cursed items are always "cursed" */
170 if (k_ptr->flags3 & (TR3_LIGHT_CURSE)) o_ptr->ident |= (ID_CURSED);
171 }
172
173
174
175
176 /*
177 * Delete a dungeon object
178 */
delete_object_idx(int o_idx)179 void delete_object_idx(int o_idx)
180 {
181 object_type *j_ptr;
182
183 /* Excise */
184 excise_object_idx(o_idx);
185
186 /* Object */
187 j_ptr = &o_list[o_idx];
188
189 /* Dungeon floor */
190 if (!j_ptr->held_m_idx)
191 {
192 int y, x, Depth;
193
194 /* Location */
195 y = j_ptr->iy;
196 x = j_ptr->ix;
197 Depth = j_ptr->dun_depth;
198
199 /* Visual update */
200 everyone_lite_spot(Depth, y, x);
201 }
202
203 /* Wipe the object */
204 object_wipe(j_ptr);
205 }
206
207
208 /*
209 * Deletes object from given location
210 */
delete_object(int Depth,int y,int x)211 void delete_object(int Depth, int y, int x)
212 {
213 cave_type *c_ptr;
214
215 /* Paranoia */
216 if (!in_bounds(Depth, y, x)) return;
217
218 /* Paranoia -- make sure the level has been allocated */
219 if (!cave[Depth])
220 {
221 plog(format("Error : tried to delete object on unallocated level %d",Depth));
222 return;
223 }
224
225 /* Find where it was */
226 c_ptr = &cave[Depth][y][x];
227
228 /* Delete the object */
229 if (c_ptr->o_idx) delete_object_idx(c_ptr->o_idx);
230 }
231
232
233 /*
234 * Move an object from index i1 to index i2 in the object list
235 */
compact_objects_aux(int i1,int i2)236 static void compact_objects_aux(int i1, int i2)
237 {
238 int i, Ind;
239 object_type *o_ptr;
240
241 /* Do nothing */
242 if (i1 == i2) return;
243
244 /* Repair objects */
245 for (i = 1; i < o_max; i++)
246 {
247 /* Get the object */
248 o_ptr = &o_list[i];
249
250 /* Skip "dead" objects */
251 if (!o_ptr->k_idx) continue;
252
253 /* Repair "next" pointers */
254 if (o_ptr->next_o_idx == i1)
255 {
256 /* Repair */
257 o_ptr->next_o_idx = i2;
258 }
259 }
260
261 /* Get the object */
262 o_ptr = &o_list[i1];
263
264 /* Monster */
265 if (o_ptr->held_m_idx)
266 {
267 monster_type *m_ptr;
268
269 /* Get the monster */
270 m_ptr = &m_list[o_ptr->held_m_idx];
271
272 /* Repair monster */
273 if (m_ptr->hold_o_idx == i1)
274 {
275 /* Repair */
276 m_ptr->hold_o_idx = i2;
277 }
278 }
279
280 /* Dungeon */
281 else
282 {
283 int y, x, Depth;
284
285 /* Get location */
286 y = o_ptr->iy;
287 x = o_ptr->ix;
288 Depth = o_ptr->dun_depth;
289
290 /* Repair grid */
291 if (cave[Depth] && (cave[Depth][y][x].o_idx == i1))
292 {
293 /* Repair */
294 cave[Depth][y][x].o_idx = i2;
295 }
296 }
297
298 /* Copy the visibility flags for each player */
299 for (Ind = 1; Ind <= NumPlayers; Ind++)
300 Players[Ind]->obj_vis[i2] = Players[Ind]->obj_vis[i1];
301
302 /* Hack -- move object */
303 COPY(&o_list[i2], &o_list[i1], object_type);
304
305 /* Hack -- wipe hole */
306 object_wipe(o_ptr);
307 }
308
309
310 /*
311 * Compact and reorder the object list
312 *
313 * This function can be very dangerous, use with caution!
314 *
315 * When compacting objects, we first destroy crops, junk and skeletons, on the basis that
316 * those are the least important objects with almost no gameplay value (MAngband-specific).
317 *
318 * When compacting other objects, we base the saving throw on a combination of
319 * object level, distance from player, and current "desperation".
320 *
321 * After compacting, we "reorder" the objects into a more compact order, and we
322 * reset the allocation info, and the "live" array.
323 */
compact_objects(int size)324 void compact_objects(int size)
325 {
326 int i, y, x, cnt;
327 int cur_lev, cur_val, chance;
328
329 /* Reorder objects when not passed a size */
330 if (!size)
331 {
332 /* Excise dead objects (backwards!) */
333 for (i = o_max - 1; i >= 1; i--)
334 {
335 object_type *o_ptr = &o_list[i];
336
337 /* Skip real objects */
338 if (o_ptr->k_idx) continue;
339
340 /* Move last object into open hole */
341 compact_objects_aux(o_max - 1, i);
342
343 /* Compress "o_max" */
344 o_max--;
345 }
346
347 /* Reset "o_nxt" */
348 o_nxt = o_max;
349
350 /* Reset "o_top" */
351 o_top = 0;
352
353 /* Collect "live" objects */
354 for (i = 1; i < o_max; i++)
355 {
356 /* Collect indexes */
357 o_fast[o_top++] = i;
358 }
359
360 return;
361 }
362
363 /* Message */
364 plog("Compacting objects...");
365
366 /*** Try destroying objects ***/
367
368 /* First do crops, junk and skeletons */
369 for (i = 1; (i < o_max) && (size); i++)
370 {
371 object_type *o_ptr = &o_list[i];
372
373 /* Nuke crops */
374 if (((o_ptr->tval == TV_FOOD) && (o_ptr->sval >= SV_FOOD_POTATO) && (o_ptr->sval < SV_FOOD_BISCUIT)) ||
375 /* Nuke junk items and skeletons */
376 ((o_ptr->tval == TV_SKELETON) || (o_ptr->tval == TV_JUNK)))
377 {
378 delete_object_idx(i);
379 size--;
380 }
381 }
382
383 /* Compact at least 'size' objects */
384 for (cnt = 1; size; cnt++)
385 {
386 /* Get more vicious each iteration */
387 cur_lev = 5 * cnt;
388
389 /* Destroy more valuable items each iteration */
390 cur_val = 500 * (cnt - 1);
391
392 /* Examine the objects */
393 for (i = 1; (i < o_max) && (size); i++)
394 {
395 object_type *o_ptr = &o_list[i];
396 object_kind *k_ptr = &k_info[o_ptr->k_idx];
397
398 /* Skip dead objects */
399 if (!o_ptr->k_idx) continue;
400
401 /* Hack -- High level objects start out "immune" */
402 if (k_ptr->level > cur_lev) continue;
403
404 /* Valuable objects start out "immune" */
405 if (object_value(NULL, o_ptr) > cur_val) continue;
406
407 /* Saving throw */
408 chance = 90;
409
410 /* Monster */
411 if (o_ptr->held_m_idx)
412 {
413 monster_type *m_ptr;
414
415 /* Get the monster */
416 m_ptr = &m_list[o_ptr->held_m_idx];
417
418 /* Monsters protect their objects */
419 //if (magik(90))
420 continue;
421 }
422
423 /* Dungeon */
424 else
425 {
426 /* Get the location */
427 y = o_ptr->iy;
428 x = o_ptr->ix;
429
430 /* Hack -- only compact items in houses in emergencies */
431 /* Make sure that houses in the wilderness are dealt with too! */
432 if ((o_ptr->dun_depth <= 0) && (cave[0][y][x].info & CAVE_ICKY))
433 {
434 /* Grant immunity except in emergencies */
435 if (cnt < 1000) chance = 100;
436 }
437 }
438
439 /* Hack -- only compact artifacts in emergencies */
440 if (true_artifact_p(o_ptr) && (cnt < 1000)) chance = 100;
441
442 /* Apply the saving throw */
443 if (magik(chance)) continue;
444
445 /* Delete the object */
446 delete_object_idx(i);
447 size--;
448 }
449 }
450
451 /* Reorder objects */
452 compact_objects(0);
453 }
454
455
456
457 /*
458 * Delete all the items when player leaves the level
459 *
460 * Note -- we do NOT visually reflect these (irrelevant) changes
461 */
462
463
wipe_o_list(int Depth)464 void wipe_o_list(int Depth)
465 {
466 int i;//, house_depth;
467
468 /* Delete the existing objects */
469 for (i = 1; i < o_max; i++)
470 {
471 object_type *o_ptr = &o_list[i];
472
473 /* Skip dead objects */
474 if (!o_ptr->k_idx) continue;
475
476 /* Skip objects not on this depth */
477 if (o_ptr->dun_depth != Depth)
478 continue;
479
480 /* Mega-Hack -- preserve artifacts */
481 /* Hack -- Preserve unknown artifacts */
482 /* We now preserve ALL artifacts, known or not */
483 if (true_artifact_p(o_ptr)/* && !object_known_p(o_ptr)*/)
484 {
485 /* Info */
486 /* s_printf("Preserving artifact %d.\n", o_ptr->name1); */
487
488 /* Mega-Hack -- Preserve the artifact */
489 a_info[o_ptr->name1].cur_num = 0;
490
491 /* Ultra-Hack -- If this artifact belongs to player, set abandoned */
492 if (o_ptr->owner_id)
493 {
494 int j;
495 for (j = 1; j <= NumPlayers; j++)
496 {
497 /* Only works when player is ingame */
498 if ((Players[j]->id == o_ptr->owner_id) && object_known_p(Players[j], o_ptr))
499 {
500 set_artifact_p(Players[j], o_ptr->name1, ARTS_ABANDONED);
501 break;
502 }
503 }
504 }
505 }
506
507 /* Monster */
508 if (o_ptr->held_m_idx)
509 {
510 monster_type *m_ptr;
511 m_ptr = &m_list[o_ptr->held_m_idx];
512 m_ptr->hold_o_idx = 0;
513 }
514
515 /* Wipe the object */
516 WIPE(o_ptr, object_type);
517 }
518
519 /* Compact the object list */
520 compact_objects(0);
521 }
522
523
524 /*
525 * Acquires and returns the index of a "free" object.
526 *
527 * This routine should almost never fail, but in case it does,
528 * we must be sure to handle "failure" of this routine.
529 *
530 * Note that this function must maintain the special "o_fast"
531 * array of pointers to "live" objects.
532 */
o_pop(void)533 s16b o_pop(void)
534 {
535 int i, n, k;
536
537
538 /* Initial allocation */
539 if (o_max < MAX_O_IDX)
540 {
541 /* Get next space */
542 i = o_max;
543
544 /* Expand object array */
545 o_max++;
546
547 /* Update "o_fast" */
548 o_fast[o_top++] = i;
549
550 /* Use this object */
551 return (i);
552 }
553
554
555 /* Check for some space */
556 for (n = 1; n < MAX_O_IDX; n++)
557 {
558 /* Get next space */
559 i = o_nxt;
560
561 /* Advance (and wrap) the "next" pointer */
562 if (++o_nxt >= MAX_O_IDX) o_nxt = 1;
563
564 /* Skip objects in use */
565 if (o_list[i].k_idx) continue;
566
567 /* Verify space XXX XXX */
568 if (o_top >= MAX_O_IDX) continue;
569
570 /* Verify not allocated */
571 for (k = 0; k < o_top; k++)
572 {
573 /* Hack -- Prevent errors */
574 if (o_fast[k] == i) i = 0;
575 }
576
577 /* Oops XXX XXX */
578 if (!i) continue;
579
580 /* Update "o_fast" */
581 o_fast[o_top++] = i;
582
583 /* Use this object */
584 return (i);
585 }
586
587
588 /* Warn the player */
589 if (server_dungeon) plog("Too many objects!");
590
591 /* Oops */
592 return (0);
593 }
594
595
596
597 /*
598 * Apply a "object restriction function" to the "object allocation table"
599 */
get_obj_num_prep(void)600 errr get_obj_num_prep(void)
601 {
602 int i;
603
604 /* Get the entry */
605 alloc_entry *table = alloc_kind_table;
606
607 /* Scan the allocation table */
608 for (i = 0; i < alloc_kind_size; i++)
609 {
610 /* Accept objects which pass the restriction, if any */
611 if (!get_obj_num_hook || (*get_obj_num_hook)(table[i].index))
612 {
613 /* Accept this object */
614 table[i].prob2 = table[i].prob1;
615 }
616
617 /* Do not use this object */
618 else
619 {
620 /* Decline this object */
621 table[i].prob2 = 0;
622 }
623 }
624
625 /* Success */
626 return (0);
627 }
628
629
630
631 /*
632 * Choose an object kind that seems "appropriate" to the given level
633 *
634 * This function uses the "prob2" field of the "object allocation table",
635 * and various local information, to calculate the "prob3" field of the
636 * same table, which is then used to choose an "appropriate" object, in
637 * a relatively efficient manner.
638 *
639 * It is (slightly) more likely to acquire an object of the given level
640 * than one of a lower level. This is done by choosing several objects
641 * appropriate to the given level and keeping the "hardest" one.
642 *
643 * Note that if no objects are "appropriate", then this function will
644 * fail, and return zero, but this should *almost* never happen.
645 */
get_obj_num(int level)646 s16b get_obj_num(int level)
647 {
648 int i, j, p;
649
650 int k_idx;
651
652 long value, total;
653
654 object_kind *k_ptr;
655
656 alloc_entry *table = alloc_kind_table;
657
658
659 /* Boost level */
660 if (level > 0)
661 {
662 /* Occasional "boost" */
663 if (randint0(GREAT_OBJ) == 0)
664 {
665 /* What a bizarre calculation */
666 level = 1 + (level * MAX_DEPTH / randint1(MAX_DEPTH));
667 }
668 }
669
670
671 /* Reset total */
672 total = 0L;
673
674 /* Process probabilities */
675 for (i = 0; i < alloc_kind_size; i++)
676 {
677 /* Objects are sorted by depth */
678 if (table[i].level > level) break;
679
680 /* Default */
681 table[i].prob3 = 0;
682
683 /* Access the index */
684 k_idx = table[i].index;
685
686 /* Access the actual kind */
687 k_ptr = &k_info[k_idx];
688
689 /* Hack -- prevent embedded chests */
690 if (opening_chest && (k_ptr->tval == TV_CHEST)) continue;
691
692 /* Accept */
693 table[i].prob3 = table[i].prob2;
694
695 /* Total */
696 total += table[i].prob3;
697 }
698
699 /* No legal objects */
700 if (total <= 0) return (0);
701
702
703 /* Pick an object */
704 value = randint0(total);
705
706 /* Find the object */
707 for (i = 0; i < alloc_kind_size; i++)
708 {
709 /* Found the entry */
710 if (value < table[i].prob3) break;
711
712 /* Decrement */
713 value = value - table[i].prob3;
714 }
715
716
717 /* Power boost */
718 p = randint0(100);
719
720 /* Try for a "better" object once (50%) or twice (10%) */
721 if (p < 60)
722 {
723 /* Save old */
724 j = i;
725
726 /* Pick a object */
727 value = randint0(total);
728
729 /* Find the monster */
730 for (i = 0; i < alloc_kind_size; i++)
731 {
732 /* Found the entry */
733 if (value < table[i].prob3) break;
734
735 /* Decrement */
736 value = value - table[i].prob3;
737 }
738
739 /* Keep the "best" one */
740 if (table[i].level < table[j].level) i = j;
741 }
742
743 /* Try for a "better" object twice (10%) */
744 if (p < 10)
745 {
746 /* Save old */
747 j = i;
748
749 /* Pick a object */
750 value = randint0(total);
751
752 /* Find the object */
753 for (i = 0; i < alloc_kind_size; i++)
754 {
755 /* Found the entry */
756 if (value < table[i].prob3) break;
757
758 /* Decrement */
759 value = value - table[i].prob3;
760 }
761
762 /* Keep the "best" one */
763 if (table[i].level < table[j].level) i = j;
764 }
765
766
767 /* Result */
768 return (table[i].index);
769 }
770
771 #define ITEM_ACT_CASE_AIM \
772 case ACT_FIRE3: \
773 case ACT_FROST5: \
774 case ACT_ELEC2: \
775 case ACT_BIZZARE: \
776 case ACT_MISSILE: \
777 case ACT_FIRE1: \
778 case ACT_FROST1: \
779 case ACT_LIGHTNING_BOLT: \
780 case ACT_ACID1: \
781 case ACT_ARROW: \
782 case ACT_STINKING_CLOUD: \
783 case ACT_FROST2: \
784 case ACT_FROST4: \
785 case ACT_FROST3: \
786 case ACT_FIRE2: \
787 case ACT_DRAIN_LIFE2: \
788 case ACT_STONE_TO_MUD: \
789 case ACT_TELE_AWAY: \
790 case ACT_CONFUSE: \
791 case ACT_DRAIN_LIFE1: \
792 case ACT_MANA_BOLT:
793
794 /* Returns TRUE if object *could be used* as fuel.
795 * "fits" is set to TRUE, if it is to be used with
796 * currently wielded light source. */
object_is_fuel(player_type * p_ptr,object_type * o_ptr,bool * fits)797 bool object_is_fuel(player_type *p_ptr, object_type *o_ptr, bool *fits)
798 {
799 object_type *lamp_o_ptr;
800 bool is_fuel = TRUE;
801 bool has_torch = FALSE;
802 bool has_lantern = FALSE;
803
804 *fits = FALSE;
805
806 /* See what a player is wielding. */
807 lamp_o_ptr = &(p_ptr->inventory[INVEN_LITE]);
808 if (lamp_o_ptr->tval == TV_LITE)
809 {
810 /* It's a lamp */
811 if (lamp_o_ptr->sval == SV_LITE_LANTERN)
812 {
813 has_lantern = TRUE;
814 }
815 /* It's a torch */
816 if (lamp_o_ptr->sval == SV_LITE_TORCH)
817 {
818 has_torch = TRUE;
819 }
820 }
821
822 /* item_tester_refill_lantern: */
823 if (!o_ptr->name3 &&
824 (o_ptr->tval == TV_FLASK ||
825 (o_ptr->tval == TV_LITE && o_ptr->sval == SV_LITE_LANTERN)))
826 {
827 is_fuel = TRUE;
828 if (has_lantern) *fits = TRUE;
829 }
830 /* item_tester_refill_torch: */
831 else if (o_ptr->tval == TV_LITE && o_ptr->sval == SV_LITE_TORCH)
832 {
833 is_fuel = TRUE;
834 if (has_torch) *fits = TRUE;
835 }
836 return is_fuel;
837 }
838
839 /*
840 * This function determines primary item tester and use flag for a given object.
841 * It uses hardcoded TVALs/SVALs, similarly to how all our code does.
842 * Note: some items have a *secondary* tester, which will also be determined
843 * and stored in the "secondary_tester" pointer.
844 */
object_tester_flag(player_type * p_ptr,object_type * o_ptr,byte * secondary_tester)845 byte object_tester_flag(player_type *p_ptr, object_type *o_ptr, byte *secondary_tester)
846 {
847 byte flag = 0;
848 u32b f1, f2, f3;
849 bool relevant_fuel = FALSE;
850
851 bool aware = object_aware_p(p_ptr, o_ptr);
852 bool tried = aware || object_tried_p(p_ptr, o_ptr);
853 *secondary_tester = 0;
854
855 /* item_tester_hook_wear: */
856 if (wield_slot(p_ptr, o_ptr) >= INVEN_WIELD)
857 {
858 flag |= ITF_WEAR;
859 }
860
861 /* item_tester_hook_activate: */
862 if (object_known_p(p_ptr, o_ptr))
863 {
864 object_flags(o_ptr, &f1, &f2, &f3);
865 if (f3 & TR3_ACTIVATE)
866 {
867 flag |= ITF_ACT;
868
869 /* Hack: ask for direction ? (FOR ACTIVATION) */
870 /* Artifacts (use-obj.c) */
871 if (true_artifact_p(o_ptr))
872 switch(a_info[o_ptr->name1].activation)
873 {
874 ITEM_ACT_CASE_AIM flag |= ITEM_ASK_AIM; break;
875 default: break;
876 }
877 /* Hack -- Dragon Scale Mail can be activated as well (use-obj.c) */
878 if (o_ptr->tval == TV_DRAG_ARMOR) flag |= ITEM_ASK_AIM;
879 /* Hack -- some Rings can be activated for double resist and element ball (use-obj.c) */
880 if (o_ptr->tval == TV_RING) flag |= ITEM_ASK_AIM;
881 }
882 }
883
884 /* ask for direction ? (FOR RODS) */
885 if (o_ptr->tval == TV_ROD)
886 {
887 /* Hack -- KNOWN Rod of Perception asks for item */
888 if ((o_ptr->sval == SV_ROD_IDENTIFY) && aware)
889 {
890 flag |= ITEM_ASK_ITEM;
891 }
892 else
893 /* Get a direction (unless KNOWN not to need it) */
894 if ((o_ptr->sval >= SV_ROD_MIN_DIRECTION) || !tried)
895 {
896 flag |= ITEM_ASK_AIM;
897 }
898 }
899
900 /* ask for another item? (FOR STAFFS) */
901 if (o_ptr->tval == TV_STAFF)
902 {
903 /* Get an item (unless KNOWN not to need it) */
904 if ((o_ptr->sval >= SV_STAFF_IDENTIFY && o_ptr->sval <= SV_STAFF_REMOVE_CURSE)
905 || !tried)
906 {
907 flag |= ITEM_ASK_ITEM;
908 }
909 /* Specify secondary tester (if player KNOWS what that spell is) */
910 if ((flag & ITEM_ASK_ITEM) && aware)
911 {
912 switch (o_ptr->sval)
913 {
914 case SV_STAFF_REMOVE_CURSE:
915 *secondary_tester = item_test(WEAR);
916 default: break;
917 }
918 }
919 }
920
921 /* ask for another item? (Id, Enchant, Curse, ...) */
922 if (o_ptr->tval == TV_SCROLL)
923 {
924 /* Get a second item (unless KNOWN not to need it) */
925 if (o_ptr->sval == SV_SCROLL_CREATE_ARTIFACT
926 || (o_ptr->sval >= SV_SCROLL_IDENTIFY && o_ptr->sval <= SV_SCROLL_RECHARGING)
927 || !tried)
928 {
929 flag |= ITEM_ASK_ITEM;
930 }
931 /* Specify secondary tester (if player KNOWS what that spell is) */
932 if ((flag & ITEM_ASK_ITEM) && aware)
933 {
934 switch (o_ptr->sval)
935 {
936 case SV_SCROLL_CURSE_WEAPON:
937 case SV_SCROLL_STAR_ENCHANT_WEAPON:
938 case SV_SCROLL_ENCHANT_WEAPON_TO_HIT:
939 case SV_SCROLL_ENCHANT_WEAPON_TO_DAM:
940 *secondary_tester = item_test(WEAPON);
941 break;
942 case SV_SCROLL_CURSE_ARMOR:
943 case SV_SCROLL_ENCHANT_ARMOR:
944 case SV_SCROLL_STAR_ENCHANT_ARMOR:
945 *secondary_tester = item_test(ARMOR);
946 break;
947 case SV_SCROLL_RECHARGING:
948 *secondary_tester = item_test(RECHARGE);
949 break;
950 default: break;
951 }
952 }
953 }
954
955 /* refill light ? */
956 if (object_is_fuel(p_ptr, o_ptr, &relevant_fuel))
957 {
958 /* torch matching torch or flask matching lantern */
959 if (relevant_fuel)
960 {
961 flag |= ITF_FUEL;
962 }
963 }
964
965 /* Return Flag */
966 return flag;
967 }
968
969
970
971
972 /*
973 * Known is true when the "attributes" of an object are "known".
974 * These include tohit, todam, toac, cost, and pval (charges).
975 *
976 * Note that "knowing" an object gives you everything that an "awareness"
977 * gives you, and much more. In fact, the player is always "aware" of any
978 * item of which he has full "knowledge".
979 *
980 * But having full knowledge of, say, one "wand of wonder", does not, by
981 * itself, give you knowledge, or even awareness, of other "wands of wonder".
982 * It happens that most "identify" routines (including "buying from a shop")
983 * will make the player "aware" of the object as well as fully "know" it.
984 *
985 * This routine also removes any inscriptions generated by "feelings".
986 */
object_known(object_type * o_ptr)987 void object_known(object_type *o_ptr)
988 {
989 /* Remove "default inscriptions" */
990 if (o_ptr->note && (o_ptr->ident & ID_SENSE))
991 {
992 /* Access the inscription */
993 cptr q = quark_str(o_ptr->note);
994
995 /* Hack -- Remove auto-inscriptions */
996 if ((streq(q, "cursed")) ||
997 (streq(q, "broken")) ||
998 (streq(q, "good")) ||
999 (streq(q, "average")) ||
1000 (streq(q, "excellent")) ||
1001 (streq(q, "worthless")) ||
1002 (streq(q, "special")) ||
1003 (streq(q, "terrible")))
1004 {
1005 /* Forget the inscription */
1006 o_ptr->note = 0;
1007 }
1008 }
1009
1010 /* Clear the "Felt" info */
1011 o_ptr->ident &= ~ID_SENSE;
1012
1013 /* Clear the "Empty" info */
1014 o_ptr->ident &= ~ID_EMPTY;
1015
1016 /* Now we know about the item */
1017 o_ptr->ident |= ID_KNOWN;
1018 }
1019
1020
1021
1022
1023
1024 /*
1025 * The player is now aware of the effects of the given object.
1026 */
object_aware(player_type * p_ptr,object_type * o_ptr)1027 void object_aware(player_type *p_ptr, object_type *o_ptr)
1028 {
1029 int item;
1030 int _tmp;
1031 object_type *j_ptr;
1032
1033 /* Fully aware of the effects */
1034 p_ptr->kind_aware[o_ptr->k_idx] = TRUE;
1035
1036 /* Update resistant flags */
1037 p_ptr->redraw |= PR_OFLAGS;
1038
1039 /* Update all similar objects */
1040 for (item = 0; item < INVEN_TOTAL; item++)
1041 {
1042 object_type *j_ptr = &p_ptr->inventory[item];
1043 if (o_ptr->k_idx == j_ptr->k_idx)
1044 {
1045 player_redraw_item(p_ptr, item);
1046 }
1047 }
1048 /* And the floor object */
1049 if ((j_ptr = player_get_floor_item(p_ptr, &_tmp)))
1050 {
1051 if (o_ptr->k_idx == j_ptr->k_idx)
1052 {
1053 player_redraw_item(p_ptr, FLOOR_INDEX);
1054 }
1055 }
1056 }
1057
1058
1059
1060 /*
1061 * Something has been "sampled"
1062 */
object_tried(player_type * p_ptr,object_type * o_ptr)1063 void object_tried(player_type *p_ptr, object_type *o_ptr)
1064 {
1065 /* Mark it as tried (even if "aware") */
1066 p_ptr->kind_tried[o_ptr->k_idx] = TRUE;
1067 }
1068
1069
1070
1071 /*
1072 * Return the "value" of an "unknown" item
1073 * Make a guess at the value of non-aware items
1074 */
object_value_base(player_type * p_ptr,object_type * o_ptr)1075 static s32b object_value_base(player_type *p_ptr, object_type *o_ptr)
1076 {
1077 object_kind *k_ptr = &k_info[o_ptr->k_idx];
1078
1079 /* Aware item -- use template cost */
1080 if (p_ptr == NULL || object_aware_p(p_ptr, o_ptr)) return (k_ptr->cost);
1081
1082 /* Analyze the type */
1083 switch (o_ptr->tval)
1084 {
1085 /* Un-aware Food */
1086 case TV_FOOD: return (5L);
1087
1088 /* Un-aware Potions */
1089 case TV_POTION: return (20L);
1090
1091 /* Un-aware Scrolls */
1092 case TV_SCROLL: return (20L);
1093
1094 /* Un-aware Staffs */
1095 case TV_STAFF: return (70L);
1096
1097 /* Un-aware Wands */
1098 case TV_WAND: return (50L);
1099
1100 /* Un-aware Rods */
1101 case TV_ROD: return (90L);
1102
1103 /* Un-aware Rings */
1104 case TV_RING: return (45L);
1105
1106 /* Un-aware Amulets */
1107 case TV_AMULET: return (45L);
1108 }
1109
1110 /* Paranoia -- Oops */
1111 return (0L);
1112 }
1113
1114
1115 /*
1116 * Return the "real" price of a "known" item, not including discounts
1117 *
1118 * Wand and staffs get cost for each charge
1119 *
1120 * Armor is worth an extra 100 gold per bonus point to armor class.
1121 *
1122 * Weapons are worth an extra 100 gold per bonus point (AC,TH,TD).
1123 *
1124 * Missiles are only worth 5 gold per bonus point, since they
1125 * usually appear in groups of 20, and we want the player to get
1126 * the same amount of cash for any "equivalent" item. Note that
1127 * missiles never have any of the "pval" flags, and in fact, they
1128 * only have a few of the available flags, primarily of the "slay"
1129 * and "brand" and "ignore" variety.
1130 *
1131 * Armor with a negative armor bonus is worthless.
1132 * Weapons with negative hit+damage bonuses are worthless.
1133 *
1134 * Every wearable item with a "pval" bonus is worth extra (see below).
1135 */
object_value_real(object_type * o_ptr)1136 static s32b object_value_real(object_type *o_ptr)
1137 {
1138 s32b value;
1139
1140 u32b f1, f2, f3;
1141
1142 object_kind *k_ptr = &k_info[o_ptr->k_idx];
1143
1144
1145 /* Hack -- "worthless" items */
1146 if (!k_ptr->cost) return (0L);
1147
1148 /* Base cost */
1149 value = k_ptr->cost;
1150
1151
1152 /* Extract some flags */
1153 object_flags(o_ptr, &f1, &f2, &f3);
1154
1155
1156 /* Artifact */
1157 if (artifact_p(o_ptr))
1158 {
1159 artifact_type *a_ptr = artifact_ptr(o_ptr);
1160
1161 /* Hack -- "worthless" artifacts */
1162 if (!a_ptr->cost) return (0L);
1163
1164 /* Hack -- Use the artifact cost instead */
1165 value = a_ptr->cost;
1166 }
1167
1168 /* Ego-Item */
1169 else if (o_ptr->name2)
1170 {
1171 ego_item_type *e_ptr = &e_info[o_ptr->name2];
1172
1173 /* Hack -- "worthless" ego-items */
1174 if (!e_ptr->cost) return (0L);
1175
1176 /* Hack -- Reward the ego-item with a bonus */
1177 value += e_ptr->cost;
1178 }
1179
1180
1181 /* Analyze pval bonus */
1182 switch (o_ptr->tval)
1183 {
1184 case TV_SHOT:
1185 case TV_ARROW:
1186 case TV_BOLT:
1187 case TV_BOW:
1188 case TV_DIGGING:
1189 case TV_HAFTED:
1190 case TV_POLEARM:
1191 case TV_SWORD:
1192 case TV_BOOTS:
1193 case TV_GLOVES:
1194 case TV_HELM:
1195 case TV_CROWN:
1196 case TV_SHIELD:
1197 case TV_CLOAK:
1198 case TV_SOFT_ARMOR:
1199 case TV_HARD_ARMOR:
1200 case TV_DRAG_ARMOR:
1201 case TV_LITE:
1202 case TV_AMULET:
1203 case TV_RING:
1204 {
1205 /* Hack -- Negative "pval" is always bad */
1206 if (o_ptr->pval < 0) return (0L);
1207
1208 /* No pval */
1209 if (!o_ptr->pval) break;
1210
1211 /* Give credit for stat bonuses */
1212 if (f1 & TR1_STR) value += (o_ptr->pval * 200L);
1213 if (f1 & TR1_INT) value += (o_ptr->pval * 200L);
1214 if (f1 & TR1_WIS) value += (o_ptr->pval * 200L);
1215 if (f1 & TR1_DEX) value += (o_ptr->pval * 200L);
1216 if (f1 & TR1_CON) value += (o_ptr->pval * 200L);
1217 if (f1 & TR1_CHR) value += (o_ptr->pval * 200L);
1218
1219 /* Give credit for stealth and searching */
1220 if (f1 & TR1_STEALTH) value += (o_ptr->pval * 100L);
1221 if (f1 & TR1_SEARCH) value += (o_ptr->pval * 100L);
1222
1223 /* Give credit for infra-vision and tunneling */
1224 if (f1 & TR1_INFRA) value += (o_ptr->pval * 50L);
1225 if (f1 & TR1_TUNNEL) value += (o_ptr->pval * 50L);
1226
1227 /* Give credit for extra attacks */
1228 if (f1 & TR1_BLOWS) value += (o_ptr->pval * 2000L);
1229
1230 /* Hack -- amulets of speed and rings of speed are
1231 * cheaper than other items of speed.
1232 */
1233 if (o_ptr->tval == TV_AMULET)
1234 {
1235 /* Give credit for speed bonus */
1236 if (f1 & TR1_SPEED) value += (o_ptr->pval * 25000L);
1237 }
1238 else if (o_ptr->tval == TV_RING)
1239 {
1240 /* Give credit for speed bonus */
1241 if (f1 & TR1_SPEED) value += (o_ptr->pval * 50000L);
1242 }
1243 else if (f1 & TR1_SPEED) value += (o_ptr->pval * 100000L);
1244 break;
1245 }
1246 }
1247
1248
1249 /* Analyze the item */
1250 switch (o_ptr->tval)
1251 {
1252 /* Wands/Staffs */
1253 case TV_WAND:
1254 case TV_STAFF:
1255 {
1256 /* Pay extra for charges */
1257 value += ((value / 20) * (o_ptr->pval / o_ptr->number));
1258
1259 /* Done */
1260 break;
1261 }
1262
1263 /* Rings/Amulets */
1264 case TV_RING:
1265 case TV_AMULET:
1266 {
1267 /* Hack -- negative bonuses are bad */
1268 if (o_ptr->to_a < 0) return (0L);
1269 if (o_ptr->to_h < 0) return (0L);
1270 if (o_ptr->to_d < 0) return (0L);
1271
1272 /* Give credit for bonuses */
1273 value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
1274
1275 /* Done */
1276 break;
1277 }
1278
1279 /* Armor */
1280 case TV_BOOTS:
1281 case TV_GLOVES:
1282 case TV_CLOAK:
1283 case TV_CROWN:
1284 case TV_HELM:
1285 case TV_SHIELD:
1286 case TV_SOFT_ARMOR:
1287 case TV_HARD_ARMOR:
1288 case TV_DRAG_ARMOR:
1289 {
1290 /* Hack -- negative armor bonus */
1291 if (o_ptr->to_a < 0) return (0L);
1292
1293 /* Give credit for bonuses */
1294 value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
1295
1296 /* Done */
1297 break;
1298 }
1299
1300 /* Bows/Weapons */
1301 case TV_BOW:
1302 case TV_DIGGING:
1303 case TV_HAFTED:
1304 case TV_SWORD:
1305 case TV_POLEARM:
1306 {
1307 /* Hack -- negative hit/damage bonuses */
1308 if (o_ptr->to_h + o_ptr->to_d < 0) return (0L);
1309
1310 /* Factor in the bonuses */
1311 value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
1312
1313 /* Hack -- Factor in extra damage dice */
1314 if ((o_ptr->dd > k_ptr->dd) && (o_ptr->ds == k_ptr->ds))
1315 {
1316 value += (o_ptr->dd - k_ptr->dd) * o_ptr->ds * 100L;
1317 }
1318
1319 /* Done */
1320 break;
1321 }
1322
1323 /* Ammo */
1324 case TV_SHOT:
1325 case TV_ARROW:
1326 case TV_BOLT:
1327 {
1328 /* Hack -- negative hit/damage bonuses */
1329 if (o_ptr->to_h + o_ptr->to_d < 0) return (0L);
1330
1331 /* Factor in the bonuses */
1332 value += ((o_ptr->to_h + o_ptr->to_d) * 5L);
1333
1334 /* Hack -- Factor in extra damage dice */
1335 if ((o_ptr->dd > k_ptr->dd) && (o_ptr->ds == k_ptr->ds))
1336 {
1337 value += (o_ptr->dd - k_ptr->dd) * o_ptr->ds * 5L;
1338 }
1339
1340 /* Done */
1341 break;
1342 }
1343 }
1344
1345
1346 /* Return the value */
1347 return (value);
1348 }
1349
1350
1351 /*
1352 * Return the price of an item including plusses (and charges)
1353 *
1354 * This function returns the "value" of the given item (qty one)
1355 *
1356 * Never notice "unknown" bonuses or properties, including "curses",
1357 * since that would give the player information he did not have.
1358 *
1359 * Note that discounted items stay discounted forever, even if
1360 * the discount is "forgotten" by the player via memory loss.
1361 */
object_value(player_type * p_ptr,object_type * o_ptr)1362 s32b object_value(player_type *p_ptr, object_type *o_ptr)
1363 {
1364 s32b value;
1365
1366
1367 /* Unknown items -- acquire a base value */
1368 if (p_ptr == NULL || object_known_p(p_ptr, o_ptr))
1369 {
1370 /* Broken items -- worthless */
1371 if (broken_p(o_ptr)) return (0L);
1372
1373 /* Cursed items -- worthless */
1374 if (cursed_p(o_ptr)) return (0L);
1375
1376 /* Real value (see above) */
1377 value = object_value_real(o_ptr);
1378 }
1379
1380 /* Known items -- acquire the actual value */
1381 else
1382 {
1383 /* Hack -- Felt broken items */
1384 if ((o_ptr->ident & ID_SENSE) && broken_p(o_ptr)) return (0L);
1385
1386 /* Hack -- Felt cursed items */
1387 if ((o_ptr->ident & ID_SENSE) && cursed_p(o_ptr)) return (0L);
1388
1389 /* Base value (see above) */
1390 value = object_value_base(p_ptr, o_ptr);
1391 }
1392
1393
1394 /* Apply discount (if any) */
1395 if (o_ptr->discount) value -= (value * o_ptr->discount / 100L);
1396
1397
1398 /* Return the final value */
1399 return (value);
1400 }
1401
1402
1403 /*
1404 * Determine if an item can "absorb" a second item on the floor -- MAngband-specific Hack
1405 *
1406 * It is very similar from the object_similar function, minus the player specific-checks.
1407 * It denies most attempts, but is allows discounts & inscription stack.
1408 *
1409 */
object_similar_floor(object_type * o_ptr,object_type * j_ptr)1410 bool object_similar_floor(object_type *o_ptr, object_type *j_ptr)
1411 {
1412 int total = o_ptr->number + j_ptr->number;
1413
1414
1415 /* Require identical object types */
1416 if (o_ptr->k_idx != j_ptr->k_idx) return (0);
1417
1418
1419 /* Analyze the items */
1420 switch (o_ptr->tval)
1421 {
1422 /* Chests */
1423 case TV_CHEST:
1424 {
1425 /* Never okay */
1426 return (0);
1427 }
1428
1429 /* Junk */
1430 case TV_JUNK:
1431 {
1432 /* Assume okay */
1433 break;
1434 }
1435
1436 /* Food and Potions and Scrolls */
1437 case TV_FOOD:
1438 case TV_POTION:
1439 case TV_SCROLL:
1440 {
1441 /* Assume okay */
1442 break;
1443 }
1444
1445 /* Staffs and Wands */
1446 case TV_STAFF:
1447 case TV_WAND:
1448 {
1449 /* Require both to be empty or identified */
1450 if (!(o_ptr->ident & (ID_EMPTY)) &&
1451 !(o_ptr->ident & (ID_KNOWN)) ||
1452 (!(j_ptr->ident & (ID_EMPTY)) &&
1453 !(o_ptr->ident & (ID_KNOWN)))) return(0);
1454
1455 /* Assume ok */
1456 break;
1457 }
1458
1459 /* Rods */
1460 case TV_ROD:
1461 {
1462 /* Assume ok */
1463 break;
1464 }
1465
1466 /* Weapons and Armor */
1467 case TV_BOW:
1468 case TV_DIGGING:
1469 case TV_HAFTED:
1470 case TV_POLEARM:
1471 case TV_SWORD:
1472 case TV_BOOTS:
1473 case TV_GLOVES:
1474 case TV_HELM:
1475 case TV_CROWN:
1476 case TV_SHIELD:
1477 case TV_CLOAK:
1478 case TV_SOFT_ARMOR:
1479 case TV_HARD_ARMOR:
1480 case TV_DRAG_ARMOR:
1481 {
1482 /* hack -- MAngband-specific bonus */
1483 if (o_ptr->bpval != j_ptr->bpval) return (0);
1484
1485 /* Fallthrough */
1486 }
1487
1488 /* Rings, Amulets, Lites */
1489 case TV_RING:
1490 case TV_AMULET:
1491 case TV_LITE:
1492 {
1493 /* Fallthrough */
1494 }
1495
1496 /* Missiles */
1497 case TV_BOLT:
1498 case TV_ARROW:
1499 case TV_SHOT:
1500 {
1501 /* Require identical knowledge of both items */
1502 if ((o_ptr->ident & ID_KNOWN) != (j_ptr->ident & ID_KNOWN)) return (0);
1503
1504 /* Require identical "bonuses" */
1505 if (o_ptr->to_h != j_ptr->to_h) return (FALSE);
1506 if (o_ptr->to_d != j_ptr->to_d) return (FALSE);
1507 if (o_ptr->to_a != j_ptr->to_a) return (FALSE);
1508
1509 /* Require identical "pval" code */
1510 if (o_ptr->pval != j_ptr->pval) return (FALSE);
1511
1512 /* Require identical "artifact" names */
1513 if (o_ptr->name1 != j_ptr->name1) return (FALSE);
1514
1515 /* Require identical "ego-item" names */
1516 if (o_ptr->name2 != j_ptr->name2) return (FALSE);
1517
1518 /* Require identical "random artifact" names */
1519 if (o_ptr->name3 != j_ptr->name3) return (FALSE);
1520
1521 /* Hack -- Never stack "powerful" items */
1522 if (o_ptr->xtra1 || j_ptr->xtra1) return (FALSE);
1523
1524 /* Hack -- Never stack recharging items */
1525 if ((o_ptr->timeout || j_ptr->timeout) && o_ptr->tval != TV_LITE)
1526 return (FALSE);
1527
1528 /* Lites must have same amount of fuel */
1529 else if(o_ptr->timeout != j_ptr->timeout && o_ptr->tval == TV_LITE)
1530 return FALSE;
1531
1532 /* Require identical "values" */
1533 if (o_ptr->ac != j_ptr->ac) return (FALSE);
1534 if (o_ptr->dd != j_ptr->dd) return (FALSE);
1535 if (o_ptr->ds != j_ptr->ds) return (FALSE);
1536
1537 /* Probably okay */
1538 break;
1539 }
1540
1541 /* Magic books */
1542 case TV_MAGIC_BOOK:
1543 case TV_PRAYER_BOOK:
1544 {
1545 /* Assume okay */
1546 break;
1547 }
1548
1549 /* Various */
1550 default:
1551 {
1552 /* Never okay -- why?*/
1553 return(0);
1554 }
1555 }
1556
1557
1558 /* Hack -- Require identical "cursed" status */
1559 if ((o_ptr->ident & ID_CURSED) != (j_ptr->ident & ID_CURSED)) return (0);
1560
1561 /* Hack -- Require identical "broken" status */
1562 if ((o_ptr->ident & ID_BROKEN) != (j_ptr->ident & ID_BROKEN)) return (0);
1563
1564 /* Hack -- require semi-matching "inscriptions" */
1565 if (o_ptr->note && j_ptr->note && (o_ptr->note != j_ptr->note)) return (0);
1566
1567 /* Hack -- normally require matching "inscriptions"
1568 if ((o_ptr->note != j_ptr->note)) return (0);*/
1569
1570 /* Hack -- normally require matching "discounts"
1571 if ((o_ptr->discount != j_ptr->discount)) return (0);*/
1572
1573 /* Maximal "stacking" limit */
1574 if (total >= MAX_STACK_SIZE) return (0);
1575
1576 /* They match, so they must be similar */
1577 return (TRUE);
1578 }
1579
1580
1581
1582 /*
1583 * Determine if an item can "absorb" a second item
1584 *
1585 * See "object_absorb()" for the actual "absorption" code.
1586 *
1587 * If permitted, we allow wands/staffs (if they are known to have equal
1588 * charges) and rods (if fully charged) to combine.
1589 *
1590 * Note that rods/staffs/wands are then unstacked when they are used.
1591 *
1592 * If permitted, we allow weapons/armor to stack, if they both known.
1593 *
1594 * Food, potions, scrolls, and "easy know" items always stack.
1595 *
1596 * Chests never stack (for various reasons).
1597 *
1598 * We do NOT allow activatable items (artifacts or dragon scale mail)
1599 * to stack, to keep the "activation" code clean. Artifacts may stack,
1600 * but only with another identical artifact (which does not exist).
1601 *
1602 * Ego items may stack as long as they have the same ego-item type.
1603 * This is primarily to allow ego-missiles to stack.
1604 */
object_similar(const player_type * p_ptr,const object_type * o_ptr,const object_type * j_ptr)1605 bool object_similar(const player_type *p_ptr, const object_type *o_ptr, const object_type *j_ptr)
1606 {
1607 int total = o_ptr->number + j_ptr->number;
1608
1609
1610 /* Require identical object types */
1611 if (o_ptr->k_idx != j_ptr->k_idx) return (0);
1612
1613
1614 /* Analyze the items */
1615 switch (o_ptr->tval)
1616 {
1617 /* Chests */
1618 case TV_CHEST:
1619 {
1620 /* Never okay */
1621 return (0);
1622 }
1623
1624 /* Food and Potions and Scrolls */
1625 case TV_FOOD:
1626 case TV_POTION:
1627 case TV_SCROLL:
1628 {
1629 /* Assume okay */
1630 break;
1631 }
1632
1633 /* Staffs and Wands */
1634 case TV_STAFF:
1635 case TV_WAND:
1636 {
1637 /* Require permission */
1638 if (!option_p(p_ptr,STACK_ALLOW_WANDS)) return (0);
1639
1640 /* Require either knowledge or known empty for both wands/staves */
1641 if ((!(o_ptr->ident & (ID_EMPTY)) &&
1642 !object_known_p(p_ptr, o_ptr)) ||
1643 (!(j_ptr->ident & (ID_EMPTY)) &&
1644 !object_known_p(p_ptr, j_ptr))) return(0);
1645
1646 /* Assume okay */
1647 break;
1648 }
1649
1650 /* Staffs and Wands and Rods */
1651 case TV_ROD:
1652 {
1653 /* Require permission */
1654 if (!option_p(p_ptr,STACK_ALLOW_WANDS)) return (0);
1655 #if 0
1656 /* Require identical charges */
1657 if (o_ptr->pval != j_ptr->pval)
1658 {
1659 /* Check to make sure they aren't stacked
1660 in the wrong order */
1661 p_ptr->notice |= (PN_REORDER);
1662 return (0);
1663 }
1664 /* Fall throu */
1665 #endif
1666 /* Probably okay */
1667 break;
1668 }
1669
1670 /* Weapons and Armor */
1671 case TV_BOW:
1672 case TV_DIGGING:
1673 case TV_HAFTED:
1674 case TV_POLEARM:
1675 case TV_SWORD:
1676 case TV_BOOTS:
1677 case TV_GLOVES:
1678 case TV_HELM:
1679 case TV_CROWN:
1680 case TV_SHIELD:
1681 case TV_CLOAK:
1682 case TV_SOFT_ARMOR:
1683 case TV_HARD_ARMOR:
1684 case TV_DRAG_ARMOR:
1685 {
1686 /* Require permission */
1687 if (!option_p(p_ptr,STACK_ALLOW_ITEMS)) return (0);
1688
1689 /* XXX XXX XXX Require identical "sense" status */
1690 /* if ((o_ptr->ident & ID_SENSE) != */
1691 /* (j_ptr->ident & ID_SENSE)) return (0); */
1692
1693 /* require identical bonuses */
1694 /* hack -- MAngband-specific bonus */
1695 if (o_ptr->bpval != j_ptr->bpval) return (0);
1696
1697 /* Fall through */
1698 }
1699
1700 /* Rings, Amulets, Lites */
1701 case TV_RING:
1702 case TV_AMULET:
1703 case TV_LITE:
1704 {
1705 /* Require full knowledge of both items */
1706 if (!object_known_p(p_ptr, o_ptr) || !object_known_p(p_ptr, j_ptr) || (o_ptr->name3)) return (0);
1707
1708 /* Fall through */
1709 }
1710
1711 /* Missiles */
1712 case TV_BOLT:
1713 case TV_ARROW:
1714 case TV_SHOT:
1715 {
1716 /* Require identical knowledge of both items */
1717 if (object_known_p(p_ptr,o_ptr) != object_known_p(p_ptr,j_ptr)) return (FALSE);
1718
1719 /* Require identical "bonuses" */
1720 if (o_ptr->to_h != j_ptr->to_h) return (FALSE);
1721 if (o_ptr->to_d != j_ptr->to_d) return (FALSE);
1722 if (o_ptr->to_a != j_ptr->to_a) return (FALSE);
1723
1724 /* Require identical "pval" code */
1725 if (o_ptr->pval != j_ptr->pval) return (FALSE);
1726
1727 /* Require identical "artifact" names */
1728 if (o_ptr->name1 != j_ptr->name1) return (FALSE);
1729
1730 /* Require identical "ego-item" names */
1731 if (o_ptr->name2 != j_ptr->name2) return (FALSE);
1732
1733 /* Require identical "random artifact" names */
1734 if (o_ptr->name3 != j_ptr->name3) return (FALSE);
1735
1736 /* Hack -- Never stack "powerful" items */
1737 if (o_ptr->xtra1 || j_ptr->xtra1) return (FALSE);
1738
1739 /* Hack -- Never stack recharging items */
1740 if (o_ptr->timeout || j_ptr->timeout) return (FALSE);
1741
1742 /* Require identical "values" */
1743 if (o_ptr->ac != j_ptr->ac) return (FALSE);
1744 if (o_ptr->dd != j_ptr->dd) return (FALSE);
1745 if (o_ptr->ds != j_ptr->ds) return (FALSE);
1746
1747 /* Probably okay */
1748 break;
1749 }
1750
1751 /* Various */
1752 default:
1753 {
1754 /* Require knowledge */
1755 if (!object_known_p(p_ptr, o_ptr) || !object_known_p(p_ptr, j_ptr)) return (0);
1756
1757 /* Probably okay */
1758 break;
1759 }
1760 }
1761
1762
1763 /* Hack -- Require identical "cursed" status */
1764 if ((o_ptr->ident & ID_CURSED) != (j_ptr->ident & ID_CURSED)) return (0);
1765
1766 /* Hack -- Require identical "broken" status */
1767 if ((o_ptr->ident & ID_BROKEN) != (j_ptr->ident & ID_BROKEN)) return (0);
1768
1769
1770 /* Hack -- require semi-matching "inscriptions" */
1771 if (o_ptr->note && j_ptr->note && (o_ptr->note != j_ptr->note)) return (0);
1772
1773 /* Hack -- normally require matching "inscriptions" */
1774 if (!option_p(p_ptr,STACK_FORCE_NOTES) && (o_ptr->note != j_ptr->note)) return (0);
1775
1776 /* Hack -- normally require matching "discounts" */
1777 if (!option_p(p_ptr,STACK_FORCE_COSTS) && (o_ptr->discount != j_ptr->discount)) return (0);
1778
1779
1780 /* Maximal "stacking" limit */
1781 if (total >= MAX_STACK_SIZE) return (0);
1782
1783
1784 /* They match, so they must be similar */
1785 return (TRUE);
1786 }
1787
1788
1789 /*
1790 * Allow one item to "absorb" another, assuming they are similar
1791 *
1792 * Player pointer "p_ptr" is allowed to be NULL, when it is not
1793 * NULL, "object known" statuses are also blended.
1794 */
object_absorb(player_type * p_ptr,object_type * o_ptr,object_type * j_ptr)1795 void object_absorb(player_type *p_ptr, object_type *o_ptr, object_type *j_ptr)
1796 {
1797 object_kind *k_ptr = &k_info[o_ptr->k_idx];
1798
1799 int total = o_ptr->number + j_ptr->number;
1800
1801 /* Add together the item counts */
1802 o_ptr->number = ((total < MAX_STACK_SIZE) ? total : (MAX_STACK_SIZE - 1));
1803
1804 /* Hack -- blend "known" status */
1805 if (p_ptr && object_known_p(p_ptr, j_ptr)) object_known(o_ptr);
1806
1807 /* Hack -- blend "rumour" status */
1808 if (j_ptr->ident & ID_RUMOUR) o_ptr->ident |= ID_RUMOUR;
1809
1810 /* Hack -- blend "mental" status */
1811 if (j_ptr->ident & ID_MENTAL) o_ptr->ident |= ID_MENTAL;
1812
1813 /* Hack -- blend "inscriptions" */
1814 if (j_ptr->note) o_ptr->note = j_ptr->note;
1815
1816 /* Hack -- could average discounts XXX XXX XXX */
1817 /* Hack -- save largest discount XXX XXX XXX */
1818 if (o_ptr->discount < j_ptr->discount) o_ptr->discount = j_ptr->discount;
1819
1820 /*
1821 * Hack -- if rods are stacking, re-calculate the
1822 * pvals (maximum timeouts) and current timeouts together
1823 */
1824 if (o_ptr->tval == TV_ROD)
1825 {
1826 o_ptr->pval = total * k_ptr->pval;
1827 o_ptr->timeout += j_ptr->timeout;
1828 }
1829
1830 /* Hack -- if wands or staves are stacking, combine the charges */
1831 if ((o_ptr->tval == TV_WAND) || (o_ptr->tval == TV_STAFF))
1832 {
1833 o_ptr->pval += j_ptr->pval;
1834 }
1835
1836 /* Forget original owner */
1837 if (o_ptr->origin_player != j_ptr->origin_player)
1838 {
1839 o_ptr->origin_player = 0;
1840 }
1841
1842 /* Merge origins */
1843 if ((o_ptr->origin != j_ptr->origin) ||
1844 (o_ptr->origin_depth != j_ptr->origin_depth) ||
1845 (o_ptr->origin_xtra != j_ptr->origin_xtra))
1846 {
1847 int act = 2;
1848
1849 if ((o_ptr->origin == ORIGIN_DROP) && (o_ptr->origin == j_ptr->origin))
1850 {
1851 monster_race *r_ptr = &r_info[o_ptr->origin_xtra];
1852 monster_race *s_ptr = &r_info[j_ptr->origin_xtra];
1853
1854 bool r_uniq = r_ptr->flags1 & RF1_UNIQUE ? TRUE : FALSE;
1855 bool s_uniq = s_ptr->flags1 & RF1_UNIQUE ? TRUE : FALSE;
1856
1857 if (r_uniq && !s_uniq) act = 0;
1858 else if (s_uniq && !r_uniq) act = 1;
1859 else act = 2;
1860 }
1861
1862 switch (act)
1863 {
1864 /* Overwrite with j_ptr */
1865 case 1:
1866 {
1867 o_ptr->origin = j_ptr->origin;
1868 o_ptr->origin_depth = j_ptr->origin_depth;
1869 o_ptr->origin_xtra = j_ptr->origin_xtra;
1870 }
1871
1872 /* Set as "mixed" */
1873 case 2:
1874 {
1875 o_ptr->origin = ORIGIN_MIXED;
1876 }
1877 }
1878 }
1879 }
1880
1881 /*
1882 * Get a random object kind, by tval.
1883 * Returns 0 if nothing was found.
1884 */
rand_tval_kind(int tval)1885 u16b rand_tval_kind(int tval)
1886 {
1887 int k_idx, kinds = 0;
1888 int tbl[MAX_FLVR_IDX];
1889
1890 for (k_idx = 0; k_idx < z_info->k_max; k_idx++)
1891 {
1892 object_kind *k_ptr = &k_info[k_idx];
1893 if (k_ptr->tval != tval) continue;
1894 tbl[kinds++] = k_idx;
1895 if (kinds >= MAX_FLVR_IDX) break;
1896 }
1897 /* Nothing found, give up */
1898 if (!kinds) return 0;
1899
1900 /* Randomly */
1901 return tbl[randint0(kinds)];
1902 }
1903
1904 /*
1905 * Find the index of the object_kind with the given tval and sval
1906 */
lookup_kind(int tval,int sval)1907 s16b lookup_kind(int tval, int sval)
1908 {
1909 int k;
1910
1911 /* Look for it */
1912 for (k = 1; k < z_info->k_max; k++)
1913 {
1914 object_kind *k_ptr = &k_info[k];
1915
1916 /* Found a match */
1917 if ((k_ptr->tval == tval) && (k_ptr->sval == sval)) return (k);
1918 }
1919 #ifdef DEBUG
1920 /* Oops */
1921 plog(format("No object (%d,%d)", tval, sval));
1922 #endif
1923 /* Oops */
1924 return (0);
1925 }
1926
1927
1928 /*
1929 * Clear an item
1930 */
invwipe(object_type * o_ptr)1931 void invwipe(object_type *o_ptr)
1932 {
1933 /* Clear the record */
1934 WIPE(o_ptr, object_type);
1935 }
1936
1937
1938 /*
1939 * Make "o_ptr" a "clean" copy of the given "kind" of object
1940 */
invcopy(object_type * o_ptr,int k_idx)1941 void invcopy(object_type *o_ptr, int k_idx)
1942 {
1943 object_kind *k_ptr = &k_info[k_idx];
1944
1945 /* Clear the record */
1946 WIPE(o_ptr, object_type);
1947
1948 /* Save the kind index */
1949 o_ptr->k_idx = k_idx;
1950
1951 /* Efficiency -- tval/sval */
1952 o_ptr->tval = k_ptr->tval;
1953 o_ptr->sval = k_ptr->sval;
1954
1955 /* Default "pval" */
1956 o_ptr->pval = k_ptr->pval;
1957
1958 /* Default number */
1959 o_ptr->number = 1;
1960
1961 /* Default weight */
1962 o_ptr->weight = k_ptr->weight;
1963
1964 /* Default magic */
1965 o_ptr->to_h = k_ptr->to_h;
1966 o_ptr->to_d = k_ptr->to_d;
1967 o_ptr->to_a = k_ptr->to_a;
1968
1969 /* Default power */
1970 o_ptr->ac = k_ptr->ac;
1971 o_ptr->dd = k_ptr->dd;
1972 o_ptr->ds = k_ptr->ds;
1973
1974 /* Hack -- worthless items are always "broken" */
1975 if (k_ptr->cost <= 0) o_ptr->ident |= ID_BROKEN;
1976
1977 /* Hack -- cursed items are always "cursed" */
1978 if ((k_ptr->flags3 & TR3_LIGHT_CURSE) ||
1979 (k_ptr->flags3 & TR3_HEAVY_CURSE) ||
1980 (k_ptr->flags3 & TR3_PERMA_CURSE))
1981 o_ptr->ident |= ID_CURSED;
1982 }
1983
1984
1985
1986
1987
1988 /*
1989 * Help determine an "enchantment bonus" for an object.
1990 *
1991 * To avoid floating point but still provide a smooth distribution of bonuses,
1992 * we simply round the results of division in such a way as to "average" the
1993 * correct floating point value.
1994 *
1995 * This function has been changed. It uses "randnor()" to choose values from
1996 * a normal distribution, whose mean moves from zero towards the max as the
1997 * level increases, and whose standard deviation is equal to 1/4 of the max,
1998 * and whose values are forced to lie between zero and the max, inclusive.
1999 *
2000 * Since the "level" rarely passes 100 before Morgoth is dead, it is very
2001 * rare to get the "full" enchantment on an object, even a deep levels.
2002 *
2003 * It is always possible (albeit unlikely) to get the "full" enchantment.
2004 *
2005 * A sample distribution of values from "m_bonus(10, N)" is shown below:
2006 *
2007 * N 0 1 2 3 4 5 6 7 8 9 10
2008 * --- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
2009 * 0 66.37 13.01 9.73 5.47 2.89 1.31 0.72 0.26 0.12 0.09 0.03
2010 * 8 46.85 24.66 12.13 8.13 4.20 2.30 1.05 0.36 0.19 0.08 0.05
2011 * 16 30.12 27.62 18.52 10.52 6.34 3.52 1.95 0.90 0.31 0.15 0.05
2012 * 24 22.44 15.62 30.14 12.92 8.55 5.30 2.39 1.63 0.62 0.28 0.11
2013 * 32 16.23 11.43 23.01 22.31 11.19 7.18 4.46 2.13 1.20 0.45 0.41
2014 * 40 10.76 8.91 12.80 29.51 16.00 9.69 5.90 3.43 1.47 0.88 0.65
2015 * 48 7.28 6.81 10.51 18.27 27.57 11.76 7.85 4.99 2.80 1.22 0.94
2016 * 56 4.41 4.73 8.52 11.96 24.94 19.78 11.06 7.18 3.68 1.96 1.78
2017 * 64 2.81 3.07 5.65 9.17 13.01 31.57 13.70 9.30 6.04 3.04 2.64
2018 * 72 1.87 1.99 3.68 7.15 10.56 20.24 25.78 12.17 7.52 4.42 4.62
2019 * 80 1.02 1.23 2.78 4.75 8.37 12.04 27.61 18.07 10.28 6.52 7.33
2020 * 88 0.70 0.57 1.56 3.12 6.34 10.06 15.76 30.46 12.58 8.47 10.38
2021 * 96 0.27 0.60 1.25 2.28 4.30 7.60 10.77 22.52 22.51 11.37 16.53
2022 * 104 0.22 0.42 0.77 1.36 2.62 5.33 8.93 13.05 29.54 15.23 22.53
2023 * 112 0.15 0.20 0.56 0.87 2.00 3.83 6.86 10.06 17.89 27.31 30.27
2024 * 120 0.03 0.11 0.31 0.46 1.31 2.48 4.60 7.78 11.67 25.53 45.72
2025 * 128 0.02 0.01 0.13 0.33 0.83 1.41 3.24 6.17 9.57 14.22 64.07
2026 */
m_bonus(int max,int level)2027 static s16b m_bonus(int max, int level)
2028 {
2029 int bonus, stand, extra, value;
2030
2031
2032 /* Paranoia -- enforce maximal "level" */
2033 if (level > MAX_DEPTH - 1) level = MAX_DEPTH - 1;
2034
2035
2036 /* The "bonus" moves towards the max */
2037 bonus = ((max * level) / MAX_DEPTH);
2038
2039 /* Hack -- determine fraction of error */
2040 extra = ((max * level) % MAX_DEPTH);
2041
2042 /* Hack -- simulate floating point computations */
2043 if (randint0(MAX_DEPTH) < extra) bonus++;
2044
2045
2046 /* The "stand" is equal to one quarter of the max */
2047 stand = (max / 4);
2048
2049 /* Hack -- determine fraction of error */
2050 extra = (max % 4);
2051
2052 /* Hack -- simulate floating point computations */
2053 if (randint0(4) < extra) stand++;
2054
2055
2056 /* Choose an "interesting" value */
2057 value = randnor(bonus, stand);
2058
2059 /* Enforce the minimum value */
2060 if (value < 0) return (0);
2061
2062 /* Enforce the maximum value */
2063 if (value > max) return (max);
2064
2065 /* Result */
2066 return (value);
2067 }
2068
2069
2070
2071 #if 0
2072
2073 /*
2074 * Cheat -- describe a created object for the user
2075 */
2076 static void object_mention(object_type *o_ptr)
2077 {
2078 char o_name[80];
2079
2080 /* Describe */
2081 object_desc_store(o_name, o_ptr, FALSE, 0);
2082
2083 /* Artifact */
2084 if (true_artifact_p(o_ptr))
2085 {
2086 /* Silly message */
2087 msg_format("Artifact (%s)", o_name);
2088 }
2089
2090 /* Randart */
2091 else if (artifact_p(o_ptr))
2092 {
2093 /* Silly message */
2094 msg_format("Randart (%s)", o_name);
2095 }
2096
2097 /* Ego-item */
2098 else if (ego_item_p(o_ptr))
2099 {
2100 /* Silly message */
2101 msg_format("Ego-item (%s)", o_name);
2102 }
2103
2104 /* Normal item */
2105 else
2106 {
2107 /* Silly message */
2108 msg_format("Object (%s)", o_name);
2109 }
2110 }
2111
2112 #endif
2113
2114
2115
2116 /*
2117 * Mega-Hack -- Attempt to create one of the "Special Objects"
2118 *
2119 * We are only called from "place_object()", and we assume that
2120 * "apply_magic()" is called immediately after we return.
2121 *
2122 * Note -- see "make_artifact()" and "apply_magic()"
2123 */
make_artifact_special(int Depth,object_type * o_ptr)2124 static bool make_artifact_special(int Depth, object_type *o_ptr)
2125 {
2126 int i;
2127 int k_idx = 0;
2128 char o_name[80];
2129
2130 /* No artifacts in the town */
2131 if (!Depth) return (FALSE);
2132
2133 /* Check the artifact list (just the "specials") */
2134 for (i = 0; i < ART_MIN_NORMAL; i++)
2135 {
2136 artifact_type *a_ptr = &a_info[i];
2137
2138 /* Skip "empty" artifacts */
2139 if (!a_ptr->name) continue;
2140
2141 /* Cannot make an artifact twice */
2142 if (a_ptr->cur_num) continue;
2143
2144 /* XXX XXX Enforce minimum "depth" (loosely) */
2145 if (a_ptr->level > Depth)
2146 {
2147 /* Acquire the "out-of-depth factor" */
2148 int d = (a_ptr->level - Depth) * 2;
2149
2150 /* Roll for out-of-depth creation */
2151 if (randint0(d) != 0) continue;
2152 }
2153
2154 /* XXX XXX Enforce maximum "depth" (loosely) */
2155 if (Depth > (a_ptr->level +20))
2156 {
2157 /* Acquire the "out-of-depth factor" */
2158 int d = (a_ptr->level - Depth) * 2;
2159
2160 /* Roll for out-of-depth creation */
2161 if (randint0(d) != 0) continue;
2162 }
2163
2164 /* Artifact "rarity roll" */
2165 if (randint0(a_ptr->rarity) != 0) continue;
2166
2167 /* Find the base object */
2168 k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
2169
2170 /* XXX XXX Enforce minimum "object" level (loosely) */
2171 if (k_info[k_idx].level > object_level)
2172 {
2173 /* Acquire the "out-of-depth factor" */
2174 int d = (k_info[k_idx].level - object_level) * 5;
2175
2176 /* Roll for out-of-depth creation */
2177 if (randint0(d) != 0) continue;
2178 }
2179
2180 /* Assign the template */
2181 invcopy(o_ptr, k_idx);
2182
2183 /* Mega-Hack -- mark the item as an artifact */
2184 o_ptr->name1 = i;
2185 object_desc(NULL, o_name, sizeof(o_name), o_ptr, TRUE, 3);
2186 plog(format("Special artifact %s created", o_name));
2187
2188
2189 /* Success */
2190 return (TRUE);
2191 }
2192
2193 /* Failure */
2194 return (FALSE);
2195 }
2196
2197
2198 /*
2199 * Attempt to change an object into an artifact
2200 *
2201 * This routine should only be called by "apply_magic()"
2202 *
2203 * Note -- see "make_artifact_special()" and "apply_magic()"
2204 */
make_artifact(int Depth,object_type * o_ptr)2205 static bool make_artifact(int Depth, object_type *o_ptr)
2206 {
2207 int i, j;
2208 char o_name[80];
2209
2210 /* No artifacts in the town */
2211 if (!Depth) return (FALSE);
2212
2213 /* Paranoia -- no "plural" artifacts */
2214 if (o_ptr->number != 1) return (FALSE);
2215
2216 /* Check the artifact list (skip the "specials") */
2217 for (i = ART_MIN_NORMAL; i < z_info->a_max; i++)
2218 {
2219 artifact_type *a_ptr = &a_info[i];
2220 bool okay = TRUE;
2221
2222 /* Skip "empty" items */
2223 if (!a_ptr->name) continue;
2224
2225 /* Cannot make an artifact twice */
2226 if (a_ptr->cur_num) continue;
2227
2228 /* Must have the correct fields */
2229 if (a_ptr->tval != o_ptr->tval) continue;
2230 if (a_ptr->sval != o_ptr->sval) continue;
2231
2232 /* XXX XXX Enforce minimum "depth" (loosely) */
2233 if (a_ptr->level > Depth)
2234 {
2235 /* Acquire the "out-of-depth factor" */
2236 int d = (a_ptr->level - Depth) * 2;
2237 printf("Out of depth?\n");
2238 /* Roll for out-of-depth creation */
2239 if (randint0(d) != 0) continue;
2240 }
2241 printf("Art rarity roll...\n");
2242 /* We must make the "rarity roll" */
2243 if (randint0(a_ptr->rarity) != 0) continue;
2244 printf("Passed!\n");
2245 /* MEGA-HACK! GAMEPLAY BREAKER! */
2246 for (j = 1; j <= NumPlayers; j++)
2247 {
2248 player_type *p_ptr = Players[j];
2249 /* There's a player on a level who already found this artifact once
2250 * -- this causes ALL other players on level to suffer */
2251 if ((p_ptr->dun_depth == Depth) && (p_ptr->a_info[i] > cfg_preserve_artifacts))
2252 {
2253 /* Artifact WON'T be generated! */
2254 okay = FALSE;
2255 break;
2256 }
2257 }
2258 if (!okay) continue;
2259
2260 /* Hack -- mark the item as an artifact */
2261 o_ptr->name1 = i;
2262 object_desc(NULL, o_name, sizeof(o_name), o_ptr, TRUE, 3);
2263 plog(format("Artifact %s created", o_name));
2264
2265 /* Success */
2266 return (TRUE);
2267 }
2268
2269 #if defined(RANDART)
2270 /* An extra chance at being a randart */
2271 if (cfg_random_artifacts && !randint0(RANDART_RARITY))
2272 {
2273 o_ptr->name1 = ART_RANDART;
2274
2275 /* Piece together a 32-bit random seed */
2276 o_ptr->name3 = randint0(0xFFFF) << 16;
2277 o_ptr->name3 += randint0(0xFFFF);
2278 /* Check the tval is allowed */
2279 if (randart_make(o_ptr) == NULL)
2280 {
2281 /* If not, wipe seed. No randart today */
2282 o_ptr->name1 = 0;
2283 o_ptr->name3 = 0L;
2284
2285 return (FALSE);
2286 }
2287
2288 return (TRUE);
2289 }
2290 #endif
2291
2292 /* Failure */
2293 return (FALSE);
2294 }
2295
2296
2297 /*
2298 * Charge a new wand.
2299 */
charge_wand(object_type * o_ptr)2300 static void charge_wand(object_type *o_ptr)
2301 {
2302 switch (o_ptr->sval)
2303 {
2304 case SV_WAND_HEAL_MONSTER: o_ptr->pval = randint1(20) + 8; break;
2305 case SV_WAND_HASTE_MONSTER: o_ptr->pval = randint1(20) + 8; break;
2306 case SV_WAND_CLONE_MONSTER: o_ptr->pval = randint1(5) + 3; break;
2307 case SV_WAND_TELEPORT_AWAY: o_ptr->pval = randint1(5) + 6; break;
2308 case SV_WAND_DISARMING: o_ptr->pval = randint1(5) + 4; break;
2309 case SV_WAND_TRAP_DOOR_DEST: o_ptr->pval = randint1(8) + 6; break;
2310 case SV_WAND_STONE_TO_MUD: o_ptr->pval = randint1(4) + 3; break;
2311 case SV_WAND_LITE: o_ptr->pval = randint1(10) + 6; break;
2312 case SV_WAND_SLEEP_MONSTER: o_ptr->pval = randint1(15) + 8; break;
2313 case SV_WAND_SLOW_MONSTER: o_ptr->pval = randint1(10) + 6; break;
2314 case SV_WAND_CONFUSE_MONSTER: o_ptr->pval = randint1(12) + 6; break;
2315 case SV_WAND_FEAR_MONSTER: o_ptr->pval = randint1(5) + 3; break;
2316 case SV_WAND_DRAIN_LIFE: o_ptr->pval = randint1(3) + 3; break;
2317 case SV_WAND_POLYMORPH: o_ptr->pval = randint1(8) + 6; break;
2318 case SV_WAND_STINKING_CLOUD: o_ptr->pval = randint1(8) + 6; break;
2319 case SV_WAND_MAGIC_MISSILE: o_ptr->pval = randint1(10) + 6; break;
2320 case SV_WAND_ACID_BOLT: o_ptr->pval = randint1(8) + 6; break;
2321 case SV_WAND_ELEC_BOLT: o_ptr->pval = randint1(8) + 6; break;
2322 case SV_WAND_FIRE_BOLT: o_ptr->pval = randint1(8) + 6; break;
2323 case SV_WAND_COLD_BOLT: o_ptr->pval = randint1(5) + 6; break;
2324 case SV_WAND_ACID_BALL: o_ptr->pval = randint1(5) + 2; break;
2325 case SV_WAND_ELEC_BALL: o_ptr->pval = randint1(8) + 4; break;
2326 case SV_WAND_FIRE_BALL: o_ptr->pval = randint1(4) + 2; break;
2327 case SV_WAND_COLD_BALL: o_ptr->pval = randint1(6) + 2; break;
2328 case SV_WAND_WONDER: o_ptr->pval = randint1(15) + 8; break;
2329 case SV_WAND_ANNIHILATION: o_ptr->pval = randint1(2) + 1; break;
2330 case SV_WAND_DRAGON_FIRE: o_ptr->pval = randint1(3) + 1; break;
2331 case SV_WAND_DRAGON_COLD: o_ptr->pval = randint1(3) + 1; break;
2332 case SV_WAND_DRAGON_BREATH: o_ptr->pval = randint1(3) + 1; break;
2333 }
2334 }
2335
2336
2337
2338 /*
2339 * Charge a new staff.
2340 */
charge_staff(object_type * o_ptr)2341 static void charge_staff(object_type *o_ptr)
2342 {
2343 switch (o_ptr->sval)
2344 {
2345 case SV_STAFF_DARKNESS: o_ptr->pval = randint1(8) + 8; break;
2346 case SV_STAFF_SLOWNESS: o_ptr->pval = randint1(8) + 8; break;
2347 case SV_STAFF_HASTE_MONSTERS: o_ptr->pval = randint1(8) + 8; break;
2348 case SV_STAFF_SUMMONING: o_ptr->pval = randint1(3) + 1; break;
2349 case SV_STAFF_TELEPORTATION: o_ptr->pval = randint1(4) + 5; break;
2350 case SV_STAFF_IDENTIFY: o_ptr->pval = randint1(15) + 5; break;
2351 case SV_STAFF_REMOVE_CURSE: o_ptr->pval = randint1(3) + 4; break;
2352 case SV_STAFF_STARLITE: o_ptr->pval = randint1(5) + 6; break;
2353 case SV_STAFF_LITE: o_ptr->pval = randint1(20) + 8; break;
2354 case SV_STAFF_MAPPING: o_ptr->pval = randint1(5) + 5; break;
2355 case SV_STAFF_DETECT_GOLD: o_ptr->pval = randint1(20) + 8; break;
2356 case SV_STAFF_DETECT_ITEM: o_ptr->pval = randint1(15) + 6; break;
2357 case SV_STAFF_DETECT_TRAP: o_ptr->pval = randint1(5) + 6; break;
2358 case SV_STAFF_DETECT_DOOR: o_ptr->pval = randint1(8) + 6; break;
2359 case SV_STAFF_DETECT_INVIS: o_ptr->pval = randint1(15) + 8; break;
2360 case SV_STAFF_DETECT_EVIL: o_ptr->pval = randint1(15) + 8; break;
2361 case SV_STAFF_CURE_LIGHT: o_ptr->pval = randint1(5) + 6; break;
2362 case SV_STAFF_CURING: o_ptr->pval = randint1(3) + 4; break;
2363 case SV_STAFF_HEALING: o_ptr->pval = randint1(2) + 1; break;
2364 case SV_STAFF_THE_MAGI: o_ptr->pval = randint1(2) + 2; break;
2365 case SV_STAFF_SLEEP_MONSTERS: o_ptr->pval = randint1(5) + 6; break;
2366 case SV_STAFF_SLOW_MONSTERS: o_ptr->pval = randint1(5) + 6; break;
2367 case SV_STAFF_SPEED: o_ptr->pval = randint1(3) + 4; break;
2368 case SV_STAFF_PROBING: o_ptr->pval = randint1(6) + 2; break;
2369 case SV_STAFF_DISPEL_EVIL: o_ptr->pval = randint1(3) + 4; break;
2370 case SV_STAFF_POWER: o_ptr->pval = randint1(3) + 1; break;
2371 case SV_STAFF_HOLINESS: o_ptr->pval = randint1(2) + 2; break;
2372 case SV_STAFF_BANISHMENT: o_ptr->pval = randint1(2) + 1; break;
2373 case SV_STAFF_EARTHQUAKES: o_ptr->pval = randint1(5) + 3; break;
2374 case SV_STAFF_DESTRUCTION: o_ptr->pval = randint1(3) + 1; break;
2375 }
2376 }
2377
2378
2379
2380 /* get an ego item from e_info */
check_ego(object_type * o_ptr,int level,int power,int idx)2381 bool check_ego(object_type *o_ptr, int level, int power, int idx)
2382 {
2383 int idxtval;
2384 ego_item_type *e_ptr = &e_info[idx];
2385
2386 /* check possible ego tval values */
2387 if (o_ptr->tval == e_ptr->tval[0])
2388 idxtval = 0;
2389 else if (o_ptr->tval == e_ptr->tval[1])
2390 idxtval = 1;
2391 else if (o_ptr->tval == e_ptr->tval[2])
2392 idxtval = 2;
2393 else
2394 return FALSE;
2395
2396 /* check sval range */
2397 if ((o_ptr->sval < e_ptr->min_sval[idxtval]) ||
2398 (o_ptr->sval > e_ptr->max_sval[idxtval]))
2399 return FALSE;
2400
2401 /* check min depth */
2402 if (level < e_ptr->level)
2403 return FALSE;
2404
2405 /* check rarity */
2406 if (randint0(e_ptr->rarity) != 0)
2407 return FALSE;
2408
2409 /* check cursed egos */
2410 if ((power > 1) && ( (e_ptr->flags3 & TR3_LIGHT_CURSE) ||
2411 (e_ptr->flags3 & TR3_HEAVY_CURSE) ||
2412 (e_ptr->flags3 & TR3_PERMA_CURSE) ) )
2413 return FALSE;
2414
2415 /* check cursed objects */
2416 if ( (power < -1) && !( (e_ptr->flags3 & TR3_LIGHT_CURSE) ||
2417 (e_ptr->flags3 & TR3_HEAVY_CURSE) ||
2418 (e_ptr->flags3 & TR3_PERMA_CURSE) ) )
2419 return FALSE;
2420
2421 /* we have a winner */
2422 return TRUE;
2423 }
2424
2425 /*
2426 * Apply magic to an item known to be a "weapon"
2427 * Uses check_ego to generate a random ego item
2428 */
a_m_aux_1(object_type * o_ptr,int level,int power)2429 static void a_m_aux_1(object_type *o_ptr, int level, int power)
2430 {
2431 int tohit1 = randint1(5) + m_bonus(5, level);
2432 int todam1 = randint1(5) + m_bonus(5, level);
2433
2434 int tohit2 = m_bonus(10, level);
2435 int todam2 = m_bonus(10, level);
2436
2437 int idx, nbtries = 1000;
2438
2439
2440 /* Good */
2441 if (power > 0)
2442 {
2443 /* Enchant */
2444 o_ptr->to_h += tohit1;
2445 o_ptr->to_d += todam1;
2446
2447 /* Very good */
2448 if (power > 1)
2449 {
2450 /* Enchant again */
2451 o_ptr->to_h += tohit2;
2452 o_ptr->to_d += todam2;
2453 }
2454 }
2455
2456 /* Cursed */
2457 else if (power < 0)
2458 {
2459 /* Penalize */
2460 o_ptr->to_h -= tohit1;
2461 o_ptr->to_d -= todam1;
2462
2463 /* Very cursed */
2464 if (power < -1)
2465 {
2466 /* Penalize again */
2467 o_ptr->to_h -= tohit2;
2468 o_ptr->to_d -= todam2;
2469 }
2470
2471 /* Cursed (if "bad") */
2472 if (o_ptr->to_h + o_ptr->to_d < 0) o_ptr->ident |= ID_CURSED;
2473 }
2474
2475 /* Analyze type */
2476 switch (o_ptr->tval)
2477 {
2478 case TV_DIGGING:
2479 {
2480 /* Very bad */
2481 if (power < -1)
2482 {
2483 /* Hack -- Horrible digging bonus */
2484 o_ptr->pval = 0 - (5 + randint1(5));
2485 }
2486
2487 /* Bad */
2488 else if (power < 0)
2489 {
2490 /* Hack -- Reverse digging bonus */
2491 o_ptr->pval = 0 - (o_ptr->pval);
2492 }
2493
2494 break;
2495 }
2496
2497
2498 case TV_HAFTED:
2499 case TV_POLEARM:
2500 case TV_SWORD:
2501 {
2502 /* Very Good */
2503 if (power > 1)
2504 {
2505 /* Hack -- Super-charge the damage dice */
2506 while ((o_ptr->dd * o_ptr->ds > 0) &&
2507 (randint0(10L * o_ptr->dd * o_ptr->ds) == 0))
2508 {
2509 o_ptr->dd++;
2510 }
2511
2512 /* Hack -- Lower the damage dice */
2513 if (o_ptr->dd > 9) o_ptr->dd = 9;
2514 }
2515
2516 break;
2517 }
2518
2519
2520 case TV_BOLT:
2521 case TV_ARROW:
2522 case TV_SHOT:
2523 {
2524 /* Very good */
2525 if (power > 1)
2526 {
2527 /* Hack -- super-charge the damage dice */
2528 while ((o_ptr->dd * o_ptr->ds > 0) &&
2529 (randint0(10L * o_ptr->dd * o_ptr->ds) == 0))
2530 {
2531 o_ptr->dd++;
2532 }
2533
2534 /* Hack -- restrict the damage dice */
2535 if (o_ptr->dd > 9) o_ptr->dd = 9;
2536 }
2537
2538 break;
2539 }
2540 }
2541
2542 /* are we done? */
2543 if ((power >= -1) && (power <= 1)) return;
2544
2545 /* Retrieve an ego item randomly */
2546 while (--nbtries)
2547 {
2548 idx = randint0(z_info->e_max);
2549
2550 /* check ego */
2551 if (check_ego(o_ptr, level, power, idx))
2552 {
2553 o_ptr->name2 = idx; /* EGO_XXX */
2554 break;
2555 }
2556 }
2557 }
2558
2559
2560 /*
2561 * Apply magic to an item known to be "armor"
2562 * Uses check_ego to generate a random ego item
2563 */
a_m_aux_2(object_type * o_ptr,int level,int power)2564 static void a_m_aux_2(object_type *o_ptr, int level, int power)
2565 {
2566 int toac1 = randint1(5) + m_bonus(5, level);
2567 int toac2 = m_bonus(10, level);
2568 int idx, nbtries = 1000;
2569
2570 /* Good */
2571 if (power > 0)
2572 {
2573 /* Enchant */
2574 o_ptr->to_a += toac1;
2575
2576 /* Very good */
2577 if (power > 1)
2578 {
2579 /* Enchant again */
2580 o_ptr->to_a += toac2;
2581 }
2582 }
2583
2584 /* Cursed */
2585 else if (power < 0)
2586 {
2587 /* Penalize */
2588 o_ptr->to_a -= toac1;
2589
2590 /* Very cursed */
2591 if (power < -1)
2592 {
2593 /* Penalize again */
2594 o_ptr->to_a -= toac2;
2595 }
2596
2597 /* Cursed (if "bad") */
2598 if (o_ptr->to_a < 0) o_ptr->ident |= ID_CURSED;
2599 }
2600
2601 /* DSM */
2602 if (o_ptr->tval == TV_DRAG_ARMOR)
2603 {
2604 /* Rating boost */
2605 rating += 30;
2606
2607 /* Mention the item */
2608 /*if (cheat_peek) object_mention(o_ptr);*/
2609
2610 return;
2611 }
2612
2613 /* Set the orcish shield's STR and CON bonus */
2614 if ((o_ptr->tval == TV_SHIELD) && (o_ptr->sval == SV_ORCISH_SHIELD))
2615 {
2616 o_ptr->bpval = randint1(2);
2617
2618 /* Cursed orcish shield */
2619 if (power < 0)
2620 {
2621 o_ptr->bpval = -o_ptr->bpval;
2622 o_ptr->ident |= ID_CURSED;
2623 }
2624 }
2625
2626 /* Set the Witan Boots stealth penalty */
2627 if ((o_ptr->tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_WITAN_BOOTS))
2628 {
2629 o_ptr->bpval = -2;
2630 }
2631
2632 /* Set the Kolla cloak's base bonuses */
2633 if ((o_ptr->tval == TV_CLOAK) && (o_ptr->sval == SV_KOLLA))
2634 {
2635 o_ptr->bpval = randint1(2);
2636
2637 /* Cursed kolla */
2638 if (o_ptr->to_a < 0)
2639 {
2640 o_ptr->bpval = -o_ptr->bpval;
2641 o_ptr->ident |= ID_CURSED;
2642 }
2643 else
2644 {
2645 rating += 20;
2646 }
2647 }
2648
2649 /* are we done? */
2650 if ((power >= -1) && (power <= 1)) return;
2651
2652 /* Retrieve an ego item randomly */
2653 while (--nbtries)
2654 {
2655 idx = randint0(z_info->e_max);
2656
2657 /* check ego */
2658 if (check_ego(o_ptr, level, power, idx))
2659 {
2660 o_ptr->name2 = idx; /* EGO_XXX */
2661 break;
2662 }
2663 }
2664 }
2665
2666
2667
2668 /*
2669 * Apply magic to an item known to be a "ring" or "amulet"
2670 *
2671 * Hack -- note special rating boost for ring of speed
2672 * Hack -- note special "pval boost" code for ring of speed
2673 * Hack -- note that some items must be cursed (or blessed)
2674 */
a_m_aux_3(object_type * o_ptr,int level,int power)2675 static void a_m_aux_3(object_type *o_ptr, int level, int power)
2676 {
2677 /* Apply magic (good or bad) according to type */
2678 switch (o_ptr->tval)
2679 {
2680 case TV_RING:
2681 {
2682 /* Analyze */
2683 switch (o_ptr->sval)
2684 {
2685 /* Strength, Constitution, Dexterity, Intelligence */
2686 case SV_RING_STR:
2687 case SV_RING_CON:
2688 case SV_RING_DEX:
2689 case SV_RING_INT:
2690 {
2691 /* Stat bonus */
2692 o_ptr->pval = 1 + m_bonus(5, level);
2693
2694 /* Cursed */
2695 if (power < 0)
2696 {
2697 /* Broken */
2698 o_ptr->ident |= ID_BROKEN;
2699
2700 /* Cursed */
2701 o_ptr->ident |= ID_CURSED;
2702
2703 /* Reverse pval */
2704 o_ptr->pval = 0 - (o_ptr->pval);
2705 }
2706
2707 break;
2708 }
2709
2710 /* Ring of Speed! */
2711 case SV_RING_SPEED:
2712 {
2713 /* Base speed (1 to 10) */
2714 o_ptr->pval = randint1(5) + m_bonus(5, level);
2715
2716 /* Super-charge the ring */
2717 while (randint0(100) < 50) o_ptr->pval++;
2718
2719 /* Cursed Ring */
2720 if (power < 0)
2721 {
2722 /* Broken */
2723 o_ptr->ident |= ID_BROKEN;
2724
2725 /* Cursed */
2726 o_ptr->ident |= ID_CURSED;
2727
2728 /* Reverse pval */
2729 o_ptr->pval = 0 - (o_ptr->pval);
2730
2731 break;
2732 }
2733
2734 /* Rating boost */
2735 rating += 25;
2736
2737 break;
2738 }
2739
2740 /* Searching */
2741 case SV_RING_SEARCHING:
2742 {
2743 /* Bonus to searching */
2744 o_ptr->pval = 1 + m_bonus(5, level);
2745
2746 /* Cursed */
2747 if (power < 0)
2748 {
2749 /* Broken */
2750 o_ptr->ident |= ID_BROKEN;
2751
2752 /* Cursed */
2753 o_ptr->ident |= ID_CURSED;
2754
2755 /* Reverse pval */
2756 o_ptr->pval = 0 - (o_ptr->pval);
2757 }
2758
2759 break;
2760 }
2761
2762 /* Flames, Acid, Ice, Lightning */
2763 case SV_RING_FLAMES:
2764 case SV_RING_ACID:
2765 case SV_RING_ICE:
2766 case SV_RING_LIGHTNING:
2767 {
2768 /* Bonus to armor class */
2769 o_ptr->to_a = 5 + randint1(5) + m_bonus(10, level);
2770 break;
2771 }
2772
2773 /* Weakness, Stupidity */
2774 case SV_RING_WEAKNESS:
2775 case SV_RING_STUPIDITY:
2776 {
2777 /* Broken */
2778 o_ptr->ident |= ID_BROKEN;
2779
2780 /* Cursed */
2781 o_ptr->ident |= ID_CURSED;
2782
2783 /* Penalize */
2784 o_ptr->pval = 0 - (1 + m_bonus(5, level));
2785
2786 break;
2787 }
2788
2789 /* WOE, Stupidity */
2790 case SV_RING_WOE:
2791 {
2792 /* Broken */
2793 o_ptr->ident |= ID_BROKEN;
2794
2795 /* Cursed */
2796 o_ptr->ident |= ID_CURSED;
2797
2798 /* Penalize */
2799 o_ptr->to_a = 0 - (5 + m_bonus(10, level));
2800 o_ptr->pval = 0 - (1 + m_bonus(5, level));
2801
2802 break;
2803 }
2804
2805 /* Ring of damage */
2806 case SV_RING_DAMAGE:
2807 {
2808 /* Bonus to damage */
2809 o_ptr->to_d = 5 + randint1(5) + m_bonus(7, level);
2810
2811 /* Cursed */
2812 if (power < 0)
2813 {
2814 /* Broken */
2815 o_ptr->ident |= ID_BROKEN;
2816
2817 /* Cursed */
2818 o_ptr->ident |= ID_CURSED;
2819
2820 /* Reverse bonus */
2821 o_ptr->to_d = 0 - (o_ptr->to_d);
2822 }
2823
2824 break;
2825 }
2826
2827 /* Ring of Accuracy */
2828 case SV_RING_ACCURACY:
2829 {
2830 /* Bonus to hit */
2831 o_ptr->to_h = 5 + randint1(5) + m_bonus(7, level);
2832
2833 /* Cursed */
2834 if (power < 0)
2835 {
2836 /* Broken */
2837 o_ptr->ident |= ID_BROKEN;
2838
2839 /* Cursed */
2840 o_ptr->ident |= ID_CURSED;
2841
2842 /* Reverse tohit */
2843 o_ptr->to_h = 0 - (o_ptr->to_h);
2844 }
2845
2846 break;
2847 }
2848
2849 /* Ring of Protection */
2850 case SV_RING_PROTECTION:
2851 {
2852 /* Bonus to armor class */
2853 o_ptr->to_a = 5 + randint1(5) + m_bonus(10, level);
2854
2855 /* Cursed */
2856 if (power < 0)
2857 {
2858 /* Broken */
2859 o_ptr->ident |= ID_BROKEN;
2860
2861 /* Cursed */
2862 o_ptr->ident |= ID_CURSED;
2863
2864 /* Reverse toac */
2865 o_ptr->to_a = 0 - (o_ptr->to_a);
2866 }
2867
2868 break;
2869 }
2870
2871 /* Ring of Slaying */
2872 case SV_RING_SLAYING:
2873 {
2874 /* Bonus to damage and to hit */
2875 o_ptr->to_d = randint1(5) + m_bonus(5, level);
2876 o_ptr->to_h = randint1(5) + m_bonus(5, level);
2877
2878 /* Cursed */
2879 if (power < 0)
2880 {
2881 /* Broken */
2882 o_ptr->ident |= ID_BROKEN;
2883
2884 /* Cursed */
2885 o_ptr->ident |= ID_CURSED;
2886
2887 /* Reverse bonuses */
2888 o_ptr->to_h = 0 - (o_ptr->to_h);
2889 o_ptr->to_d = 0 - (o_ptr->to_d);
2890 }
2891
2892 break;
2893 }
2894 }
2895
2896 break;
2897 }
2898
2899 case TV_AMULET:
2900 {
2901 /* Analyze */
2902 switch (o_ptr->sval)
2903 {
2904 /* Amulet of wisdom/charisma */
2905 case SV_AMULET_WISDOM:
2906 case SV_AMULET_CHARISMA:
2907 {
2908 o_ptr->pval = 1 + m_bonus(5, level);
2909
2910 /* Cursed */
2911 if (power < 0)
2912 {
2913 /* Broken */
2914 o_ptr->ident |= ID_BROKEN;
2915
2916 /* Cursed */
2917 o_ptr->ident |= ID_CURSED;
2918
2919 /* Reverse bonuses */
2920 o_ptr->pval = 0 - (o_ptr->pval);
2921 }
2922
2923 break;
2924 }
2925
2926 /* Amulet of searching */
2927 case SV_AMULET_SEARCHING:
2928 {
2929 o_ptr->pval = randint1(5) + m_bonus(5, level);
2930
2931 /* Cursed */
2932 if (power < 0)
2933 {
2934 /* Broken */
2935 o_ptr->ident |= ID_BROKEN;
2936
2937 /* Cursed */
2938 o_ptr->ident |= ID_CURSED;
2939
2940 /* Reverse bonuses */
2941 o_ptr->pval = 0 - (o_ptr->pval);
2942 }
2943
2944 break;
2945 }
2946
2947 /* Amulet of ESP -- never cursed */
2948 case SV_AMULET_ESP:
2949 {
2950 o_ptr->pval = randint1(5) + m_bonus(5, level);
2951
2952 break;
2953 }
2954
2955 /* Amulet of the Magi -- never cursed */
2956 case SV_AMULET_THE_MAGI:
2957 {
2958 o_ptr->pval = 1 + m_bonus(2, level);
2959 o_ptr->to_a = randint1(5) + m_bonus(5, level);
2960
2961 /* mangband-specific -- TURN IT ON IF YOU NEED
2962 o_ptr->xtra1 = OBJECT_XTRA_TYPE_RESIST;
2963 o_ptr->xtra2 = (byte)randint1(OBJECT_XTRA_SIZE_RESIST);
2964 */
2965
2966 break;
2967 }
2968
2969 /* Amulet of speed */
2970 case SV_AMULET_SPEED:
2971 {
2972 // Amulets of speed can't give very
2973 // much, and are rarely +3.
2974 o_ptr->pval = randint1(randint1(3));
2975
2976 /* Cursed */
2977 if (power < 0)
2978 {
2979 /* Broken */
2980 o_ptr->ident |= ID_BROKEN;
2981
2982 /* Cursed */
2983 o_ptr->ident |= ID_CURSED;
2984
2985 /* Reverse bonuses */
2986 o_ptr->pval = 0 - (o_ptr->pval);
2987 }
2988
2989 break;
2990 }
2991
2992 /* Amulet of Terken -- never cursed */
2993 case SV_AMULET_TERKEN:
2994 {
2995 o_ptr->pval = randint1(5) + m_bonus(5, level);
2996
2997 o_ptr->xtra1 = OBJECT_XTRA_TYPE_POWER;
2998 o_ptr->xtra2 = (byte)randint0(OBJECT_XTRA_SIZE_POWER);
2999 break;
3000 }
3001
3002 /* Amulet of the Moon -- never cursed */
3003 case SV_AMULET_THE_MOON:
3004 {
3005 o_ptr->pval = randint1(5) + m_bonus(5, level);
3006 o_ptr->to_h = randint1(5);
3007 o_ptr->to_d = randint1(5);
3008
3009 break;
3010 }
3011
3012 /* Amulet of Devotion -- never cursed */
3013 case SV_AMULET_DEVOTION:
3014 {
3015 o_ptr->pval = 1 + m_bonus(3, level);
3016
3017 /* Boost the rating */
3018 rating += 25;
3019
3020 break;
3021 }
3022
3023 /* Amulet of Weaponmastery -- never cursed */
3024 case SV_AMULET_WEPMASTERY:
3025 {
3026 o_ptr->to_h = 1 + m_bonus(4, level);
3027 o_ptr->to_d = 1 + m_bonus(4, level);
3028 o_ptr->pval = 1 + m_bonus(2, level);
3029
3030 /* Boost the rating */
3031 rating += 25;
3032
3033 break;
3034 }
3035
3036 /* Amulet of Trickery -- never cursed */
3037 case SV_AMULET_TRICKERY:
3038 {
3039 o_ptr->pval = randint1(1) + m_bonus(3, level);
3040
3041 /* Boost the rating */
3042 rating += 25;
3043
3044 break;
3045 }
3046
3047 /* Amulet of infravision */
3048 case SV_AMULET_INFRA:
3049 {
3050 o_ptr->pval = randint1(5) + m_bonus(5, level);
3051
3052 /* Cursed */
3053 if (power < 0)
3054 {
3055 /* Broken */
3056 o_ptr->ident |= ID_BROKEN;
3057
3058 /* Cursed */
3059 o_ptr->ident |= ID_CURSED;
3060
3061 /* Reverse bonuses */
3062 o_ptr->pval = 0 - (o_ptr->pval);
3063 }
3064
3065 break;
3066 }
3067
3068 /* Amulet of Doom -- always cursed */
3069 case SV_AMULET_DOOM:
3070 {
3071 /* Broken */
3072 o_ptr->ident |= ID_BROKEN;
3073
3074 /* Cursed */
3075 o_ptr->ident |= ID_CURSED;
3076
3077 /* Penalize */
3078 o_ptr->pval = 0 - (randint1(5) + m_bonus(5, level));
3079 o_ptr->to_a = 0 - (randint1(5) + m_bonus(5, level));
3080
3081 break;
3082 }
3083 }
3084
3085 break;
3086 }
3087 }
3088 }
3089
3090
3091 /*
3092 * Apply magic to an item known to be "boring"
3093 *
3094 * Hack -- note the special code for various items
3095 */
a_m_aux_4(object_type * o_ptr,int level,int power)3096 static void a_m_aux_4(object_type *o_ptr, int level, int power)
3097 {
3098 /* Apply magic (good or bad) according to type */
3099 switch (o_ptr->tval)
3100 {
3101 case TV_LITE:
3102
3103 /* Hack -- Torches -- random fuel */
3104 if (o_ptr->sval == SV_LITE_TORCH)
3105 {
3106 if (o_ptr->pval) o_ptr->pval = randint1(o_ptr->pval);
3107 }
3108
3109 /* Hack -- Lanterns -- random fuel */
3110 if (o_ptr->sval == SV_LITE_LANTERN)
3111 {
3112 if (o_ptr->pval) o_ptr->pval = randint1(o_ptr->pval);
3113 }
3114
3115 break;
3116
3117
3118 case TV_WAND:
3119
3120 /* Hack -- charge wands */
3121 charge_wand(o_ptr);
3122
3123 break;
3124
3125
3126 case TV_STAFF:
3127
3128 /* Hack -- charge staffs */
3129 charge_staff(o_ptr);
3130
3131 break;
3132
3133 case TV_ROD:
3134
3135 /* Transfer the pval. */
3136 o_ptr->pval = k_info[o_ptr->k_idx].pval;
3137 break;
3138
3139 case TV_CHEST:
3140
3141 /* Hack -- skip ruined chests */
3142 if (k_info[o_ptr->k_idx].level <= 0) break;
3143
3144 /* Hack -- pick a "difficulty" */
3145 o_ptr->pval = randint1(k_info[o_ptr->k_idx].level);
3146
3147 /* Never exceed "difficulty" of 55 to 59 */
3148 if (o_ptr->pval > 55) o_ptr->pval = 55 + randint0(5);
3149
3150 break;
3151 }
3152 }
3153
3154
3155
3156 /*
3157 * Complete the "creation" of an object by applying "magic" to the item
3158 *
3159 * This includes not only rolling for random bonuses, but also putting the
3160 * finishing touches on ego-items and artifacts, giving charges to wands and
3161 * staffs, giving fuel to lites, and placing traps on chests.
3162 *
3163 * In particular, note that "Instant Artifacts", if "created" by an external
3164 * routine, must pass through this function to complete the actual creation.
3165 *
3166 * The base "chance" of the item being "good" increases with the "level"
3167 * parameter, which is usually derived from the dungeon level, being equal
3168 * to the level plus 10, up to a maximum of 75. If "good" is true, then
3169 * the object is guaranteed to be "good". If an object is "good", then
3170 * the chance that the object will be "great" (ego-item or artifact), also
3171 * increases with the "level", being equal to half the level, plus 5, up to
3172 * a maximum of 20. If "great" is true, then the object is guaranteed to be
3173 * "great". At dungeon level 65 and below, 15/100 objects are "great".
3174 *
3175 * If the object is not "good", there is a chance it will be "cursed", and
3176 * if it is "cursed", there is a chance it will be "broken". These chances
3177 * are related to the "good" / "great" chances above.
3178 *
3179 * Otherwise "normal" rings and amulets will be "good" half the time and
3180 * "cursed" half the time, unless the ring/amulet is always good or cursed.
3181 *
3182 * If "okay" is true, and the object is going to be "great", then there is
3183 * a chance that an artifact will be created. This is true even if both the
3184 * "good" and "great" arguments are false. As a total hack, if "great" is
3185 * true, then the item gets 3 extra "attempts" to become an artifact.
3186 */
apply_magic(int Depth,object_type * o_ptr,int lev,bool okay,bool good,bool great)3187 void apply_magic(int Depth, object_type *o_ptr, int lev, bool okay, bool good, bool great)
3188 {
3189 int i, rolls, f1, f2, power;
3190
3191
3192 /* Magic ammo are always +0 +0 */
3193 if (((o_ptr->tval == TV_SHOT) || (o_ptr->tval == TV_ARROW) ||
3194 (o_ptr->tval == TV_BOLT)) && (o_ptr->sval == SV_AMMO_MAGIC))
3195 return;
3196
3197 /* Maximum "level" for various things */
3198 if (lev > MAX_DEPTH - 1) lev = MAX_DEPTH - 1;
3199
3200
3201 /* Base chance of being "good" */
3202 f1 = lev + 10;
3203
3204 /* Maximal chance of being "good" */
3205 if (f1 > 75) f1 = 75;
3206
3207 /* Base chance of being "great" */
3208 f2 = f1 / 2;
3209
3210 /* Maximal chance of being "great" */
3211 if (f2 > 20) f2 = 20;
3212
3213
3214 /* Assume normal */
3215 power = 0;
3216
3217 /* Roll for "good" */
3218 if (good || magik(f1))
3219 {
3220 /* Assume "good" */
3221 power = 1;
3222
3223 /* Roll for "great" */
3224 if (great || magik(f2)) power = 2;
3225 }
3226
3227 /* Roll for "cursed" */
3228 else if (magik(f1))
3229 {
3230 /* Assume "cursed" */
3231 power = -1;
3232
3233 /* Roll for "broken" */
3234 if (magik(f2)) power = -2;
3235 }
3236
3237
3238 /* Assume no rolls */
3239 rolls = 0;
3240
3241 /* Get one roll if excellent */
3242 if (power >= 2) rolls = 1;
3243
3244 /* Hack -- Get four rolls if forced great */
3245 if (great) rolls = 4;
3246
3247 /* Hack -- Get no rolls if not allowed */
3248 if (!okay || artifact_p(o_ptr)) rolls = 0;
3249
3250 /* Roll for artifacts if allowed */
3251 for (i = 0; i < rolls; i++)
3252 {
3253 /* Roll for an artifact */
3254 if (make_artifact(Depth, o_ptr)) break;
3255 }
3256
3257
3258 /* Hack -- analyze artifacts */
3259 if (artifact_p(o_ptr))
3260 {
3261 artifact_type *a_ptr = artifact_ptr(o_ptr);
3262
3263 if (true_artifact_p(o_ptr))
3264 {
3265 /* Hack -- Mark the artifact as "created" */
3266 a_ptr->cur_num = 1;
3267
3268 /* Hack -- reset ownership (just in case) */
3269 a_ptr->owner_id = 0;
3270 a_ptr->owner_name = 0;
3271 }
3272
3273 /* Info */
3274 /* s_printf("Created artifact %d.\n", o_ptr->name1); */
3275
3276 /* Extract the other fields */
3277 o_ptr->pval = a_ptr->pval;
3278 o_ptr->ac = a_ptr->ac;
3279 o_ptr->dd = a_ptr->dd;
3280 o_ptr->ds = a_ptr->ds;
3281 o_ptr->to_a = a_ptr->to_a;
3282 o_ptr->to_h = a_ptr->to_h;
3283 o_ptr->to_d = a_ptr->to_d;
3284 o_ptr->weight = a_ptr->weight;
3285
3286 /* Hack -- extract the "broken" flag */
3287 if (!a_ptr->cost) o_ptr->ident |= ID_BROKEN;
3288
3289 /* Hack -- extract the "cursed" flag */
3290 if ((a_ptr->flags3 & TR3_LIGHT_CURSE) ||
3291 (a_ptr->flags3 & TR3_HEAVY_CURSE) ||
3292 (a_ptr->flags3 & TR3_PERMA_CURSE))
3293 o_ptr->ident |= ID_CURSED;
3294
3295
3296 /* Mega-Hack -- increase the rating */
3297 rating += 10;
3298
3299 /* Mega-Hack -- increase the rating again */
3300 if (a_ptr->cost > 50000L) rating += 10;
3301
3302 /* Set the good item flag */
3303 good_item_flag = TRUE;
3304
3305 /* Cheat -- peek at the item */
3306 /* if (cheat_peek) object_mention(o_ptr); */
3307
3308 /* Done */
3309 return;
3310 }
3311
3312
3313 /* Apply magic */
3314 switch (o_ptr->tval)
3315 {
3316 case TV_DIGGING:
3317 case TV_HAFTED:
3318 case TV_POLEARM:
3319 case TV_SWORD:
3320 case TV_BOW:
3321 case TV_SHOT:
3322 case TV_ARROW:
3323 case TV_BOLT:
3324 {
3325 if (power) a_m_aux_1(o_ptr, lev, power);
3326 break;
3327 }
3328
3329 case TV_DRAG_ARMOR:
3330 case TV_HARD_ARMOR:
3331 case TV_SOFT_ARMOR:
3332 case TV_SHIELD:
3333 case TV_HELM:
3334 case TV_CROWN:
3335 case TV_CLOAK:
3336 case TV_GLOVES:
3337 case TV_BOOTS:
3338 {
3339 // Power is no longer required since things such as
3340 // Kollas need magic applied to finish their normal
3341 // generation.
3342 //if (power) a_m_aux_2(o_ptr, lev, power);
3343 a_m_aux_2(o_ptr, lev, power);
3344 break;
3345 }
3346
3347 case TV_RING:
3348 case TV_AMULET:
3349 {
3350 if (!power && (randint0(100) < 50)) power = -1;
3351 a_m_aux_3(o_ptr, lev, power);
3352 break;
3353 }
3354
3355 default:
3356 {
3357 a_m_aux_4(o_ptr, lev, power);
3358 break;
3359 }
3360 }
3361
3362
3363 /* Hack -- analyze ego-items */
3364 if (o_ptr->name2)
3365 {
3366 ego_item_type *e_ptr = &e_info[o_ptr->name2];
3367
3368 /* Extra powers */
3369 if (e_ptr->xtra)
3370 {
3371 o_ptr->xtra1 = e_ptr->xtra;
3372 switch (o_ptr->xtra1)
3373 {
3374 case OBJECT_XTRA_TYPE_SUSTAIN:
3375 {
3376 o_ptr->xtra2 = (byte)randint0(OBJECT_XTRA_SIZE_SUSTAIN);
3377 break;
3378 }
3379
3380 case OBJECT_XTRA_TYPE_RESIST:
3381 {
3382 o_ptr->xtra2 = (byte)randint0(OBJECT_XTRA_SIZE_RESIST);
3383 break;
3384 }
3385
3386 case OBJECT_XTRA_TYPE_POWER:
3387 {
3388 o_ptr->xtra2 = (byte)randint0(OBJECT_XTRA_SIZE_POWER);
3389 break;
3390 }
3391 }
3392 }
3393
3394 /* Hack -- acquire "broken" flag */
3395 if (!e_ptr->cost) o_ptr->ident |= ID_BROKEN;
3396
3397 /* Hack -- acquire "cursed" flag */
3398 if ((e_ptr->flags3 & TR3_LIGHT_CURSE) ||
3399 (e_ptr->flags3 & TR3_HEAVY_CURSE) ||
3400 (e_ptr->flags3 & TR3_PERMA_CURSE))
3401 o_ptr->ident |= ID_CURSED;
3402
3403
3404 /* Hack -- apply extra penalties if needed */
3405 if (cursed_p(o_ptr) || broken_p(o_ptr))
3406 {
3407 /* Hack -- obtain bonuses */
3408 if (e_ptr->max_to_h) o_ptr->to_h -= randint1(e_ptr->max_to_h);
3409 if (e_ptr->max_to_d) o_ptr->to_d -= randint1(e_ptr->max_to_d);
3410 if (e_ptr->max_to_a) o_ptr->to_a -= randint1(e_ptr->max_to_a);
3411
3412 /* Hack -- obtain pval */
3413 if (e_ptr->max_pval) o_ptr->pval -= randint1(e_ptr->max_pval);
3414 }
3415
3416 /* Hack -- apply extra bonuses if needed */
3417 else
3418 {
3419 /* Hack -- obtain bonuses */
3420 /* Don't forget minuses!! */
3421 if (e_ptr->max_to_h > 0) o_ptr->to_h += randint1(e_ptr->max_to_h);
3422 else if (e_ptr->max_to_h < 0) o_ptr->to_h -= randint1(-e_ptr->max_to_h);
3423 if (e_ptr->max_to_d > 0) o_ptr->to_d += randint1(e_ptr->max_to_d);
3424 else if (e_ptr->max_to_d < 0) o_ptr->to_d -= randint1(-e_ptr->max_to_d);
3425 if (e_ptr->max_to_a > 0) o_ptr->to_a += randint1(e_ptr->max_to_a);
3426 else if (e_ptr->max_to_a < 0) o_ptr->to_a -= randint1(-e_ptr->max_to_a);
3427
3428 /* Hack -- obtain pval */
3429 /* Don't forget minuses!! */
3430 if (e_ptr->max_pval > 0) o_ptr->pval += randint1(e_ptr->max_pval);
3431 else if (e_ptr->max_pval < 0) o_ptr->pval -= randint1(-e_ptr->max_pval);
3432 }
3433
3434 /* Hack -- apply rating bonus */
3435 rating += e_ptr->rating;
3436
3437 /* Cheat -- describe the item */
3438 /*if (cheat_peek) object_mention(o_ptr);*/
3439
3440 /* Done */
3441 return;
3442 }
3443
3444
3445 /* Examine real objects */
3446 if (o_ptr->k_idx)
3447 {
3448 object_kind *k_ptr = &k_info[o_ptr->k_idx];
3449
3450 /* Hack -- acquire "broken" flag */
3451 if (!k_ptr->cost) o_ptr->ident |= ID_BROKEN;
3452
3453 /* Hack -- acquire "cursed" flag */
3454 if ((k_ptr->flags3 & TR3_LIGHT_CURSE) ||
3455 (k_ptr->flags3 & TR3_HEAVY_CURSE) ||
3456 (k_ptr->flags3 & TR3_PERMA_CURSE))
3457 o_ptr->ident |= ID_CURSED;
3458 }
3459 }
3460
3461
3462
3463 /*
3464 * Hack -- determine if a template is "good"
3465 */
kind_is_good(int k_idx)3466 static bool kind_is_good(int k_idx)
3467 {
3468 object_kind *k_ptr = &k_info[k_idx];
3469
3470 /* Analyze the item type */
3471 switch (k_ptr->tval)
3472 {
3473 /* Armor -- Good unless damaged */
3474 case TV_HARD_ARMOR:
3475 case TV_SOFT_ARMOR:
3476 case TV_DRAG_ARMOR:
3477 case TV_SHIELD:
3478 case TV_CLOAK:
3479 case TV_BOOTS:
3480 case TV_GLOVES:
3481 case TV_HELM:
3482 case TV_CROWN:
3483 {
3484 if (k_ptr->to_a < 0) return (FALSE);
3485 return (TRUE);
3486 }
3487
3488 /* Weapons -- Good unless damaged */
3489 case TV_BOW:
3490 case TV_SWORD:
3491 case TV_HAFTED:
3492 case TV_POLEARM:
3493 case TV_DIGGING:
3494 {
3495 if (k_ptr->to_h < 0) return (FALSE);
3496 if (k_ptr->to_d < 0) return (FALSE);
3497 return (TRUE);
3498 }
3499
3500 /* Ammo -- Arrows/Bolts are good */
3501 /* Shots should be good too, why not? */
3502 case TV_BOLT:
3503 case TV_ARROW:
3504 case TV_SHOT:
3505 {
3506 /* Magic ammo never get good */
3507 return (k_ptr->sval != SV_AMMO_MAGIC);
3508 }
3509
3510 /* Books -- High level books are good */
3511 case TV_MAGIC_BOOK:
3512 case TV_PRAYER_BOOK:
3513 {
3514 if (k_ptr->sval >= SV_BOOK_MIN_GOOD) return (TRUE);
3515 return (FALSE);
3516 }
3517
3518 /* Rings -- Rings of Speed are good */
3519 case TV_RING:
3520 {
3521 if (k_ptr->sval == SV_RING_SPEED) return (TRUE);
3522 return (FALSE);
3523 }
3524 }
3525
3526 /* Assume not good */
3527 return (FALSE);
3528 }
3529
3530
3531
place_specific_object(int Depth,int y1,int x1,object_type * forge,int lev,int num)3532 bool place_specific_object(int Depth, int y1, int x1, object_type *forge, int lev, int num)
3533 {
3534 int o_idx, i, d, x, y, xtra_hack;
3535
3536 /* Scatter some objects */
3537 for (; num > 0; --num)
3538 {
3539 /* Check near the player for space */
3540 for (i = 0; i < 25; ++i)
3541 {
3542 /* Increasing Distance */
3543 d = (i + 4) / 5;
3544
3545 /* Pick a location */
3546 scatter(Depth, &y, &x, y1, x1, d, 0);
3547
3548 /* Must have a clean grid */
3549 if (!cave_clean_bold(Depth, y, x)) continue;
3550
3551 /* Place a great object */
3552
3553 /* Make an object */
3554 o_idx = o_pop();
3555
3556 /* Success */
3557 if (o_idx)
3558 {
3559 cave_type *c_ptr;
3560 object_type *o_ptr;
3561 int i;
3562
3563 o_ptr = &o_list[o_idx];
3564
3565 (*o_ptr) = (*forge);
3566
3567 o_ptr->ident = 0;
3568
3569 o_ptr->iy = y;
3570 o_ptr->ix = x;
3571 o_ptr->dun_depth = Depth;
3572
3573 c_ptr = &cave[Depth][y][x];
3574 c_ptr->o_idx = o_idx;
3575
3576 /* Make sure no one sees it at first */
3577 for (i = 1; i <= NumPlayers; i++)
3578 {
3579 /* He can't see it */
3580 Players[i]->obj_vis[o_idx] = FALSE;
3581 }
3582
3583
3584 xtra_hack = forge->xtra2;
3585 apply_magic(Depth, o_ptr, lev, TRUE, FALSE, FALSE);
3586 o_ptr->xtra2 = xtra_hack;
3587
3588 o_ptr->to_h = forge->to_h;
3589 o_ptr->to_d = forge->to_d;
3590 o_ptr->to_a = forge->to_a;
3591 o_ptr->pval = forge->pval;
3592
3593 /* Identify fully? */
3594 if ((forge->ident & ID_KNOWN))
3595 {
3596 object_known(o_ptr);
3597 }
3598
3599 /* Notice */
3600 note_spot_depth(Depth, y, x);
3601
3602 /* Redraw */
3603 everyone_lite_spot(Depth, y, x);
3604
3605 }
3606
3607 /* Placement accomplished */
3608 break;
3609 }
3610 }
3611
3612 return !num;
3613 }
3614
3615
3616 /*
3617 * Attempt to place an object (normal or good/great) at the given location.
3618 *
3619 * This routine plays nasty games to generate the "special artifacts".
3620 *
3621 * This routine uses "object_level" for the "generation level".
3622 *
3623 * This routine requires a clean floor grid destination.
3624 */
place_object(int Depth,int y,int x,bool good,bool great,byte origin)3625 object_type* place_object(int Depth, int y, int x, bool good, bool great, byte origin)
3626 {
3627 int o_idx, prob, base;
3628
3629 int old = rating;
3630
3631 object_type forge;
3632
3633
3634 /* Paranoia -- check bounds */
3635 if (!in_bounds(Depth, y, x)) return (NULL);
3636
3637 /* Require clean floor space */
3638 if (!cave_clean_bold(Depth, y, x)) return (NULL);
3639
3640 /* Chance of "special object" */
3641 prob = (good ? 10 : 1000);
3642
3643 /* Base level for the object */
3644 base = (good ? (object_level + 10) : object_level);
3645
3646
3647 /* Hack -- clear out the forgery */
3648 invwipe(&forge);
3649
3650 /* Generate a special object, or a normal object */
3651 if ((randint0(prob) != 0) || !make_artifact_special(Depth, &forge))
3652 {
3653 int k_idx;
3654
3655 /* Good objects */
3656 if (good)
3657 {
3658 /* Activate restriction */
3659 get_obj_num_hook = kind_is_good;
3660
3661 /* Prepare allocation table */
3662 get_obj_num_prep();
3663 }
3664
3665 /* Pick a random object */
3666 k_idx = get_obj_num(base);
3667
3668 /* Good objects */
3669 if (good)
3670 {
3671 /* Clear restriction */
3672 get_obj_num_hook = NULL;
3673
3674 /* Prepare allocation table */
3675 get_obj_num_prep();
3676 }
3677
3678 /* Handle failure */
3679 if (!k_idx) return (NULL);
3680
3681 /* Prepare the object */
3682 invcopy(&forge, k_idx);
3683 }
3684
3685 /* Apply magic (allow artifacts) */
3686 apply_magic(Depth, &forge, object_level, TRUE, good, great);
3687
3688 /* Hack -- generate multiple spikes/missiles (except artifacts!) */
3689 switch (forge.tval)
3690 {
3691 case TV_SPIKE:
3692 case TV_SHOT:
3693 case TV_ARROW:
3694 case TV_BOLT: if (!artifact_p(&forge)) forge.number = damroll(6, 7);
3695 }
3696
3697
3698 /* Make an object */
3699 o_idx = o_pop();
3700
3701 /* Success */
3702 if (o_idx)
3703 {
3704 cave_type *c_ptr;
3705 object_type *o_ptr;
3706 int i;
3707
3708 o_ptr = &o_list[o_idx];
3709
3710 (*o_ptr) = (forge);
3711
3712 o_ptr->iy = y;
3713 o_ptr->ix = x;
3714 o_ptr->dun_depth = Depth;
3715
3716 c_ptr = &cave[Depth][y][x];
3717 c_ptr->o_idx = o_idx;
3718
3719 /* Notice "okay" out-of-depth objects (unless already noticed) */
3720 if (!cursed_p(o_ptr) && !broken_p(o_ptr) &&
3721 (rating == old) && (k_info[o_ptr->k_idx].level > Depth))
3722 {
3723 /* Rating increase */
3724 rating += (k_info[o_ptr->k_idx].level - Depth);
3725
3726 /* Cheat -- peek at items */
3727 /*if (cheat_peek) object_mention(o_ptr);*/
3728 }
3729
3730 /* Make sure no one sees it at first */
3731 for (i = 1; i <= NumPlayers; i++)
3732 {
3733 /* He can't see it */
3734 Players[i]->obj_vis[o_idx] = FALSE;
3735 }
3736
3737 /* Add origin */
3738 o_ptr->origin = origin;
3739 o_ptr->origin_depth = Depth;
3740
3741 #ifdef DEBUG
3742 {
3743 char tmp[120];
3744 object_desc(NULL, tmp, sizeof(tmp), o_ptr, FALSE, 1);
3745 /* Audit item allocation */
3746 cheat(format("%s %s", artifact_p(o_ptr) ? "+a": "+o", tmp));
3747 }
3748 #endif
3749 }
3750
3751 /* Observe placement. (dungeon level has already been generated) */
3752 if (server_dungeon && o_idx)
3753 {
3754 player_type *q_ptr;
3755
3756 /* Notice it */
3757 note_spot_depth(Depth, y, x);
3758
3759 /* Display it */
3760 everyone_lite_spot(Depth, y, x);
3761
3762 /* Under some player */
3763 if ((q_ptr = player_on_cave(Depth,y,x)))
3764 {
3765 msg_print(q_ptr, "You feel something roll beneath your feet.");
3766 floor_item_notify(q_ptr, o_idx, TRUE);
3767 }
3768 }
3769
3770 /* Success */
3771 if (o_idx) return &o_list[o_idx];
3772
3773 return FALSE;
3774 }
3775
3776
3777
3778 /*
3779 * Scatter some "great" objects near the player
3780 *
3781 * TODO: port version from 312 (!) (or later?)
3782 * This version ignores the "great" bool
3783 */
acquirement(int Depth,int y1,int x1,int num,bool great)3784 void acquirement(int Depth, int y1, int x1, int num, bool great)
3785 {
3786 int y, x, i, d;
3787 int oblev;
3788
3789 /* Scatter some objects */
3790 for (; num > 0; --num)
3791 {
3792 /* Check near the player for space */
3793 for (i = 0; i < 25; ++i)
3794 {
3795 /* Increasing Distance */
3796 d = (i + 4) / 5;
3797
3798 /* Pick a location */
3799 scatter(Depth, &y, &x, y1, x1, d, 0);
3800
3801 /* Must have a clean grid */
3802 if (!cave_clean_bold(Depth, y, x)) continue;
3803
3804 /* Place a great object */
3805 oblev = object_level;
3806 object_level = Depth;
3807 place_object(Depth, y, x, TRUE, TRUE, ORIGIN_ACQUIRE);
3808 object_level = oblev;
3809
3810 /* Placement accomplished */
3811 break;
3812 }
3813 }
3814 }
3815
3816
3817
3818
3819
3820 /*
3821 * Places a random trap at the given location.
3822 *
3823 * The location must be a valid, empty, clean, floor grid.
3824 *
3825 * Note that all traps start out as "invisible" and "untyped", and then
3826 * when they are "discovered" (by detecting them or setting them off),
3827 * the trap is "instantiated" as a visible, "typed", trap.
3828 */
place_trap(int Depth,int y,int x)3829 void place_trap(int Depth, int y, int x)
3830 {
3831 cave_type *c_ptr;
3832
3833 /* Paranoia -- verify location */
3834 if (!in_bounds(Depth, y, x)) return;
3835
3836 /* Require empty, clean, floor grid */
3837 if (!cave_naked_bold(Depth, y, x)) return;
3838
3839 /* Access the grid */
3840 c_ptr = &cave[Depth][y][x];
3841
3842 /* Place an invisible trap */
3843 c_ptr->feat = FEAT_INVIS;
3844
3845 /* Note: we don't use cave_set_feat here, so that
3846 * the clients DON'T get any floor updates... */
3847 }
3848
3849
3850 /*
3851 * XXX XXX XXX Do not use these hard-coded values.
3852 */
3853 #define OBJ_GOLD_LIST 480 /* First "gold" entry */
3854 #define MAX_GOLD 18 /* Number of "gold" entries */
3855
3856 /*
3857 * Places a treasure (Gold or Gems) at given location
3858 * The location must be a valid, empty, floor grid.
3859 */
place_gold(int Depth,int y,int x)3860 void place_gold(int Depth, int y, int x)
3861 {
3862 int i, j, o_idx;
3863
3864 s32b base;
3865
3866 cave_type *c_ptr;
3867 object_type *o_ptr;
3868
3869
3870 /* Paranoia -- check bounds */
3871 if (!in_bounds(Depth, y, x)) return;
3872
3873 /* Require clean floor grid */
3874 if (!cave_clean_bold(Depth, y, x)) return;
3875
3876
3877 /* Hack -- Pick a Treasure variety */
3878 i = ((randint1(object_level + 2) + 2) / 2) - 1;
3879
3880 /* Apply "extra" magic */
3881 if (randint0(GREAT_OBJ) == 0)
3882 {
3883 i += randint1(object_level + 1);
3884 }
3885
3886 /* Hack -- Creeping Coins only generate "themselves" */
3887 if (coin_type) i = coin_type;
3888
3889 /* Do not create "illegal" Treasure Types */
3890 if (i >= MAX_GOLD) i = MAX_GOLD - 1;
3891
3892
3893 /* Make an object */
3894 o_idx = o_pop();
3895
3896 /* Success */
3897 if (o_idx)
3898 {
3899 o_ptr = &o_list[o_idx];
3900
3901 invcopy(o_ptr, OBJ_GOLD_LIST + i);
3902
3903 o_ptr->iy = y;
3904 o_ptr->ix = x;
3905 o_ptr->dun_depth = Depth;
3906
3907 c_ptr = &cave[Depth][y][x];
3908 c_ptr->o_idx = o_idx;
3909
3910 /* Hack -- Base coin cost */
3911 base = k_info[OBJ_GOLD_LIST+i].cost;
3912
3913 /* Determine how much the treasure is "worth" */
3914 o_ptr->pval = (base + (8L * randint1(base)) + randint1(8));
3915
3916 /* No one can see it */
3917 for (j = 1; j <= NumPlayers; j++)
3918 {
3919 /* This player can't see it */
3920 Players[j]->obj_vis[o_idx] = FALSE;
3921 }
3922 }
3923
3924 /* Observe placement. (dungeon level has already been generated) */
3925 if (server_dungeon && o_idx)
3926 {
3927 player_type *q_ptr;
3928
3929 /* Notice it */
3930 note_spot_depth(Depth, y, x);
3931
3932 /* Display it */
3933 everyone_lite_spot(Depth, y, x);
3934
3935 /* Under some player */
3936 if ((q_ptr = player_on_cave(Depth,y,x)))
3937 {
3938 msg_print(q_ptr, "You feel something roll beneath your feet.");
3939 floor_item_notify(q_ptr, o_idx, TRUE);
3940 }
3941 }
3942
3943 }
3944
3945
3946
3947 /*
3948 * Let an item 'o_ptr' fall to the ground at or near (y,x).
3949 * The initial location is assumed to be "in_bounds()".
3950 *
3951 * This function takes a parameter "chance". This is the percentage
3952 * chance that the item will "disappear" instead of drop. If the object
3953 * has been thrown, then this is the chance of disappearance on contact.
3954 *
3955 * Hack -- this function uses "chance" to determine if it should produce
3956 * some form of "description" of the drop event (under the player).
3957 *
3958 * This function should probably be broken up into a function to determine
3959 * a "drop location", and several functions to actually "drop" an object.
3960 *
3961 * XXX XXX XXX Consider allowing objects to combine on the ground.
3962 */
drop_near(object_type * o_ptr,int chance,int Depth,int y,int x)3963 void drop_near(object_type *o_ptr, int chance, int Depth, int y, int x)
3964 {
3965 int k, d, ny, nx, y1, x1, o_idx;
3966
3967 cave_type *c_ptr;
3968 object_type *j_ptr;
3969
3970 bool flag = FALSE;
3971 bool comb = FALSE;
3972
3973 if(o_ptr == NULL) return;
3974
3975
3976 /* Start at the drop point */
3977 ny = y1 = y; nx = x1 = x;
3978
3979 /* See if the object "survives" the fall */
3980 if (artifact_p(o_ptr) || (randint0(100) >= chance))
3981 {
3982 /* Start at the drop point */
3983 ny = y1 = y; nx = x1 = x;
3984
3985 /* Try (20 times) to find an adjacent usable location */
3986 for (k = 0; !flag && (k < 50); ++k)
3987 {
3988 /* Distance distribution */
3989 d = ((k + 14) / 15);
3990
3991 /* Pick a "nearby" location */
3992 scatter(Depth, &ny, &nx, y1, x1, d, 0);
3993
3994 /* Get the cave grid */
3995 c_ptr = &cave[Depth][ny][nx];
3996
3997 if (c_ptr->o_idx) {
3998 j_ptr = &o_list[c_ptr->o_idx];
3999
4000 /* Check for combination */
4001 if (object_similar_floor(o_ptr, j_ptr))
4002 {
4003 flag = TRUE;
4004 comb = TRUE;
4005 }
4006 }
4007
4008 /* Require clean floor space */
4009 if (!cave_clean_bold(Depth, ny, nx)) continue;
4010
4011 /* Here looks good */
4012 flag = TRUE;
4013 }
4014 }
4015
4016 /* Try really hard to place an artifact */
4017 if (!flag && artifact_p(o_ptr))
4018 {
4019 /* Start at the drop point */
4020 ny = y1 = y; nx = x1 = x;
4021
4022 /* Try really hard to drop it */
4023 for (k = 0; !flag && (k < 1000); k++)
4024 {
4025 d = 1;
4026
4027 /* Pick a location */
4028 scatter(Depth, &ny, &nx, y1, x1, d, 0);
4029
4030 /* Do not move through walls */
4031 if (!cave_floor_bold(Depth, ny, nx)) continue;
4032
4033 /* Hack -- "bounce" to that location */
4034 y1 = ny; x1 = nx;
4035
4036 /* Get the cave grid */
4037 c_ptr = &cave[Depth][ny][nx];
4038
4039 /* XXX XXX XXX */
4040
4041 /* Nothing here? Use it */
4042 if (!(c_ptr->o_idx)) flag = TRUE;
4043
4044 /* After trying 99 places, crush any (normal) object */
4045 else if ((k>99) && cave_valid_bold(Depth, ny, nx)) flag = TRUE;
4046 }
4047
4048 /* Hack -- Artifacts will destroy ANYTHING to stay alive */
4049 if (!flag)
4050 {
4051 /* Location */
4052 ny = y;
4053 nx = x;
4054
4055 /* Always okay */
4056 flag = TRUE;
4057
4058 /* Description */
4059 /*object_desc(o_name, o_ptr, FALSE, 0);*/
4060
4061 /* Message */
4062 /*msg_format("The %s crashes to the floor.", o_name);*/
4063 }
4064 }
4065
4066
4067 /* Successful drop */
4068 if (flag)
4069 {
4070 /* Assume fails */
4071 flag = FALSE;
4072
4073 /* Crush contents or combine two objects? */
4074 if (!comb) {
4075 /* Crush anything under us (for artifacts) */
4076 delete_object(Depth, ny, nx);
4077
4078 /* Make a new object */
4079 o_idx = o_pop();
4080
4081 /* Success */
4082 if (o_idx)
4083 {
4084 /* Structure copy */
4085 o_list[o_idx] = *o_ptr;
4086
4087 /* Access */
4088 o_ptr = &o_list[o_idx];
4089
4090 /* Locate */
4091 o_ptr->iy = ny;
4092 o_ptr->ix = nx;
4093 o_ptr->dun_depth = Depth;
4094
4095 /* Place */
4096 c_ptr = &cave[Depth][ny][nx];
4097 c_ptr->o_idx = o_idx;
4098
4099 /* Notify ! */
4100 flag = TRUE;
4101 }
4102 }
4103 else
4104 {
4105 /* Use old object */
4106 o_idx = c_ptr->o_idx;
4107
4108 /* Absorb */
4109 object_absorb(NULL, j_ptr, o_ptr);
4110
4111 /* Notify ! */
4112 flag = TRUE;
4113 }
4114 }
4115 if (flag) {
4116 player_type *q_ptr;
4117
4118 /* Clear visibility flags */
4119 for (k = 1; k <= NumPlayers; k++)
4120 {
4121 /* This player cannot see it */
4122 Players[k]->obj_vis[o_idx] = FALSE;
4123 }
4124
4125 /* Note the spot */
4126 note_spot_depth(Depth, ny, nx);
4127
4128 /* Draw the spot */
4129 everyone_lite_spot(Depth, ny, nx);
4130
4131
4132 /* Mega-Hack -- no message if "dropped" by player */
4133 /* Message when an object falls under the player */
4134 if ((q_ptr = player_on_cave_p(c_ptr)))
4135 {
4136 if (chance) msg_print(q_ptr, "You feel something roll beneath your feet.");
4137 floor_item_notify(q_ptr, o_idx, TRUE);
4138 sound(q_ptr, MSG_DROP);
4139 }
4140 }
4141
4142
4143 /* Poor little object */
4144 if (!flag)
4145 {
4146 /* Describe */
4147
4148 /* Message */
4149 /*
4150 object_desc(o_name, o_ptr, FALSE, 0);
4151 msg_format("The %s disappear%s.",
4152 o_name, ((o_ptr->number == 1) ? "s" : ""));
4153 */
4154
4155 delete_object_ptr(o_ptr);
4156 }
4157 }
4158
4159
4160
4161
4162 /*
4163 * Hack -- instantiate a trap
4164 *
4165 * XXX XXX XXX This routine should be redone to reflect trap "level".
4166 * That is, it does not make sense to have spiked pits at 50 feet.
4167 * Actually, it is not this routine, but the "trap instantiation"
4168 * code, which should also check for "trap doors" on quest levels.
4169 */
pick_trap(int Depth,int y,int x)4170 void pick_trap(int Depth, int y, int x)
4171 {
4172 int feat;
4173
4174 cave_type *c_ptr = &cave[Depth][y][x];
4175
4176 /* Paranoia */
4177 if (c_ptr->feat != FEAT_INVIS) return;
4178
4179 /* Pick a trap */
4180 while (1)
4181 {
4182 /* Hack -- pick a trap */
4183 feat = FEAT_TRAP_HEAD + randint0(16);
4184
4185 /* Hack -- no trap doors on quest levels */
4186 if ((feat == FEAT_TRAP_HEAD + 0x00) && is_quest(Depth)) continue;
4187
4188 /* Hack -- no trap doors on the deepest level */
4189 if ((feat == FEAT_TRAP_HEAD + 0x00) && (Depth >= MAX_DEPTH-1)) continue;
4190
4191 /* Done */
4192 break;
4193 }
4194
4195 /* Activate the trap */
4196 c_ptr->feat = feat;
4197
4198 /* Notice */
4199 note_spot_depth(Depth, y, x);
4200
4201 /* Redraw */
4202 everyone_lite_spot(Depth, y, x);
4203 }
4204
4205
4206
4207
4208 /*
4209 * Describe the charges on an item in the inventory.
4210 */
inven_item_charges(player_type * p_ptr,int item)4211 void inven_item_charges(player_type *p_ptr, int item)
4212 {
4213 object_type *o_ptr = &p_ptr->inventory[item];
4214
4215 /* Require staff/wand */
4216 if ((o_ptr->tval != TV_STAFF) && (o_ptr->tval != TV_WAND)) return;
4217
4218 /* Require known item */
4219 if (!object_known_p(p_ptr, o_ptr)) return;
4220
4221 /* Multiple charges */
4222 if (o_ptr->pval != 1)
4223 {
4224 /* Print a message */
4225 msg_format(p_ptr, "You have %d charges remaining.", o_ptr->pval);
4226 }
4227
4228 /* Single charge */
4229 else
4230 {
4231 /* Print a message */
4232 msg_format(p_ptr, "You have %d charge remaining.", o_ptr->pval);
4233 }
4234 }
4235
4236
4237 /*
4238 * Describe an item in the inventory.
4239 */
inven_item_describe(player_type * p_ptr,int item)4240 void inven_item_describe(player_type *p_ptr, int item)
4241 {
4242 object_type *o_ptr = &p_ptr->inventory[item];
4243
4244 char o_name[80];
4245
4246 /* Get a description */
4247 object_desc(p_ptr, o_name, sizeof(o_name), o_ptr, TRUE, 3);
4248
4249 /* Print a message */
4250 msg_format(p_ptr, "You have %s.", o_name);
4251 }
4252
4253
4254 /*
4255 * Increase the "number" of an item in the inventory
4256 */
inven_item_increase(player_type * p_ptr,int item,int num)4257 void inven_item_increase(player_type *p_ptr, int item, int num)
4258 {
4259 object_type *o_ptr = &p_ptr->inventory[item];
4260
4261 /* Apply */
4262 num += o_ptr->number;
4263
4264 /* Bounds check */
4265 if (num > 255) num = 255;
4266 else if (num < 0) num = 0;
4267
4268 /* Un-apply */
4269 num -= o_ptr->number;
4270
4271 /* Change the number and weight */
4272 if (num)
4273 {
4274 /* Add the number */
4275 o_ptr->number += num;
4276
4277 /* Add the weight */
4278 p_ptr->total_weight += (num * o_ptr->weight);
4279
4280 /* Recalculate bonuses */
4281 p_ptr->update |= (PU_BONUS);
4282
4283 /* Recalculate mana XXX */
4284 p_ptr->update |= (PU_MANA);
4285
4286 /* Combine the pack */
4287 p_ptr->notice |= (PN_COMBINE);
4288
4289 /* Window stuff */
4290 p_ptr->window |= (PW_PLAYER);
4291
4292 /* Redraw this slot */
4293 p_ptr->redraw_inven |= (1LL << item);
4294 }
4295
4296 /* Mega-hack! If an artifact was "decreased", forget ownership */
4297 if (true_artifact_p(o_ptr) && (num < 0))
4298 {
4299 a_info[o_ptr->name1].owner_name = 0;
4300 a_info[o_ptr->name1].owner_id = 0;
4301 }
4302
4303 /* Hack -- redraw fuel items */
4304 if ((item == INVEN_LITE) && (num < 0))
4305 {
4306 player_redraw_fuel_items(p_ptr);
4307 }
4308 }
4309
4310
4311 /*
4312 * Erase an inventory slot if it has no more items
4313 */
inven_item_optimize(player_type * p_ptr,int item)4314 void inven_item_optimize(player_type *p_ptr, int item)
4315 {
4316 object_type *o_ptr = &p_ptr->inventory[item];
4317
4318 /* Only optimize real items */
4319 if (!o_ptr->k_idx) return;
4320
4321 /* Only optimize empty items */
4322 if (o_ptr->number) return;
4323
4324 /* The item is in the pack */
4325 if (item < INVEN_WIELD)
4326 {
4327 int i;
4328
4329 /* One less item */
4330 p_ptr->inven_cnt--;
4331
4332 /* Slide everything down */
4333 for (i = item; i < INVEN_PACK; i++)
4334 {
4335 /* Structure copy */
4336 p_ptr->inventory[i] = p_ptr->inventory[i+1];
4337
4338 /* Slot changed */
4339 p_ptr->redraw_inven |= (1LL << i);
4340 }
4341
4342 /* Erase the "final" slot */
4343 invwipe(&p_ptr->inventory[i]);
4344
4345 /* Slot changed */
4346 p_ptr->redraw_inven |= (1LL << i);
4347 }
4348
4349 /* The item is being wielded */
4350 else
4351 {
4352 /* One less item */
4353 p_ptr->equip_cnt--;
4354
4355 /* Erase the empty slot */
4356 invwipe(&p_ptr->inventory[item]);
4357
4358 /* Redraw slot */
4359 p_ptr->redraw_inven |= (1LL << item);
4360
4361 /* Recalculate bonuses */
4362 p_ptr->update |= (PU_BONUS);
4363
4364 /* Recalculate torch */
4365 p_ptr->update |= (PU_TORCH);
4366
4367 /* Recalculate mana XXX */
4368 p_ptr->update |= (PU_MANA);
4369 }
4370
4371 /* Window stuff */
4372 p_ptr->window |= (PW_SPELL | PW_PLAYER);
4373 }
4374
4375
4376 /*
4377 * Describe the charges on an item on the floor.
4378 */
floor_item_charges(int item)4379 void floor_item_charges(int item)
4380 {
4381 object_type *o_ptr = &o_list[item];
4382
4383 /* Require staff/wand */
4384 if ((o_ptr->tval != TV_STAFF) && (o_ptr->tval != TV_WAND)) return;
4385
4386 /* Require known item */
4387 /*if (!object_known_p(o_ptr)) return;*/
4388
4389 /* Multiple charges */
4390 if (o_ptr->pval != 1)
4391 {
4392 /* Print a message */
4393 /*msg_format("There are %d charges remaining.", o_ptr->pval);*/
4394 }
4395
4396 /* Single charge */
4397 else
4398 {
4399 /* Print a message */
4400 /*msg_format("There is %d charge remaining.", o_ptr->pval);*/
4401 }
4402 }
4403
4404
4405
4406 /*
4407 * Describe an item in the inventory.
4408 */
floor_item_describe(int item)4409 void floor_item_describe(int item)
4410 {
4411 /* Get a description */
4412 /*object_desc(o_name, o_ptr, TRUE, 3);*/
4413
4414 /* Print a message */
4415 /*msg_format("You see %s.", o_name);*/
4416 }
4417
4418 /*
4419 * Inform player about item he is standing on
4420 */
floor_item_notify(player_type * p_ptr,s16b o_idx,bool force)4421 void floor_item_notify(player_type *p_ptr, s16b o_idx, bool force)
4422 {
4423 object_type *o_ptr;
4424 char o_name[80];
4425 char o_name_one[80];
4426 byte ga; char gc;
4427 byte attr;
4428 byte flag, secondary_tester;
4429 int i;
4430
4431 /* XXX HACK XXX -- find OTHER players who also see this item */
4432 if (o_idx) for (i = 1; i <= NumPlayers; i++)
4433 {
4434 if (Players[i]->dun_depth != p_ptr->dun_depth) continue;
4435 if (Players[i]->obj_vis[o_idx]) Players[i]->window |= (PW_ITEMLIST);
4436 }
4437
4438 if (!force && p_ptr->delta_floor_item == o_idx) return;
4439 p_ptr->delta_floor_item = o_idx;
4440
4441 if (o_idx)
4442 {
4443 o_ptr = &o_list[o_idx];
4444
4445 /* Pick color */
4446 attr = p_ptr->tval_attr[o_ptr->tval % 128];
4447 if (!option_p(p_ptr, USE_COLOR)) attr = TERM_WHITE;
4448
4449 /* Get a/c symbols */
4450 gc = object_char_p(p_ptr, o_ptr);
4451 ga = object_attr_p(p_ptr, o_ptr);
4452
4453 /* Describe the object */
4454 object_desc(p_ptr, o_name, sizeof(o_name) - 1, o_ptr, TRUE, 3);
4455 object_desc_one(p_ptr, o_name_one, sizeof(o_name) - 1, o_ptr, FALSE, 0);
4456 flag = object_tester_flag(p_ptr, o_ptr, &secondary_tester);
4457 send_floor(p_ptr, ga, gc, attr, o_ptr->number, o_ptr->tval, flag, secondary_tester, o_name, o_name_one);
4458 }
4459 else
4460 {
4461 send_floor(p_ptr, 0, 0, 0, 0, 0, 0, 0, "", "");
4462 }
4463 }
4464
4465 /*
4466 * Increase the "number" of an item on the floor
4467 */
floor_item_increase(int item,int num)4468 void floor_item_increase(int item, int num)
4469 {
4470 object_type *o_ptr = &o_list[item];
4471
4472 /* Apply */
4473 num += o_ptr->number;
4474
4475 /* Bounds check */
4476 if (num > 255) num = 255;
4477 else if (num < 0) num = 0;
4478
4479 /* Un-apply */
4480 num -= o_ptr->number;
4481
4482 /* Change the number */
4483 o_ptr->number += num;
4484 }
4485
4486
4487 /*
4488 * Optimize an item on the floor (destroy "empty" items)
4489 */
floor_item_optimize(int item)4490 void floor_item_optimize(int item)
4491 {
4492 object_type *o_ptr = &o_list[item];
4493
4494 /* Paranoia -- be sure it exists */
4495 if (!o_ptr->k_idx) return;
4496
4497 /* Only optimize empty items */
4498 if (o_ptr->number) return;
4499
4500 /* Delete it */
4501 delete_object_idx(item);
4502 }
4503
4504
4505 /*
4506 * Check if we're allowed to get rid of an item easily.
4507 */
inven_drop_okay(player_type * p_ptr,object_type * o_ptr)4508 bool inven_drop_okay(player_type *p_ptr, object_type *o_ptr)
4509 {
4510 /* Never drop artifacts above their base depth */
4511 if (true_artifact_p(o_ptr) && (p_ptr->dun_depth < a_info[o_ptr->name1].level))
4512 {
4513 /* Do not apply this rule to ironman and DMs */
4514 if (!cfg_ironman && !dm_flag_p(p_ptr,ARTIFACT_CONTROL))
4515 {
4516 return (FALSE);
4517 }
4518 }
4519 /* If you add more rules here, make sure dm_flag_p(p_ptr,OBJECT_CONTROL)
4520 * overrides them ... */
4521 return (TRUE);
4522 }
4523
4524
4525 /*
4526 * Check if we have space for an item in the pack without overflow
4527 */
inven_carry_okay(player_type * p_ptr,object_type * o_ptr)4528 bool inven_carry_okay(player_type *p_ptr, object_type *o_ptr)
4529 {
4530 int i;
4531
4532 /* Empty slot? */
4533 if (p_ptr->inven_cnt < INVEN_PACK) return (TRUE);
4534
4535 /* Similar slot? */
4536 for (i = 0; i < INVEN_PACK; i++)
4537 {
4538 /* Get that item */
4539 object_type *j_ptr = &p_ptr->inventory[i];
4540
4541 /* Check if the two items can be combined */
4542 if (object_similar(p_ptr, j_ptr, o_ptr)) return (TRUE);
4543 }
4544
4545 /* Nope */
4546 return (FALSE);
4547 }
4548
4549
4550 /*
4551 * Add an item to the players inventory, and return the slot used.
4552 *
4553 * If the new item can combine with an existing item in the inventory,
4554 * it will do so, using "object_similar()" and "object_absorb()", otherwise,
4555 * the item will be placed into the "proper" location in the inventory.
4556 *
4557 * This function can be used to "over-fill" the player's pack, but only
4558 * once, and such an action must trigger the "overflow" code immediately.
4559 * Note that when the pack is being "over-filled", the new item must be
4560 * placed into the "overflow" slot, and the "overflow" must take place
4561 * before the pack is reordered, but (optionally) after the pack is
4562 * combined. This may be tricky. See "dungeon.c" for info.
4563 */
inven_carry(player_type * p_ptr,object_type * o_ptr)4564 s16b inven_carry(player_type *p_ptr, object_type *o_ptr)
4565 {
4566 int i, j, k;
4567 int n = -1;
4568
4569 object_type *j_ptr;
4570
4571 /* Hack -- change ownee! */
4572 object_own(p_ptr, o_ptr);
4573
4574 /* Check for combining */
4575 for (j = 0; j < INVEN_PACK; j++)
4576 {
4577 j_ptr = &p_ptr->inventory[j];
4578
4579 /* Skip empty items */
4580 if (!j_ptr->k_idx) continue;
4581
4582 /* Hack -- track last item */
4583 n = j;
4584
4585 /* Check if the two items can be combined */
4586 if (object_similar(p_ptr, j_ptr, o_ptr))
4587 {
4588 /* Combine the items */
4589 object_absorb(p_ptr, j_ptr, o_ptr);
4590
4591 /* Increase the weight */
4592 p_ptr->total_weight += (o_ptr->number * o_ptr->weight);
4593
4594 /* Recalculate bonuses */
4595 p_ptr->update |= (PU_BONUS);
4596
4597 /* Redraw slot */
4598 p_ptr->redraw_inven |= (1LL << j);
4599
4600 /* Window stuff */
4601 p_ptr->window |= (PW_SPELL | PW_PLAYER);
4602
4603 /* Success */
4604 return (j);
4605 }
4606 }
4607
4608
4609 /* Paranoia */
4610 if (p_ptr->inven_cnt > INVEN_PACK) return (-1);
4611
4612
4613 /* Find an empty slot */
4614 for (j = 0; j <= INVEN_PACK; j++)
4615 {
4616 j_ptr = &p_ptr->inventory[j];
4617
4618 /* Use it if found */
4619 if (!j_ptr->k_idx) break;
4620 }
4621
4622 /* Use that slot */
4623 i = j;
4624
4625
4626 /* Hack -- pre-reorder the pack */
4627 if (i < INVEN_PACK)
4628 {
4629 s32b o_value, j_value;
4630
4631 /* Get the "value" of the item */
4632 o_value = object_value(p_ptr, o_ptr);
4633
4634 /* Scan every occupied slot */
4635 for (j = 0; j < INVEN_PACK; j++)
4636 {
4637 j_ptr = &p_ptr->inventory[j];
4638
4639 /* Use empty slots */
4640 if (!j_ptr->k_idx) break;
4641
4642 /* Hack -- readable books always come first */
4643 if ((o_ptr->tval == p_ptr->cp_ptr->spell_book) &&
4644 (j_ptr->tval != p_ptr->cp_ptr->spell_book)) break;
4645 if ((j_ptr->tval == p_ptr->cp_ptr->spell_book) &&
4646 (o_ptr->tval != p_ptr->cp_ptr->spell_book)) continue;
4647
4648 /* Objects sort by decreasing type */
4649 if (o_ptr->tval > j_ptr->tval) break;
4650 if (o_ptr->tval < j_ptr->tval) continue;
4651
4652 /* Non-aware (flavored) items always come last */
4653 if (!object_aware_p(p_ptr, o_ptr)) continue;
4654 if (!object_aware_p(p_ptr, j_ptr)) break;
4655
4656 /* Objects sort by increasing sval */
4657 if (o_ptr->sval < j_ptr->sval) break;
4658 if (o_ptr->sval > j_ptr->sval) continue;
4659
4660 /* Unidentified objects always come last */
4661 if (!object_known_p(p_ptr, o_ptr)) continue;
4662 if (!object_known_p(p_ptr, j_ptr)) break;
4663
4664 /* Determine the "value" of the pack item */
4665 j_value = object_value(p_ptr, j_ptr);
4666
4667 /* Objects sort by decreasing value */
4668 if (o_value > j_value) break;
4669 if (o_value < j_value) continue;
4670 }
4671
4672 /* Use that slot */
4673 i = j;
4674
4675 /* Structure slide (make room) */
4676 for (k = n; k >= i; k--)
4677 {
4678 /* Hack -- Slide the item */
4679 p_ptr->inventory[k+1] = p_ptr->inventory[k];
4680
4681 /* Redraw this slot */
4682 p_ptr->redraw_inven |= (1LL << (k+1));
4683 }
4684
4685 /* Paranoia -- Wipe the new slot */
4686 invwipe(&p_ptr->inventory[i]);
4687
4688 /* Redraw this slot */
4689 p_ptr->redraw_inven |= (1LL << i);
4690 }
4691
4692
4693 /* Structure copy to insert the new item */
4694 p_ptr->inventory[i] = (*o_ptr);
4695
4696 /* Forget monster */
4697 p_ptr->inventory[i].held_m_idx = 0;
4698
4699 /* Forget the old location */
4700 p_ptr->inventory[i].iy = p_ptr->inventory[i].ix = p_ptr->inventory[i].dun_depth = 0;
4701
4702 /* Increase the weight, prepare to redraw */
4703 p_ptr->total_weight += (o_ptr->number * o_ptr->weight);
4704
4705 /* Count the items */
4706 p_ptr->inven_cnt++;
4707
4708 /* Recalculate bonuses */
4709 p_ptr->update |= (PU_BONUS);
4710
4711 /* Reorder pack */
4712 p_ptr->notice |= (PN_REORDER);
4713
4714 /* Window stuff */
4715 p_ptr->window |= (PW_SPELL | PW_PLAYER);
4716
4717 /* Redraw slot */
4718 p_ptr->redraw_inven |= (1LL << i);
4719
4720 /* Return the slot */
4721 return (i);
4722 }
4723
4724
4725
4726
4727 /*
4728 * Combine items in the pack
4729 *
4730 * Note special handling of the "overflow" slot
4731 */
combine_pack(player_type * p_ptr)4732 void combine_pack(player_type *p_ptr)
4733 {
4734 int i, j, k;
4735
4736 object_type *o_ptr;
4737 object_type *j_ptr;
4738
4739 bool flag = FALSE;
4740
4741
4742 /* Combine the pack (backwards) */
4743 for (i = INVEN_PACK; i > 0; i--)
4744 {
4745 /* Get the item */
4746 o_ptr = &p_ptr->inventory[i];
4747
4748 /* Skip empty items */
4749 if (!o_ptr->k_idx) continue;
4750
4751 /* Scan the items above that item */
4752 for (j = 0; j < i; j++)
4753 {
4754 /* Get the item */
4755 j_ptr = &p_ptr->inventory[j];
4756
4757 /* Skip empty items */
4758 if (!j_ptr->k_idx) continue;
4759
4760 /* Can we drop "o_ptr" onto "j_ptr"? */
4761 if (object_similar(p_ptr, j_ptr, o_ptr))
4762 {
4763 /* Take note */
4764 flag = TRUE;
4765
4766 /* Add together the item counts */
4767 object_absorb(p_ptr, j_ptr, o_ptr);
4768
4769 /* One object is gone */
4770 p_ptr->inven_cnt--;
4771
4772 /* Slide everything down */
4773 for (k = i; k < INVEN_PACK; k++)
4774 {
4775 /* Structure copy */
4776 p_ptr->inventory[k] = p_ptr->inventory[k+1];
4777
4778 /* Redraw slot */
4779 p_ptr->redraw_inven |= (1LL << k);
4780 }
4781
4782 /* Erase the "final" slot */
4783 invwipe(&p_ptr->inventory[k]);
4784
4785 /* Redraw slot */
4786 p_ptr->redraw_inven |= (1LL << k);
4787
4788 /* Window stuff */
4789 p_ptr->window |= (PW_SPELL);
4790
4791 /* Done */
4792 break;
4793 }
4794 }
4795 }
4796
4797 /* Message */
4798 if (flag) msg_print(p_ptr, "You combine some items in your pack.");
4799 }
4800
4801
4802 /*
4803 * Reorder items in the pack
4804 *
4805 * Note special handling of the "overflow" slot
4806 *
4807 * Note special handling of empty slots XXX XXX XXX XXX
4808 */
reorder_pack(player_type * p_ptr)4809 void reorder_pack(player_type *p_ptr)
4810 {
4811 int i, j, k;
4812
4813 s32b o_value;
4814 s32b j_value;
4815
4816 object_type *o_ptr;
4817 object_type *j_ptr;
4818
4819 object_type temp;
4820
4821 bool flag = FALSE;
4822
4823
4824 /* Re-order the pack (forwards) */
4825 for (i = 0; i < INVEN_PACK; i++)
4826 {
4827 /* Mega-Hack -- allow "proper" over-flow */
4828 if ((i == INVEN_PACK) && (p_ptr->inven_cnt == INVEN_PACK)) break;
4829
4830 /* Get the item */
4831 o_ptr = &p_ptr->inventory[i];
4832
4833 /* Skip empty slots */
4834 if (!o_ptr->k_idx) continue;
4835
4836 /* Get the "value" of the item */
4837 o_value = object_value(p_ptr, o_ptr);
4838
4839 /* Scan every occupied slot */
4840 for (j = 0; j < INVEN_PACK; j++)
4841 {
4842 /* Get the item already there */
4843 j_ptr = &p_ptr->inventory[j];
4844
4845 /* Use empty slots */
4846 if (!j_ptr->k_idx) break;
4847
4848 /* Hack -- readable books always come first */
4849 if ((o_ptr->tval == p_ptr->cp_ptr->spell_book) &&
4850 (j_ptr->tval != p_ptr->cp_ptr->spell_book)) break;
4851 if ((j_ptr->tval == p_ptr->cp_ptr->spell_book) &&
4852 (o_ptr->tval != p_ptr->cp_ptr->spell_book)) continue;
4853
4854 /* Objects sort by decreasing type */
4855 if (o_ptr->tval > j_ptr->tval) break;
4856 if (o_ptr->tval < j_ptr->tval) continue;
4857
4858 /* Non-aware (flavored) items always come last */
4859 if (!object_aware_p(p_ptr, o_ptr)) continue;
4860 if (!object_aware_p(p_ptr, j_ptr)) break;
4861
4862 /* Objects sort by increasing sval */
4863 if (o_ptr->sval < j_ptr->sval) break;
4864 if (o_ptr->sval > j_ptr->sval) continue;
4865
4866 /* Unidentified objects always come last */
4867 if (!object_known_p(p_ptr, o_ptr)) continue;
4868 if (!object_known_p(p_ptr, j_ptr)) break;
4869
4870 /* Determine the "value" of the pack item */
4871 j_value = object_value(p_ptr, j_ptr);
4872
4873 /* Objects sort by decreasing value */
4874 if (o_value > j_value) break;
4875 if (o_value < j_value) continue;
4876 }
4877
4878 /* Never move down */
4879 if (j >= i) continue;
4880
4881 /* Take note */
4882 flag = TRUE;
4883
4884 /* Save the moving item */
4885 temp = p_ptr->inventory[i];
4886
4887 /* Structure slide (make room) */
4888 for (k = i; k > j; k--)
4889 {
4890 /* Slide the item */
4891 p_ptr->inventory[k] = p_ptr->inventory[k-1];
4892
4893 /* Redraw slot */
4894 p_ptr->redraw_inven |= (1LL << k);
4895 }
4896
4897 /* Insert the moved item */
4898 p_ptr->inventory[j] = temp;
4899
4900 /* Redraw slot */
4901 p_ptr->redraw_inven |= (1LL << j);
4902 }
4903
4904 /* Message */
4905 if (flag) msg_print(p_ptr, "You reorder some items in your pack.");
4906 }
4907
4908
4909 /*
4910 * Hack -- find out if a player is standing on an object "o_idx", and redraw
4911 * the floor info. We also update PW_ITEMLIST for each player who is tracking
4912 * this object.
4913 */
notify_player_standing_on(int o_idx)4914 static void notify_player_standing_on(int o_idx)
4915 {
4916 player_type *p_ptr;
4917 object_type *o_ptr;
4918 int Depth, y, x;
4919 int Ind;
4920
4921 /* Get the object */
4922 o_ptr = &o_list[o_idx];
4923
4924 /* Get location */
4925 Depth = o_ptr->dun_depth;
4926 y = o_ptr->iy;
4927 x = o_ptr->ix;
4928
4929 /* Unallocated cave? */
4930 if (!cave[Depth]) return;
4931
4932 /* Get the player standing here */
4933 p_ptr = player_on_cave(Depth, y, x);
4934 if (p_ptr)
4935 {
4936 /* Let's schedule floor redraw */
4937 p_ptr->redraw |= (PR_FLOOR);
4938 }
4939
4940 /* Hack -- also update itemlist for ALL players */
4941 for (Ind = 1; Ind <= NumPlayers; Ind++)
4942 {
4943 p_ptr = Players[Ind];
4944 if (p_ptr->obj_vis[o_idx]) p_ptr->window |= (PW_ITEMLIST);
4945 }
4946 }
4947
4948 /*
4949 * Hack -- process the objects
4950 */
process_objects(void)4951 void process_objects(void)
4952 {
4953 int i, k;
4954
4955 object_type *o_ptr;
4956
4957
4958 /* Hack -- only every ten game turns */
4959 if ((turn.turn % 10) != 5) return;
4960
4961
4962 /* Process objects */
4963 for (k = o_top - 1; k >= 0; k--)
4964 {
4965 /* Access index */
4966 i = o_fast[k];
4967
4968 /* Access object */
4969 o_ptr = &o_list[i];
4970
4971 /* Excise dead objects */
4972 if (!o_ptr->k_idx)
4973 {
4974 /* Excise it */
4975 o_fast[k] = o_fast[--o_top];
4976
4977 /* Skip */
4978 continue;
4979 }
4980
4981 /* Recharge rods on the ground */
4982 if ((o_ptr->tval == TV_ROD) && (o_ptr->timeout))
4983 {
4984 /* Charge it (charge ALL rods) */
4985 /* Note: this is the behavior in vanilla Angband 3.0.9 */
4986 o_ptr->timeout -= o_ptr->number;
4987
4988 /* Alternate code */
4989 /* Only charging rods should recharge (same as charging from the inventory) */
4990 /*object_kind* k_ptr = &k_info[o_ptr->k_idx];
4991 int temp = (o_ptr->timeout + (k_ptr->pval - 1)) / k_ptr->pval;
4992 if (temp > o_ptr->number) temp = o_ptr->number;
4993 o_ptr->timeout -= temp;*/
4994
4995 /* Boundary control */
4996 if (o_ptr->timeout < 0) o_ptr->timeout = 0;
4997
4998 /* Notify player standing on top of that item */
4999 notify_player_standing_on(i);
5000 }
5001 }
5002
5003
5004 #ifdef SHIMMER_OBJECTS
5005
5006 #if 0
5007 /* Optimize */
5008 if (!avoid_other && scan_objects)
5009 {
5010 /* Process the objects */
5011 for (i = 1; i < o_max; i++)
5012 {
5013 o_ptr = &o_list[i];
5014
5015 /* Skip dead objects */
5016 if (!o_ptr->k_idx) continue;
5017
5018 /* XXX XXX XXX Skip unseen objects */
5019
5020 /* Shimmer Multi-Hued Objects XXX XXX XXX */
5021 lite_spot(o_ptr->iy, o_ptr->ix);
5022 }
5023
5024 /* Clear the flag */
5025 scan_objects = FALSE;
5026 }
5027 #endif
5028
5029 #endif
5030
5031 }
5032
5033 /*
5034 * Set the "o_idx" fields in the cave array to correspond
5035 * to the objects in the "o_list".
5036 */
setup_objects(void)5037 void setup_objects(void)
5038 {
5039 int i;
5040
5041 for (i = 1; i < o_max; i++)
5042 {
5043 object_type *o_ptr = &o_list[i];
5044
5045 /* Skip dead objects */
5046 if (!o_ptr->k_idx) continue;
5047
5048 /* Skip objects on depths that aren't allocated */
5049 if (!cave[o_ptr->dun_depth]) continue;
5050
5051 /* Set the o_idx correctly */
5052 cave[o_ptr->dun_depth][o_ptr->iy][o_ptr->ix].o_idx = i;
5053 }
5054 }
5055
5056
5057
5058 /* Takes a (partial) item_kind name and returns an index, or 0 if no match
5059 * was found.
5060 */
item_kind_index_fuzzy(char * name)5061 int item_kind_index_fuzzy(char * name)
5062 {
5063 char match[MAX_CHARS];
5064 char* str;
5065 char* dst;
5066 int i;
5067
5068 /* Lowercase our search string */
5069 for(str=name;*str;str++) *str=tolower(*str);
5070
5071 /* for each item kind race */
5072 for (i = 1; i <= z_info->k_max; i++)
5073 {
5074 /* Clean up it's name */
5075 dst = match;
5076 for(str=(k_name + k_info[i].name);*str;str++)
5077 {
5078 if (isalpha(*str) || *str==32) *dst++ = tolower(*str);
5079 }
5080 *dst++ = '\0';
5081 /* If cleaned name matches our search string, return it */
5082 if (strstr(match,name)) { return i; }
5083 }
5084 return 0;
5085 }
5086
5087
5088 /* Takes a (partial) item ego name and returns an index, or 0 if no match
5089 * was found.
5090 */
ego_kind_index_fuzzy(char * name)5091 int ego_kind_index_fuzzy(char * name)
5092 {
5093 char match[MAX_CHARS];
5094 char* str;
5095 char* dst;
5096 int i;
5097
5098 /* Lowercase our search string */
5099 for(str=name;*str;str++) *str=tolower(*str);
5100
5101 /* for each ego kind race */
5102 for (i = 1; i <= z_info->e_max; i++)
5103 {
5104 /* Clean up it's name */
5105 dst = match;
5106 for(str=(e_name + e_info[i].name);*str;str++)
5107 {
5108 if (isalpha(*str) || *str==32) *dst++ = tolower(*str);
5109 }
5110 *dst++ = '\0';
5111 /* If cleaned name matches our search string, return it */
5112 if (strstr(match,name)) return i;
5113 }
5114 return 0;
5115 }
5116
5117 /*
5118 * Distribute charges of rods, staves, or wands.
5119 *
5120 * o_ptr = source item
5121 * q_ptr = target item, must be of the same type as o_ptr
5122 * amt = number of items that are transfered
5123 */
distribute_charges(object_type * o_ptr,object_type * q_ptr,int amt)5124 void distribute_charges(object_type *o_ptr, object_type *q_ptr, int amt)
5125 {
5126 /*
5127 * Hack -- If rods, staves, or wands are dropped, the total maximum
5128 * timeout or charges need to be allocated between the two stacks.
5129 * If all the items are being dropped, it makes for a neater message
5130 * to leave the original stack's pval alone. -LM-
5131 */
5132 if ((o_ptr->tval == TV_WAND) ||
5133 (o_ptr->tval == TV_STAFF) ||
5134 (o_ptr->tval == TV_ROD))
5135 {
5136 q_ptr->pval = o_ptr->pval * amt / o_ptr->number;
5137
5138 if (amt < o_ptr->number) o_ptr->pval -= q_ptr->pval;
5139
5140 /*
5141 * Hack -- Rods also need to have their timeouts distributed.
5142 *
5143 * The dropped stack will accept all time remaining to charge up to
5144 * its maximum.
5145 */
5146 if ((o_ptr->tval == TV_ROD) && (o_ptr->timeout))
5147 {
5148 if (q_ptr->pval > o_ptr->timeout)
5149 q_ptr->timeout = o_ptr->timeout;
5150 else
5151 q_ptr->timeout = q_ptr->pval;
5152
5153 if (amt < o_ptr->number)
5154 o_ptr->timeout -= q_ptr->timeout;
5155 }
5156 }
5157 }
5158
5159
reduce_charges(object_type * o_ptr,int amt)5160 void reduce_charges(object_type *o_ptr, int amt)
5161 {
5162 /*
5163 * Hack -- If rods or wand are destroyed, the total maximum timeout or
5164 * charges of the stack needs to be reduced, unless all the items are
5165 * being destroyed. -LM-
5166 */
5167 if (((o_ptr->tval == TV_WAND) ||
5168 (o_ptr->tval == TV_STAFF) ||
5169 (o_ptr->tval == TV_ROD)) &&
5170 (amt < o_ptr->number))
5171 {
5172 o_ptr->pval -= o_ptr->pval * amt / o_ptr->number;
5173 }
5174 }
5175
artifact_notify(player_type * p_ptr,object_type * o_ptr)5176 void artifact_notify(player_type *p_ptr, object_type *o_ptr)
5177 {
5178 /* If this is the first time, log it */
5179 if (p_ptr->a_info[o_ptr->name1] == ARTS_NOT_FOUND)
5180 {
5181 char o_name[80];
5182 char buf[80];
5183 object_desc(NULL, o_name, sizeof(o_name), o_ptr, FALSE, 0);
5184 sprintf(buf, "Found The %s", o_name);
5185 log_history_event(p_ptr, buf, TRUE);
5186
5187 /* Mark artifact as found */
5188 set_artifact_p(p_ptr, o_ptr->name1, ARTS_FOUND);
5189 }
5190 }
5191
object_audit(player_type * p_ptr,object_type * o_ptr,int number)5192 void object_audit(player_type *p_ptr, object_type *o_ptr, int number)
5193 {
5194 if (o_ptr->owner_id && o_ptr->owner_id != p_ptr->id)
5195 {
5196 char o_name[80];
5197 char buf[512];
5198 /* Create the object copy (structure copy)
5199 object_type temp_obj;
5200 if (o_ptr->number != number)
5201 {
5202 object_copy(&temp_obj, o_ptr);
5203 o_ptr = &temp_obj;
5204 o_ptr->number = number;
5205 }
5206 */ /* ^ - no need (yet), we cam just temp-adjust number */
5207 int actual_number = o_ptr->number;
5208 o_ptr->number = number;
5209
5210 /* Log transaction */
5211 sprintf(buf,"TR %s-%ld | %s-%ld $ %ld",
5212 quark_str(o_ptr->owner_name), (long)o_ptr->owner_id,
5213 p_ptr->name, (long)p_ptr->id, (long)object_value(p_ptr, o_ptr) * number);
5214 audit(buf);
5215 /* Object name */
5216 object_desc(NULL, o_name, sizeof(o_name), o_ptr, TRUE, 3);
5217 sprintf(buf,"TR+%s", o_name);
5218 audit(buf);
5219
5220 /* Restore real number */
5221 o_ptr->number = actual_number;
5222 }
5223 }
5224
object_own(player_type * p_ptr,object_type * o_ptr)5225 void object_own(player_type *p_ptr, object_type *o_ptr)
5226 {
5227 /* Log ownership change */
5228 object_audit(p_ptr, o_ptr, o_ptr->number);
5229
5230 /* Handle artifacts */
5231 if (true_artifact_p(o_ptr) && object_known_p(p_ptr, o_ptr))
5232 {
5233 artifact_notify(p_ptr, o_ptr);
5234 }
5235
5236 /* Store artifact owner */
5237 if (true_artifact_p(o_ptr))
5238 {
5239 artifact_type *a_ptr = &a_info[o_ptr->name1];
5240 a_ptr->owner_id = p_ptr->id;
5241 a_ptr->owner_name = quark_add(p_ptr->name);
5242 }
5243
5244 /* Set original owner ONCE */
5245 if (o_ptr->origin_player == 0)
5246 {
5247 o_ptr->origin_player = quark_add(p_ptr->name);
5248 }
5249
5250 /* Set new owner */
5251 o_ptr->owner_id = p_ptr->id;
5252 o_ptr->owner_name = quark_add(p_ptr->name);
5253 }
5254
5255 /* Return pointer to a floor object, if any, or NULL */
player_get_floor_item(player_type * p_ptr,int * idx)5256 object_type* player_get_floor_item(player_type *p_ptr, int *idx)
5257 {
5258 object_type *o_ptr = NULL;
5259 int o_idx;
5260
5261 o_idx = cave[p_ptr->dun_depth][p_ptr->py][p_ptr->px].o_idx;
5262 if (o_idx > 0)
5263 {
5264 *idx = 0 - o_idx;
5265 o_ptr = &o_list[o_idx];
5266 }
5267
5268 return o_ptr;
5269 }
5270
5271 /*
5272 * Select an item from an index provided by Player.
5273 *
5274 * Note: this function DOES test with item_tester_*
5275 * framework.
5276 *
5277 * Note: if a floor item has been selected, "idx" is changed
5278 * to reflect it's "o_list" index. For inven/equip items, "idx"
5279 * is undefined.
5280 *
5281 */
player_get_item(player_type * p_ptr,int item,int * idx)5282 object_type* player_get_item(player_type *p_ptr, int item, int *idx)
5283 {
5284 object_type *o_ptr = NULL;
5285 int o_idx;
5286
5287 /* Get the item (in the pack) */
5288 if (item >= 0 && item < INVEN_TOTAL)
5289 {
5290 o_ptr = &p_ptr->inventory[item];
5291 }
5292
5293 /* Get the item (on the floor) */
5294 else
5295 {
5296 o_idx = cave[p_ptr->dun_depth][p_ptr->py][p_ptr->px].o_idx;
5297 if (o_idx == 0)
5298 {
5299 msg_print(p_ptr, "There is nothing on the floor.");
5300 return NULL;
5301 }
5302 o_ptr = &o_list[o_idx];
5303
5304 /* HACK -- invert value */
5305 *idx = 0 - o_idx;
5306 }
5307
5308 /* Perform item test */
5309 if (!item_tester_okay(o_ptr))
5310 {
5311 return NULL;
5312 }
5313
5314 return o_ptr;
5315 }
5316
5317 /* Schedule network update for indexed item.
5318 * If "item" is < 0, we treat it as an o_list[] index.
5319 * If "item" is >= 0, we treat it as an inventory[] slot index. */
player_redraw_item(player_type * p_ptr,int item)5320 void player_redraw_item(player_type *p_ptr, int item)
5321 {
5322 /* Inven/equip */
5323 if (item >= 0) p_ptr->redraw_inven |= (1LL << item);
5324 /* Floor */
5325 else p_ptr->redraw |= (PR_FLOOR);
5326 }
5327
5328 /* After changing the lightsource from torch to lantern,
5329 * update all flags for fuel objects. */
player_redraw_fuel_items(player_type * p_ptr)5330 void player_redraw_fuel_items(player_type *p_ptr)
5331 {
5332 object_type *o_ptr;
5333 bool fits;
5334 int item;
5335 /* Inventory */
5336 for (item = 0; item < INVEN_WIELD; item++)
5337 {
5338 o_ptr = &p_ptr->inventory[item];
5339 if (object_is_fuel(p_ptr, o_ptr, &fits))
5340 {
5341 player_redraw_item(p_ptr, item);
5342 }
5343 }
5344 /* And the floor object */
5345 if ((o_ptr = player_get_floor_item(p_ptr, &item)))
5346 {
5347 if (object_is_fuel(p_ptr, o_ptr, &fits))
5348 {
5349 player_redraw_item(p_ptr, FLOOR_INDEX);
5350 }
5351 }
5352 }
5353
5354 /*
5355 * Get the indexes of objects at a given floor location. -TNB-
5356 *
5357 * Return the number of object indexes acquired.
5358 *
5359 * Valid flags are any combination of the bits:
5360 * 0x01 -- Verify item tester
5361 * 0x02 -- Marked/visible items only
5362 * 0x04 -- Only the top item
5363 */
scan_floor(player_type * p_ptr,int * items,int max_size,int y,int x,int mode)5364 int scan_floor(player_type *p_ptr, int *items, int max_size, int y, int x, int mode)
5365 {
5366 int this_o_idx, next_o_idx;
5367
5368 int num = 0;
5369
5370 int Depth = p_ptr->dun_depth;
5371
5372 /* Sanity */
5373 if (!in_bounds(p_ptr->dun_depth, y, x)) return 0;
5374
5375
5376 /* Scan all objects in the grid */
5377 for (this_o_idx = cave[Depth][y][x].o_idx; this_o_idx; this_o_idx = next_o_idx)
5378 {
5379 object_type *o_ptr;
5380
5381 /* XXX Hack -- Enforce limit */
5382 if (num >= max_size) break;
5383
5384
5385 /* Get the object */
5386 o_ptr = &o_list[this_o_idx];
5387
5388 /* Get the next object */
5389 next_o_idx = o_ptr->next_o_idx;
5390
5391 /* Item tester */
5392 if ((mode & 0x01) && !item_tester_okay(o_ptr)) continue;
5393
5394 #if 0 /* We don't support squelch */
5395 /* Marked */
5396 if ((mode & 0x02) && (!o_ptr->marked || squelch_hide_item(o_ptr)))
5397 continue;
5398 #else
5399 /* MAngband-specific: squelch/mode 0x02 alternative */
5400 if ((mode & 0x02) && !(p_ptr->obj_vis[this_o_idx])) continue;
5401 #endif
5402
5403 /* Accept this item */
5404 items[num++] = this_o_idx;
5405
5406 /* Only one */
5407 if (mode & 0x04) break;
5408 }
5409
5410 return num;
5411 }
5412
5413
5414
5415 /**
5416 * Sort comparator for objects using only tval and sval.
5417 * -1 if o1 should be first
5418 * 1 if o2 should be first
5419 * 0 if it doesn't matter
5420 */
compare_types(const object_type * o1,const object_type * o2)5421 static int compare_types(const object_type *o1, const object_type *o2)
5422 {
5423 if (o1->tval == o2->tval)
5424 return CMP(o1->sval, o2->sval);
5425 else
5426 return CMP(o1->tval, o2->tval);
5427 }
5428
5429 /* some handy macros for sorting */
5430 #define object_is_known_artifact(p_ptr, o) (artifact_p(o) && object_known_p(p_ptr, o))
5431 #define object_is_worthless(p_ptr, o) (object_value(p_ptr, o/*, 1*/) == 0)
5432
5433 /**
5434 * Sort comparator for objects
5435 * -1 if o1 should be first
5436 * 1 if o2 should be first
5437 * 0 if it doesn't matter
5438 *
5439 * The sort order is designed with the "list items" command in mind.
5440 */
compare_items(player_type * p_ptr,const object_type * o1,const object_type * o2)5441 static int compare_items(player_type *p_ptr, const object_type *o1, const object_type *o2)
5442 {
5443 /* known artifacts will sort first */
5444 if (object_is_known_artifact(p_ptr, o1) && object_is_known_artifact(p_ptr, o2))
5445 return compare_types(o1, o2);
5446 if (object_is_known_artifact(p_ptr, o1)) return -1;
5447 if (object_is_known_artifact(p_ptr, o2)) return 1;
5448
5449 /* unknown objects will sort next */
5450 if (!object_aware_p(p_ptr, o1) && !object_aware_p(p_ptr, o2))
5451 return compare_types(o1, o2);
5452 if (!object_aware_p(p_ptr, o1)) return -1;
5453 if (!object_aware_p(p_ptr, o2)) return 1;
5454
5455 /* if only one of them is worthless, the other comes first */
5456 if (object_is_worthless(p_ptr, (object_type*)o1) && !object_is_worthless(p_ptr, (object_type*)o2)) return 1;
5457 if (!object_is_worthless(p_ptr, (object_type*)o1) && object_is_worthless(p_ptr, (object_type*)o2)) return -1;
5458
5459 /* otherwise, just compare tvals and svals */
5460 /* NOTE: arguably there could be a better order than this */
5461 return compare_types(o1, o2);
5462 }
5463
5464 /* Prepare some fake objects */
5465 #define MAX_FAKE_OBJECTS 8
scan_floor_mimics(player_type * p_ptr,int y,int x,int * dst,object_type * o_ptr,int * cnt)5466 int scan_floor_mimics(player_type *p_ptr, int y, int x, int *dst, object_type *o_ptr, int *cnt)
5467 {
5468 int Depth = p_ptr->dun_depth;
5469 if (!cave[Depth]) return 0;
5470 if (cave[Depth][y][x].m_idx > 0)
5471 {
5472 monster_type *m_ptr = &m_list[cave[Depth][y][x].m_idx];
5473 if (m_ptr->mimic_k_idx)
5474 {
5475 invwipe(&o_ptr[*cnt]);
5476 invcopy(&o_ptr[*cnt], m_ptr->mimic_k_idx);
5477 (*cnt)+=1;
5478 *dst = -(*cnt);
5479 return 1;
5480 }
5481 }
5482 return 0;
5483 }
5484
5485 /* Forward-compatibility with V310b */
5486 #define ODESC_FULL 2
5487 #define squelch_item_ok(O_PTR) FALSE
5488
5489 /*
5490 * Display visible items, similar to display_monlist
5491 */
display_itemlist(player_type * p_ptr)5492 void display_itemlist(player_type *p_ptr)
5493 {
5494 int max;
5495 int mx, my;
5496 unsigned num;
5497 int line = 1, x = 0;
5498 int cur_x;
5499 unsigned i;
5500 unsigned disp_count = 0;
5501 byte a;
5502 char c;
5503
5504 object_type *types[MAX_ITEMLIST];
5505 int counts[MAX_ITEMLIST];
5506 unsigned counter = 0;
5507
5508 int dungeon_hgt = MAX_HGT; /*p_ptr->depth == 0 ? TOWN_HGT : DUNGEON_HGT;*/
5509 int dungeon_wid = MAX_WID; /*p_ptr->depth == 0 ? TOWN_WID : DUNGEON_WID;*/
5510
5511 byte attr;
5512 char buf[80];
5513
5514 int floor_list[MAX_FLOOR_STACK + 1]; /* +1 for mimics */
5515 object_type fake_objects[8]; /* Allow up to 8 mimics */
5516 int mimic_hack = 0;
5517
5518 /* Begin */
5519 text_out_init(p_ptr);
5520
5521 /* Look at each square of the dungeon for items */
5522 for (my = 0; my < dungeon_hgt; my++)
5523 {
5524 for (mx = 0; mx < dungeon_wid; mx++)
5525 {
5526 num = scan_floor(p_ptr, floor_list, MAX_FLOOR_STACK, my, mx, 0x02);
5527
5528 /* Hack -- also add mimics (can't trick the DM, though)*/
5529 if (mimic_hack < 8 && !(p_ptr->dm_flags & DM_SEE_MONSTERS))
5530 num += scan_floor_mimics(p_ptr, my, mx, &floor_list[num], fake_objects, &mimic_hack);
5531
5532 /* Iterate over all the items found on this square */
5533 for (i = 0; i < num; i++)
5534 {
5535 object_type *o_ptr;
5536 unsigned j;
5537
5538 if (floor_list[i] < 0)
5539 { printf("Use fake object: [%d]-> %d\n",floor_list[i], 0 - floor_list[i] - 1);
5540 o_ptr = &fake_objects[0 - floor_list[i] - 1];
5541 }
5542 else
5543 o_ptr = &o_list[floor_list[i]];
5544
5545 /* Skip gold/squelched */
5546 if (o_ptr->tval == TV_GOLD || squelch_item_ok(o_ptr))
5547 continue;
5548
5549 /* See if we've already seen a similar item; if so, just add */
5550 /* to its count */
5551 for (j = 0; j < counter; j++)
5552 {
5553 if (object_similar(p_ptr, o_ptr, types[j]))
5554 {
5555 counts[j] += o_ptr->number;
5556 break;
5557 }
5558 }
5559
5560 /* We saw a new item. So insert it at the end of the list and */
5561 /* then sort it forward using compare_items(). The types list */
5562 /* is always kept sorted. */
5563 if (j == counter)
5564 {
5565 types[counter] = o_ptr;
5566 counts[counter] = o_ptr->number;
5567
5568 while (j > 0 && compare_items(p_ptr, types[j - 1], types[j]) > 0)
5569 {
5570 object_type *tmp_o = types[j - 1];
5571 int tmpcount;
5572
5573 types[j - 1] = types[j];
5574 types[j] = tmp_o;
5575 tmpcount = counts[j - 1];
5576 counts[j - 1] = counts[j];
5577 counts[j] = tmpcount;
5578 j--;
5579 }
5580 counter++;
5581 /* Problem: we're out of stack space */
5582 if (counter >= MAX_ITEMLIST - 1) break;
5583 }
5584 /* long breakout */
5585 if (counter >= MAX_ITEMLIST - 1) break;
5586 }
5587 /* long breakout */
5588 if (counter >= MAX_ITEMLIST - 1) break;
5589 }
5590 /* long breakout */
5591 if (counter >= MAX_ITEMLIST - 1) break;
5592 }
5593
5594 /* Note no visible items */
5595 if (!counter)
5596 {
5597 /* Clear display and print note */
5598 text_out_c(TERM_SLATE, "You see no items.\n");
5599
5600 /* Done */
5601 text_out_done();
5602 return;
5603 }
5604 else
5605 {
5606 /* Reprint Message */
5607 text_out(format("You can see %d item%s:",
5608 counter, (counter > 1 ? "s" : "")));
5609 text_out("\n");
5610 }
5611
5612 for (i = 0; i < counter; i++)
5613 {
5614 /* o_name will hold the object_desc() name for the object. */
5615 /* o_desc will also need to put a (x4) behind it. */
5616 /* can there be more than 999 stackable items on a level? */
5617 char o_name[80];
5618 char o_desc[86];
5619
5620 object_type *o_ptr = types[i];
5621
5622 /* We shouldn't list coins or squelched items */
5623 if (o_ptr->tval == TV_GOLD || squelch_item_ok(o_ptr))
5624 continue;
5625
5626 object_desc(p_ptr, o_name, sizeof(o_name), o_ptr, FALSE, ODESC_FULL);
5627 if (counts[i] > 1)
5628 sprintf(o_desc, "%s (x%d)", o_name, counts[i]);
5629 else
5630 sprintf(o_desc, "%s", o_name);
5631
5632 /* Reset position */
5633 cur_x = x;
5634
5635 /* Note that the number of items actually displayed */
5636 disp_count++;
5637
5638 if (artifact_p(o_ptr) && object_known_p(p_ptr, o_ptr))
5639 /* known artifact */
5640 attr = TERM_VIOLET;
5641 else if (!object_aware_p(p_ptr, o_ptr))
5642 /* unaware of kind */
5643 attr = TERM_RED;
5644 else if (object_value(p_ptr, o_ptr/*, 1*/) == 0)
5645 /* worthless */
5646 attr = TERM_SLATE;
5647 else
5648 /* default */
5649 attr = TERM_WHITE;
5650
5651 a = object_kind_attr_p(p_ptr, o_ptr->k_idx);
5652 c = object_kind_char_p(p_ptr, o_ptr->k_idx);
5653
5654 /* Display the pict */
5655 text_out(" ");
5656 text_out_c(a, format("%c", c));
5657 text_out(" ");
5658
5659 /* Print and bump line counter */
5660 text_out_c(attr, o_desc);
5661 if (i == counter - 1) break;
5662 text_out(" ");
5663 text_out("\n");
5664 line++;
5665 }
5666
5667 /* Done */
5668 text_out_done();
5669 }
5670