1 /* $Id$ */
2 /* File: object.c */
3
4 /* Purpose: misc code for objects */
5
6 /*
7 * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
8 *
9 * This software may be copied and distributed for educational, research, and
10 * not for profit purposes provided that this copyright and statement are
11 * included in all such copies.
12 */
13
14 #define SERVER
15
16 #include "angband.h"
17
18
19 /*
20 * Allow to use client option auto_inscribe?
21 */
22 // DGDGDGDG -- na, dont let tehm be lazy
23 // Alas, I'm too lazy.. see '/at' - Jir -
24 #define AUTO_INSCRIBER
25
26 /* At 50% there were too many cursed jewelry in general in my opinion, using a macro now - C. Blue */
27 #define CURSED_JEWELRY_CHANCE 25
28
29 /* Add extra price bonus to randart armour/weapon which has especially 'useful' mod combo.
30 Pretty experimental and totally optional. Just disable in case some randarts end up with
31 outrageous prices. - C. Blue */
32 #define RANDART_PRICE_BONUS
33
34 /* Prevent Weapons of Morgul from dropping in Ironman Deep Dive Challenge? - C. Blue */
35 #define NO_MORGUL_IN_IDDC
36
37
38 /*
39 * Excise a dungeon object from any stacks
40 * Borrowed from ToME.
41 */
excise_object_idx(int o_idx)42 void excise_object_idx(int o_idx)
43 {
44 object_type *j_ptr, *o_ptr;
45 u16b this_o_idx, next_o_idx = 0;
46 u16b prev_o_idx = 0;
47 int i;
48
49 /* Object */
50 j_ptr = &o_list[o_idx];
51
52 #ifdef MONSTER_INVENTORY
53 /* Monster */
54 if (j_ptr->held_m_idx)
55 {
56 monster_type *m_ptr;
57
58 /* Monster */
59 m_ptr = &m_list[j_ptr->held_m_idx];
60
61 /* Scan all objects the monster has */
62 for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
63 {
64 /* Acquire object */
65 o_ptr = &o_list[this_o_idx];
66
67 /* Acquire next object */
68 next_o_idx = o_ptr->next_o_idx;
69
70 /* Done */
71 if (this_o_idx == o_idx)
72 {
73 /* No previous */
74 if (prev_o_idx == 0)
75 {
76 /* Remove from list */
77 m_ptr->hold_o_idx = next_o_idx;
78 }
79
80 /* Real previous */
81 else
82 {
83 object_type *k_ptr;
84
85 /* Previous object */
86 k_ptr = &o_list[prev_o_idx];
87
88 /* Remove from list */
89 k_ptr->next_o_idx = next_o_idx;
90 }
91
92 /* Forget next pointer */
93 o_ptr->next_o_idx = 0;
94
95 /* Done */
96 break;
97 }
98
99 /* Save prev_o_idx */
100 prev_o_idx = this_o_idx;
101 }
102 return;
103 }
104 else
105 #endif // MONSTER_INVENTORY
106
107 /* Dungeon */
108 {
109 cave_type *c_ptr;
110 cave_type **zcave;
111
112 int y = j_ptr->iy;
113 int x = j_ptr->ix;
114
115 /* Grid */
116 if (!(zcave = getcave(&j_ptr->wpos))) return;
117
118 /* Somewhere out of this world */
119 if (!in_bounds2(&j_ptr->wpos, y, x)) return;
120
121 c_ptr = &zcave[y][x];
122
123 /* Scan all objects in the grid */
124 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
125 {
126 /* Acquire object */
127 o_ptr = &o_list[this_o_idx];
128
129 /* Acquire next object */
130 next_o_idx = o_ptr->next_o_idx;
131
132 /* Done */
133 if (this_o_idx == o_idx)
134 {
135 /* No previous */
136 if (prev_o_idx == 0)
137 {
138 /* Remove from list */
139 if (c_ptr) c_ptr->o_idx = next_o_idx;
140 }
141
142 /* Real previous */
143 else
144 {
145 object_type *k_ptr;
146
147 /* Previous object */
148 k_ptr = &o_list[prev_o_idx];
149
150 /* Remove from list */
151 k_ptr->next_o_idx = next_o_idx;
152 }
153
154 /* Forget next pointer */
155 o_ptr->next_o_idx = 0;
156
157 /* Done */
158 break;
159 }
160 #ifdef MAX_ITEMS_STACKING
161 else {
162 /* decrement it's stack position index */
163 if (o_ptr->stack_pos) o_ptr->stack_pos--;
164 }
165 #endif
166
167 /* Save prev_o_idx */
168 prev_o_idx = this_o_idx;
169 }
170
171 /* Fix visibility of item pile - C. Blue
172 If object was visible to a player, then the top object of that pile becomes visible now! */
173 if (c_ptr->o_idx) /* any object left at all? */
174 for (i = 1; i <= NumPlayers; i++) /* FIX_PILE_VISIBILITY_DEBUG */
175 if (Players[i]->obj_vis[o_idx])
176 Players[i]->obj_vis[c_ptr->o_idx] = TRUE;
177 }
178 }
179
180
181
182 /*
183 * Delete a dungeon object
184 */
delete_object_idx(int o_idx,bool unfound_art)185 void delete_object_idx(int o_idx, bool unfound_art) {
186 object_type *o_ptr = &o_list[o_idx];
187 int i;
188
189 int y = o_ptr->iy;
190 int x = o_ptr->ix;
191 //cave_type **zcave;
192 struct worldpos *wpos = &o_ptr->wpos;
193
194
195 /* Artifact becomes 'not found' status */
196 if (true_artifact_p(o_ptr) && unfound_art)
197 handle_art_d(o_ptr->name1);
198 /* uh, we abuse this */
199 if (unfound_art) questitem_d(o_ptr, o_ptr->number);
200
201 #ifdef PLAYER_STORES
202 /* Log removal of player store items */
203 if (!(o_ptr->held_m_idx) && o_ptr->note && strstr(quark_str(o_ptr->note), "@S")
204 && inside_house(wpos, o_ptr->ix, o_ptr->iy)) {
205 char o_name[ONAME_LEN];//, p_name[NAME_LEN];
206 object_desc(0, o_name, o_ptr, TRUE, 3);
207 //s_printf("PLAYER_STORE_REMOVED: %s - %s (%d,%d,%d; %d,%d).\n",
208 s_printf("PLAYER_STORE_REMOVED: %s (%d,%d,%d; %d,%d).\n",
209 //p_name, o_name, wpos->wx, wpos->wy, wpos->wz,
210 o_name, wpos->wx, wpos->wy, wpos->wz,
211 o_ptr->ix, o_ptr->iy);
212 }
213 #endif
214
215 /* Excise */
216 excise_object_idx(o_idx);
217
218 /* No one can see it anymore */
219 for (i = 1; i < NumPlayers + 1; i++)
220 Players[i]->obj_vis[o_idx] = FALSE;
221
222 /* Visual update */
223 /* Dungeon floor */
224 if (!(o_ptr->held_m_idx)) everyone_lite_spot(wpos, y, x);
225
226 /* Wipe the object */
227 WIPE(o_ptr, object_type);
228 }
229
230 /*
231 * Deletes object from given location
232 */
delete_object(struct worldpos * wpos,int y,int x,bool unfound_art)233 void delete_object(struct worldpos *wpos, int y, int x, bool unfound_art) /* maybe */
234 {
235 cave_type *c_ptr;
236
237 cave_type **zcave;
238 /* Refuse "illegal" locations */
239 if (!in_bounds(y, x)) return;
240
241 if ((zcave = getcave(wpos))) {
242 u16b this_o_idx, next_o_idx = 0;
243
244 c_ptr = &zcave[y][x];
245 #if 0
246 /* Refuse "illegal" locations */
247 if (!in_bounds(Depth, y, x)) return;
248
249 if(cave[Depth]){ /* This is fast indexing method first */
250 /* Find where it was */
251 c_ptr = &cave[Depth][y][x];
252 #endif // 0
253
254 /* Delete the object */
255 // if (c_ptr->o_idx) delete_object_idx(c_ptr->o_idx, unfound_art);
256
257 /* Scan all objects in the grid */
258 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
259 {
260 object_type *o_ptr;
261
262 /* Acquire object */
263 o_ptr = &o_list[this_o_idx];
264
265 /* Acquire next object */
266 next_o_idx = o_ptr->next_o_idx;
267
268 /* Wipe the object */
269 delete_object_idx(this_o_idx, unfound_art);
270 }
271
272 /* Objects are gone */
273 c_ptr->o_idx = 0;
274
275 // everyone_lite_spot(wpos, y, x);
276 }
277 else{ /* Cave depth not static (houses etc) - do slow method */
278 int i;
279 for (i = 0; i < o_max; i++) {
280 object_type *o_ptr = &o_list[i];
281 if (o_ptr->k_idx && inarea(wpos, &o_ptr->wpos))
282 {
283 if (y == o_ptr->iy && x == o_ptr->ix) {
284 delete_object_idx(i, unfound_art);
285 }
286 }
287 }
288 }
289 }
290
291
292
293 /*
294 * Compact and Reorder the object list
295 *
296 * This function can be very dangerous, use with caution!
297 *
298 * When actually "compacting" objects, we base the saving throw on a
299 * combination of object level, distance from player, and current
300 * "desperation".
301 *
302 * After "compacting" (if needed), we "reorder" the objects into a more
303 * compact order, and we reset the allocation info, and the "live" array.
304 */
305 /*
306 * Debugging is twice as hard as writing the code in the first
307 * place. Therefore, if you write the code as cleverly as possible,
308 * you are, by definition, not smart enough to debug it.
309 * -- Brian W. Kernighan
310 */
311 //#define DONT_COMPACT_NEARBY
312 void compact_objects(int size, bool purge) {
313 int i, y, x, num, cnt, Ind; //, j, ny, nx;
314
315 s32b cur_val, cur_lev, chance;
316 #ifdef DONT_COMPACT_NEARBY
317 s32b cur_dis;
318 #endif
319 struct worldpos *wpos;
320 // object_type *q_ptr;
321 cave_type *c_ptr, **zcave;
322
323 int tmp_max = o_max;
324 quest_info *q_ptr;
325
326 /* Compact */
327 if (size) {
328 /* Message */
329 s_printf("Compacting objects...\n");
330 }
331
332
333 /* Compact at least 'size' objects */
334 for (num = 0, cnt = 1; num < size; cnt++) {
335 /* Get more vicious each iteration */
336 cur_lev = 5 * cnt;
337
338 /* Destroy more valuable items each iteration */
339 cur_val = 500 * (cnt - 1);
340
341 #ifdef DONT_COMPACT_NEARBY
342 /* Get closer each iteration */
343 cur_dis = 5 * (20 - cnt);
344 #endif
345
346 /* Examine the objects */
347 for (i = 1; i < o_max; i++) {
348 object_type *o_ptr = &o_list[i];
349
350 object_kind *k_ptr = &k_info[o_ptr->k_idx];
351
352 /* Skip dead objects */
353 if (!o_ptr->k_idx) continue;
354
355 /* Questors are immune */
356 if (o_ptr->questor) continue;
357
358 /* Hack -- High level objects start out "immune" */
359 if (k_ptr->level > cur_lev) continue;
360
361 /* Get the location */
362 y = o_ptr->iy;
363 x = o_ptr->ix;
364
365 #ifdef DONT_COMPACT_NEARBY
366 /* Nearby objects start out "immune" */
367 if ((cur_dis > 0) && (distance(py, px, y, x) < cur_dis)) continue;
368 #endif
369
370 /* Valuable objects start out "immune" */
371 if (object_value(0, &o_list[i]) > cur_val) continue;
372
373 /* Saving throw */
374 chance = 90;
375
376 /* Hack -- only compact artifacts in emergencies */
377 if (artifact_p(o_ptr) && (cnt < 1000)) chance = 100;
378
379 if ((zcave = getcave(&o_ptr->wpos))) {
380 /* Hack -- only compact items in houses (or surface vaults) or inns in emergencies */
381 if (!o_ptr->wpos.wz && (zcave[y][x].info & (CAVE_ICKY | CAVE_PROT)))
382 #if 0
383 if (cnt < 1000) /* Grant immunity except in emergencies */
384 #endif
385 chance = 100;
386
387 /* Don't compact items on protected grids in special locations) */
388 else if ((zcave[y][x].info & CAVE_PROT)) //IDDC town inns!
389 chance = 100;
390 }
391
392 /* Apply the saving throw */
393 if (rand_int(100) < chance) continue;
394
395 /* Delete it */
396 delete_object_idx(i, TRUE);
397
398 /* Count it */
399 num++;
400 }
401 }
402
403
404 /* Excise dead objects (backwards!) */
405 for (i = o_max - 1; i >= 1; i--) {
406 /* Get the i'th object */
407 object_type *o_ptr = &o_list[i];
408
409 /* Skip real objects */
410 /* real objects in unreal location are not skipped. */
411 /* hack -- items on wilderness are preserved, since
412 * they can be house contents. */
413 if (o_ptr->k_idx) {
414 /* Skip questors always
415 NOTE: This will even keep them alive in the dungeon although
416 the dungeon floor might've gotten deallocated already. */
417 if (o_ptr->questor) continue;
418
419 if ((!o_ptr->wpos.wz && (!purge || o_ptr->owner)) ||
420 getcave(&o_ptr->wpos)) continue;
421
422 /* Delete it first */
423 delete_object_idx(i, TRUE);
424 }
425
426 /* One less object */
427 tmp_max--;
428 }
429
430 /*
431 * Now, all objects that wanted removed have been wiped.
432 * Their spaces remain. Fill in the gaps and pull back the list.
433 */
434
435 /* were any removed? */
436 if (o_max != tmp_max) {
437 int *old_idx;
438 int z = 1;
439 monster_type *m_ptr;
440 object_type *o_ptr;
441
442 /* allocate storage for map */
443 old_idx = calloc(1, o_max * sizeof(int));
444
445 /* map the list and compress it */
446 for (i = 1; i < o_max; i++) {
447 if (o_list[i].k_idx) {
448 if (z != i) {
449 /* Copy structure */
450 o_list[z] = o_list[i];
451
452 /* Quests: keep questor_m_idx information consistent */
453 if (o_list[z].questor) {
454 q_ptr = &q_info[o_list[z].quest - 1];
455 /* paranoia check, after server restarted after heavy code changes or sth */
456 if (q_ptr->defined && q_ptr->questors > o_list[z].questor_idx) {
457 /* fix its index */
458 #if 0
459 s_printf("QUEST_COMPACT_OBJECTS: quest %d - questor %d o_idx %d->%d\n", o_list[z].quest - 1, o_list[z].questor_idx, q_ptr->questor[o_list[z].questor_idx].mo_idx, z);
460 #endif
461 q_ptr->questor[o_list[z].questor_idx].mo_idx = z;
462 } else {
463 s_printf("QUEST_COMPACT_OBJECTS: deprecated questor, quest %d - questor %d o_idx %d->%d\n", o_list[z].quest - 1, o_list[z].questor_idx, q_ptr->questor[o_list[z].questor_idx].mo_idx, z);
464 o_list[z].questor = FALSE;
465 o_list[z].quest = 0; //do this too, or questitem_d() will falsely recognise it as a quest item
466 /* delete it too? */
467 }
468 }
469
470 /* this needs to go through all objects - mikaelh */
471 for (Ind = 1; Ind <= NumPlayers; Ind++) {
472 if (Players[Ind]->conn == NOT_CONNECTED) continue;
473 Players[Ind]->obj_vis[z] = Players[Ind]->obj_vis[i];
474
475 /* clear the old stuff */
476 Players[Ind]->obj_vis[i] = FALSE;
477 }
478 }
479
480 old_idx[i] = z;
481 z++;
482 }
483 }
484
485 /* wipe any cleared spaces */
486 for (i = tmp_max; i < o_max; i++) {
487 WIPE(&o_list[i], object_type);
488 }
489
490 /* now, we can fix o_max */
491 o_max = tmp_max;
492
493 /* relink objects correctly */
494 for (i = 1; i < o_max; i++) {
495 if (o_list[i].next_o_idx) {
496 /* get the new mapping */
497 o_list[i].next_o_idx = old_idx[o_list[i].next_o_idx];
498 }
499 }
500
501 #ifdef MONSTER_INVENTORY
502 /* fix monsters' inventories */
503 for (i = 1; i < m_max; i++) {
504 m_ptr = &m_list[i];
505 if (m_ptr->hold_o_idx) {
506 m_ptr->hold_o_idx = old_idx[m_ptr->hold_o_idx];
507 }
508 }
509 #endif /* MONSTER_INVENTORY */
510
511 /* update cave grid object indices to still point to
512 the correct objects in our newly resorted o_list */
513 for (i = 1; i < o_max; i++) {
514 o_ptr = &o_list[i];
515 wpos = &o_ptr->wpos;
516 x = o_ptr->ix;
517 y = o_ptr->iy;
518
519 if ((zcave = getcave(wpos))) {
520 c_ptr = &zcave[y][x];
521 if (in_bounds2(wpos, y, x)) {
522 if (old_idx[c_ptr->o_idx] == i) {
523 c_ptr->o_idx = i;
524 }
525 }
526 else{
527 y = 255 - y;
528 if (in_bounds2(wpos, y, x)) {
529 c_ptr = &zcave[y][x];
530 if (c_ptr->feat == FEAT_MON_TRAP) {
531 struct c_special *cs_ptr;
532 if ((cs_ptr = GetCS(c_ptr, CS_MON_TRAP))) {
533 if (old_idx[cs_ptr->sc.montrap.trap_kit] == i) {
534 cs_ptr->sc.montrap.trap_kit = i;
535 }
536 }
537 }
538 }
539 }
540 }
541 }
542
543 /* free the allocated memory!! - mikaelh */
544 free(old_idx);
545 }
546
547 /* Reset "o_nxt" */
548 o_nxt = o_max;
549
550 /* Reset "o_top" */
551 o_top = 0;
552
553 /* Collect "live" objects */
554 for (i = 0; i < o_max; i++) {
555 /* Collect indexes */
556 o_fast[o_top++] = i;
557 }
558 }
559
560
561 /*
562 * Delete all the items when player leaves the level
563 *
564 * Note -- we do NOT visually reflect these (irrelevant) changes
565 */
566
567 void wipe_o_list(struct worldpos *wpos) {
568 int i;
569 cave_type **zcave;
570 monster_type *m_ptr;
571 bool flag = FALSE;
572
573 if((zcave = getcave(wpos))) flag = TRUE;
574
575
576 /* Delete the existing objects */
577 for (i = 1; i < o_max; i++) {
578 object_type *o_ptr = &o_list[i];
579
580 /* Skip dead objects */
581 if (!o_ptr->k_idx) continue;
582
583 /* Skip objects not on this depth */
584 if (!inarea(&o_ptr->wpos, wpos))
585 continue;
586
587 /* Mega-Hack -- preserve artifacts */
588 /* Hack -- Preserve unknown artifacts */
589 /* We now preserve ALL artifacts, known or not */
590 if (true_artifact_p(o_ptr)/* && !object_known_p(o_ptr)*/)
591 {
592 /* Info */
593 /* s_printf("Preserving artifact %d.\n", o_ptr->name1); */
594
595 /* Mega-Hack -- Preserve the artifact */
596 handle_art_d(o_ptr->name1);
597 }
598 questitem_d(o_ptr, o_ptr->number);
599
600 #ifdef MONSTER_INVENTORY
601 /* Monster */
602 if (o_ptr->held_m_idx) {
603 /* Monster */
604 m_ptr = &m_list[o_ptr->held_m_idx];
605
606 /* Hack -- see above */
607 m_ptr->hold_o_idx = 0;
608 }
609
610 /* Dungeon */
611 else
612 #endif // MONSTER_INVENTORY
613 // if (flag && in_bounds2(wpos, o_ptr->iy, o_ptr->ix))
614 if (flag && in_bounds_array(o_ptr->iy, o_ptr->ix))
615 zcave[o_ptr->iy][o_ptr->ix].o_idx = 0;
616
617 /* Wipe the object */
618 WIPE(o_ptr, object_type);
619 }
620
621 /* Compact the object list */
622 compact_objects(0, FALSE);
623 }
624 /*
625 * Delete all the items, but except those in houses. - Jir -
626 * Also skips questors and special quest items now. Note that this is also the
627 * command to be used by all admin slash commands. - C. Blue
628 *
629 * Note -- we do NOT visually reflect these (irrelevant) changes
630 * (cave[Depth][y][x].info & CAVE_ICKY)
631 */
632 void wipe_o_list_safely(struct worldpos *wpos) {
633 int i;
634
635 cave_type **zcave;
636 monster_type *m_ptr;
637
638 if (!(zcave = getcave(wpos))) return;
639
640 /* Delete the existing objects */
641 for (i = 1; i < o_max; i++) {
642 object_type *o_ptr = &o_list[i];
643
644 /* Skip dead objects */
645 if (!o_ptr->k_idx) continue;
646
647 /* Skip questors */
648 if (o_ptr->questor ||
649 (o_ptr->quest && o_ptr->tval == TV_SPECIAL && o_ptr->sval == SV_QUEST))
650 continue;
651
652 /* Skip objects not on this depth */
653 if(!(inarea(wpos, &o_ptr->wpos)))
654 continue;
655
656 /* DEBUG -after getting weird crashes today 2007-12-21 in bree from /clv, and multiplying townies, I added this inbound check- C. Blue */
657 // if (in_bounds_array(o_ptr->iy, o_ptr->ix)) {
658 /* Skip objects inside a house but not in a vault in dungeon/tower */
659 if (!wpos->wz && zcave[o_ptr->iy][o_ptr->ix].info & CAVE_ICKY)
660 continue;
661 // }
662
663 /* Mega-Hack -- preserve artifacts */
664 /* Hack -- Preserve unknown artifacts */
665 /* We now preserve ALL artifacts, known or not */
666 if (artifact_p(o_ptr)/* && !object_known_p(o_ptr)*/)
667 {
668 /* Info */
669 /* s_printf("Preserving artifact %d.\n", o_ptr->name1); */
670
671 /* Mega-Hack -- Preserve the artifact */
672 handle_art_d(o_ptr->name1);
673 }
674
675 #ifdef MONSTER_INVENTORY
676 /* Monster */
677 if (o_ptr->held_m_idx) {
678 /* Monster */
679 m_ptr = &m_list[o_ptr->held_m_idx];
680
681 /* Hack -- see above */
682 m_ptr->hold_o_idx = 0;
683 }
684
685 /* Dungeon */
686 else if (in_bounds_array(o_ptr->iy, o_ptr->ix))
687 #endif // MONSTER_INVENTORY
688 {
689 zcave[o_ptr->iy][o_ptr->ix].o_idx = 0;
690 }
691
692 /* Wipe the object */
693 WIPE(o_ptr, object_type);
694 }
695
696 /* Compact the object list */
697 compact_objects(0, FALSE);
698 }
699 /* Exactly like wipe_o_list() but actually makes exceptions for special dungeon floors. - C. Blue
700 Special means: Static IDDC town floor. (Could maybe be used for quests too in some way.) */
701 void wipe_o_list_special(struct worldpos *wpos) {
702 int i;
703 cave_type **zcave;
704 monster_type *m_ptr;
705 bool flag = FALSE;
706
707 if ((zcave = getcave(wpos))) flag = TRUE;
708
709 #if 0 /* actually disabled for now! (anti-cheeze, to be safe) */
710 if (sustained_wpos(wpos)) return;
711 #endif
712
713 /* Delete the existing objects */
714 for (i = 1; i < o_max; i++) {
715 object_type *o_ptr = &o_list[i];
716
717 /* Skip dead objects */
718 if (!o_ptr->k_idx) continue;
719
720 /* Skip objects not on this depth */
721 if (!inarea(&o_ptr->wpos, wpos))
722 continue;
723
724 /* Mega-Hack -- preserve artifacts */
725 /* Hack -- Preserve unknown artifacts */
726 /* We now preserve ALL artifacts, known or not */
727 if (true_artifact_p(o_ptr)/* && !object_known_p(o_ptr)*/)
728 {
729 /* Info */
730 /* s_printf("Preserving artifact %d.\n", o_ptr->name1); */
731
732 /* Mega-Hack -- Preserve the artifact */
733 handle_art_d(o_ptr->name1);
734 }
735 questitem_d(o_ptr, o_ptr->number);
736
737 #ifdef MONSTER_INVENTORY
738 /* Monster */
739 if (o_ptr->held_m_idx) {
740 /* Monster */
741 m_ptr = &m_list[o_ptr->held_m_idx];
742
743 /* Hack -- see above */
744 m_ptr->hold_o_idx = 0;
745 }
746
747 /* Dungeon */
748 else
749 #endif // MONSTER_INVENTORY
750 // if (flag && in_bounds2(wpos, o_ptr->iy, o_ptr->ix))
751 if (flag && in_bounds_array(o_ptr->iy, o_ptr->ix))
752 zcave[o_ptr->iy][o_ptr->ix].o_idx = 0;
753
754 /* Wipe the object */
755 WIPE(o_ptr, object_type);
756 }
757
758 /* Compact the object list */
759 compact_objects(0, FALSE);
760 }
761
762
763 /*
764 * Acquires and returns the index of a "free" object.
765 *
766 * This routine should almost never fail, but in case it does,
767 * we must be sure to handle "failure" of this routine.
768 *
769 * Note that this function must maintain the special "o_fast"
770 * array of pointers to "live" objects.
771 */
772 s16b o_pop(void)
773 {
774 int i, n, k;
775
776 /* Initial allocation */
777 if (o_max < MAX_O_IDX)
778 {
779 /* Get next space */
780 i = o_max;
781
782 /* Expand object array */
783 o_max++;
784
785 /* Update "o_fast" */
786 o_fast[o_top++] = i;
787
788 /* Use this object */
789 return (i);
790 }
791
792
793 /* Check for some space */
794 for (n = 1; n < MAX_O_IDX; n++)
795 {
796 /* Get next space */
797 i = o_nxt;
798
799 /* Advance (and wrap) the "next" pointer */
800 if (++o_nxt >= MAX_O_IDX) o_nxt = 1;
801
802 /* Skip objects in use */
803 if (o_list[i].k_idx) continue;
804
805 /* Verify space XXX XXX */
806 if (o_top >= MAX_O_IDX) continue;
807
808 /* Verify not allocated */
809 for (k = 0; k < o_top; k++)
810 {
811 /* Hack -- Prevent errors */
812 if (o_fast[k] == i) i = 0;
813 }
814
815 /* Oops XXX XXX */
816 if (!i) continue;
817
818 /* Update "o_fast" */
819 o_fast[o_top++] = i;
820
821 /* Use this object */
822 return (i);
823 }
824
825
826 /* Warn the player */
827 if (server_dungeon) s_printf("Too many objects!\n");
828
829 /* Oops */
830 return (0);
831 }
832
833
834
835 /*
836 * Apply a "object restriction function" to the "object allocation table"
837 */
838 errr get_obj_num_prep(u32b resf) {
839 long i, n, p, adj;
840 long k_idx;
841
842 /* Get the entry */
843 alloc_entry *table = alloc_kind_table;
844
845 /* Copy the hook into a local variable for speed */
846 int (*hook)(int k_idx, u32b resf) = get_obj_num_hook;
847
848 if (hook) {
849 /* Scan the allocation table */
850 for (i = 0, n = alloc_kind_size; i < n; i++) {
851 /* Get the entry */
852 alloc_entry *entry = &table[i];
853
854 /* Obtain the base probability */
855 p = entry->prob1;
856
857 /* Default probability for this pass */
858 entry->prob2 = 0;
859
860 /* Access the index */
861 k_idx = entry->index;
862
863 /* Call the hook and adjust the probability */
864 adj = (*hook)(k_idx, resf);
865 p = adj * p / 100;
866
867 if (p && (resf & RESF_STOREFLAT)) p = 100;
868
869 /* Save the probability */
870 entry->prob2 = p;
871 }
872 } else {
873 /* Scan the allocation table */
874 for (i = 0, n = alloc_kind_size; i < n; i++)
875 {
876 /* Get the entry */
877 alloc_entry *entry = &table[i];
878
879 /* Obtain the base probability */
880 p = entry->prob1;
881
882 if (p && (resf & RESF_STOREFLAT)) p = 100;
883
884 /* Default probability for this pass */
885 entry->prob2 = 0;
886
887 /* Save the probability */
888 entry->prob2 = p;
889 }
890 }
891
892 /* Success */
893 return (0);
894 }
895
896
897
898 /*
899 * Apply a "object restriction function" to the "object allocation table"
900 * This function only takes objects of a certain TVAL! - C. Blue
901 * (note that kind_is_legal_special and this function are somewhat redundant)
902 * (this function supports STOREFLAT but isn't called by store.c, what gives)
903 */
904 errr get_obj_num_prep_tval(int tval, u32b resf) {
905 long i, n, p, adj;
906 long k_idx;
907
908 /* Get the entry */
909 alloc_entry *table = alloc_kind_table;
910
911 /* Copy the hook into a local variable for speed */
912 int (*hook)(int k_idx, u32b resf) = get_obj_num_hook;
913
914 if (hook) {
915 /* Scan the allocation table */
916 for (i = 0, n = alloc_kind_size; i < n; i++) {
917 /* Get the entry */
918 alloc_entry *entry = &table[i];
919
920 /* Obtain the base probability */
921 p = entry->prob1;
922
923 /* Default probability for this pass */
924 entry->prob2 = 0;
925
926 /* Access the index */
927 k_idx = entry->index;
928
929 /* Call the hook and adjust the probability */
930 adj = (*hook)(k_idx, resf);
931 p = adj * p / 100;
932
933 if (p && (resf & RESF_STOREFLAT)) p = 100;
934
935 /* Only accept a specific tval */
936 if (k_info[table[i].index].tval != tval)
937 continue;
938
939 /* Save the probability */
940 entry->prob2 = p;
941 }
942 } else {
943 /* Scan the allocation table */
944 for (i = 0, n = alloc_kind_size; i < n; i++) {
945 /* Get the entry */
946 alloc_entry *entry = &table[i];
947
948 /* Obtain the base probability */
949 p = entry->prob1;
950
951 /* Default probability for this pass */
952 entry->prob2 = 0;
953
954 /* Access the index */
955 k_idx = entry->index;
956
957 if (p && (resf & RESF_STOREFLAT)) p = 100;
958
959 /* Only accept a specific tval */
960 if (k_info[table[i].index].tval != tval)
961 continue;
962
963 /* Save the probability */
964 entry->prob2 = p;
965 }
966 }
967
968 /* Success */
969 return (0);
970 }
971
972
973
974 /*
975 * Choose an object kind that seems "appropriate" to the given level
976 *
977 * This function uses the "prob2" field of the "object allocation table",
978 * and various local information, to calculate the "prob3" field of the
979 * same table, which is then used to choose an "appropriate" object, in
980 * a relatively efficient manner.
981 *
982 * It is (slightly) more likely to acquire an object of the given level
983 * than one of a lower level. This is done by choosing several objects
984 * appropriate to the given level and keeping the "hardest" one.
985 *
986 * Note that if no objects are "appropriate", then this function will
987 * fail, and return zero, but this should *almost* never happen.
988 */
989 s16b get_obj_num(int max_level, u32b resf) {
990 long i, j, n, p;
991 long value, total;
992 long k_idx;
993
994 object_kind *k_ptr;
995 alloc_entry *table = alloc_kind_table;
996
997
998 /* Boost level */
999 if (max_level > 0) {
1000 /* Occasional "boost" */
1001 if (rand_int(GREAT_OBJ) == 0) {
1002 /* What a bizarre calculation */
1003 max_level = 1 + ((max_level * MAX_DEPTH_OBJ) / randint(MAX_DEPTH_OBJ));
1004 }
1005 }
1006
1007 /* Reset total */
1008 total = 0L;
1009
1010 /* Cap maximum level */
1011 if (max_level > 254) max_level = 254;
1012 if ((resf & RESF_STOREFLAT)) max_level = 254;
1013
1014 /* Calculate loop bounds */
1015 n = alloc_kind_index_level[max_level + 1];
1016
1017 if (opening_chest) {
1018 /* Process probabilities */
1019 for (i = 0; i < n; i++) {
1020 /* Default */
1021 table[i].prob3 = 0;
1022
1023 /* Access the index */
1024 k_idx = table[i].index;
1025
1026 /* Access the actual kind */
1027 k_ptr = &k_info[k_idx];
1028
1029 /* Hack -- prevent embedded chests */
1030 if (k_ptr->tval == TV_CHEST) continue;
1031
1032 /* Accept */
1033 table[i].prob3 = table[i].prob2;
1034
1035 /* Total */
1036 total += table[i].prob3;
1037 }
1038 } else {
1039 /* Process probabilities */
1040 for (i = 0; i < n; i++) {
1041 /* Default */
1042 table[i].prob3 = 0;
1043
1044 /* Accept */
1045 table[i].prob3 = table[i].prob2;
1046
1047 if (table[i].prob3 && (resf & RESF_STOREFLAT)) table[i].prob3 = 100;
1048
1049 /* Total */
1050 total += table[i].prob3;
1051 }
1052 }
1053
1054 /* No legal objects */
1055 if (total <= 0) return (0);
1056
1057
1058 /* Pick an object */
1059 value = rand_int(total);
1060
1061 /* Find the object */
1062 for (i = 0; i < n; i++) {
1063 /* Found the entry */
1064 if (value < table[i].prob3) break;
1065
1066 /* Decrement */
1067 value = value - table[i].prob3;
1068 }
1069
1070 /* don't try for a better object? */
1071 if ((resf & RESF_STOREFLAT)) return (table[i].index);
1072
1073 /* Power boost */
1074 p = rand_int(100);
1075
1076 /* Try for a "better" object once (50%) or twice (10%) */
1077 if (p < 60) {
1078 /* Save old */
1079 j = i;
1080
1081 /* Pick a object */
1082 value = rand_int(total);
1083
1084 /* Find the monster */
1085 for (i = 0; i < n; i++) {
1086 /* Found the entry */
1087 if (value < table[i].prob3) break;
1088
1089 /* Decrement */
1090 value = value - table[i].prob3;
1091 }
1092
1093 /* Keep the "best" one */
1094 if (table[i].level < table[j].level) i = j;
1095 }
1096
1097 /* Try for a "better" object twice (10%) */
1098 if (p < 10) {
1099 /* Save old */
1100 j = i;
1101
1102 /* Pick a object */
1103 value = rand_int(total);
1104
1105 /* Find the object */
1106 for (i = 0; i < n; i++) {
1107 /* Found the entry */
1108 if (value < table[i].prob3) break;
1109
1110 /* Decrement */
1111 value = value - table[i].prob3;
1112 }
1113
1114 /* Keep the "best" one */
1115 if (table[i].level < table[j].level) i = j;
1116 }
1117
1118
1119 /* Result */
1120 return (table[i].index);
1121 }
1122
1123
1124
1125
1126
1127
1128
1129
1130 /*
1131 * Known is true when the "attributes" of an object are "known".
1132 * These include tohit, todam, toac, cost, and pval (charges).
1133 *
1134 * Note that "knowing" an object gives you everything that an "awareness"
1135 * gives you, and much more. In fact, the player is always "aware" of any
1136 * item of which he has full "knowledge".
1137 *
1138 * But having full knowledge of, say, one "wand of wonder", does not, by
1139 * itself, give you knowledge, or even awareness, of other "wands of wonder".
1140 * It happens that most "identify" routines (including "buying from a shop")
1141 * will make the player "aware" of the object as well as fully "know" it.
1142 *
1143 * This routine also removes any inscriptions generated by "feelings".
1144 */
1145 void object_known(object_type *o_ptr)
1146 {
1147 /* Remove "default inscriptions" */
1148 if (o_ptr->note && (o_ptr->ident & ID_SENSE)) {
1149 /* Access the inscription */
1150 cptr q = quark_str(o_ptr->note);
1151
1152 /* Hack -- Remove auto-inscriptions */
1153 if ((streq(q, "bad")) ||
1154 //(streq(q, "cursed")) ||//shouldn't get removed, but can't happen on flavoured items anyway
1155 (streq(q, "broken")) ||
1156 (streq(q, "good")) ||
1157 (streq(q, "average")) ||
1158 (streq(q, "excellent")) ||
1159 (streq(q, "worthless")) ||
1160 (streq(q, "special")) ||
1161 (streq(q, "terrible"))) {
1162 /* Forget the inscription */
1163 o_ptr->note = 0;
1164 }
1165 }
1166
1167 /* Clear the "Felt" info */
1168 o_ptr->ident &= ~(ID_SENSE | ID_SENSE_HEAVY);
1169
1170 /* Clear the "Empty" info */
1171 o_ptr->ident &= ~ID_EMPTY;
1172
1173 /* Now we know about the item */
1174 o_ptr->ident |= (ID_KNOWN | ID_SENSED_ONCE);
1175
1176 /* Artifact becomes 'found' status - omg it must already become
1177 'found' if a player picks it up! That gave headaches! */
1178 if (true_artifact_p(o_ptr)) handle_art_ipara(o_ptr->name1);
1179
1180 }
1181
1182
1183
1184
1185 /*
1186 * The player is now aware of the effects of the given object.
1187 */
1188 bool object_aware(int Ind, object_type *o_ptr) {
1189 int i;
1190
1191 if (object_aware_p(Ind, o_ptr)) return FALSE;
1192
1193 /* Fully aware of the effects */
1194 Players[Ind]->obj_aware[o_ptr->k_idx] = TRUE;
1195
1196 /* Make it refresh, although the object mem structure didn't change */
1197 for (i = 0; i < INVEN_TOTAL; i++)
1198 if (Players[Ind]->inventory[i].k_idx == o_ptr->k_idx)
1199 Players[Ind]->inventory[i].changed = !Players[Ind]->inventory[i].changed;
1200 return TRUE;
1201 }
1202
1203
1204
1205 /*
1206 * Something has been "sampled"
1207 */
1208 void object_tried(int Ind, object_type *o_ptr, bool flipped) {
1209 int i;
1210
1211 if (object_tried_p(Ind, o_ptr)) return;
1212
1213 /* Mark it as tried (even if "aware") */
1214 Players[Ind]->obj_tried[o_ptr->k_idx] = TRUE;
1215
1216 /* Make it refresh, although the object mem structure didn't change */
1217 if (flipped) return; /* already changed by object_aware()? don't cancel out! */
1218 for (i = 0; i < INVEN_TOTAL; i++)
1219 if (Players[Ind]->inventory[i].k_idx == o_ptr->k_idx)
1220 Players[Ind]->inventory[i].changed = !Players[Ind]->inventory[i].changed;
1221
1222 return;
1223 }
1224
1225
1226
1227 /*
1228 * Return the "value" of an "unknown" item
1229 * Make a guess at the value of non-aware items
1230 */
1231 static s64b object_value_base(int Ind, object_type *o_ptr)
1232 {
1233 object_kind *k_ptr = &k_info[o_ptr->k_idx];
1234
1235 /* Aware item -- use template cost */
1236 if (Ind == 0 || object_aware_p(Ind, o_ptr)) return (k_ptr->cost);
1237
1238 /* Analyze the type */
1239 switch (o_ptr->tval)
1240 {
1241 /* Un-aware Food */
1242 case TV_FOOD: return (5L);
1243
1244 /* Un-aware Potions */
1245 case TV_POTION:
1246 case TV_POTION2: return (20L);
1247
1248 /* Un-aware Scrolls */
1249 case TV_SCROLL: return (20L);
1250
1251 /* Un-aware Staffs */
1252 case TV_STAFF: return (70L);
1253
1254 /* Un-aware Wands */
1255 case TV_WAND: return (50L);
1256
1257 /* Un-aware Rods */
1258 case TV_ROD: return (90L);
1259
1260 /* Un-aware Rings */
1261 case TV_RING: return (45L);
1262
1263 /* Un-aware Amulets */
1264 case TV_AMULET: return (45L);
1265 }
1266
1267 /* Paranoia -- Oops */
1268 return (0L);
1269 }
1270
1271 void eliminate_common_ego_flags(object_type *o_ptr, u32b *f1, u32b *f2, u32b *f3, u32b *f4, u32b *f5, u32b *f6, u32b *esp) {
1272 s16b j;
1273 ego_item_type *e_ptr;
1274 object_kind *k_ptr = &k_info[o_ptr->k_idx];
1275
1276 /* Hack -- eliminate Base object powers */
1277 (*f1) &= ~k_ptr->flags1;
1278 (*f2) &= ~k_ptr->flags2;
1279 (*f3) &= ~k_ptr->flags3;
1280 (*f4) &= ~k_ptr->flags4;
1281 (*f5) &= ~k_ptr->flags5;
1282 (*f6) &= ~k_ptr->flags6;
1283 (*esp) &= ~k_ptr->esp;
1284
1285 if (o_ptr->name1) return; /* if used on artifacts, we're done here */
1286
1287 /* Hack -- eliminate 'promised' (ie 100% occurring) ego powers */
1288 if (!o_ptr->name2) return;
1289 e_ptr = &e_info[o_ptr->name2];
1290 for (j = 0; j < 5; j++) {
1291 /* Rarity check */
1292 if (e_ptr->rar[j] > 99) {
1293 *(f1) &= ~e_ptr->flags1[j];
1294 *(f2) &= ~e_ptr->flags2[j];
1295 *(f3) &= ~e_ptr->flags3[j];
1296 *(f4) &= ~e_ptr->flags4[j];
1297 *(f5) &= ~e_ptr->flags5[j];
1298 *(f6) &= ~e_ptr->flags6[j];
1299 *(esp) &= ~e_ptr->esp[j];
1300 }
1301 }
1302
1303 /* Hack -- eliminate 'promised' (ie 100% occurring) ego powers */
1304 if (!o_ptr->name2b) return;
1305 e_ptr = &e_info[o_ptr->name2b];
1306 for (j = 0; j < 5; j++) {
1307 /* Rarity check */
1308 if (e_ptr->rar[j] > 99) {
1309 *(f1) &= ~e_ptr->flags1[j];
1310 *(f2) &= ~e_ptr->flags2[j];
1311 *(f3) &= ~e_ptr->flags3[j];
1312 *(f4) &= ~e_ptr->flags4[j];
1313 *(f5) &= ~e_ptr->flags5[j];
1314 *(f6) &= ~e_ptr->flags6[j];
1315 *(esp) &= ~e_ptr->esp[j];
1316 }
1317 }
1318 }
1319
1320 /* Return the value of the flags the object has... */
1321 s32b flag_cost(object_type *o_ptr, int plusses) {
1322 s32b total = 0; //, am;
1323 u32b f1, f2, f3, f4, f5, f6, esp;
1324
1325
1326 object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
1327
1328 if (f5 & TR5_TEMPORARY) return 0;
1329 //if (f4 & TR4_CURSE_NO_DROP) return 0;
1330
1331 /* Hack - This shouldn't be here, still.. */
1332 eliminate_common_ego_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
1333
1334
1335 if (f3 & TR3_WRAITH) total += 250000;
1336 if (f5 & TR5_INVIS) total += 30000;
1337 if (!(f4 & TR4_FUEL_LITE)) {
1338 if (f3 & TR3_LITE1) total += 750;
1339 if (f4 & TR4_LITE2) total += 1250;
1340 if (f4 & TR4_LITE3) total += 2750;
1341 }
1342
1343 if ((!(f4 & TR4_FUEL_LITE)) && (f3 & TR3_IGNORE_FIRE)) total += 100;
1344
1345 if (f5 & TR5_CHAOTIC) total += 10000;
1346 if (f1 & TR1_VAMPIRIC) total += 13000;
1347 if (f1 & TR1_SLAY_ANIMAL) total += 3500;
1348 if (f1 & TR1_SLAY_EVIL) total += 4500;
1349 if (f1 & TR1_SLAY_UNDEAD) total += 3500;
1350 if (f1 & TR1_SLAY_DEMON) total += 3500;
1351 if (f1 & TR1_SLAY_ORC) total += 3000;
1352 if (f1 & TR1_SLAY_TROLL) total += 3500;
1353 if (f1 & TR1_SLAY_GIANT) total += 3500;
1354 if (f1 & TR1_SLAY_DRAGON) total += 3500;
1355 if (f1 & TR1_KILL_DEMON) total += 5500;
1356 if (f1 & TR1_KILL_UNDEAD) total += 5500;
1357 if (f1 & TR1_KILL_DRAGON) total += 5500;
1358 if (f5 & TR5_VORPAL) total += 5000;
1359 if (f5 & TR5_IMPACT) total += 5000;
1360 if (f1 & TR1_BRAND_POIS) total += 7500;
1361 if (f1 & TR1_BRAND_ACID) total += 7500;
1362 if (f1 & TR1_BRAND_ELEC) total += 7500;
1363 if (f1 & TR1_BRAND_FIRE) total += 5000;
1364 if (f1 & TR1_BRAND_COLD) total += 5000;
1365 if (f2 & TR2_SUST_STR) total += 850;
1366 if (f2 & TR2_SUST_INT) total += 850;
1367 if (f2 & TR2_SUST_WIS) total += 850;
1368 if (f2 & TR2_SUST_DEX) total += 850;
1369 if (f2 & TR2_SUST_CON) total += 850;
1370 if (f2 & TR2_SUST_CHR) total += 250;
1371 /* f6 Not yet implemented in object_flags/eliminate_common_ego_flags etc. Really needed??
1372 // if (f5 & TR5_SENS_FIRE) total -= 100;
1373 if (f6 & TR6_SENS_COLD) total -= 100;
1374 if (f6 & TR6_SENS_ACID) total -= 100;
1375 if (f6 & TR6_SENS_ELEC) total -= 100;
1376 if (f6 & TR6_SENS_POIS) total -= 100; */
1377 if (f5 & TR5_REFLECT) total += 10000;
1378 if (f2 & TR2_FREE_ACT) total += 4500;
1379 if (f2 & TR2_HOLD_LIFE) total += 8500;
1380 if (f2 & TR2_RES_ACID) total += 1250;
1381 if (f2 & TR2_RES_ELEC) total += 1250;
1382 if (f2 & TR2_RES_FIRE) total += 1250;
1383 if (f2 & TR2_RES_COLD) total += 1250;
1384 if (f2 & TR2_RES_POIS) total += 5000;
1385 if (f2 & TR2_RES_FEAR) total += 2000;
1386 if (f2 & TR2_RES_LITE) total += 2750;
1387 if (f2 & TR2_RES_DARK) total += 2750;
1388 if (f2 & TR2_RES_BLIND) total += 8000;
1389 if (f2 & TR2_RES_CONF) total += 3500;
1390 if (f2 & TR2_RES_SOUND) total += 10000;
1391 if (f2 & TR2_RES_SHARDS) total += 4000;
1392 if (f2 & TR2_RES_NETHER) total += 15000;
1393 if (f2 & TR2_RES_NEXUS) total += 7000;
1394 if (f2 & TR2_RES_CHAOS) total += 15000;
1395 if (f2 & TR2_RES_DISEN) total += 20000;
1396 if (f3 & TR3_SH_FIRE) total += 3000;
1397 if (f5 & TR5_SH_COLD) total += 3000;
1398 if (f3 & TR3_SH_ELEC) total += 3000;
1399 if (f3 & TR3_DECAY) total += 0;
1400 if (f3 & TR3_NO_TELE) total += 2500;
1401 if (f3 & TR3_NO_MAGIC) total += 2500;
1402 if (f3 & TR3_TY_CURSE) total -= 15000;
1403 if (f3 & TR3_EASY_KNOW) total += 0;
1404 if (f3 & TR3_HIDE_TYPE) total += 0;
1405 if (f3 & TR3_SHOW_MODS) total += 0;
1406 if (f3 & TR3_INSTA_ART) total += 0;
1407 if (f3 & TR3_SEE_INVIS) total += 2000;
1408 if (esp & ESP_ORC) total += 1000;
1409 if (esp & ESP_TROLL) total += 2000;
1410 if (esp & ESP_DRAGON) total += 5000;
1411 if (esp & ESP_GIANT) total += 3000;
1412 if (esp & ESP_DEMON) total += 6000;
1413 if (esp & ESP_UNDEAD) total += 6000;
1414 if (esp & ESP_EVIL) total += 20000;
1415 if (esp & ESP_ANIMAL) total += 6000;
1416 if (esp & ESP_DRAGONRIDER) total += 3000;
1417 if (esp & ESP_GOOD) total += 8000;
1418 if (esp & ESP_NONLIVING) total += 5000;
1419 if (esp & ESP_UNIQUE) total += 4000;
1420 if (esp & ESP_SPIDER) total += 2000;
1421 // if (esp) total += (12500 * count_bits(esp));
1422 if (esp & ESP_ALL) total += 150000;/* was 125k, but ESP crowns cost 150k */
1423 if (f3 & TR3_SLOW_DIGEST) total += 750;
1424 if (f3 & TR3_REGEN) total += 2500;
1425 if (f5 & TR5_REGEN_MANA) total += 2500;
1426 if (f3 & TR3_XTRA_MIGHT) total += 2250;
1427 if (f3 & TR3_XTRA_SHOTS) total += 10000;
1428 if (f5 & TR5_IGNORE_WATER) total += 0;
1429 if (f5 & TR5_IGNORE_MANA) total += 0;
1430 if (f5 & TR5_IGNORE_DISEN) total += 0;
1431 if (f3 & TR3_IGNORE_ACID) total += 100;
1432 if (f3 & TR3_IGNORE_ELEC) total += 100;
1433 if (f3 & TR3_IGNORE_COLD) total += 100;
1434 if (f3 & TR3_ACTIVATE) total += 100;
1435 if (f3 & TR3_DRAIN_EXP) total -= 12500;
1436 if (f3 & TR3_TELEPORT)
1437 {
1438 if (o_ptr->ident & ID_CURSED)
1439 total -= 7500;
1440 else
1441 total += 500;
1442 }
1443 // if (f3 & TR3_AGGRAVATE) total -= 10000; /* penalty 1 of 2 */
1444 if (f3 & TR3_BLESSED) total += 750;
1445 if (f3 & TR3_CURSED) total -= 5000;
1446 if (f3 & TR3_HEAVY_CURSE) total -= 12500;
1447 if (f3 & TR3_PERMA_CURSE) total -= 15000;
1448 if (f3 & TR3_FEATHER) total += 1250;
1449
1450 if (f4 & TR4_LEVITATE) total += 10000;
1451 if (f4 & TR4_NEVER_BLOW) total -= 15000;
1452 if (f4 & TR4_PRECOGNITION) total += 250000;
1453 if (f4 & TR4_BLACK_BREATH) total -= 12500;
1454 if (f4 & TR4_DG_CURSE) total -= 25000;
1455 if (f4 & TR4_CLONE) total -= 10000;
1456 // if (f5 & TR5_LEVELS) total += o_ptr->elevel * 2000;
1457
1458 #if 1 /* experimentally like this (see above for original position/code) */
1459 #if 1
1460 if (f2 & TR2_IM_ACID) total += ((total + 10000) * 3) / 2;
1461 if (f2 & TR2_IM_ELEC) total += ((total + 10000) * 3) / 2;
1462 if (f2 & TR2_IM_FIRE) total += ((total + 10000) * 3) / 2;
1463 if (f2 & TR2_IM_COLD) total += ((total + 10000) * 3) / 2;
1464 #else
1465 if (f2 & TR2_IM_ACID) total += 10000;
1466 if (f2 & TR2_IM_ELEC) total += 10000;
1467 if (f2 & TR2_IM_FIRE) total += 10000;
1468 if (f2 & TR2_IM_COLD) total += 10000;
1469 if (f2 & (TR2_IM_ACID | TR2_IM_ELEC | TR2_IM_FIRE | TR2_IM_COLD))
1470 total = (total * 3) / 2;
1471 #endif
1472 #endif
1473
1474 /* Hack -- ammos shouldn't be that expensive */
1475 if (is_ammo(o_ptr->tval))
1476 total >>= 2;
1477
1478 return total;
1479 }
1480
1481
1482 /*
1483 * Return the "real" price of a "known" item, not including discounts
1484 *
1485 * Wand and staffs get cost for each charge
1486 *
1487 * Armor is worth an extra 100 gold per bonus point to armor class.
1488 *
1489 * Weapons are worth an extra 100 gold per bonus point (AC,TH,TD).
1490 *
1491 * Missiles are only worth 5 gold per bonus point, since they
1492 * usually appear in groups of 20, and we want the player to get
1493 * the same amount of cash for any "equivalent" item. Note that
1494 * missiles never have any of the "pval" flags, and in fact, they
1495 * only have a few of the available flags, primarily of the "slay"
1496 * and "brand" and "ignore" variety.
1497 *
1498 * Armor with a negative armor bonus is worthless.
1499 * Weapons with negative hit+damage bonuses are worthless.
1500 *
1501 * Every wearable item with a "pval" bonus is worth extra (see below).
1502 */
1503 /*
1504 * Now Arrows can explode, so the pval counts. - Jir -
1505 *
1506 * pval brings exponensial price boost, so that =int+6 is *much*
1507 * more expensive than =int+2.
1508 * Probably, it's not formula job but that of table..?
1509 *
1510 * XXX: 'Ego randarts' are not handled correltly, so be careful!
1511 */
1512 /* Ego powers multiply the price instead of adding? */
1513 #define EGO_MDEV_FACTOR
1514 s64b object_value_real(int Ind, object_type *o_ptr) {
1515 u32b f1, f2, f3, f4, f5, f6, esp;
1516 object_kind *k_ptr = &k_info[o_ptr->k_idx];
1517 bool star = (Ind == 0 || object_fully_known_p(Ind, o_ptr));
1518
1519 /* Base cost */
1520 s64b value = k_ptr->cost;
1521 int i;
1522
1523 /* Hack -- "worthless" items */
1524 if (!value) return (0L);
1525
1526 /* Sigil (ignore it) */
1527 s32b temp_sigil = o_ptr->sigil;
1528 s32b temp_sseed = o_ptr->sseed;
1529 o_ptr->sigil = 0;
1530 o_ptr->sseed = 0;
1531
1532 /* Extract some flags */
1533 object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
1534
1535 /* Sigil (restore it) */
1536 o_ptr->sigil = temp_sigil;
1537 o_ptr->sseed = temp_sseed;
1538
1539 /* Artifact */
1540 if (o_ptr->name1) {
1541 artifact_type *a_ptr;
1542
1543 /* Randarts */
1544 if (o_ptr->name1 == ART_RANDART) {
1545 /* use dedicated artifact pricing function - C. Blue */
1546 return(artifact_value_real(Ind, o_ptr));
1547 } else {
1548 a_ptr = &a_info[o_ptr->name1];
1549 value = a_ptr->cost;
1550
1551 /* Let true arts' prices be totally determined in a_info.txt */
1552 return(value);
1553 }
1554
1555 /* Hack -- "worthless" artifacts */
1556 if (!value) return (0L);
1557
1558 /* Hack -- Use the artifact cost instead */
1559 // value = a_ptr->cost;
1560 }
1561
1562 else {
1563 /* Ego-Item */
1564 if (o_ptr->name2) {
1565 ego_item_type *e_ptr = &e_info[o_ptr->name2];
1566
1567 /* Hack -- "worthless" ego-items */
1568 if (!e_ptr->cost) return (0L);
1569
1570 #ifdef EGO_MDEV_FACTOR
1571 /* Hack: Ego magic devices cost a multiple of their base price */
1572 if (is_magic_device(o_ptr->tval)) {
1573 /* Hack -- Reward the ego-item with a bonus */
1574 value += e_ptr->cost / 2;
1575
1576 /* these egos are defined to multiply the price.. */
1577 switch (o_ptr->name2) {
1578 case EGO_PLENTY: value = (value * 3) / 2; break;
1579 case EGO_RSIMPLICITY: value *= 2; break;
1580 case EGO_RCHARGING: value *= 2; break;
1581 case EGO_RISTARI: value *= 3; break;
1582 /* for undefined egos, just add up to the normal ego cost */
1583 default: value += e_ptr->cost / 2;
1584 }
1585 } else
1586 #endif
1587 /* Hack -- Reward the ego-item with a bonus */
1588 value += e_ptr->cost;
1589
1590 /* Hope this won't cause inflation.. */
1591 if (star) value += flag_cost(o_ptr, o_ptr->pval);
1592 /* Note: flag_cost contains all the resistances and other flags,
1593 while down here in object_value_real only the 'visible' boni
1594 are checked (pval, bpval, tohit, todam, toac), all those stats
1595 whose changes are observable without *ID* - C. Blue */
1596
1597 if (o_ptr->name2b) {
1598 ego_item_type *e_ptr = &e_info[o_ptr->name2b];
1599
1600 /* Hack -- "worthless" ego-items */
1601 if (!e_ptr->cost) return (0L);
1602
1603 #ifdef EGO_MDEV_FACTOR
1604 /* Hack: Ego magic devices cost a multiple of their base price */
1605 if (is_magic_device(o_ptr->tval)) {
1606 /* Hack -- Reward the ego-item with a bonus */
1607 value += e_ptr->cost / 2;
1608
1609 /* these egos are defined to multiply the price.. */
1610 switch (o_ptr->name2b) {
1611 case EGO_PLENTY: value = (value * 3) / 2; break;
1612 case EGO_RSIMPLICITY: value *= 2; break;
1613 case EGO_RCHARGING: value *= 2; break;
1614 case EGO_RISTARI: value *= 3; break;
1615 /* for undefined egos, just add up to the normal ego cost */
1616 default: value += e_ptr->cost / 2;
1617 }
1618 } else
1619 #endif
1620 /* Hack -- Reward the ego-item with a bonus */
1621 value += e_ptr->cost;
1622 }
1623 }
1624 }
1625 /* Hack */
1626 if (f3 & TR3_AUTO_CURSE) return 0;
1627
1628 /* Bad items don't sell. Good items with some bad modifiers DO sell ((*defenders*)). -C. Blue */
1629 switch (o_ptr->tval) {
1630 case TV_SHIELD:
1631 #ifdef NEW_SHIELDS_NO_AC
1632 /* Shields of Preservation won't sell anymore without this exception,
1633 because they don't have any positive stat left (o_ptr->to_a was it before). */
1634 if ((((o_ptr->to_h) < 0 && ((o_ptr->to_h - k_ptr->to_h) < 0)) ||
1635 ((o_ptr->to_d) < 0 && ((o_ptr->to_d - k_ptr->to_d) < 0 || k_ptr->to_d < 0)) ||
1636 ((o_ptr->to_a) < 0 && ((o_ptr->to_a - k_ptr->to_a) < 0 || k_ptr->to_a < 0)) ||
1637 (o_ptr->pval < 0) || (o_ptr->bpval < 0)) &&
1638 !(((o_ptr->to_h) > 0) ||
1639 ((o_ptr->to_d) > 0) ||
1640 (value > k_ptr->cost) || /* <- hack: check for ego power value - this is the exception required for shields now */
1641 (o_ptr->pval > 0) || (o_ptr->bpval > 0))) return (0L);
1642 break;
1643 #endif
1644 case TV_BOOTS:
1645 case TV_GLOVES:
1646 case TV_HELM:
1647 case TV_CROWN:
1648 case TV_CLOAK:
1649 case TV_SOFT_ARMOR:
1650 case TV_HARD_ARMOR:
1651 case TV_DRAG_ARMOR:
1652 if ((((o_ptr->to_h) < 0 && ((o_ptr->to_h - k_ptr->to_h) < 0)) ||
1653 ((o_ptr->to_d) < 0 && ((o_ptr->to_d - k_ptr->to_d) < 0 || k_ptr->to_d < 0)) ||
1654 ((o_ptr->to_a) < 0 && ((o_ptr->to_a - k_ptr->to_a) < 0 || k_ptr->to_a < 0)) ||
1655 (o_ptr->pval < 0) || (o_ptr->bpval < 0)) &&
1656 !(((o_ptr->to_h) > 0) ||
1657 ((o_ptr->to_d) > 0) ||
1658 ((o_ptr->to_a) > 0) ||
1659 (o_ptr->pval > 0) || (o_ptr->bpval > 0))) return (0L);
1660 break;
1661
1662 case TV_DIGGING:
1663 case TV_BLUNT:
1664 case TV_POLEARM:
1665 case TV_SWORD:
1666 case TV_AXE:
1667 case TV_SHOT:
1668 case TV_ARROW:
1669 case TV_BOLT:
1670 case TV_BOW:
1671 case TV_BOOMERANG:
1672
1673 case TV_MSTAFF:
1674 case TV_LITE:
1675 case TV_AMULET:
1676 case TV_RING:
1677 case TV_TRAPKIT:
1678
1679 default:
1680 if ((((o_ptr->to_h) < 0 && ((o_ptr->to_h - k_ptr->to_h) < 0 || k_ptr->to_h < 0)) ||
1681 ((o_ptr->to_d) < 0 && ((o_ptr->to_d - k_ptr->to_d) < 0 || k_ptr->to_d < 0)) ||
1682 ((o_ptr->to_a) < 0 && ((o_ptr->to_a - k_ptr->to_a) < 0 || k_ptr->to_a < 0)) ||
1683 /* to allow Mummy Wrappings in bm! - C. Blue */
1684 // (o_ptr->pval < 0) || (o_ptr->bpval < 0)) &&
1685 // (o_ptr->pval < 0) || (o_ptr->bpval < k_ptr->pval)) &&
1686 // (o_ptr->pval < 0) || (o_ptr->tval != TV_ROD && o_ptr->bpval < k_ptr->pval)) &&
1687 (o_ptr->pval < 0) || (o_ptr->bpval < 0 && o_ptr->bpval < k_ptr->pval)) &&
1688 !(((o_ptr->to_h) > 0) ||
1689 ((o_ptr->to_d) > 0) ||
1690 ((o_ptr->to_a) > 0) ||
1691 (o_ptr->pval > 0) || (o_ptr->bpval > 0))) return (0L);
1692 break;
1693 }
1694
1695 /* Analyze pval bonus */
1696 switch (o_ptr->tval)
1697 {
1698 case TV_SHOT:
1699 case TV_ARROW:
1700 case TV_BOLT:
1701 case TV_BOW:
1702 case TV_BOOMERANG:
1703 case TV_AXE:
1704 case TV_MSTAFF:
1705 case TV_DIGGING:
1706 case TV_BLUNT:
1707 case TV_POLEARM:
1708 case TV_SWORD:
1709 case TV_BOOTS:
1710 case TV_GLOVES:
1711 case TV_HELM:
1712 case TV_CROWN:
1713 case TV_SHIELD:
1714 case TV_CLOAK:
1715 case TV_SOFT_ARMOR:
1716 case TV_HARD_ARMOR:
1717 case TV_DRAG_ARMOR:
1718 case TV_LITE:
1719 case TV_AMULET:
1720 case TV_RING:
1721 case TV_TRAPKIT:
1722 {
1723 /* they should be of bpval.. hopefully. */
1724 int pval = o_ptr->bpval, kpval = k_ptr->pval;
1725 /* If the bpval has been set to the k_info pval,
1726 don't increase the item's value for this
1727 granted pval, since it's already included in
1728 the k_info price! */
1729 if (pval >= kpval) {
1730 pval -= kpval;
1731 kpval = 0;
1732 }
1733
1734 /* Don't use bpval of costumes - mikaelh */
1735 if ((o_ptr->tval == TV_SOFT_ARMOR) && (o_ptr->sval == SV_COSTUME)) {
1736 pval = 0;
1737 }
1738
1739 // int boost = 1 << pval;
1740
1741 /* Hack -- Negative "pval" is always bad */
1742 // if (pval < 0) return (0L);
1743
1744 for (i = 0; i < 2; i++)
1745 {
1746 int count = 0;
1747
1748 /* No pval */
1749 // if (!pval)
1750 if (pval <= 0)
1751 {
1752 pval = o_ptr->pval;
1753 continue;
1754 }
1755 /* If the k_info pval became the object's
1756 pval instead of bpval (shouldn't happen)
1757 then take care of it and again don't
1758 increase the value for this granted pval: */
1759 else if (pval >= kpval) {
1760 pval -= kpval;
1761 kpval = 0;
1762 }
1763
1764 /* Give credit for stat bonuses */
1765 // if (f1 & TR1_STR) value += (pval * 200L);
1766 // if (f1 & TR1_STR) value += (boost * 200L);
1767 if (f1 & TR1_STR) count++;
1768 if (f1 & TR1_INT) count++;
1769 if ((f1 & TR1_WIS) && !(f1 & TR1_INT)) count++; /* slightly useless combination */
1770 if (f1 & TR1_DEX) count++;
1771 if (f1 & TR1_CON) count++;
1772 #if 1 /* make CHR cheaper? */
1773 if (f1 & TR1_CHR) {
1774 if (count <= 1) count++;
1775 else value += pval * 1000;
1776 }
1777 #else
1778 if (f1 & TR1_CHR) value += pval * 1000;
1779 #endif
1780 /* hack for double-stat rings - C. Blue */
1781 if ((o_ptr->tval == TV_RING) && (
1782 (o_ptr->sval == SV_RING_MIGHT) ||
1783 (o_ptr->sval == SV_RING_READYWIT) ||
1784 (o_ptr->sval == SV_RING_TOUGHNESS) ||
1785 (o_ptr->sval == SV_RING_CUNNINGNESS))
1786 ) {
1787 count /= 2;
1788 if (count) value += count * PRICE_BOOST((count + pval), 2, 1)* 300L;
1789 } else {
1790 if (count) value += count * PRICE_BOOST((count + pval), 2, 1)* 200L;
1791 }
1792
1793 // if (f5 & (TR5_CRIT)) value += (PRICE_BOOST(pval, 0, 1)* 300L);//was 500, then 400
1794 // if (f5 & (TR5_CRIT)) value += pval * pval * 5000L;/* was 20k, but speed is only 10k */
1795 if (f5 & (TR5_CRIT)) value += (pval + 2) * (pval + 2) * 1500L;/* was 20k, but speed is only 10k */
1796 if (f5 & (TR5_LUCK)) value += (PRICE_BOOST(pval, 0, 1)* 10L);
1797
1798 /* Give credit for stealth and searching */
1799 // if (f1 & TR1_STEALTH) value += (PRICE_BOOST(pval, 3, 1) * 100L);
1800 if (f1 & TR1_STEALTH) value += pval * pval * 250L;//100
1801 if (f1 & TR1_SEARCH) value += pval * pval * 200L;//200
1802 if (f5 & TR5_DISARM) value += pval * pval * 100L;
1803
1804 /* Give credit for infra-vision and tunneling */
1805 if (f1 & TR1_INFRA) value += pval * pval * 150L;//100
1806 if (f1 & TR1_TUNNEL) value += pval * pval * 175L;//50
1807
1808 /* Give credit for extra attacks */
1809 if (o_ptr->tval == TV_RING) {
1810 if (f1 & TR1_BLOWS) value += (PRICE_BOOST(pval, 0, 1) * 2000L);//1500
1811 } else {
1812 // if (f1 & TR1_BLOWS) value += (PRICE_BOOST(pval, 0, 1) * 3000L);
1813 if (f1 & TR1_BLOWS) value += pval * (pval + 2) * 5000L;
1814 }
1815
1816 /* Give credit for extra casting */
1817 if (f1 & TR1_SPELL) value += (PRICE_BOOST(pval, 0, 1) * 4000L);
1818
1819 /* Give credit for extra HP bonus */
1820 if (f1 & TR1_LIFE) value += (PRICE_BOOST(pval, 0, 1) * 3000L);
1821
1822
1823 /* Flags moved here exclusively from flag_cost */
1824 if (f1 & TR1_MANA) value += (200 * pval * (pval + 5));
1825
1826 /* End of flags, moved here from flag_cost */
1827
1828
1829 /* Hack -- amulets of speed and rings of speed are
1830 * cheaper than other items of speed.
1831 */
1832 if (o_ptr->tval == TV_AMULET) {
1833 /* Give credit for speed bonus */
1834 //if (f1 & TR1_SPEED) value += (boost * 25000L);
1835 if (f1 & TR1_SPEED) value += pval * pval * 5000L;
1836 } else if (o_ptr->tval == TV_RING) {
1837 /* Give credit for speed bonus */
1838 //if (f1 & TR1_SPEED) value += (PRICE_BOOST(pval, 0, 4) * 50000L);
1839 if (f1 & TR1_SPEED) value += pval * pval * 10000L;
1840 // if (f1 & TR1_SPEED) value += pval * pval * 7000L;
1841 }
1842 /* randarts and speed boots */
1843 // else if (f1 & TR1_SPEED) value += (PRICE_BOOST(pval, 0, 4) * 100000L);
1844 // else if (f1 & TR1_SPEED) value += pval * pval * 10000L;
1845 else if (f1 & TR1_SPEED) value += (pval + 1) * (pval + 1) * 6000L;//7000 -> //5000
1846
1847 pval = o_ptr->pval;
1848
1849 if (o_ptr->name2) {
1850 artifact_type *a_ptr;
1851
1852 a_ptr = ego_make(o_ptr);
1853 f1 &= ~(k_ptr->flags1 & TR1_PVAL_MASK & ~a_ptr->flags1);
1854 f5 &= ~(k_ptr->flags5 & TR5_PVAL_MASK & ~a_ptr->flags5);
1855 }
1856 }
1857 break;
1858 }
1859 }
1860
1861
1862 /* Analyze the item */
1863 switch (o_ptr->tval) {
1864 case TV_BOOK:
1865 if (o_ptr->sval == SV_SPELLBOOK) {
1866 /* 1: 145, 2: 240, 3: 375, 4: 540, 5: 735 */
1867 /* */
1868 int sl = school_spells[o_ptr->pval].skill_level + 5,
1869 ego_value = value - k_ptr->cost,
1870 ev = ego_value > 700 ? 700 : ego_value;
1871 /* override k_info.txt to have easier handling of possible changes here */
1872 value = 4;
1873 /* Pay extra for the spell */
1874 value = value * (sl * sl);
1875 /* Add up 'fireproof' etc cost, but related it to the actual scroll cost. */
1876 value += value < ego_value ? (value < ev ? ev : value) : ego_value;
1877 }
1878 /* Done */
1879 break;
1880
1881 /* Wands/Staffs */
1882 case TV_WAND:
1883 /* Pay extra for charges */
1884 value += ((value / 20) * o_ptr->pval) / o_ptr->number;
1885
1886 /* Done */
1887 break;
1888
1889 case TV_STAFF:
1890 /* Pay extra for charges */
1891 value += ((value / 20) * o_ptr->pval);
1892
1893 /* Done */
1894 break;
1895
1896 /* Rings/Amulets */
1897 case TV_RING:
1898 case TV_AMULET:
1899 #if 0
1900 /* Hack -- negative bonuses are bad */
1901 if (o_ptr->to_a < 0) return (0L);
1902 if (o_ptr->to_h < 0) return (0L);
1903 if (o_ptr->to_d < 0) return (0L);
1904 #endif
1905
1906 /* keep consistent with store.c: price_item():
1907 This price will be the store-sells price so it must be higher than the store-buys price there. */
1908 if ((o_ptr->tval == TV_RING) && (o_ptr->sval == SV_RING_POLYMORPH)) {
1909 if (o_ptr->pval != 0)
1910 value += (r_info[o_ptr->pval].level * r_info[o_ptr->pval].mexp >= r_info[o_ptr->pval].level * 100) ?
1911 r_info[o_ptr->pval].level * r_info[o_ptr->pval].mexp :
1912 r_info[o_ptr->pval].level * 100;
1913 }
1914
1915 /* Give credit for bonuses */
1916 // value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
1917 /* Ignore base boni that come from k_info.txt (eg quarterstaff +10 AC) */
1918 value += ((PRICE_BOOST(o_ptr->to_h, 12, 4) +
1919 PRICE_BOOST(o_ptr->to_d, 7, 3) +
1920 PRICE_BOOST(o_ptr->to_a, 11, 4)) * 100L);
1921
1922 /* Done */
1923 break;
1924
1925 /* Armor */
1926 case TV_BOOTS:
1927 case TV_GLOVES:
1928 case TV_CLOAK:
1929 case TV_CROWN:
1930 case TV_HELM:
1931 case TV_SHIELD:
1932 case TV_SOFT_ARMOR:
1933 case TV_HARD_ARMOR:
1934 case TV_DRAG_ARMOR:
1935 #if 0
1936 /* Hack -- negative armor bonus */
1937 if (o_ptr->to_a < 0) return (0L);
1938 #endif
1939 /* Give credit for bonuses */
1940 // value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
1941 /* Ignore base boni that come from k_info.txt (eg quarterstaff +10 AC) */
1942 value += ( ((o_ptr->to_h <= 0 || o_ptr->to_h <= k_ptr->to_h)? 0 :
1943 ((k_ptr->to_h < 0)? PRICE_BOOST(o_ptr->to_h, 9, 5):
1944 PRICE_BOOST((o_ptr->to_h - k_ptr->to_h), 9, 5))) +
1945 ((o_ptr->to_d <= 0 || o_ptr->to_d <= k_ptr->to_d)? 0 :
1946 ((k_ptr->to_d < 0)? PRICE_BOOST(o_ptr->to_d, 9, 5):
1947 PRICE_BOOST((o_ptr->to_d - k_ptr->to_d), 9, 5))) +
1948 ((o_ptr->to_a <= 0 || o_ptr->to_a <= k_ptr->to_a)? 0 :
1949 ((k_ptr->to_a < 0)? PRICE_BOOST(o_ptr->to_a, 9, 5):
1950 PRICE_BOOST((o_ptr->to_a - k_ptr->to_a), 9, 5))) ) * 100L;
1951
1952 /* Costumes */
1953 if ((o_ptr->tval == TV_SOFT_ARMOR) && (o_ptr->sval == SV_COSTUME)) {
1954 value += r_info[o_ptr->bpval].mexp / 10;
1955 }
1956
1957 /* Done */
1958 break;
1959
1960 /* Bows/Weapons */
1961 case TV_BOW:
1962 case TV_BOOMERANG:
1963 case TV_AXE:
1964 case TV_DIGGING:
1965 case TV_BLUNT:
1966 case TV_SWORD:
1967 case TV_POLEARM:
1968 case TV_MSTAFF:
1969 case TV_TRAPKIT:
1970 #if 0
1971 /* Hack -- negative hit/damage bonuses */
1972 if (o_ptr->to_h + o_ptr->to_d < 0)
1973 {
1974 /* Hack -- negative hit/damage are of no importance */
1975 if (o_ptr->tval == TV_MSTAFF) break;
1976 if (o_ptr->name2 == EGO_STAR_DF) break;
1977 else return (0L);
1978 }
1979 #endif
1980 /* Factor in the bonuses */
1981 // value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
1982 /* Ignore base boni that come from k_info.txt (eg quarterstaff +10 AC) */
1983 value += ( ((o_ptr->to_h <= 0 || o_ptr->to_h <= k_ptr->to_h)? 0 :
1984 ((k_ptr->to_h < 0)? PRICE_BOOST(o_ptr->to_h, 9, 5):
1985 PRICE_BOOST((o_ptr->to_h - k_ptr->to_h), 9, 5))) +
1986 ((o_ptr->to_d <= 0 || o_ptr->to_d <= k_ptr->to_d)? 0 :
1987 ((k_ptr->to_d < 0)? PRICE_BOOST(o_ptr->to_d, 9, 5):
1988 PRICE_BOOST((o_ptr->to_d - k_ptr->to_d), 9, 5))) +
1989 ((o_ptr->to_a <= 0 || o_ptr->to_a <= k_ptr->to_a)? 0 :
1990 ((k_ptr->to_a < 0)? PRICE_BOOST(o_ptr->to_a, 9, 5):
1991 PRICE_BOOST((o_ptr->to_a - k_ptr->to_a), 9, 5))) ) * 100L;
1992
1993 /* Hack -- Factor in extra damage dice */
1994 if ((i = o_ptr->dd * (o_ptr->ds + 1) - k_ptr->dd * (k_ptr->ds + 1)))
1995 value += i * i * i;
1996
1997 /* Done */
1998 break;
1999
2000 /* Ammo */
2001 case TV_SHOT:
2002 case TV_ARROW:
2003 case TV_BOLT:
2004 /* Hack -- negative hit/damage bonuses */
2005 // if (o_ptr->to_h + o_ptr->to_d < 0) return (0L);
2006
2007 /* Factor in the bonuses */
2008 // value += ((o_ptr->to_h + o_ptr->to_d) * 5L);
2009 /* Ignore base boni that come from k_info.txt (eg quarterstaff +10 AC) */
2010 value += ( ((o_ptr->to_h <= 0 || o_ptr->to_h <= k_ptr->to_h)? 0 :
2011 ((k_ptr->to_h < 0)? PRICE_BOOST(o_ptr->to_h, 9, 5):
2012 PRICE_BOOST((o_ptr->to_h - k_ptr->to_h), 9, 5))) +
2013 ((o_ptr->to_d <= 0 || o_ptr->to_d <= k_ptr->to_d)? 0 :
2014 ((k_ptr->to_d < 0)? PRICE_BOOST(o_ptr->to_d, 9, 5):
2015 PRICE_BOOST((o_ptr->to_d - k_ptr->to_d), 9, 5))) ) * 5L;
2016
2017 /* Hack -- Factor in extra damage dice */
2018 if ((i = o_ptr->dd * (o_ptr->ds + 1) - k_ptr->dd * (k_ptr->ds + 1)))
2019 value += i * 5000L;
2020
2021 /* Special attack (exploding arrow) */
2022 if (o_ptr->pval != 0) {
2023 if (o_ptr->name1 != ART_RANDART) value *= 8;
2024 else value *= 2;
2025 }
2026
2027 /* Done */
2028 break;
2029 }
2030
2031 /* hack against those 500k randarts */
2032 if (o_ptr->name1 == ART_RANDART) {
2033 value >>= 1; /* general randart value nerf */
2034 // if (f3 & TR3_AGGRAVATE) value >>= 1; /* aggravate penalty 2 of 2 */
2035 }
2036
2037 /* hack for Ethereal ammunition */
2038 if (o_ptr->name2 == EGO_ETHEREAL || o_ptr->name2b == EGO_ETHEREAL)
2039 value *= 3; /* in theory 1 eth = 10 normal ammo, but this is appropriate */
2040
2041 if (f3 & TR3_AGGRAVATE) value >>= 1; /* one generic aggravate penalty fits it all */
2042
2043 /* Return the value */
2044 return (value);
2045 }
2046
2047
2048 /* Return a sensible pricing for randarts, which
2049 gets added to k_info base item price - C. Blue
2050 Note: Some pretty unimportant flags are missing. */
2051 s32b artifact_flag_cost(object_type *o_ptr, int plusses) {
2052 artifact_type *a_ptr;
2053 s32b total = 0, am, minus, slay = 0;
2054 u32b f1, f2, f3, f4, f5, f6, esp;
2055 int res_amass = 0, res_base;
2056
2057 object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
2058
2059 if (f5 & TR5_TEMPORARY) return 0;
2060
2061 /* Hack - This shouldn't be here, still.. */
2062 eliminate_common_ego_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
2063
2064 /* hack: Artifact ammunition actually uses a_ptr->cost.. somewhat inconsistent, sorry */
2065 if ((o_ptr->name1 == ART_RANDART) && is_ammo(o_ptr->tval)) {
2066 a_ptr = randart_make(o_ptr);
2067 return(a_ptr->cost);
2068 }
2069
2070 if (f4 & TR4_AUTO_ID) {
2071 if (o_ptr->tval == TV_GLOVES)
2072 total += 100000;
2073 else
2074 total += 65000;
2075 }
2076 if (f3 & TR3_WRAITH) total += 100000;
2077 if (f5 & TR5_INVIS) total += 10000;
2078 if (!(f4 & TR4_FUEL_LITE)) {
2079 if (f3 & TR3_LITE1) total += 750;
2080 if (f4 & TR4_LITE2) total += 1250;
2081 if (f4 & TR4_LITE3) total += 2750;
2082 }
2083
2084 if ((!(f4 & TR4_FUEL_LITE)) && (f3 & TR3_IGNORE_FIRE)) total += 100;
2085 if (f5 & TR5_CHAOTIC) total += 0;
2086 if (f1 & TR1_VAMPIRIC) total += 30000;
2087
2088 if (f1 & TR1_SLAY_ANIMAL) slay += 1500;
2089 if (f1 & TR1_SLAY_EVIL) slay += 5500;
2090 if (f1 & TR1_SLAY_UNDEAD) slay += 3000;
2091 if (f1 & TR1_SLAY_DEMON) slay += 3500;
2092 if (f1 & TR1_SLAY_ORC) slay += 1000;
2093 if (f1 & TR1_SLAY_TROLL) slay += 1500;
2094 if (f1 & TR1_SLAY_GIANT) slay += 2000;
2095 if (f1 & TR1_SLAY_DRAGON) slay += 3000;
2096 if (f1 & TR1_KILL_DEMON) slay += 7500;
2097 if (f1 & TR1_KILL_UNDEAD) slay += 7500;
2098 if (f1 & TR1_KILL_DRAGON) slay += 7500;
2099 if (f1 & TR1_BRAND_POIS) slay += 2500;
2100 if (f1 & TR1_BRAND_ACID) slay += 4500;
2101 if (f1 & TR1_BRAND_ELEC) slay += 4500;
2102 if (f1 & TR1_BRAND_FIRE) slay += 3000;
2103 if (f1 & TR1_BRAND_COLD) slay += 2500;
2104
2105 /* slay value depends on weapon dice :-o */
2106 if (f4 & (TR4_MUST2H | TR4_SHOULD2H)) {
2107 total += (slay * ((o_ptr->dd * (o_ptr->ds + 1)) + 80)) / 100;
2108 } else {
2109 total += (slay * ((5 * o_ptr->dd * (o_ptr->ds + 1)) + 50)) / 100;
2110 }
2111
2112 if (f5 & TR5_VORPAL) total += 20000;
2113 if (f5 & TR5_IMPACT) total += 5000;
2114 if (f2 & TR2_SUST_STR) total += 2850;
2115 if (f2 & TR2_SUST_INT) total += 2850;
2116 if (f2 & TR2_SUST_WIS) total += 2850;
2117 if (f2 & TR2_SUST_DEX) total += 2850;
2118 if (f2 & TR2_SUST_CON) total += 2850;
2119 if (f2 & TR2_SUST_CHR) total += 1250;
2120 if (f5 & TR5_REFLECT) total += 10000;
2121 if (f2 & TR2_FREE_ACT) {
2122 total += 4500;
2123 res_amass++;
2124 }
2125 if (f2 & TR2_HOLD_LIFE) {
2126 total += 8500;
2127 res_amass++;
2128 }
2129
2130 /* f6 Not yet implemented in object_flags/eliminate_common_ego_flags etc. Really needed??
2131 // if (f5 & TR5_SENS_FIRE) total -= 100;
2132 if (f6 & TR6_SENS_COLD) total -= 100;
2133 if (f6 & TR6_SENS_ACID) total -= 100;
2134 if (f6 & TR6_SENS_ELEC) total -= 100;
2135 if (f6 & TR6_SENS_POIS) total -= 100; */
2136
2137 if (f2 & TR2_IM_ACID) {
2138 total += 30000;
2139 res_amass += 2;
2140 f2 |= TR2_RES_ACID;
2141 } else if (f2 & TR2_RES_ACID) total += 1250;
2142 if (f2 & TR2_IM_ELEC) {
2143 total += 20000;
2144 res_amass += 2;
2145 f2 |= TR2_RES_ELEC;
2146 } else if (f2 & TR2_RES_ELEC) total += 1250;
2147 if (f2 & TR2_IM_FIRE) {
2148 total += 30000;
2149 res_amass += 2;
2150 f2 |= TR2_RES_FIRE;
2151 } else if (f2 & TR2_RES_FIRE) total += 1250;
2152 if (f2 & TR2_IM_COLD) {
2153 total += 20000;
2154 res_amass += 2;
2155 f2 |= TR2_RES_COLD;
2156 } else if (f2 & TR2_RES_COLD) total += 1250;
2157 /* count (semi)complete base res as 1up too */
2158 res_base =
2159 (f2 & (TR2_RES_ACID)) ? 1 : 0 +
2160 (f2 & (TR2_RES_ELEC)) ? 1 : 0 +
2161 (f2 & (TR2_RES_FIRE)) ? 1 : 0 +
2162 (f2 & (TR2_RES_COLD)) ? 1 : 0;
2163 if (res_base == 3) res_amass++;
2164 else if (res_base == 4) res_amass += 2;
2165
2166 if (f2 & TR2_RES_POIS) {
2167 total += 5000;
2168 res_amass++;
2169 }
2170 if (f2 & TR2_RES_FEAR) total += 2000;
2171 if (f2 & TR2_RES_LITE) total += 2750;
2172 if (f2 & TR2_RES_DARK) {
2173 total += 2750;
2174 res_amass++;
2175 }
2176 if (f2 & TR2_RES_BLIND) total += 6000;
2177 if (f2 & TR2_RES_CONF) total += 1500;
2178 if (f2 & TR2_RES_SOUND) {
2179 total += 7000;
2180 res_amass += 2;
2181 }
2182 if (f2 & TR2_RES_SHARDS) {
2183 total += 4000;
2184 res_amass++;
2185 }
2186 if (f2 & TR2_RES_NETHER) {
2187 total += 10000;
2188 res_amass += 2;
2189 }
2190 if (f2 & TR2_RES_NEXUS) {
2191 total += 7000;
2192 res_amass += 2;
2193 }
2194 if (f2 & TR2_RES_CHAOS) {
2195 total += 10000;
2196 res_amass += 2;
2197 }
2198 if (f2 & TR2_RES_DISEN) {
2199 total += 10000;
2200 res_amass += 2;
2201 }
2202 if (f5 & TR5_RES_MANA) {
2203 total += 15000;
2204 res_amass += 2;
2205 }
2206
2207 if (f3 & TR3_SH_FIRE) total += 2000;
2208 if (f5 & TR5_SH_COLD) total += 2000;
2209 if (f3 & TR3_SH_ELEC) total += 2000;
2210 if (f3 & TR3_DECAY) total += 0;
2211 //done elsewhere if (f3 & TR3_NO_TELE) total -= 50000;
2212 if (f3 & TR3_NO_MAGIC) total += 0;
2213 if (f3 & TR3_TY_CURSE) total -= 15000;
2214 if (f3 & TR3_EASY_KNOW) total += 0;
2215 if (f3 & TR3_HIDE_TYPE) total += 0;
2216 if (f3 & TR3_SHOW_MODS) total += 0;
2217 if (f3 & TR3_INSTA_ART) total += 0;
2218 if (f3 & TR3_SEE_INVIS) total += 2000;
2219 if (esp & ESP_ORC) total += 1000;
2220 if (esp & ESP_TROLL) total += 2000;
2221 if (esp & ESP_DRAGON) total += 5000;
2222 if (esp & ESP_GIANT) total += 3000;
2223 if (esp & ESP_DEMON) total += 6000;
2224 if (esp & ESP_UNDEAD) total += 6000;
2225 if (esp & ESP_EVIL) total += 20000;
2226 if (esp & ESP_ANIMAL) total += 6000;
2227 if (esp & ESP_DRAGONRIDER) total += 3000;
2228 if (esp & ESP_GOOD) total += 8000;
2229 if (esp & ESP_NONLIVING) total += 5000;
2230 if (esp & ESP_UNIQUE) total += 4000;
2231 if (esp & ESP_SPIDER) total += 2000;
2232 if (esp & ESP_ALL) total += 150000;// + 40000; /* hm, extra bonus */
2233 if (f3 & TR3_SLOW_DIGEST) total += 750;
2234 if (f3 & TR3_REGEN) total += 3500;
2235 if (f5 & TR5_REGEN_MANA) total += 2500;
2236 if (f3 & TR3_XTRA_MIGHT) total += 10000;
2237 if (f3 & TR3_XTRA_SHOTS) total += 10000;
2238 if (f5 & TR5_IGNORE_WATER) total += 0;
2239 if (f5 & TR5_IGNORE_MANA) total += 0;
2240 if (f5 & TR5_IGNORE_DISEN) total += 0;
2241 if (f3 & TR3_IGNORE_ACID) total += 0;
2242 if (f3 & TR3_IGNORE_ELEC) total += 0;
2243 if (f3 & TR3_IGNORE_COLD) total += 0;
2244 if (f3 & TR3_ACTIVATE) total += 100;
2245 if (f3 & TR3_DRAIN_EXP) total -= 20000;
2246 if (f3 & TR3_TELEPORT) {
2247 if (o_ptr->ident & ID_CURSED)
2248 total -= 7500;
2249 else
2250 total += 500;
2251 }
2252 // if (f3 & TR3_AGGRAVATE) total -= 10000; /* penalty 1 of 2 */
2253 if (f3 & TR3_BLESSED) total += 750;
2254 if (f3 & TR3_CURSED) total -= 5000;
2255 if (f3 & TR3_HEAVY_CURSE) total -= 12500;
2256 if (f3 & TR3_PERMA_CURSE) total -= 50000;
2257 if (f3 & TR3_FEATHER) total += 1700;
2258
2259 if (f4 & TR4_LEVITATE) total += 10000;
2260 if (f4 & TR4_NEVER_BLOW) total -= 15000;
2261 if (f4 & TR4_PRECOGNITION) total += 250000;
2262 if (f4 & TR4_BLACK_BREATH) total -= 40000;
2263 if (f4 & TR4_DG_CURSE) total -= 25000;
2264 if (f4 & TR4_CLONE) total -= 20000;
2265 // if (f5 & TR5_LEVELS) total += o_ptr->elevel * 2000;
2266
2267 am = ((f4 & (TR4_ANTIMAGIC_50)) ? 50 : 0)
2268 + ((f4 & (TR4_ANTIMAGIC_30)) ? 30 : 0)
2269 + ((f4 & (TR4_ANTIMAGIC_20)) ? 20 : 0)
2270 + ((f4 & (TR4_ANTIMAGIC_10)) ? 10 : 0);
2271 minus = o_ptr->to_h + o_ptr->to_d; // + pval;// + (o_ptr->to_a /
2272 if (minus < 0) minus = 0;
2273 // + ((o_ptr->tval == TV_SWORD && o_ptr->sval == SV_DARK_SWORD) ? -5 : 0);
2274 // if (am > 0) total += (PRICE_BOOST(am, 1, 1)* 2000L);
2275 am -= minus;
2276 if (am > 50) am = 50; /* paranoia, mustn't happen */
2277 if (am > 37) {
2278 am -= 37;
2279 total += (am * am) * 100;
2280 }
2281
2282 /* accumulation of many resistances is extra valuable (like PDSM ;)) - C. Blue */
2283 if (res_amass >= 6) {
2284 if (res_amass > 10) res_amass = 10; /* limit to 3..5 powerful resses */
2285 res_amass -= 3;
2286 total += (res_amass * res_amass) * 2000;
2287 }
2288
2289 /* Hack -- ammos shouldn't be that expensive */
2290 if (is_ammo(o_ptr->tval))
2291 total >>= 2;
2292
2293 return total;
2294 }
2295
2296 /* Return rating for especially useful armour, that means
2297 armour that has top +AC and at the same time useful resistances.
2298 We don't discriminate between pre/postking though. - C. Blue */
2299 static int artifact_flag_rating_armour(object_type *o_ptr) {
2300 s32b total = 0, slay = 0;
2301 u32b f1, f2, f3, f4, f5, f6, esp;
2302
2303 /* this routine treats armour only */
2304 if ((o_ptr->name1 != ART_RANDART) || !is_armour(o_ptr->tval)) return 0;
2305
2306 object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
2307
2308 if (f5 & TR5_TEMPORARY) return 0;
2309
2310 /* Hack - This shouldn't be here, still.. */
2311 eliminate_common_ego_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
2312
2313
2314 if (f2 & TR2_IM_ACID) {
2315 total += 6;
2316 f2 |= TR2_RES_ACID;
2317 }
2318 else if (f2 & TR2_RES_ACID) total++;
2319 if (f2 & TR2_IM_ELEC) {
2320 total += 6;
2321 f2 |= TR2_RES_ELEC;
2322 }
2323 else if (f2 & TR2_RES_ELEC) total++;
2324 if (f2 & TR2_IM_FIRE) {
2325 total += 6;
2326 f2 |= TR2_RES_FIRE;
2327 }
2328 else if (f2 & TR2_RES_FIRE) total++;
2329 if (f2 & TR2_IM_COLD) {
2330 total += 6;
2331 f2 |= TR2_RES_COLD;
2332 }
2333 else if (f2 & TR2_RES_COLD) total++;
2334 /* count complete base res as 1up too */
2335 if ((f2 & (TR2_RES_ACID | TR2_RES_ELEC | TR2_RES_FIRE | TR2_RES_COLD))
2336 == (TR2_RES_ACID | TR2_RES_ELEC | TR2_RES_FIRE | TR2_RES_COLD))
2337 total += 4;
2338 if (f2 & TR2_RES_POIS) total += 4;
2339 if (f2 & TR2_RES_LITE) total += 2;
2340 if (f2 & TR2_RES_DARK) total += 2;
2341 if (f2 & TR2_RES_BLIND) total += 2;
2342 if (f2 & TR2_RES_SOUND) total += 4;
2343 if (f2 & TR2_RES_SHARDS) total += 4;
2344 if (f2 & TR2_RES_NETHER) total += 4;
2345 if (f2 & TR2_RES_NEXUS) total += 3;
2346 if (f2 & TR2_RES_CHAOS) total += 4;
2347 if (f2 & TR2_RES_DISEN) total += 4;
2348 if (f5 & TR5_RES_MANA) total += 2;
2349 if (f5 & TR5_REGEN_MANA) total += 2;
2350 if (f4 & TR4_LEVITATE) total += 2;
2351 if (f2 & TR2_FREE_ACT) total += 2;
2352 if (f2 & TR2_HOLD_LIFE) total += 4;
2353 /* Give credit for extra HP bonus */
2354 if (f1 & TR1_LIFE) total += o_ptr->pval * 2;
2355 /* Too good to ignore */
2356 if (esp & ESP_EVIL) total += 1;
2357 if (esp & ESP_ALL) total += 3;
2358
2359 /* Glove mods mostly */
2360 if (f1 & TR1_VAMPIRIC) total += 10;
2361 if (f1 & TR1_BLOWS) total += o_ptr->pval * 5;
2362 if (f5 & TR5_CRIT) total += o_ptr->pval;
2363 if (f1 & TR1_KILL_DEMON) slay++;
2364 if (f1 & TR1_KILL_UNDEAD) slay++;
2365 if (f1 & TR1_KILL_DRAGON) slay++;
2366 if (f1 & TR1_SLAY_EVIL) {
2367 if (slay <= 1) slay += 2;
2368 else if (slay <= 2) slay += 1;
2369 }
2370 if (f1 & TR1_BRAND_ACID) {
2371 if (slay <= 1) slay += 2;
2372 else if (slay <= 2) slay += 1;
2373 }
2374 if (f1 & TR1_BRAND_ELEC) {
2375 if (slay <= 1) slay += 2;
2376 else if (slay <= 2) slay += 1;
2377 }
2378 total += slay * 4;
2379
2380
2381 if (f3 & TR3_DRAIN_EXP) total >>= 1;
2382
2383 return total;
2384 }
2385
2386 /* Return rating for especially useful weapons, that means a
2387 weapon that has top +hit and especially +dam, and at the
2388 same time useful damage mods such as EA/Vamp/Crit. - C. Blue */
2389 static int artifact_flag_rating_weapon(object_type *o_ptr) {
2390 s32b total = 0;
2391 u32b f1, f2, f3, f4, f5, f6, esp;
2392 int slay = 0;
2393
2394 /* this routine treats armour only */
2395 if ((o_ptr->name1 != ART_RANDART) || !is_weapon(o_ptr->tval)) return 0;
2396
2397 object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
2398
2399 if (f5 & TR5_TEMPORARY) return 0;
2400 if (f4 & TR4_NEVER_BLOW) return 0;
2401
2402 /* Hack - This shouldn't be here, still.. */
2403 eliminate_common_ego_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
2404
2405
2406 /* Too useful to ignore, but not really helping damage */
2407 if (f2 & TR2_IM_ACID) total++;
2408 if (f2 & TR2_IM_ELEC) total++;
2409 if (f2 & TR2_IM_FIRE) total++;
2410 if (f2 & TR2_IM_COLD) total++;
2411 if (esp & ESP_ALL) total++;
2412
2413 /* 'The' weapon mods */
2414 if (f1 & TR1_VAMPIRIC) total += 3;
2415 // if (f1 & TR1_BLOWS) total += o_ptr->pval * 2;
2416 if (f1 & TR1_BLOWS) total += (o_ptr->pval * (o_ptr->pval + 1));
2417 if (f5 & TR5_CRIT) total += (o_ptr->pval + 5) / 3;
2418 else if (f5 & TR5_VORPAL) total += 2;
2419
2420 if (f1 & TR1_KILL_DEMON) slay++;
2421 if (f1 & TR1_KILL_UNDEAD) slay++;
2422 if (f1 & TR1_KILL_DRAGON) slay++;
2423 if (f1 & TR1_SLAY_EVIL) {
2424 if (slay <= 1) slay += 2;
2425 else if (slay <= 2) slay += 1;
2426 }
2427 if (f1 & TR1_BRAND_ACID) {
2428 if (slay <= 1) slay += 2;
2429 else if (slay <= 2) slay += 1;
2430 }
2431 if (f1 & TR1_BRAND_ELEC) {
2432 if (slay <= 1) slay += 2;
2433 else if (slay <= 2) slay += 1;
2434 }
2435 /* slay value depends on weapon dice :-o */
2436 if (f4 & (TR4_MUST2H | TR4_SHOULD2H)) {
2437 total += (slay * ((o_ptr->dd * (o_ptr->ds + 1)) + 70)) / 80;
2438 } else {
2439 total += (slay * ((o_ptr->dd * (o_ptr->ds + 1)) + 30)) / 35;
2440 }
2441
2442 /* for randart Dark Swords */
2443 if (f4 & TR4_ANTIMAGIC_50) {
2444 /* more AM is valuable for compensating +hit,+dam. */
2445 slay = 15; /* abuse 'slay' */
2446 if (f4 & TR4_ANTIMAGIC_30) slay += 30;
2447 if (f4 & TR4_ANTIMAGIC_20) slay += 20;
2448 if (f4 & TR4_ANTIMAGIC_10) slay += 10;
2449 /* 10 base, 20x, +0, +6 , +16 , +30 , +48 , +70 */
2450 /* 15 base, 20x, +0, +9.5, +22.5, +37.5, +57.5, +81.5 */
2451 total += (20 * slay * slay) - 3000;
2452 }
2453
2454
2455 if (f4 & TR4_CLONE) total >>= 1;
2456
2457 return total;
2458 }
2459
2460 /* Return a sensible pricing for randarts, which
2461 gets added to k_info base item price - C. Blue */
2462 s64b artifact_value_real(int Ind, object_type *o_ptr) {
2463 u32b f1, f2, f3, f4, f5, f6, esp;
2464 object_kind *k_ptr = &k_info[o_ptr->k_idx];
2465 bool star = (Ind == 0 || object_fully_known_p(Ind, o_ptr));
2466
2467 /* Base cost */
2468 s64b value = k_ptr->cost;
2469 int i;
2470 /* Hack -- "worthless" items */
2471 if (!value) return (0L);
2472
2473 /* Extract some flags */
2474 object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
2475
2476 /* Artifact */
2477 if (o_ptr->name1) {
2478 artifact_type *a_ptr;
2479
2480 /* Randarts */
2481 if (o_ptr->name1 == ART_RANDART) {
2482 a_ptr = randart_make(o_ptr);
2483 if (a_ptr->flags3 & TR3_AUTO_CURSE) return (0L);
2484 else {
2485 /* start with base item kind price (k_info) */
2486 value = object_value_base(0, o_ptr);
2487 /* randarts get a base value boost */
2488 value += 5000;// + o_ptr->level * 200;
2489 /* randart ammo is always very useful so it gets an extra base value boost */
2490 if (is_ammo(o_ptr->tval)) value += 5000;
2491 /* add full value if *ID*ed */
2492 if (star) value += artifact_flag_cost(o_ptr, o_ptr->pval);
2493
2494 /* maybe todo (see function below):
2495 value = artifact_value_real(a_ptr);
2496 */
2497 }
2498 if (value < 0) value = 0;
2499 } else {
2500 a_ptr = &a_info[o_ptr->name1];
2501 value = a_ptr->cost;
2502
2503 /* Let true arts' prices be totally determined in a_info.txt */
2504 return (value);
2505 }
2506
2507 /* Hack -- "worthless" artifacts */
2508 if (!value) return (0L);
2509
2510 /* Hack -- Use the artifact cost instead */
2511 // value = a_ptr->cost;
2512 }
2513
2514 /* Bad items don't sell. Good items with some bad modifiers DO sell ((*defenders*)). -C. Blue */
2515 switch (o_ptr->tval) {
2516 case TV_BOOTS:
2517 case TV_GLOVES:
2518 case TV_HELM:
2519 case TV_CROWN:
2520 case TV_SHIELD:
2521 case TV_CLOAK:
2522 case TV_SOFT_ARMOR:
2523 case TV_HARD_ARMOR:
2524 case TV_DRAG_ARMOR:
2525 if ((((o_ptr->to_h) < 0 && ((o_ptr->to_h - k_ptr->to_h) < 0)) ||
2526 ((o_ptr->to_d) < 0 && ((o_ptr->to_d - k_ptr->to_d) < 0 || k_ptr->to_d < 0)) ||
2527 ((o_ptr->to_a) < 0 && ((o_ptr->to_a - k_ptr->to_a) < 0 || k_ptr->to_a < 0)) ||
2528 (o_ptr->pval < 0) || (o_ptr->bpval < 0)) &&
2529 !(((o_ptr->to_h) > 0) ||
2530 ((o_ptr->to_d) > 0) ||
2531 ((o_ptr->to_a) > 0) ||
2532 (o_ptr->pval > 0) || (o_ptr->bpval > 0))) return (0L);
2533 break;
2534
2535 case TV_DIGGING:
2536 case TV_BLUNT:
2537 case TV_POLEARM:
2538 case TV_SWORD:
2539 case TV_AXE:
2540 case TV_SHOT:
2541 case TV_ARROW:
2542 case TV_BOLT:
2543 case TV_BOW:
2544 case TV_BOOMERANG:
2545
2546 case TV_MSTAFF:
2547 case TV_LITE:
2548 case TV_AMULET:
2549 case TV_RING:
2550 case TV_TRAPKIT:
2551
2552 default:
2553 if ((((o_ptr->to_h) < 0 && ((o_ptr->to_h - k_ptr->to_h) < 0 || k_ptr->to_h < 0)) ||
2554 ((o_ptr->to_d) < 0 && ((o_ptr->to_d - k_ptr->to_d) < 0 || k_ptr->to_d < 0)) ||
2555 ((o_ptr->to_a) < 0 && ((o_ptr->to_a - k_ptr->to_a) < 0 || k_ptr->to_a < 0)) ||
2556 /* to allow Mummy Wrappings in bm! - C. Blue */
2557 // (o_ptr->pval < 0) || (o_ptr->bpval < 0)) &&
2558 // (o_ptr->pval < 0) || (o_ptr->bpval < k_ptr->pval)) &&
2559 // (o_ptr->pval < 0) || (o_ptr->tval != TV_ROD && o_ptr->bpval < k_ptr->pval)) &&
2560 (o_ptr->pval < 0) || (o_ptr->bpval < 0 && o_ptr->bpval < k_ptr->pval)) &&
2561 !(((o_ptr->to_h) > 0) ||
2562 ((o_ptr->to_d) > 0) ||
2563 ((o_ptr->to_a) > 0) ||
2564 (o_ptr->pval > 0) || (o_ptr->bpval > 0))) return (0L);
2565 break;
2566 }
2567
2568 /* Analyze pval bonus */
2569 switch (o_ptr->tval) {
2570 case TV_SHOT:
2571 case TV_ARROW:
2572 case TV_BOLT:
2573 case TV_BOW:
2574 case TV_BOOMERANG:
2575 case TV_AXE:
2576 case TV_MSTAFF:
2577 case TV_DIGGING:
2578 case TV_BLUNT:
2579 case TV_POLEARM:
2580 case TV_SWORD:
2581 case TV_BOOTS:
2582 case TV_GLOVES:
2583 case TV_HELM:
2584 case TV_CROWN:
2585 case TV_SHIELD:
2586 case TV_CLOAK:
2587 case TV_SOFT_ARMOR:
2588 case TV_HARD_ARMOR:
2589 case TV_DRAG_ARMOR:
2590 case TV_LITE:
2591 case TV_AMULET:
2592 case TV_RING:
2593 case TV_TRAPKIT:
2594 {
2595 /* they should be of bpval.. hopefully. */
2596 int pval = o_ptr->bpval, kpval = k_ptr->pval;
2597 /* If the bpval has been set to the k_info pval,
2598 don't increase the item's value for this
2599 granted pval, since it's already included in
2600 the k_info price! */
2601 if (pval >= kpval) {
2602 pval -= kpval;
2603 kpval = 0;
2604 }
2605
2606 // int boost = 1 << pval;
2607
2608 /* Hack -- Negative "pval" is always bad */
2609 // if (pval < 0) return (0L);
2610
2611 for (i = 0; i < 2; i++) {
2612 int count = 0;
2613
2614 /* No pval */
2615 // if (!pval)
2616 if (pval <= 0) {
2617 pval = o_ptr->pval;
2618 continue;
2619 }
2620 /* If the k_info pval became the object's
2621 pval instead of bpval (shouldn't happen)
2622 then take care of it and again don't
2623 increase the value for this granted pval: */
2624 else if (pval >= kpval) {
2625 pval -= kpval;
2626 kpval = 0;
2627 }
2628
2629 /* Give credit for stat bonuses */
2630 // if (f1 & TR1_STR) value += (pval * 200L);
2631 // if (f1 & TR1_STR) value += (boost * 200L);
2632 if (f1 & TR1_STR) count++;
2633 if (f1 & TR1_INT) count++;
2634 if ((f1 & TR1_WIS) && !(f1 & TR1_INT)) count++; /* slightly useless combination */
2635 if (f1 & TR1_DEX) count++;
2636 if (f1 & TR1_CON) count++;
2637 if (f1 & TR1_CHR) value += pval * 1000;
2638
2639 /* hack for double-stat rings - C. Blue */
2640 if ((o_ptr->tval == TV_RING) && (
2641 (o_ptr->sval == SV_RING_MIGHT) ||
2642 (o_ptr->sval == SV_RING_READYWIT) ||
2643 (o_ptr->sval == SV_RING_TOUGHNESS) ||
2644 (o_ptr->sval == SV_RING_CUNNINGNESS))
2645 ) {
2646 count /= 2;
2647 if (count) value += count * PRICE_BOOST((count + pval), 2, 1)* 300L;
2648 } else {
2649 if (count) value += count * PRICE_BOOST((count + pval), 2, 1)* 200L;
2650 }
2651
2652 // if (f5 & (TR5_CRIT)) value += (PRICE_BOOST(pval, 0, 1)* 300L);//was 500, then 400
2653 // if (f5 & (TR5_CRIT)) value += pval * pval * 5000L;/* was 20k, but speed is only 10k */
2654 if (f5 & (TR5_CRIT)) value += (pval + 2) * (pval + 2) * 1500L;/* was 20k, but speed is only 10k */
2655 if (f5 & (TR5_LUCK)) value += (PRICE_BOOST(pval, 0, 1)* 10L);
2656
2657 /* Give credit for stealth and searching */
2658 // if (f1 & TR1_STEALTH) value += (PRICE_BOOST(pval, 3, 1) * 100L);
2659 if (f1 & TR1_STEALTH) value += (pval + 1) * (pval + 1) * 400L;//100
2660 if (f1 & TR1_SEARCH) value += pval * pval * 200L;//200
2661 if (f5 & TR5_DISARM) value += pval * pval * 100L;
2662
2663 /* Give credit for infra-vision and tunneling */
2664 if (f1 & TR1_INFRA) value += pval * pval * 150L;//100
2665 if (f1 & TR1_TUNNEL) value += pval * pval * 175L;//50
2666
2667 /* Give credit for extra attacks */
2668 if (o_ptr->tval == TV_RING) {
2669 if (f1 & TR1_BLOWS) value += (PRICE_BOOST(pval, 0, 1) * 2000L);//1500
2670 } else {
2671 // if (f1 & TR1_BLOWS) value += (PRICE_BOOST(pval, 0, 1) * 3000L);
2672 if (f1 & TR1_BLOWS) value += pval * (pval + 2) * 5000L;
2673 }
2674
2675 /* Give credit for extra casting */
2676 if (f1 & TR1_SPELL) value += (PRICE_BOOST(pval, 0, 1) * 4000L);
2677
2678 /* Give credit for extra HP bonus */
2679 if (f1 & TR1_LIFE) value += (PRICE_BOOST(pval, 0, 1) * 3000L);
2680
2681
2682 /* Flags moved here exclusively from flag_cost */
2683 if (f1 & TR1_MANA) value += (700 * pval * pval);
2684 /* End of flags, moved here from flag_cost */
2685
2686
2687 /* Hack -- amulets of speed and rings of speed are
2688 * cheaper than other items of speed.
2689 */
2690 if (o_ptr->tval == TV_AMULET) {
2691 /* Give credit for speed bonus */
2692 //if (f1 & TR1_SPEED) value += (boost * 25000L);
2693 if (f1 & TR1_SPEED) value += pval * pval * 5000L;
2694 } else if (o_ptr->tval == TV_RING) {
2695 /* Give credit for speed bonus */
2696 //if (f1 & TR1_SPEED) value += (PRICE_BOOST(pval, 0, 4) * 50000L);
2697 if (f1 & TR1_SPEED) value += pval * pval * 10000L;
2698 // if (f1 & TR1_SPEED) value += pval * pval * 7000L;
2699 }
2700 /* randarts and speed boots */
2701 // else if (f1 & TR1_SPEED) value += (PRICE_BOOST(pval, 0, 4) * 100000L);
2702 // else if (f1 & TR1_SPEED) value += pval * pval * 10000L;
2703 else if (f1 & TR1_SPEED) value += (pval + 1) * (pval + 1) * 6000L;//7000 -> //5000
2704
2705 pval = o_ptr->pval;
2706
2707 if (o_ptr->name2) {
2708 artifact_type *a_ptr;
2709
2710 a_ptr = ego_make(o_ptr);
2711 f1 &= ~(k_ptr->flags1 & TR1_PVAL_MASK & ~a_ptr->flags1);
2712 f5 &= ~(k_ptr->flags5 & TR5_PVAL_MASK & ~a_ptr->flags5);
2713 }
2714 }
2715 break;
2716 }
2717 }
2718
2719
2720 /* Analyze the item */
2721 switch (o_ptr->tval) {
2722 case TV_BOOK:
2723 if (o_ptr->sval == SV_SPELLBOOK) {
2724 /* 1: 145, 2: 240, 3: 375, 4: 540, 5: 735 */
2725 int sl = school_spells[o_ptr->pval].skill_level + 5;
2726 /* override k_info.txt to have easier handling of possible changes here */
2727 value = 4;
2728 /* Pay extra for the spell */
2729 value = value * (sl * sl);
2730 }
2731 /* Done */
2732 break;
2733
2734 /* Wands/Staffs */
2735 case TV_WAND:
2736 /* Pay extra for charges */
2737 value += ((value / 20) * o_ptr->pval) / o_ptr->number;
2738 /* Done */
2739 break;
2740
2741 case TV_STAFF:
2742 /* Pay extra for charges */
2743 value += ((value / 20) * o_ptr->pval);
2744 /* Done */
2745 break;
2746
2747 /* Rings/Amulets */
2748 case TV_RING:
2749 case TV_AMULET:
2750 #if 0
2751 /* Hack -- negative bonuses are bad */
2752 if (o_ptr->to_a < 0) return (0L);
2753 if (o_ptr->to_h < 0) return (0L);
2754 if (o_ptr->to_d < 0) return (0L);
2755 #endif
2756 if ((o_ptr->tval == TV_RING) && (o_ptr->sval == SV_RING_POLYMORPH)) {
2757 value += r_info[o_ptr->pval].level * r_info[o_ptr->pval].mexp;
2758 }
2759
2760 /* Give credit for bonuses */
2761 // value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
2762 /* Ignore base boni that come from k_info.txt (eg quarterstaff +10 AC) */
2763 value += ((PRICE_BOOST(o_ptr->to_h, 12, 4) +
2764 PRICE_BOOST(o_ptr->to_d, 7, 3) +
2765 PRICE_BOOST(o_ptr->to_a, 11, 4)) * 100L);
2766
2767 /* Done */
2768 break;
2769
2770 /* Armor */
2771 case TV_BOOTS:
2772 case TV_GLOVES:
2773 case TV_CLOAK:
2774 case TV_CROWN:
2775 case TV_HELM:
2776 case TV_SHIELD:
2777 case TV_SOFT_ARMOR:
2778 case TV_HARD_ARMOR:
2779 case TV_DRAG_ARMOR:
2780 #if 0
2781 /* Hack -- negative armor bonus */
2782 if (o_ptr->to_a < 0) return (0L);
2783 #endif
2784 /* Give credit for bonuses */
2785 // value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
2786 /* Ignore base boni that come from k_info.txt (eg quarterstaff +10 AC) */
2787 value += ( ((o_ptr->to_h <= 0 || o_ptr->to_h <= k_ptr->to_h)? 0 :
2788 ((k_ptr->to_h < 0)? PRICE_BOOST(o_ptr->to_h, 9, 5):
2789 PRICE_BOOST((o_ptr->to_h - k_ptr->to_h), 9, 5))) +
2790 ((o_ptr->to_d <= 0 || o_ptr->to_d <= k_ptr->to_d)? 0 :
2791 ((k_ptr->to_d < 0)? PRICE_BOOST(o_ptr->to_d, 9, 5):
2792 PRICE_BOOST((o_ptr->to_d - k_ptr->to_d), 9, 5))) +
2793 ((o_ptr->to_a <= 0 || o_ptr->to_a <= k_ptr->to_a)? 0 :
2794 ((k_ptr->to_a < 0)? PRICE_BOOST(o_ptr->to_a, 9, 5):
2795 PRICE_BOOST((o_ptr->to_a - k_ptr->to_a), 9, 5))) ) * 100L;
2796
2797 /* Costumes */
2798 if ((o_ptr->tval == TV_SOFT_ARMOR) && (o_ptr->sval == SV_COSTUME)) {
2799 value += r_info[o_ptr->bpval].mexp;
2800 }
2801
2802 /* Done */
2803 break;
2804
2805 /* Bows/Weapons */
2806 case TV_BOW:
2807 case TV_BOOMERANG:
2808 case TV_AXE:
2809 case TV_DIGGING:
2810 case TV_BLUNT:
2811 case TV_SWORD:
2812 case TV_POLEARM:
2813 case TV_MSTAFF:
2814 case TV_TRAPKIT:
2815 #if 0
2816 /* Hack -- negative hit/damage bonuses */
2817 if (o_ptr->to_h + o_ptr->to_d < 0) {
2818 /* Hack -- negative hit/damage are of no importance */
2819 if (o_ptr->tval == TV_MSTAFF) break;
2820 if (o_ptr->name2 == EGO_STAR_DF) break;
2821 else return (0L);
2822 }
2823 #endif
2824 /* Factor in the bonuses */
2825 // value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
2826 /* Ignore base boni that come from k_info.txt (eg quarterstaff +10 AC) */
2827 value += ( ((o_ptr->to_h <= 0 || o_ptr->to_h <= k_ptr->to_h)? 0 :
2828 ((k_ptr->to_h < 0)? PRICE_BOOST(o_ptr->to_h, 9, 5):
2829 PRICE_BOOST((o_ptr->to_h - k_ptr->to_h), 9, 5))) +
2830 ((o_ptr->to_d <= 0 || o_ptr->to_d <= k_ptr->to_d)? 0 :
2831 ((k_ptr->to_d < 0)? PRICE_BOOST(o_ptr->to_d, 9, 5):
2832 PRICE_BOOST((o_ptr->to_d - k_ptr->to_d), 9, 5))) +
2833 ((o_ptr->to_a <= 0 || o_ptr->to_a <= k_ptr->to_a)? 0 :
2834 ((k_ptr->to_a < 0)? PRICE_BOOST(o_ptr->to_a, 9, 5):
2835 PRICE_BOOST((o_ptr->to_a - k_ptr->to_a), 9, 5))) ) * 100L;
2836
2837 /* Hack -- Factor in extra damage dice */
2838 if ((i = o_ptr->dd * (o_ptr->ds + 1) - k_ptr->dd * (k_ptr->ds + 1)))
2839 value += i * i * i;
2840
2841 /* Done */
2842 break;
2843
2844 /* Ammo */
2845 case TV_SHOT:
2846 case TV_ARROW:
2847 case TV_BOLT:
2848 /* Hack -- negative hit/damage bonuses */
2849 // if (o_ptr->to_h + o_ptr->to_d < 0) return (0L);
2850
2851 /* Factor in the bonuses */
2852 // value += ((o_ptr->to_h + o_ptr->to_d) * 5L);
2853 /* Ignore base boni that come from k_info.txt (eg quarterstaff +10 AC) */
2854 value += ( ((o_ptr->to_h <= 0 || o_ptr->to_h <= k_ptr->to_h)? 0 :
2855 ((k_ptr->to_h < 0)? PRICE_BOOST(o_ptr->to_h, 9, 5):
2856 PRICE_BOOST((o_ptr->to_h - k_ptr->to_h), 9, 5))) +
2857 ((o_ptr->to_d <= 0 || o_ptr->to_d <= k_ptr->to_d)? 0 :
2858 ((k_ptr->to_d < 0)? PRICE_BOOST(o_ptr->to_d, 9, 5):
2859 PRICE_BOOST((o_ptr->to_d - k_ptr->to_d), 9, 5))) ) * 5L;
2860
2861 /* Hack -- Factor in extra damage dice */
2862 if ((i = o_ptr->dd * (o_ptr->ds + 1) - k_ptr->dd * (k_ptr->ds + 1)))
2863 value += i * 5000L;
2864
2865 /* Done */
2866 break;
2867 }
2868
2869 #ifdef RANDART_PRICE_BONUS /* just disable in case some randarts end up with outrageous value */
2870 /* OPTIONAL/EXPERIMENTAL: Add extra bonus for ranged weapon that has absolute top damage */
2871 if (o_ptr->tval == TV_BOW && (i = o_ptr->to_h + o_ptr->to_d * 2) >= 60) {
2872 #if 1
2873 int ultraboost = i * (o_ptr->to_h + 10);
2874 /* boost excessively for 'end game' dam/usability */
2875 if ((f3 & TR3_XTRA_SHOTS) && (f3 & TR3_XTRA_MIGHT) &&
2876 o_ptr->to_d >= 24) value += (o_ptr->to_d - 23) * ultraboost * 10;
2877 #endif
2878
2879 i = i - 30;
2880 if (f3 & TR3_XTRA_SHOTS) i *= 2;
2881 if (f3 & TR3_XTRA_MIGHT) i *= 4;
2882 value += i * 500;
2883 }
2884 /* OPTIONAL/EXPERIMENTAL: Add extra bonus for armour that has both, top AC and resists */
2885 else if (is_armour(o_ptr->tval) && o_ptr->to_a >= 25) {
2886 i = artifact_flag_rating_armour(o_ptr);
2887 if (i >= 15) value += (o_ptr->to_a + i - 30) * 3000;
2888 }
2889 /* OPTIONAL/EXPERIMENTAL: Add extra bonus for weapon that has both, top hit/_dam_ and ea/crit/vamp */
2890 else if (is_weapon(o_ptr->tval) && (o_ptr->to_h + o_ptr->to_d * 2) >= 60) {
2891 /* generate two different values, pick the higher one */
2892 s64b v1 = 0, v2 = 0;
2893
2894 /* first bonus prefers weapons with high flag rating */
2895 i = artifact_flag_rating_weapon(o_ptr) * 4;
2896 if (i >= 24) {
2897 #if 1 /* ultraboost for top-end stats? This can result in x2.5 prices for those, up to ~1M Au! */
2898 int ultraboost = i * (o_ptr->to_h + 10);
2899 /* boost excessively for 'end game' dam/usability */
2900 if (o_ptr->to_d > 25) value += (o_ptr->to_d - 25) * ultraboost * 25;
2901 /* boost even further for being vampiric in addition to being awesome */
2902 if ((f1 & TR1_VAMPIRIC) && o_ptr->to_d >= 20) value += (o_ptr->to_d - 20) * ultraboost * 15;
2903 #endif
2904 /* boost the value for especially good rating */
2905 v1 = (o_ptr->to_h + o_ptr->to_d * 2 + i - 70) * 2000;
2906 }
2907
2908 /* second bonus prefers weapons with just high hit/dam/dice */
2909 i = o_ptr->to_h + o_ptr->to_d * 2;
2910 if (i >= 75) {
2911 int j;
2912
2913 i = (i - 75) * 2;
2914
2915 /* extra damage dice? */
2916 j = (o_ptr->dd * (o_ptr->ds + 1)) - (k_ptr->dd * (k_ptr->ds + 1));
2917 if (j > 0) i += j;
2918
2919 v2 = (i + 2) * (i + 2) * 40;
2920 }
2921
2922 /* apply the more advantageous bonus */
2923 if (v1 > v2) value += v1; else value += v2;
2924 }
2925 #endif
2926
2927 if (f3 & TR3_AGGRAVATE) value >>= 1; /* one generic aggravate penalty fits it all */
2928 if (f3 & TR3_NO_TELE) value >>= 1; /* generic no-tele penalty fits too ^^ */
2929
2930 /* Return the value */
2931 return (value);
2932 }
2933
2934
2935 /*
2936 * Return the price of an item including plusses (and charges)
2937 *
2938 * This function returns the "value" of the given item (qty one)
2939 *
2940 * Never notice "unknown" bonuses or properties, including "curses",
2941 * since that would give the player information he did not have.
2942 *
2943 * Note that discounted items stay discounted forever, even if
2944 * the discount is "forgotten" by the player via memory loss.
2945 */
2946 s64b object_value(int Ind, object_type *o_ptr) {
2947 s64b value;
2948
2949 /* Known items -- acquire the actual value */
2950 if (Ind == 0 || object_known_p(Ind, o_ptr)) {
2951 /* Broken items -- worthless */
2952 if (broken_p(o_ptr)) return (0L);
2953
2954 /* Cursed items -- worthless */
2955 if (cursed_p(o_ptr)) return (0L);
2956
2957 /* Real value (see above) */
2958 value = object_value_real(Ind, o_ptr);
2959 }
2960
2961 /* Unknown items -- acquire a base value */
2962 else {
2963 /* Hack -- Felt broken items */
2964 if ((o_ptr->ident & ID_SENSED_ONCE) && broken_p(o_ptr)) return (0L);
2965
2966 /* Hack -- Felt cursed items */
2967 if ((o_ptr->ident & ID_SENSED_ONCE) && cursed_p(o_ptr)) return (0L);
2968
2969 /* Base value (see above) */
2970 value = object_value_base(Ind, o_ptr);
2971 }
2972
2973
2974 /* Apply discount (if any) */
2975 if (o_ptr->discount) value -= (value * o_ptr->discount / 100L);
2976
2977 /* Return the final value */
2978 return (value);
2979 }
2980
2981
2982
2983
2984
2985 /*
2986 * Determine if an item can "absorb" a second item
2987 *
2988 * See "object_absorb()" for the actual "absorption" code.
2989 *
2990 * If permitted, we allow wands/staffs (if they are known to have equal
2991 * charges) and rods (if fully charged) to combine.
2992 *
2993 * Note that rods/staffs/wands are then unstacked when they are used.
2994 *
2995 * If permitted, we allow weapons/armor to stack, if they both known.
2996 *
2997 * Food, potions, scrolls, and "easy know" items always stack.
2998 *
2999 * Chests never stack (for various reasons).
3000 *
3001 * We do NOT allow activatable items (artifacts or dragon scale mail)
3002 * to stack, to keep the "activation" code clean. Artifacts may stack,
3003 * but only with another identical artifact (which does not exist).
3004 *
3005 * Ego items may stack as long as they have the same ego-item type.
3006 * This is primarily to allow ego-missiles to stack.
3007 *
3008 * o_ptr and j_ptr no longer are simmetric;
3009 * j_ptr should be the new item or level-reqs gets meanless.
3010 *
3011 * 'tolerance' flag:
3012 * 0 - no tolerance
3013 * +0x1 - tolerance for ammo to_h and to_d enchantment
3014 * +0x2 - tolerance for level 0 items
3015 * +0x4 - tolerance for discount and inscription
3016 * (added for dropping items on top of stacks inside houses)
3017 * +0x8 - ignore non-matching inscriptions. For player stores, which erase inscriptions on purchase anyway!
3018 * -- C. Blue
3019 */
3020 bool object_similar(int Ind, object_type *o_ptr, object_type *j_ptr, s16b tolerance) {
3021 player_type *p_ptr = NULL;
3022 int total = o_ptr->number + j_ptr->number;
3023
3024
3025 /* Hack -- gold always merge */
3026 if (o_ptr->tval == TV_GOLD && j_ptr->tval == TV_GOLD) {
3027 /* special exception: pile colour from coin-type monsters is immutable! */
3028 if (o_ptr->sval != j_ptr->sval && (o_ptr->xtra2 || j_ptr->xtra2)) return FALSE;
3029 return(TRUE);
3030 }
3031
3032
3033 /* Don't EVER stack questors oO */
3034 if (o_ptr->questor) return FALSE;
3035 /* Don't ever stack special quest items */
3036 if (o_ptr->tval == TV_SPECIAL && o_ptr->sval == SV_QUEST) return FALSE;
3037 /* Don't stack quest items if not from same quest AND stage! */
3038 if (o_ptr->quest != j_ptr->quest || o_ptr->quest_stage != j_ptr->quest_stage) return FALSE;
3039
3040
3041 /* Don't stack potions of blood because of their timeout */
3042 if ((o_ptr->tval == TV_POTION || o_ptr->tval == TV_FOOD) && o_ptr->timeout) return FALSE;
3043
3044
3045 /* Require identical object types */
3046 if (o_ptr->k_idx != j_ptr->k_idx) return (FALSE);
3047
3048 /* Level 0 items and other items won't merge, since level 0 can't be sold to shops */
3049 if (!(tolerance & 0x2) &&
3050 (!o_ptr->level || !j_ptr->level) &&
3051 (o_ptr->level != j_ptr->level))
3052 return (FALSE);
3053
3054 /* Require same owner or convertable to same owner */
3055 //
3056 /* if (o_ptr->owner != j_ptr->owner) return (FALSE); */
3057 if (Ind) {
3058 p_ptr = Players[Ind];
3059 if (((o_ptr->owner != j_ptr->owner)
3060 && ((p_ptr->lev < j_ptr->level)
3061 || (j_ptr->level < 1)))
3062 && (j_ptr->owner)) return (FALSE);
3063 if ((o_ptr->owner != p_ptr->id)
3064 && (o_ptr->owner != j_ptr->owner)) return (FALSE);
3065
3066 /* Require objects from the same modus! */
3067 /* A non-everlasting player won't have his items stacked w/ everlasting stuff */
3068 if (compat_pomode(Ind, j_ptr)) return(FALSE);
3069 } else {
3070 if (o_ptr->owner != j_ptr->owner) return (FALSE);
3071 /* no stacks of unowned everlasting items in shops after a now-dead
3072 everlasting player sold an item to the shop before he died :) */
3073 if (compat_omode(o_ptr, j_ptr)) return(FALSE);
3074 }
3075
3076 /* Analyze the items */
3077 switch (o_ptr->tval) {
3078 /* quest items */
3079 case TV_SPECIAL:
3080 if (o_ptr->sval == SV_QUEST) {
3081 if ((o_ptr->pval != j_ptr->pval) ||
3082 (o_ptr->xtra1 != j_ptr->xtra1) ||
3083 (o_ptr->xtra2 != j_ptr->xtra2) ||
3084 (o_ptr->weight != j_ptr->weight) ||
3085 (o_ptr->quest != j_ptr->quest) ||
3086 (o_ptr->quest_stage != j_ptr->quest_stage))
3087 return FALSE;
3088 break;
3089 }
3090 return FALSE;
3091
3092 /* Chests */
3093 case TV_KEY:
3094 case TV_CHEST:
3095 /* Never okay */
3096 return (FALSE);
3097
3098 /* Food and Potions and Scrolls */
3099 case TV_SCROLL:
3100 /* cheques may have different value, so they must not stack */
3101 if (o_ptr->sval == SV_SCROLL_CHEQUE) return FALSE;
3102 case TV_FOOD:
3103 case TV_POTION:
3104 case TV_POTION2:
3105 /* Hack for ego foods :) */
3106 if (o_ptr->name2 != j_ptr->name2) return (FALSE);
3107 if (o_ptr->name2b != j_ptr->name2b) return (FALSE);
3108
3109 /* Assume okay */
3110 break;
3111
3112 /* Staffs and Wands */
3113 case TV_WAND:
3114 /* Require either knowledge or known empty for both wands. */
3115 if ((!(o_ptr->ident & (ID_EMPTY)) &&
3116 (!Ind || !object_known_p(Ind, o_ptr))) ||
3117 (!(j_ptr->ident & (ID_EMPTY)) &&
3118 (!Ind || !object_known_p(Ind, j_ptr)))) return(FALSE);
3119
3120 /* Beware artifatcs should not combine with "lesser" thing */
3121 if (o_ptr->name1 != j_ptr->name1) return (FALSE);
3122
3123 /* Do not combine recharged ones with non recharged ones. */
3124 // if ((f4 & TR4_RECHARGED) != (f14 & TR4_RECHARGED)) return (FALSE);
3125
3126 /* Do not combine different ego or normal ones */
3127 if (o_ptr->name2 != j_ptr->name2) return (FALSE);
3128
3129 /* Do not combine different ego or normal ones */
3130 if (o_ptr->name2b != j_ptr->name2b) return (FALSE);
3131
3132 /* Assume okay */
3133 break;
3134
3135 case TV_STAFF:
3136 /* Require knowledge */
3137 if (!Ind || !object_known_p(Ind, o_ptr) || !object_known_p(Ind, j_ptr)) return (FALSE);
3138
3139 if (!Ind || !p_ptr->stack_allow_wands) return (FALSE);
3140
3141 /* Require identical charges */
3142 if (o_ptr->pval != j_ptr->pval) return (FALSE);
3143
3144 if (o_ptr->name2 != j_ptr->name2) return (FALSE);
3145 if (o_ptr->name2b != j_ptr->name2b) return (FALSE);
3146
3147 /* Probably okay */
3148 break;
3149
3150 /* Fall through */
3151 /* NO MORE FALLING THROUGH! MUHAHAHA the_sandman */
3152
3153 /* Staffs and Wands and Rods */
3154 case TV_ROD:
3155 /* Overpoweredness, Hello! - the_sandman */
3156 if (o_ptr->sval == SV_ROD_HAVOC) return (FALSE);
3157
3158 /* Require permission */
3159 if (!Ind || !p_ptr->stack_allow_wands) return (FALSE);
3160
3161 /* this is only for rods... the_sandman */
3162 if (o_ptr->pval == 0 && j_ptr->pval != 0) return (FALSE); //lol :)
3163
3164 if (o_ptr->name2 != j_ptr->name2) return (FALSE);
3165 if (o_ptr->name2b != j_ptr->name2b) return (FALSE);
3166
3167 /* Probably okay */
3168 break;
3169
3170 /* Weapons and Armor */
3171 case TV_DRAG_ARMOR: return(FALSE);
3172 case TV_BOW:
3173 case TV_BOOMERANG:
3174 case TV_DIGGING:
3175 case TV_BLUNT:
3176 case TV_POLEARM:
3177 case TV_SWORD:
3178 case TV_AXE:
3179 case TV_MSTAFF:
3180 case TV_BOOTS:
3181 case TV_GLOVES:
3182 case TV_HELM:
3183 case TV_CROWN:
3184 case TV_SHIELD:
3185 case TV_CLOAK:
3186 case TV_SOFT_ARMOR:
3187 case TV_HARD_ARMOR:
3188 case TV_TRAPKIT: /* so they don't stack carelessly - the_sandman */
3189 /* Require permission */
3190 if (!Ind || !p_ptr->stack_allow_items) return (FALSE);
3191
3192 /* XXX XXX XXX Require identical "sense" status */
3193 /* if ((o_ptr->ident & ID_SENSE) != */
3194 /* (j_ptr->ident & ID_SENSE)) return (FALSE); */
3195
3196 /* Costumes must be for same monster */
3197 if ((o_ptr->tval == TV_SOFT_ARMOR) && (o_ptr->sval == SV_COSTUME)) {
3198 if (o_ptr->bpval != j_ptr->bpval) return(FALSE);
3199 }
3200
3201 /* Fall through */
3202
3203 /* Rings, Amulets, Lites */
3204 case TV_RING:
3205 /* no more, due to their 'timeout' ! */
3206 if ((o_ptr->tval == TV_RING) && (o_ptr->sval == SV_RING_POLYMORPH)) return (FALSE);
3207 case TV_AMULET:
3208 case TV_LITE:
3209 case TV_TOOL:
3210 case TV_BOOK: /* Books can be 'fireproof' */
3211 /* custom tomes which appear identical, spell-wise too, may stack */
3212 if (o_ptr->tval == TV_BOOK && is_custom_tome(o_ptr->sval) &&
3213 ((o_ptr->xtra1 != j_ptr->xtra1) ||
3214 (o_ptr->xtra2 != j_ptr->xtra2) ||
3215 (o_ptr->xtra3 != j_ptr->xtra3) ||
3216 (o_ptr->xtra4 != j_ptr->xtra4) ||
3217 (o_ptr->xtra5 != j_ptr->xtra5) ||
3218 (o_ptr->xtra6 != j_ptr->xtra6) ||
3219 (o_ptr->xtra7 != j_ptr->xtra7) ||
3220 (o_ptr->xtra8 != j_ptr->xtra8) ||
3221 (o_ptr->xtra9 != j_ptr->xtra9)))
3222 return(FALSE);
3223
3224 // if (o_ptr->tval == TV_BOOK) { /* this was probably only meant for books..? */
3225 /* Require full knowledge of both items */
3226 if (!Ind || !object_known_p(Ind, o_ptr) ||
3227 // !object_known_p(Ind, j_ptr) || (o_ptr->name3)) return (FALSE);
3228 !object_known_p(Ind, j_ptr))
3229 return (FALSE);
3230 // }
3231
3232 /* different bpval? */
3233 if (o_ptr->bpval != j_ptr->bpval) return(FALSE);
3234
3235 /* Fall through */
3236
3237 /* Missiles */
3238 case TV_BOLT:
3239 case TV_ARROW:
3240 case TV_SHOT:
3241 /* Require identical "boni" -
3242 except for ammunition which carries special inscription (will merge!) - C. Blue */
3243 if (!((tolerance & 0x1) && !(cursed_p(o_ptr) || cursed_p(j_ptr) ||
3244 artifact_p(o_ptr) || artifact_p(j_ptr))) ||
3245 (!is_ammo(o_ptr->tval) ||
3246 (!check_guard_inscription(o_ptr->note, 'M') && !check_guard_inscription(j_ptr->note, 'M')))) {
3247 if (o_ptr->to_h != j_ptr->to_h) return (FALSE);
3248 if (o_ptr->to_d != j_ptr->to_d) return (FALSE);
3249 }
3250 if (o_ptr->to_a != j_ptr->to_a) return (FALSE);
3251
3252 /* Require identical "pval" code */
3253 if (o_ptr->pval != j_ptr->pval) return (FALSE);
3254
3255 /* Require identical "artifact" names <- this shouldnt happen right? */
3256 if (o_ptr->name1 != j_ptr->name1) return (FALSE);
3257
3258 /* Require identical "ego-item" names.
3259 Allow swapped ego powers: Ie Arrow (SlayDragon,Ethereal) combines with Arrow (Ethereal,SlayDragon).
3260 Note: This code assumes there's no ego power which can be both prefix and postfix. */
3261 #if 0
3262 /* This is buggy, it allows stacking of normal items with items that only have one ego power - mikaelh */
3263 if ((o_ptr->name2 != j_ptr->name2) && (o_ptr->name2 != j_ptr->name2b)) return (FALSE);
3264 if ((o_ptr->name2b != j_ptr->name2) && (o_ptr->name2b != j_ptr->name2b)) return (FALSE);
3265 #else
3266 /* This one only allows name2 and name2b to be swapped */
3267 if (! ((o_ptr->name2 == j_ptr->name2b) && (o_ptr->name2b == j_ptr->name2)))
3268 {
3269 if (o_ptr->name2 != j_ptr->name2) return (FALSE);
3270 if (o_ptr->name2b != j_ptr->name2b) return (FALSE);
3271 }
3272 #endif
3273
3274 /* Require identical random seeds
3275 hack: fix 'old' ammo that didn't have NO_SEED flag yet.. */
3276 if (!is_ammo(o_ptr->tval) && o_ptr->name3 != j_ptr->name3) return (FALSE);
3277
3278 /* Hack -- Never stack "powerful" items */
3279 // if (o_ptr->xtra1 || j_ptr->xtra1) return (FALSE);
3280
3281 /* Hack -- Never stack recharging items */
3282 if (o_ptr->timeout != j_ptr->timeout) return (FALSE);
3283
3284 /* Require identical "values" */
3285 if (o_ptr->ac != j_ptr->ac) return (FALSE);
3286 if (o_ptr->dd != j_ptr->dd) return (FALSE);
3287 if (o_ptr->ds != j_ptr->ds) return (FALSE);
3288
3289 /* Probably okay */
3290 break;
3291
3292 case TV_GOLEM:
3293 if (o_ptr->pval != j_ptr->pval) return(FALSE);
3294 break;
3295
3296 /* Various */
3297 default:
3298 /* Require knowledge */
3299 if (Ind && (!object_known_p(Ind, o_ptr) ||
3300 !object_known_p(Ind, j_ptr))) return (FALSE);
3301
3302 /* Probably okay */
3303 break;
3304 }
3305
3306
3307 /* Hack -- Require identical "cursed" status */
3308 if ((o_ptr->ident & ID_CURSED) != (j_ptr->ident & ID_CURSED)) return (FALSE);
3309
3310 /* Hack -- Require identical "broken" status */
3311 if ((o_ptr->ident & ID_BROKEN) != (j_ptr->ident & ID_BROKEN)) return (FALSE);
3312
3313 /* Inscriptions matter not for player-stores (they get erased anyway!) */
3314 if (!(tolerance & 0x8)) {
3315 /* Hack -- require semi-matching "inscriptions" */
3316 /* Hack^2 -- books do merge.. it's to prevent some crashes */
3317 if (o_ptr->note && j_ptr->note && (o_ptr->note != j_ptr->note)
3318 && strcmp(quark_str(o_ptr->note), "on sale")
3319 && strcmp(quark_str(j_ptr->note), "on sale")
3320 && strcmp(quark_str(o_ptr->note), "stolen")
3321 && strcmp(quark_str(j_ptr->note), "stolen")
3322 && !is_realm_book(o_ptr)
3323 && !check_guard_inscription(o_ptr->note, 'M')
3324 && !check_guard_inscription(j_ptr->note, 'M')) return (FALSE);
3325
3326 /* Hack -- normally require matching "inscriptions" */
3327 if (!(tolerance & 0x4) && (!Ind || !p_ptr->stack_force_notes) && (o_ptr->note != j_ptr->note)) return (FALSE);
3328 }
3329
3330 /* Hack -- normally require matching "discounts" */
3331 if (!(tolerance & 0x4) && (!Ind || !p_ptr->stack_force_costs) && (o_ptr->discount != j_ptr->discount)) return (FALSE);
3332
3333
3334 /* Maximal "stacking" limit */
3335 if (total >= MAX_STACK_SIZE) return (FALSE);
3336
3337 /* An everlasting player will have _his_ items stack w/ non-everlasting stuff
3338 (especially new items bought in the shops) and convert them all to everlasting */
3339 if (Ind && (p_ptr->mode & MODE_EVERLASTING)) {
3340 o_ptr->mode = MODE_EVERLASTING;
3341 j_ptr->mode = MODE_EVERLASTING;
3342 }
3343
3344 /* A PvP-player will get his items convert to pvp-mode */
3345 if (Ind && (p_ptr->mode & MODE_PVP)) {
3346 o_ptr->mode = MODE_PVP;
3347 j_ptr->mode = MODE_PVP;
3348 }
3349
3350 /* They match, so they must be similar */
3351 return (TRUE);
3352 }
3353
3354
3355 /*
3356 * Allow one item to "absorb" another, assuming they are similar
3357 */
3358 void object_absorb(int Ind, object_type *o_ptr, object_type *j_ptr) {
3359 int total = o_ptr->number + j_ptr->number;
3360
3361 /* Prepare ammo for possible combining */
3362 // int o_to_h, o_to_d;
3363 bool merge_inscriptions = check_guard_inscription(o_ptr->note, 'M') || check_guard_inscription(j_ptr->note, 'M');
3364 bool merge_ammo = (is_ammo(o_ptr->tval) && merge_inscriptions);
3365
3366 /* Combine ammo even of different enchantment grade! - C. Blue */
3367 if (merge_ammo) {
3368 o_ptr->to_h = ((o_ptr->to_h * o_ptr->number) + (j_ptr->to_h * j_ptr->number)) / (o_ptr->number + j_ptr->number);
3369 o_ptr->to_d = ((o_ptr->to_d * o_ptr->number) + (j_ptr->to_d * j_ptr->number)) / (o_ptr->number + j_ptr->number);
3370 }
3371
3372 /* Add together the item counts */
3373 o_ptr->number = ((total < MAX_STACK_SIZE) ? total : (MAX_STACK_SIZE - 1));
3374
3375 /* NEVER clone gold!!! - mikaelh
3376 * o_ptr->number > 1 gold could be seperated by eg. bashing
3377 * creating/destroying (o_ptr->pval - j_ptr->pval) gold.
3378 * Colour won't always be right but let's make one item with combined
3379 * amount of gold?
3380 */
3381 if (o_ptr->tval == TV_GOLD) {
3382 o_ptr->number = 1;
3383 #if 0
3384 /* use 'colour' of the bigger pile */
3385 if (o_ptr->pval < j_ptr->pval) {
3386 o_ptr->sval = j_ptr->sval;
3387 o_ptr->k_idx = j_ptr->k_idx;
3388 }
3389 o_ptr->pval += j_ptr->pval;
3390 #else
3391 o_ptr->pval += j_ptr->pval;
3392 /* determine new 'colour' depending on the total amount */
3393 if (j_ptr->xtra1) {
3394 /* player-dropped piles are compact */
3395 o_ptr->k_idx = gold_colour(o_ptr->pval, FALSE, TRUE);
3396 o_ptr->sval = k_info[o_ptr->k_idx].sval;
3397 } else if (!o_ptr->xtra2 && !j_ptr->xtra2) { /* coin-type monster piles don't change type to something else */
3398 /* standard piles */
3399 o_ptr->k_idx = gold_colour(o_ptr->pval, TRUE, FALSE);
3400 o_ptr->sval = k_info[o_ptr->k_idx].sval;
3401 }
3402 #endif
3403 }
3404
3405 /* Hack -- blend "known" status */
3406 if (Ind && object_known_p(Ind, j_ptr)) object_known(o_ptr);
3407
3408 /* Hack -- blend "rumour" status */
3409 if (j_ptr->ident & ID_RUMOUR) o_ptr->ident |= ID_RUMOUR;
3410
3411 /* Hack -- blend "mental" status */
3412 if (j_ptr->ident & ID_MENTAL) o_ptr->ident |= ID_MENTAL;
3413
3414 /* Hack -- could average discounts XXX XXX XXX */
3415 /* Hack -- save largest discount XXX XXX XXX */
3416 if (o_ptr->discount < j_ptr->discount) o_ptr->discount = j_ptr->discount;
3417
3418 /* Hack -- blend "inscriptions" */
3419 // if (j_ptr->note) o_ptr->note = j_ptr->note;
3420 // if (o_ptr->note) j_ptr->note = o_ptr->note;
3421
3422 /* Usually, the old object 'j_ptr' takes over the inscription of added object 'o_ptr'.
3423 However, in some cases it's reversed, if..
3424 o_ptr's inscription is empty or one of the automatic inscriptions AND j_ptr's
3425 inscription is not empty, or..
3426 o_ptr's inscription contains the !M tag and j_ptr does not and j_ptr isnt one of
3427 the automatic inscriptions. */
3428 if (j_ptr->note &&
3429 (!o_ptr->note || streq(quark_str(o_ptr->note), "handmade") ||
3430 (streq(quark_str(o_ptr->note), "stolen") && !streq(quark_str(j_ptr->note), "handmade")))) { /* don't overwrite 'stolen' with 'handmade' */
3431 o_ptr->note = j_ptr->note;
3432 }
3433 else if (merge_inscriptions) {
3434 if (check_guard_inscription(o_ptr->note, 'M') && (!check_guard_inscription(j_ptr->note, 'M'))
3435 && (j_ptr->note) && strcmp(quark_str(j_ptr->note), "handmade") && strcmp(quark_str(j_ptr->note), "stolen"))
3436 o_ptr->note = j_ptr->note;
3437 }
3438 /* hack to fix special case: old item just had an 'on sale' inscription and that doesn't apply anymore */
3439 if (o_ptr->note && !strcmp(quark_str(o_ptr->note), "on sale") && o_ptr->discount != 50) o_ptr->note = 0;
3440
3441 /* blend level-req into lower one */
3442 if (o_ptr->level > j_ptr->level) o_ptr->level = j_ptr->level;
3443
3444 /* Hack -- if wands are stacking, combine the charges. -LM- */
3445 if (o_ptr->tval == TV_WAND)
3446 o_ptr->pval += j_ptr->pval;
3447
3448 /* Hack -- if rods are stacking, average out the timeout. the_sandman */
3449 if (o_ptr->tval == TV_ROD) {
3450 o_ptr->pval = (o_ptr->number) * (o_ptr->pval) + (j_ptr->pval);
3451 o_ptr->pval = (o_ptr->pval) / (o_ptr->number + 1);
3452 }
3453 }
3454
3455
3456
3457 /*
3458 * Find the index of the object_kind with the given tval and sval
3459 */
3460 s16b lookup_kind(int tval, int sval)
3461 {
3462 int k;
3463
3464 /* Look for it */
3465 for (k = 1; k < max_k_idx; k++)
3466 {
3467 object_kind *k_ptr = &k_info[k];
3468
3469 /* Found a match */
3470 if ((k_ptr->tval == tval) && (k_ptr->sval == sval)) return (k);
3471 }
3472
3473 /* Oops */
3474 #if DEBUG_LEVEL > 2
3475 s_printf("No object (%d,%d)\n", tval, sval);
3476 #endif // DEBUG_LEVEL
3477
3478 /* Oops */
3479 return (0);
3480 }
3481
3482
3483 /*
3484 * Clear an item
3485 */
3486 void invwipe(object_type *o_ptr)
3487 {
3488 /* Clear the record */
3489 WIPE(o_ptr, object_type);
3490 }
3491
3492
3493 /*
3494 * Make "o_ptr" a "clean" copy of the given "kind" of object
3495 */
3496 void invcopy(object_type *o_ptr, int k_idx)
3497 {
3498 object_kind *k_ptr = &k_info[k_idx];
3499
3500 /* Clear the record */
3501 WIPE(o_ptr, object_type);
3502
3503 /* Save the kind index */
3504 o_ptr->k_idx = k_idx;
3505
3506 /* Efficiency -- tval/sval */
3507 o_ptr->tval = k_ptr->tval;
3508 o_ptr->sval = k_ptr->sval;
3509
3510 /* Default "pval" */
3511 // o_ptr->pval = k_ptr->pval;
3512 if (o_ptr->tval == TV_POTION ||
3513 o_ptr->tval == TV_POTION2 ||
3514 o_ptr->tval == TV_FLASK ||
3515 o_ptr->tval == TV_FOOD)
3516 o_ptr->pval = k_ptr->pval;
3517 else if (o_ptr->tval == TV_LITE)
3518 o_ptr->timeout = k_ptr->pval;//hack
3519
3520 else if (o_ptr->tval != TV_ROD)
3521 o_ptr->bpval = k_ptr->pval;
3522
3523 /* Default number */
3524 o_ptr->number = 1;
3525
3526 /* Default weight */
3527 o_ptr->weight = k_ptr->weight;
3528
3529 /* Default magic */
3530 o_ptr->to_h = k_ptr->to_h;
3531 o_ptr->to_d = k_ptr->to_d;
3532 o_ptr->to_a = k_ptr->to_a;
3533
3534 /* Default power */
3535 o_ptr->ac = k_ptr->ac;
3536 o_ptr->dd = k_ptr->dd;
3537 o_ptr->ds = k_ptr->ds;
3538
3539 /* Hack -- worthless items are always "broken" */
3540 if (k_ptr->cost <= 0) o_ptr->ident |= ID_BROKEN;
3541
3542 /* Hack -- cursed items are always "cursed" */
3543 if (k_ptr->flags3 & TR3_CURSED) o_ptr->ident |= ID_CURSED;
3544 }
3545
3546
3547
3548
3549
3550 /*
3551 * Help determine an "enchantment bonus" for an object.
3552 *
3553 * To avoid floating point but still provide a smooth distribution of bonuses,
3554 * we simply round the results of division in such a way as to "average" the
3555 * correct floating point value.
3556 *
3557 * This function has been changed. It uses "randnor()" to choose values from
3558 * a normal distribution, whose mean moves from zero towards the max as the
3559 * level increases, and whose standard deviation is equal to 1/4 of the max,
3560 * and whose values are forced to lie between zero and the max, inclusive.
3561 *
3562 * Since the "level" rarely passes 100 before Morgoth is dead, it is very
3563 * rare to get the "full" enchantment on an object, even a deep levels.
3564 *
3565 * It is always possible (albeit unlikely) to get the "full" enchantment.
3566 *
3567 * A sample distribution of values from "m_bonus(10, N)" is shown below:
3568 *
3569 * N 0 1 2 3 4 5 6 7 8 9 10
3570 * --- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
3571 * 0 66.37 13.01 9.73 5.47 2.89 1.31 0.72 0.26 0.12 0.09 0.03
3572 * 8 46.85 24.66 12.13 8.13 4.20 2.30 1.05 0.36 0.19 0.08 0.05
3573 * 16 30.12 27.62 18.52 10.52 6.34 3.52 1.95 0.90 0.31 0.15 0.05
3574 * 24 22.44 15.62 30.14 12.92 8.55 5.30 2.39 1.63 0.62 0.28 0.11
3575 * 32 16.23 11.43 23.01 22.31 11.19 7.18 4.46 2.13 1.20 0.45 0.41
3576 * 40 10.76 8.91 12.80 29.51 16.00 9.69 5.90 3.43 1.47 0.88 0.65
3577 * 48 7.28 6.81 10.51 18.27 27.57 11.76 7.85 4.99 2.80 1.22 0.94
3578 * 56 4.41 4.73 8.52 11.96 24.94 19.78 11.06 7.18 3.68 1.96 1.78
3579 * 64 2.81 3.07 5.65 9.17 13.01 31.57 13.70 9.30 6.04 3.04 2.64
3580 * 72 1.87 1.99 3.68 7.15 10.56 20.24 25.78 12.17 7.52 4.42 4.62
3581 * 80 1.02 1.23 2.78 4.75 8.37 12.04 27.61 18.07 10.28 6.52 7.33
3582 * 88 0.70 0.57 1.56 3.12 6.34 10.06 15.76 30.46 12.58 8.47 10.38
3583 * 96 0.27 0.60 1.25 2.28 4.30 7.60 10.77 22.52 22.51 11.37 16.53
3584 * 104 0.22 0.42 0.77 1.36 2.62 5.33 8.93 13.05 29.54 15.23 22.53
3585 * 112 0.15 0.20 0.56 0.87 2.00 3.83 6.86 10.06 17.89 27.31 30.27
3586 * 120 0.03 0.11 0.31 0.46 1.31 2.48 4.60 7.78 11.67 25.53 45.72
3587 * 128 0.02 0.01 0.13 0.33 0.83 1.41 3.24 6.17 9.57 14.22 64.07
3588 */
3589 s16b m_bonus(int max, int level)
3590 {
3591 int bonus, stand, extra, value;
3592
3593
3594 /* Paranoia -- enforce maximal "level" */
3595 if (level > MAX_DEPTH_OBJ - 1) level = MAX_DEPTH_OBJ - 1;
3596
3597
3598 /* The "bonus" moves towards the max */
3599 bonus = ((max * level) / MAX_DEPTH_OBJ);
3600
3601 /* Hack -- determine fraction of error */
3602 extra = ((max * level) % MAX_DEPTH_OBJ);
3603
3604 /* Hack -- simulate floating point computations */
3605 if (rand_int(MAX_DEPTH_OBJ) < extra) bonus++;
3606
3607
3608 /* The "stand" is equal to one quarter of the max */
3609 stand = (max / 4);
3610
3611 /* Hack -- determine fraction of error */
3612 extra = (max % 4);
3613
3614 /* Hack -- simulate floating point computations */
3615 if (rand_int(4) < extra) stand++;
3616
3617
3618 /* Choose an "interesting" value */
3619 value = randnor(bonus, stand);
3620
3621 /* Enforce the minimum value */
3622 if (value < 0) return (0);
3623
3624 /* Enforce the maximum value */
3625 if (value > max) return (max);
3626
3627 /* Result */
3628 return (value);
3629 }
3630
3631 static void log_arts(int a_idx, struct worldpos *wpos) {
3632 switch (a_idx) {
3633 case ART_DWARVEN_ALE:
3634 s_printf("ARTIFACT: 'Pint of Ale of the Khazad' created at %d,%d,%d.\n", wpos->wx, wpos->wy, wpos->wz);
3635 return;
3636 #if 0
3637 case ART_BILBO:
3638 s_printf("ARTIFACT: 'Picklock of Bilbo Baggins' created at %d,%d,%d.\n", wpos->wx, wpos->wy, wpos->wz);
3639 return;
3640 #endif
3641 case ART_MIRROROFGLORY:
3642 s_printf("ARTIFACT: 'Mirror of Glory' created at %d,%d,%d.\n", wpos->wx, wpos->wy, wpos->wz);
3643 return;
3644 case ART_DREADNOUGHT:
3645 s_printf("ARTIFACT: 'Dreadnought' created at %d,%d,%d.\n", wpos->wx, wpos->wy, wpos->wz);
3646 return;
3647 #if 0
3648 case ART_NARYA:
3649 s_printf("ARTIFACT: 'Narya' created at %d,%d,%d.\n", wpos->wx, wpos->wy, wpos->wz);
3650 return;
3651 case ART_NENYA:
3652 s_printf("ARTIFACT: 'Nenya' created at %d,%d,%d.\n", wpos->wx, wpos->wy, wpos->wz);
3653 return;
3654 case ART_VILYA:
3655 s_printf("ARTIFACT: 'Vilya' created at %d,%d,%d.\n", wpos->wx, wpos->wy, wpos->wz);
3656 return;
3657 #endif
3658 #if 0
3659 default:
3660 s_printf("ARTIFACT: '%s' created at %d,%d,%d.\n", a_name + a_info[a_idx].name, wpos->wx, wpos->wy, wpos->wz);
3661 return;
3662 #endif
3663 }
3664 return;
3665 }
3666
3667 /*
3668 * Mega-Hack -- Attempt to create one of the "Special Objects"
3669 *
3670 * We are only called from "place_object()", and we assume that
3671 * "apply_magic()" is called immediately after we return.
3672 *
3673 * Note -- see "make_artifact()" and "apply_magic()"
3674 */
3675 static bool make_artifact_special(struct worldpos *wpos, object_type *o_ptr, u32b resf) {
3676 int i, d, dlev = getlevel(wpos);
3677 int k_idx = 0;
3678 bool winner_arts_only = ((resf & RESF_NOTRUEART) && (resf & RESF_WINNER));
3679 #ifdef IDDC_EASY_TRUE_ARTIFACTS
3680 int difficulty = in_irondeepdive(wpos) ? 1 : 0;
3681 #endif
3682 artifact_type *a_ptr;
3683 int im, a_map[MAX_A_IDX];
3684
3685 /* Check if artifact generation is currently disabled -
3686 added this for maintenance reasons -C. Blue */
3687 if (cfg.arts_disabled ||
3688 ((resf & RESF_NOTRUEART) && !(resf & RESF_WINNER)))
3689 return (FALSE);
3690
3691 /* No artifacts in the town */
3692 if (istown(wpos)) return (FALSE);
3693
3694 /* shuffle art indices for fairness */
3695 for (i = 0; i < MAX_A_IDX; i++) a_map[i] = i;
3696 intshuffle(a_map, MAX_A_IDX);
3697
3698 /* Check the artifact list (just the "specials") */
3699 for (im = 0; im < MAX_A_IDX; im++) {
3700 i = a_map[im];
3701 a_ptr = &a_info[i];
3702
3703 /* Skip "empty" artifacts */
3704 if (!a_ptr->name) continue;
3705
3706 /* Hack: "Disabled" */
3707 if (a_ptr->rarity == 255) continue;
3708
3709 /* Cannot make an artifact twice */
3710 if (a_ptr->cur_num) continue;
3711
3712 /* Cannot generate non special ones */
3713 if (!(a_ptr->flags3 & TR3_INSTA_ART)) continue;
3714
3715 /* Cannot generate some artifacts because they can only exists in special dungeons/quests/... */
3716 // if ((a_ptr->flags4 & TR4_SPECIAL_GENE) && (!a_allow_special[i]) && (!vanilla_town)) continue;
3717 if (a_ptr->flags4 & TR4_SPECIAL_GENE) continue;
3718
3719 /* Allow non-dropchosen/specialgene winner arts */
3720 if (winner_arts_only && !(a_ptr->flags5 & TR5_WINNERS_ONLY))
3721 continue;
3722
3723 /* XXX XXX Enforce minimum "depth" (loosely) */
3724 if (a_ptr->level > dlev) {
3725 /* Acquire the "out-of-depth factor" */
3726 d = (a_ptr->level - dlev) * 2;
3727
3728 /* Roll for out-of-depth creation */
3729 if (rand_int(d) != 0) continue;
3730 }
3731
3732 /* New: Prevent too many low-level artifacts on high dungeon levels.
3733 They tend to spawn very often due to their relatively low rarity,
3734 and are simply a small piece of cash, or even annoying if unsellable (Gorlim). */
3735 d = ((dlev - 20) / 2) - a_ptr->level;
3736 /* Don't start checking before dungeon level 40. */
3737 if ((dlev >= 40) && (d > 0) && !magik(350 / (d + 3))) continue;
3738
3739 /* Artifact "rarity roll" */
3740 #ifdef IDDC_EASY_TRUE_ARTIFACTS
3741 if (rand_int(a_ptr->rarity >> difficulty) != 0) continue;
3742 #else
3743 if (rand_int(a_ptr->rarity) != 0) continue;
3744 #endif
3745
3746 /* Find the base object */
3747 k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
3748
3749 #if 0 /* although this makes level in k_info pointless, it just doesn't make sense to check an insta-art's level twice */
3750 /* XXX XXX Enforce minimum "object" level (loosely) */
3751 if (k_info[k_idx].level > object_level) {
3752 /* Acquire the "out-of-depth factor" */
3753 int d = (k_info[k_idx].level - object_level) * 5;
3754
3755 /* Roll for out-of-depth creation */
3756 if (rand_int(d) != 0) continue;
3757 }
3758 #endif
3759
3760 /* Assign the template */
3761 invcopy(o_ptr, k_idx);
3762
3763 /* Mega-Hack -- mark the item as an artifact */
3764 o_ptr->name1 = i;
3765
3766 /* Hack -- Mark the artifact as "created" */
3767 handle_art_inum(o_ptr->name1);
3768
3769 log_arts(i, wpos);
3770
3771 /* Success */
3772 return (TRUE);
3773 }
3774
3775 /* Failure */
3776 return (FALSE);
3777 }
3778
3779
3780 /*
3781 * Attempt to change an object into an artifact
3782 *
3783 * This routine should only be called by "apply_magic()"
3784 *
3785 * Note -- see "make_artifact_special()" and "apply_magic()"
3786 */
3787 static bool make_artifact(struct worldpos *wpos, object_type *o_ptr, u32b resf) {
3788 int i, tries = 0, d, dlev = getlevel(wpos);
3789 bool winner_arts_only = ((resf & RESF_NOTRUEART) && (resf & RESF_WINNER));
3790 #ifdef IDDC_EASY_TRUE_ARTIFACTS
3791 int difficulty = in_irondeepdive(wpos) ? 1 : 0;
3792 #endif
3793 artifact_type *a_ptr;
3794 int im, a_map[MAX_A_IDX];
3795
3796 /* No artifacts in the town, except if it's specifically requested */
3797 if (istown(wpos) && !(resf & RESF_FORCERANDART)) return (FALSE);
3798
3799 /* Paranoia -- no "plural" artifacts */
3800 if (o_ptr->number != 1) return (FALSE);
3801
3802 /* shuffle art indices for fairness */
3803 for (i = 0; i < MAX_A_IDX; i++) a_map[i] = i;
3804 intshuffle(a_map, MAX_A_IDX);
3805
3806 /* Check if true artifact generation is currently disabled -
3807 added this for maintenance reasons -C. Blue */
3808 if (!cfg.arts_disabled &&
3809 !((resf & RESF_NOTRUEART) && !(resf & RESF_WINNER))) {
3810 /* Check the artifact list (skip the "specials") */
3811 for (im = 0; im < MAX_A_IDX; im++) {
3812 i = a_map[im];
3813 a_ptr = &a_info[i];
3814
3815 /* Skip "empty" items */
3816 if (!a_ptr->name) continue;
3817
3818 /* Hack: "Disabled" */
3819 if (a_ptr->rarity == 255) continue;
3820
3821 /* Cannot make an artifact twice */
3822 if (a_ptr->cur_num) continue;
3823
3824 /* Cannot generate special ones */
3825 if (a_ptr->flags3 & TR3_INSTA_ART) continue;
3826
3827 /* Cannot generate some artifacts because they can only exists in special dungeons/quests/... */
3828 // if ((a_ptr->flags4 & TR4_SPECIAL_GENE) && (!a_allow_special[i]) && (!vanilla_town)) continue;
3829 if (a_ptr->flags4 & TR4_SPECIAL_GENE) continue;
3830
3831 /* Allow non-dropchosen/specialgene winner arts */
3832 if (winner_arts_only && !(a_ptr->flags5 & TR5_WINNERS_ONLY))
3833 continue;
3834
3835 /* Must have the correct fields */
3836 if (a_ptr->tval != o_ptr->tval) continue;
3837 if (a_ptr->sval != o_ptr->sval) continue;
3838
3839 /* XXX XXX Enforce minimum "depth" (loosely) */
3840 if (a_ptr->level > dlev) {
3841 /* Acquire the "out-of-depth factor" */
3842 d = (a_ptr->level - dlev) * 2;
3843
3844 /* Roll for out-of-depth creation */
3845 if (rand_int(d) != 0) continue;
3846 }
3847
3848 /* New: Prevent too many low-level artifacts on high dungeon levels.
3849 They tend to spawn very often due to their relatively low rarity,
3850 and are simply a small piece of cash, or even annoying if unsellable (Gorlim). */
3851 d = ((dlev - 20) / 2) - a_ptr->level;
3852 /* Don't start checking before dungeon level 40. */
3853 if ((dlev >= 40) && (d > 0) && !magik(350 / (d + 3))) continue;
3854
3855 /* We must make the "rarity roll" */
3856 #ifdef IDDC_EASY_TRUE_ARTIFACTS
3857 if (rand_int(a_ptr->rarity >> difficulty) != 0) continue;
3858 #else
3859 if (rand_int(a_ptr->rarity) != 0) continue;
3860 #endif
3861
3862 /* Hack -- mark the item as an artifact */
3863 o_ptr->name1 = i;
3864
3865 /* Hack -- Mark the artifact as "created" */
3866 handle_art_inum(o_ptr->name1);
3867
3868 log_arts(i, wpos);
3869
3870 /* Success */
3871 return (TRUE);
3872 }
3873 }
3874
3875 /* Break here if randarts aren't allowed */
3876 if (resf & RESF_NORANDART) return (FALSE);
3877
3878 /* An extra chance at being a randart. XXX RANDART */
3879 if (!rand_int(RANDART_RARITY) || (resf & RESF_FORCERANDART)) {
3880 /* Randart ammo should be very rare! */
3881 if (!(resf & RESF_FORCERANDART) && is_ammo(o_ptr->tval) && magik(80)) return(FALSE); /* was 95 */
3882
3883 /* We turn this item into a randart! */
3884 o_ptr->name1 = ART_RANDART;
3885
3886 /* NOTE: MAKE SURE FOLLOWING CODE IS CONSISTENT WITH create_artifact_aux() IN spells2.c! */
3887
3888 /* Start loop. Break when artifact is allowed */
3889 while (tries < 10) {
3890 tries++;
3891
3892 /* Piece together a 32-bit random seed */
3893 o_ptr->name3 = rand_int(0xFFFF) << 16;
3894 o_ptr->name3 += rand_int(0xFFFF);
3895
3896 /* Check the tval is allowed */
3897 if (randart_make(o_ptr) == NULL) {
3898 /* If not, wipe seed. No randart today */
3899 o_ptr->name1 = 0;
3900 o_ptr->name3 = 0L;
3901
3902 return (FALSE);
3903 }
3904
3905 /* Check if we can break the loop (artifact is allowed) */
3906 a_ptr = randart_make(o_ptr);
3907 if ((resf & RESF_LIFE) || !(a_ptr->flags1 & TR1_LIFE)) break;
3908 }
3909
3910 /* after too many tries, in theory allow non-winner to find a +LIFE randart.
3911 shouldn't matter much in reality though. */
3912 return (TRUE);
3913 }
3914
3915 /* Failure */
3916 return (FALSE);
3917 }
3918
3919
3920 /*
3921 * Ported from PernAngband - Jir -
3922 *
3923 * 'level' is not depth of dungeon but an index of item value.
3924 *
3925 * In PernMangband, ego-items use random-seed 'name3' just
3926 * as same as randarts.
3927 * (Be careful not to allow randarts ego!)
3928 */
3929 /*
3930 * Attempt to change an object into an ego
3931 *
3932 * This routine should only be called by "apply_magic()"
3933 */
3934 static bool make_ego_item(int level, object_type *o_ptr, bool good, u32b resf)
3935 {
3936 int i = 0, j, n;
3937 int *ok_ego, ok_num = 0;
3938 bool ret = FALSE, double_ok = !(resf & RESF_NODOUBLEEGO);
3939 byte tval = o_ptr->tval;
3940 #if 0 /* make_ego_item() is called BEFORE the book is set to a specific school spell! */
3941 bool crystal =
3942 o_ptr->tval == TV_BOOK &&
3943 o_ptr->sval == SV_SPELLBOOK &&
3944 get_spellbook_name_colour(o_ptr->pval) == TERM_YELLOW;
3945 #endif
3946
3947 if (artifact_p(o_ptr) || o_ptr->name2) return (FALSE);
3948
3949 C_MAKE(ok_ego, e_tval_size[tval], int);
3950
3951 /* Grab the ok ego */
3952 for (i = 0, n = e_tval_size[tval]; i < n; i++) {
3953 ego_item_type *e_ptr = &e_info[e_tval[tval][i]];
3954 bool ok = FALSE;
3955 #if 0 /* done in e_info */
3956 bool cursed = FALSE;
3957 #endif
3958
3959 /* Must have the correct fields */
3960 for (j = 0; j < MAX_EGO_BASETYPES; j++) {
3961 if ((e_ptr->tval[j] == o_ptr->tval) && (e_ptr->min_sval[j] <= o_ptr->sval) && (e_ptr->max_sval[j] >= o_ptr->sval)) ok = TRUE;
3962
3963 #if 0 /* done in e_info */
3964 for (k = 0; k < 5-4; k++) if (e_ptr->flags3[k] & TR3_CURSED) cursed = TRUE;
3965 #endif
3966 if (ok) break;
3967 }
3968 #if 0 /* done in e_info */
3969 /* No curse-free ego powers on broken or rusty items; no elven filthy rags */
3970 if (!cursed && (o_ptr->k_idx == 30 || o_ptr->k_idx == 47 || o_ptr->k_idx == 110 || (o_ptr->k_idx == 102 && i == EGO_ELVENKIND))) ok = FALSE;
3971 #endif
3972 if (!ok) {
3973 /* Doesnt count as a try*/
3974 continue;
3975 }
3976
3977 /* Good should be good, bad should be bad */
3978 if (good && (!e_ptr->cost)) continue;
3979 if ((!good) && e_ptr->cost) continue;
3980
3981 /* ok */
3982 ok_ego[ok_num++] = e_tval[tval][i];
3983 }
3984
3985 if (!ok_num) {
3986 /* Fix memory leak - mikaelh */
3987 C_FREE(ok_ego, e_tval_size[tval], int);
3988
3989 return(FALSE);
3990 }
3991
3992 /* Now test them a few times */
3993 // for (i = 0; i < ok_num * 10; i++) // I wonder..
3994 for (j = 0; j < ok_num * 10; j++) {
3995 ego_item_type *e_ptr;
3996
3997 i = ok_ego[rand_int(ok_num)];
3998 e_ptr = &e_info[i];
3999
4000 if (i == EGO_ETHEREAL && (resf & RESF_NOETHEREAL)) continue;
4001 #ifdef NO_MORGUL_IN_IDDC
4002 if (i == EGO_MORGUL && in_irondeepdive(&o_ptr->wpos)) continue;
4003 #endif
4004
4005 /* XXX XXX Enforce minimum "depth" (loosely) */
4006 if (e_ptr->level > level) {
4007 /* Acquire the "out-of-depth factor" */
4008 int d = (e_ptr->level - level);
4009
4010 /* Roll for out-of-depth creation */
4011 if (rand_int(d) != 0) continue;
4012 }
4013
4014 /* We must make the "rarity roll" */
4015 // if (rand_int(e_ptr->mrarity - luck(-(e_ptr->mrarity / 2), e_ptr->mrarity / 2)) > e_ptr->rarity)
4016 #if 0
4017 k = e_ptr->mrarity - e_ptr->rarity;
4018 if (k && rand_int(k)) continue;
4019 #endif // 0
4020
4021 if (e_ptr->mrarity == 255) continue;
4022 if (rand_int(e_ptr->mrarity) > e_ptr->rarity) continue;
4023 // if (rand_int(e_ptr->rarity) < e_ptr->mrarity) continue;
4024
4025 /* Hack -- mark the item as an ego */
4026 o_ptr->name2 = i;
4027
4028 /* Piece together a 32-bit random seed */
4029 if (e_ptr->fego1[0] & ETR1_NO_SEED) o_ptr->name3 = 0;
4030 else {
4031 o_ptr->name3 = rand_int(0xFFFF) << 16;
4032 o_ptr->name3 += rand_int(0xFFFF);
4033 }
4034
4035 if ((e_ptr->fego1[0] & ETR1_NO_DOUBLE_EGO)) double_ok = FALSE;
4036
4037 /* Success */
4038 ret = TRUE;
4039 break;
4040 }
4041
4042 /*
4043 * Sometimes(rarely) tries for a double ego
4044 * Also make sure we dont already have a name2b, wchih would mean a special ego item
4045 */
4046 /* try only when it's already ego - Jir - */
4047 // if (magik(7 + luck(-7, 7)) && (!o_ptr->name2b))
4048 if (ret && double_ok && magik(7) && (!o_ptr->name2b)) {
4049 /* Now test them a few times */
4050 for (j = 0; j < ok_num * 10; j++) {
4051 ego_item_type *e_ptr;
4052
4053 i = ok_ego[rand_int(ok_num)];
4054 e_ptr = &e_info[i];
4055
4056 if (i == EGO_ETHEREAL && (resf & RESF_NOETHEREAL)) continue;
4057 #ifdef NO_MORGUL_IN_IDDC
4058 if (i == EGO_MORGUL && in_irondeepdive(&o_ptr->wpos)) continue;
4059 #endif
4060 if ((e_ptr->fego1[0] & ETR1_NO_DOUBLE_EGO)) continue;
4061
4062 /* Cannot be a double ego of the same ego type */
4063 if (i == o_ptr->name2) continue;
4064
4065 /* Cannot have 2 suffixes or 2 prefixes */
4066 if (e_info[o_ptr->name2].before && e_ptr->before) continue;
4067 if ((!e_info[o_ptr->name2].before) && (!e_ptr->before)) continue;
4068
4069 /* XXX XXX Enforce minimum "depth" (loosely) */
4070 if (e_ptr->level > level) {
4071 /* Acquire the "out-of-depth factor" */
4072 int d = (e_ptr->level - level);
4073
4074 /* Roll for out-of-depth creation */
4075 if (rand_int(d) != 0) continue;
4076 }
4077
4078 /* We must make the "rarity roll" */
4079 // if (rand_int(e_ptr->mrarity - luck(-(e_ptr->mrarity / 2), e_ptr->mrarity / 2)) > e_ptr->rarity)
4080 if (e_ptr->mrarity == 255) continue;
4081 if (rand_int(e_ptr->mrarity) > e_ptr->rarity) continue;
4082 // if (rand_int(e_ptr->rarity) < e_ptr->mrarity) continue;
4083
4084 /* Don't allow silyl combinations that either don't
4085 make sense or that cause technical problems: */
4086
4087 /* Prevent redundant resistance flags (elven armour of resist xxxx) */
4088 switch (o_ptr->name2) {
4089 case EGO_RESIST_FIRE:
4090 if (i == EGO_DWARVEN_ARMOR) {
4091 /* upgrade first ego power! */
4092 o_ptr->name2 = i;
4093 i = 0;
4094 break;
4095 }
4096 case EGO_RESIST_COLD:
4097 case EGO_RESIST_ELEC:
4098 case EGO_RESIST_ACID:
4099 if (i == EGO_ELVENKIND) {
4100 /* upgrade first ego power! */
4101 o_ptr->name2 = i;
4102 i = 0;
4103 break;
4104 }
4105 break;
4106 case EGO_ELVENKIND:
4107 switch (i) {
4108 case EGO_RESIST_FIRE: case EGO_RESIST_COLD:
4109 case EGO_RESIST_ELEC: case EGO_RESIST_ACID:
4110 continue;
4111 }
4112 break;
4113 case EGO_DWARVEN_ARMOR:
4114 switch (i) {
4115 case EGO_RESIST_FIRE:
4116 continue;
4117 }
4118 break;
4119 }
4120
4121 /* Prevent two ego powers that can both be activated */
4122 switch (o_ptr->name2) {
4123 case EGO_CLOAK_LORDLY_RES:
4124 switch (i) {
4125 case EGO_AURA_ELEC2:
4126 case EGO_AURA_COLD2:
4127 case EGO_AURA_FIRE2:
4128 continue;
4129 }
4130 break;
4131 case EGO_AURA_ELEC2:
4132 case EGO_AURA_COLD2:
4133 case EGO_AURA_FIRE2:
4134 if (i == EGO_CLOAK_LORDLY_RES) {
4135 /* upgrade first ego power! */
4136 o_ptr->name2 = i;
4137 i = 0;
4138 break;
4139 }
4140 break;
4141 case EGO_SPECTRAL:
4142 switch (i) {
4143 case EGO_FURY:
4144 /* upgrade first ego power! */
4145 o_ptr->name2 = i;
4146 i = 0;
4147 break;
4148 case EGO_DRAGON: /* of the Thunderlords */
4149 /* upgrade first ego power! */
4150 o_ptr->name2 = i;
4151 i = 0;
4152 break;
4153 }
4154 break;
4155 case EGO_FURY:
4156 case EGO_DRAGON: /* of the Thunderlords */
4157 if (i == EGO_SPECTRAL) continue;
4158 }
4159
4160 /* Prevent contradicting ego powers */
4161 switch (o_ptr->name2) {
4162 case EGO_CLOAK_INVIS:
4163 switch (i) {
4164 case EGO_AURA_ELEC2:
4165 case EGO_AURA_COLD2:
4166 case EGO_AURA_FIRE2:
4167 continue;
4168 }
4169 break;
4170 case EGO_AURA_ELEC2:
4171 case EGO_AURA_COLD2:
4172 case EGO_AURA_FIRE2:
4173 if (i == EGO_CLOAK_INVIS) {
4174 /* upgrade first ego power! */
4175 o_ptr->name2 = i;
4176 i = 0;
4177 break;
4178 }
4179 break;
4180 }
4181
4182 /* Hack: If we upgraded the first ego power, the second one hasn't become set.
4183 In that case i == 0 here. */
4184 if (i == 0) break;
4185
4186 /* Hack -- mark the item as an ego */
4187 o_ptr->name2b = i;
4188
4189 /* Piece together a 32-bit random seed */
4190 if (!(e_ptr->fego1[0] & ETR1_NO_SEED) && !o_ptr->name3) {
4191 o_ptr->name3 = rand_int(0xFFFF) << 16;
4192 o_ptr->name3 += rand_int(0xFFFF);
4193 }
4194 break;
4195 }
4196 }
4197 C_FREE(ok_ego, e_tval_size[tval], int);
4198
4199 /* Return */
4200 return (ret);
4201 }
4202
4203
4204 /*
4205 * Charge a new wand.
4206 */
4207 static void charge_wand(object_type *o_ptr)
4208 {
4209 switch (o_ptr->sval) {
4210 case SV_WAND_HEAL_MONSTER: o_ptr->pval = randint(20) + 8; break;
4211 case SV_WAND_HASTE_MONSTER: o_ptr->pval = randint(20) + 8; break;
4212 case SV_WAND_CLONE_MONSTER: o_ptr->pval = randint(5) + 3; break;
4213 case SV_WAND_TELEPORT_AWAY: o_ptr->pval = randint(5) + 6; break;
4214 case SV_WAND_DISARMING: o_ptr->pval = randint(5) + 4; break;
4215 case SV_WAND_TRAP_DOOR_DEST: o_ptr->pval = randint(8) + 6; break;
4216 case SV_WAND_STONE_TO_MUD: o_ptr->pval = randint(8) + 3; break;
4217 case SV_WAND_LITE: o_ptr->pval = randint(10) + 6; break;
4218 case SV_WAND_SLEEP_MONSTER: o_ptr->pval = randint(15) + 8; break;
4219 case SV_WAND_SLOW_MONSTER: o_ptr->pval = randint(10) + 6; break;
4220 case SV_WAND_CONFUSE_MONSTER: o_ptr->pval = randint(12) + 6; break;
4221 case SV_WAND_FEAR_MONSTER: o_ptr->pval = randint(5) + 3; break;
4222 case SV_WAND_DRAIN_LIFE: o_ptr->pval = randint(3) + 3; break;
4223 case SV_WAND_WALL_CREATION: o_ptr->pval = randint(4) + 3; break;
4224 case SV_WAND_POLYMORPH: o_ptr->pval = randint(8) + 6; break;
4225 case SV_WAND_STINKING_CLOUD: o_ptr->pval = randint(8) + 6; break;
4226 case SV_WAND_MAGIC_MISSILE: o_ptr->pval = randint(10) + 6; break;
4227 case SV_WAND_ACID_BOLT: o_ptr->pval = randint(8) + 6; break;
4228 case SV_WAND_CHARM_MONSTER: o_ptr->pval = randint(6) + 2; break;
4229 case SV_WAND_FIRE_BOLT: o_ptr->pval = randint(8) + 6; break;
4230 case SV_WAND_COLD_BOLT: o_ptr->pval = randint(5) + 6; break;
4231 case SV_WAND_ACID_BALL: o_ptr->pval = randint(5) + 2; break;
4232 case SV_WAND_ELEC_BALL: o_ptr->pval = randint(8) + 4; break;
4233 case SV_WAND_FIRE_BALL: o_ptr->pval = randint(4) + 2; break;
4234 case SV_WAND_COLD_BALL: o_ptr->pval = randint(6) + 2; break;
4235 case SV_WAND_WONDER: o_ptr->pval = randint(15) + 8; break;
4236 case SV_WAND_ANNIHILATION: o_ptr->pval = randint(2) + 1; break;
4237 case SV_WAND_DRAGON_FIRE: o_ptr->pval = randint(3) + 1; break;
4238 case SV_WAND_DRAGON_COLD: o_ptr->pval = randint(3) + 1; break;
4239 case SV_WAND_DRAGON_BREATH: o_ptr->pval = randint(3) + 1; break;
4240 case SV_WAND_ROCKETS: o_ptr->pval = randint(2) + 1; break;
4241 case SV_WAND_ELEC_BOLT: o_ptr->pval = randint(8) + 6; break;
4242 case SV_WAND_TELEPORT_TO: o_ptr->pval = randint(3) + 3; break;
4243 }
4244 }
4245
4246
4247
4248 /*
4249 * Charge a new staff.
4250 */
4251 static void charge_staff(object_type *o_ptr)
4252 {
4253 switch (o_ptr->sval) {
4254 case SV_STAFF_DARKNESS: o_ptr->pval = randint(8) + 8; break;
4255 case SV_STAFF_SLOWNESS: o_ptr->pval = randint(8) + 8; break;
4256 case SV_STAFF_HASTE_MONSTERS: o_ptr->pval = randint(8) + 8; break;
4257 case SV_STAFF_SUMMONING: o_ptr->pval = randint(3) + 1; break;
4258 case SV_STAFF_TELEPORTATION: o_ptr->pval = randint(4) + 5; break;
4259 case SV_STAFF_IDENTIFY: o_ptr->pval = randint(15) + 5; break;
4260 case SV_STAFF_REMOVE_CURSE: o_ptr->pval = randint(3) + 4; break;
4261 case SV_STAFF_STARLITE: o_ptr->pval = randint(5) + 6; break;
4262 case SV_STAFF_LITE: o_ptr->pval = randint(20) + 8; break;
4263 case SV_STAFF_MAPPING: o_ptr->pval = randint(5) + 5; break;
4264 case SV_STAFF_DETECT_GOLD: o_ptr->pval = randint(20) + 8; break;
4265 case SV_STAFF_DETECT_ITEM: o_ptr->pval = randint(15) + 6; break;
4266 case SV_STAFF_DETECT_TRAP: o_ptr->pval = randint(5) + 6; break;
4267 case SV_STAFF_DETECT_DOOR: o_ptr->pval = randint(8) + 6; break;
4268 case SV_STAFF_DETECT_INVIS: o_ptr->pval = randint(15) + 8; break;
4269 case SV_STAFF_DETECT_EVIL: o_ptr->pval = randint(15) + 8; break;
4270 case SV_STAFF_CURE_SERIOUS: o_ptr->pval = randint(5) + 6; break;
4271 case SV_STAFF_CURING: o_ptr->pval = randint(3) + 4; break;
4272 case SV_STAFF_HEALING: o_ptr->pval = randint(2) + 1; break;
4273 case SV_STAFF_THE_MAGI: o_ptr->pval = randint(2) + 2; break;
4274 case SV_STAFF_SLEEP_MONSTERS: o_ptr->pval = randint(5) + 6; break;
4275 case SV_STAFF_SLOW_MONSTERS: o_ptr->pval = randint(5) + 6; break;
4276 case SV_STAFF_SPEED: o_ptr->pval = randint(3) + 4; break;
4277 case SV_STAFF_PROBING: o_ptr->pval = randint(6) + 2; break;
4278 case SV_STAFF_DISPEL_EVIL: o_ptr->pval = randint(3) + 4; break;
4279 case SV_STAFF_POWER: o_ptr->pval = randint(3) + 1; break;
4280 case SV_STAFF_HOLINESS: o_ptr->pval = randint(2) + 2; break;
4281 case SV_STAFF_GENOCIDE: o_ptr->pval = randint(2) + 1; break;
4282 case SV_STAFF_EARTHQUAKES: o_ptr->pval = randint(5) + 3; break;
4283 case SV_STAFF_DESTRUCTION: o_ptr->pval = randint(3) + 1; break;
4284 case SV_STAFF_STAR_IDENTIFY: o_ptr->pval = randint(5) + 3; break;
4285 }
4286 }
4287
4288
4289
4290 /*
4291 * Apply magic to an item known to be a "weapon"
4292 *
4293 * Hack -- note special base damage dice boosting
4294 * Hack -- note special processing for weapon/digger
4295 * Hack -- note special rating boost for dragon scale mail
4296 */
4297 static void a_m_aux_1(object_type *o_ptr, int level, int power, u32b resf) {
4298 int tohit1 = randint(5) + m_bonus(5, level);
4299 int todam1 = randint(5) + m_bonus(5, level);
4300
4301 int tohit2 = m_bonus(10, level);
4302 int todam2 = m_bonus(10, level);
4303 //int tries;
4304
4305 artifact_bias = 0;
4306
4307 /* Very good */
4308 if (power > 1) {
4309 /* Make ego item */
4310 // if (!rand_int(RANDART_WEAPON) && (o_ptr->tval != TV_TRAPKIT)) create_artifact(o_ptr, FALSE, TRUE); else
4311 make_ego_item(level, o_ptr, TRUE, resf);
4312 } else if (power < -1) {
4313 /* Make ego item */
4314 make_ego_item(level, o_ptr, FALSE, resf);
4315 }
4316
4317 /* Good */
4318 if ((power > 0) && (o_ptr->tval != TV_MSTAFF)) {
4319 /* Enchant */
4320 o_ptr->to_h += tohit1;
4321 o_ptr->to_d += todam1;
4322
4323 /* Very good */
4324 if (power > 1) {
4325 /* Enchant again */
4326 o_ptr->to_h += tohit2;
4327 o_ptr->to_d += todam2;
4328 }
4329 }
4330 /* Cursed */
4331 else if (power < 0) {
4332 /* Penalize */
4333 o_ptr->to_h -= tohit1;
4334 o_ptr->to_d -= todam1;
4335
4336 /* Very cursed */
4337 if (power < -1) {
4338 /* Penalize again */
4339 o_ptr->to_h -= tohit2;
4340 o_ptr->to_d -= todam2;
4341 }
4342
4343 /* Cursed (if "bad") */
4344 #ifdef PREVENT_CURSED_TOOLS
4345 /* little hack - no cursed diggers/tools */
4346 if ((o_ptr->tval != TV_DIGGING && o_ptr->tval != TV_TOOL) &&
4347 (o_ptr->to_h + o_ptr->to_d < 0))
4348 #else
4349 if (o_ptr->to_h + o_ptr->to_d < 0)
4350 #endif
4351 o_ptr->ident |= ID_CURSED;
4352 }
4353
4354
4355 /* Some special cases */
4356 switch (o_ptr->tval) {
4357 case TV_MSTAFF:
4358 break;
4359 case TV_BOLT:
4360 case TV_ARROW:
4361 case TV_SHOT:
4362 if (o_ptr->sval == SV_AMMO_MAGIC) {
4363 o_ptr->to_h = o_ptr->to_d = o_ptr->pval = o_ptr->name2 = o_ptr->name3 = 0;
4364 break;
4365 }
4366
4367 // if ((power == 1) && !o_ptr->name2 && o_ptr->sval != SV_AMMO_MAGIC)
4368 else if ((power == 1) && !o_ptr->name2) {
4369 // if (randint(100) < 7)
4370 if (randint(500) < level + 5) {
4371 /* Exploding missile */
4372 int power[28] = { GF_ELEC, GF_POIS, GF_ACID,
4373 GF_COLD, GF_FIRE, GF_PLASMA, GF_LITE,
4374 GF_DARK, GF_SHARDS, GF_SOUND,
4375 GF_CONFUSION, GF_FORCE, GF_INERTIA,
4376 GF_MANA, GF_METEOR, GF_ICE, GF_CHAOS,
4377 GF_NETHER, GF_NEXUS, GF_TIME,
4378 GF_GRAVITY, GF_KILL_WALL, GF_AWAY_ALL,
4379 GF_TURN_ALL, GF_NUKE, GF_STUN,
4380 GF_DISINTEGRATE, GF_HELL_FIRE };
4381
4382 // o_ptr->pval2 = power[rand_int(25)];
4383 o_ptr->pval = power[rand_int(28)];
4384 }
4385 }
4386 break;
4387 case TV_BOOMERANG:
4388 case TV_BOW:
4389 if (o_ptr->name2 == EGO_ACCURACY || o_ptr->name2b == EGO_ACCURACY) {
4390 if (o_ptr->to_h < 18) o_ptr->to_h = 18;
4391 }
4392 if (o_ptr->name2 == EGO_VELOCITY || o_ptr->name2b == EGO_VELOCITY) {
4393 if (o_ptr->to_d < 18) o_ptr->to_d = 18;
4394 }
4395 break;
4396 }
4397
4398 /* CAP_ITEM_BONI */
4399 switch (o_ptr->tval) {
4400 case TV_BOLT:
4401 case TV_ARROW:
4402 case TV_SHOT:
4403 if (o_ptr->to_h > 15) o_ptr->to_h = 15;
4404 if (o_ptr->to_d > 15) o_ptr->to_d = 15;
4405 break;
4406 case TV_BOW:
4407 case TV_BOOMERANG:
4408 default:
4409 if (o_ptr->to_h > 30) o_ptr->to_h = 30;
4410 if (o_ptr->to_d > 30) o_ptr->to_d = 30;
4411 break;
4412 }
4413 }
4414
4415
4416 /*
4417 * Apply magic to an item known to be "armor"
4418 *
4419 * Hack -- note special processing for crown/helm
4420 * Hack -- note special processing for robe of permanence
4421 */
4422 static void a_m_aux_2(object_type *o_ptr, int level, int power, u32b resf) {
4423 int toac1 = randint(5) + m_bonus(5, level);
4424 int toac2 = m_bonus(10, level);
4425
4426 artifact_bias = 0;
4427
4428 /* Very good */
4429 if (power > 1) {
4430 /* Make ego item */
4431 // if (!rand_int(RANDART_ARMOR)) create_artifact(o_ptr, FALSE, TRUE); else
4432 make_ego_item(level, o_ptr, TRUE, resf);
4433 } else if (power < -1) {
4434 /* Make ego item */
4435 make_ego_item(level, o_ptr, FALSE, resf);
4436 }
4437
4438 #ifdef NEW_SHIELDS_NO_AC
4439 /* shields cannot be cursed (aka getting ac malus) or get an ac bonus, if they aren't egos */
4440 if ((k_info[o_ptr->k_idx].flags3 & TR3_EASY_KNOW)) ;
4441 else
4442 #endif
4443 /* Good */
4444 if (power > 0) {
4445 /* Enchant */
4446 o_ptr->to_a += toac1;
4447
4448 /* Very good */
4449 if (power > 1) {
4450 /* Enchant again */
4451 o_ptr->to_a += toac2;
4452 }
4453 }
4454 /* Cursed */
4455 else if (power < 0) {
4456 /* Penalize */
4457 o_ptr->to_a -= toac1;
4458
4459 /* Very cursed */
4460 if (power < -1) {
4461 /* Penalize again */
4462 o_ptr->to_a -= toac2;
4463 }
4464
4465 /* Cursed (if "bad") */
4466 if (o_ptr->to_a < 0) o_ptr->ident |= ID_CURSED;
4467 }
4468
4469 #if 1 // once..
4470 /* Analyze type */
4471 switch (o_ptr->tval) {
4472 case TV_CLOAK:
4473 if (o_ptr->sval == SV_ELVEN_CLOAK) {
4474 //experimentally changed: o_ptr->bpval = randint(4); /* No cursed elven cloaks...? */
4475 o_ptr->bpval = randint(3); /* No cursed elven cloaks...? */
4476 }
4477 #if 1
4478 /* Set the Kolla cloak's base bonuses*/
4479 if (o_ptr->sval == SV_KOLLA) {
4480 o_ptr->bpval = randint(2);
4481 }
4482 #endif
4483 break;
4484 case TV_DRAG_ARMOR:
4485 if (o_ptr->sval == SV_DRAGON_MULTIHUED) {
4486 /* give 2 random immunities */
4487 int imm1 = rand_int(5), imm2 = rand_int(4);
4488 if (imm2 == imm1) imm2 = 4;
4489 o_ptr->xtra2 |= 0x1 << imm1;
4490 o_ptr->xtra2 |= 0x1 << imm2;
4491 }
4492 break;
4493 case TV_SOFT_ARMOR:
4494 /* Costumes */
4495 if (o_ptr->sval == SV_COSTUME) {
4496 int i, tries = 0;
4497 monster_race *r_ptr;
4498
4499 /* Santa Claus costumes during xmas */
4500 if (season_xmas) {
4501 o_ptr->bpval = RI_SANTA1; /* JOKEBAND Santa Claus */
4502 o_ptr->level = 1;
4503 } else {
4504 /* Default to the "player" */
4505 o_ptr->bpval = 0;
4506 o_ptr->level = 1;
4507
4508 while (tries++ != 1000) {
4509 i = randint(MAX_R_IDX - 2); /* skip 0, ie player, and the 'undefined ghost' (MAX_R_IDX - 1) */
4510 r_ptr = &r_info[i];
4511
4512 if (!r_ptr->name) continue;
4513 // if (r_ptr->flags1 & RF1_UNIQUE) continue;
4514 // if (r_ptr->level >= level + (power * 5)) continue;
4515 // if (!mon_allowed(r_ptr)) continue;
4516 if (!mon_allowed_chance(r_ptr)) continue;
4517 if (r_ptr->rarity == 255) continue;
4518
4519 break;
4520 }
4521 if (tries < 1000) {
4522 o_ptr->bpval = i;
4523 o_ptr->level = r_info[i].level / 4;
4524 if (o_ptr->level < 1) o_ptr->level = 1;
4525 }
4526 }
4527 }
4528 break;
4529 case TV_SHIELD:
4530 if (o_ptr->sval == SV_DRAGON_SHIELD) {
4531 /* pfft */
4532 // dragon_resist(o_ptr);
4533 break;
4534 }
4535
4536 #if 1
4537 /* Set the orcish shield's STR and CON bonus */
4538 if (o_ptr->sval == SV_ORCISH_SHIELD) {
4539 o_ptr->bpval = randint(2);
4540
4541 /* Cursed orcish shield */
4542 if (power < 0) {
4543 o_ptr->bpval = -o_ptr->bpval;
4544 #ifdef NEW_SHIELDS_NO_AC
4545 /* Cursed (if "bad") */
4546 o_ptr->ident |= ID_CURSED;
4547 #endif
4548 }
4549 break;
4550 }
4551 #endif
4552 #if 1
4553 case TV_BOOTS:
4554 /* Set the Witan Boots stealth penalty */
4555 if (o_ptr->sval == SV_PAIR_OF_WITAN_BOOTS)
4556 o_ptr->bpval = -2;
4557 #endif
4558 }
4559 #endif
4560
4561 /* CAP_ITEM_BONI */
4562 #ifdef USE_NEW_SHIELDS /* should actually be USE_BLOCKING, but could be too */
4563 /* dramatic a change if it gets enabled temporarily - C. Blue */
4564 if (o_ptr->tval == TV_SHIELD) {
4565 #ifndef NEW_SHIELDS_NO_AC
4566 if (o_ptr->to_a > 15) o_ptr->to_a = 15;
4567 #else
4568 o_ptr->to_a = 0;
4569 #endif
4570 } else
4571 #endif
4572 {
4573 // if (o_ptr->to_a > 50) o_ptr->to_a = 50;
4574 #ifndef TO_AC_CAP_30
4575 if (o_ptr->to_a > 35) o_ptr->to_a = 35;
4576 #else
4577 if (o_ptr->to_a > 30) o_ptr->to_a = 30;
4578 #endif
4579 }
4580 }
4581
4582
4583
4584 /*
4585 * Apply magic to an item known to be a "ring" or "amulet"
4586 *
4587 * Hack -- note special rating boost for ring of speed
4588 * Hack -- note special rating boost for amulet of the magi
4589 * Hack -- note special "pval boost" code for ring of speed
4590 * Hack -- note that some items must be cursed (or blessed)
4591 */
4592 static void a_m_aux_3(object_type *o_ptr, int level, int power, u32b resf) {
4593 int tries = 0, i;
4594 artifact_bias = 0;
4595
4596 if (!power && (rand_int(100) < CURSED_JEWELRY_CHANCE)) power = -1;
4597
4598 /* Very good */
4599 if (power > 1) {
4600 #if 0
4601 if (!rand_int(RANDART_JEWEL)) create_artifact(o_ptr, FALSE, TRUE);
4602 else
4603 #endif
4604 /* Make ego item */
4605 make_ego_item(level, o_ptr, TRUE, resf);
4606 } else if (power < -1) {
4607 /* Make ego item */
4608 make_ego_item(level, o_ptr, FALSE, resf);
4609 }
4610
4611
4612 /* prolly something should be done.. - Jir - */
4613 /* Apply magic (good or bad) according to type */
4614 switch (o_ptr->tval) {
4615 case TV_RING:
4616 /* Analyze */
4617 switch (o_ptr->sval) {
4618 case SV_RING_POLYMORPH:
4619 if (power < 1) power = 1;
4620
4621 /* Be sure to be a player */
4622 o_ptr->pval = 0;
4623 o_ptr->timeout = 0;
4624
4625 if (magik(45)) {
4626 monster_race *r_ptr;
4627
4628 while (tries++ != 1000) {
4629 i = randint(MAX_R_IDX - 2); /* skip 0, ie player and the 'undefined ghost' (MAX_R_IDX - 1) */
4630 r_ptr = &r_info[i];
4631
4632 if (!r_ptr->name) continue;
4633 if (r_ptr->flags1 & RF1_UNIQUE) continue;
4634 if (r_ptr->level >= level + (power * 5)) continue;
4635 // if (!mon_allowed(r_ptr)) continue;
4636 if (!mon_allowed_chance(r_ptr)) continue;
4637 if (r_ptr->rarity == 255) continue;
4638
4639 break;
4640 }
4641 if (tries < 1000) {
4642 o_ptr->pval = i;
4643 o_ptr->level = ring_of_polymorph_level(r_info[i].level);
4644 o_ptr->timeout = 3000 + rand_int(3001);
4645 } else o_ptr->level = 1;
4646 } else o_ptr->level = 1;
4647 break;
4648
4649 /* Strength, Constitution, Dexterity, Intelligence */
4650 case SV_RING_ATTACKS:
4651 /* Stat bonus */
4652 o_ptr->bpval = m_bonus(3, level);
4653 if (o_ptr->bpval < 1) o_ptr->bpval = 1;
4654
4655 /* Cursed */
4656 if (power < 0) {
4657 /* Cursed */
4658 o_ptr->ident |= (ID_CURSED);
4659
4660 /* Reverse bpval */
4661 o_ptr->bpval = 0 - (o_ptr->bpval);
4662 }
4663 break;
4664
4665 /* Critical hits */
4666 case SV_RING_CRIT:
4667 /* Stat bonus */
4668 o_ptr->bpval = m_bonus(10, level);
4669 if (o_ptr->bpval < 1) o_ptr->bpval = 1;
4670
4671 /* Cursed */
4672 if (power < 0) {
4673 /* Cursed */
4674 o_ptr->ident |= (ID_CURSED);
4675
4676 /* Reverse bpval */
4677 o_ptr->bpval = 0 - (o_ptr->bpval);
4678 }
4679 break;
4680
4681 case SV_RING_MIGHT:
4682 case SV_RING_READYWIT:
4683 case SV_RING_TOUGHNESS:
4684 case SV_RING_CUNNINGNESS:
4685 /* Stat bonus */
4686 o_ptr->bpval = 1 + m_bonus(4, level); /* (5, level) for single-stat rings (traditional) */
4687
4688 /* Cursed */
4689 if (power < 0) {
4690 /* Cursed */
4691 o_ptr->ident |= (ID_CURSED);
4692
4693 /* Reverse bpval */
4694 o_ptr->bpval = 0 - (o_ptr->bpval);
4695 }
4696 break;
4697
4698 case SV_RING_SEARCHING:
4699 case SV_RING_STEALTH:
4700 /* Stat bonus */
4701 o_ptr->bpval = 1 + m_bonus(5, level);
4702
4703 /* Cursed */
4704 if (power < 0) {
4705 /* Cursed */
4706 o_ptr->ident |= (ID_CURSED);
4707
4708 /* Reverse bpval */
4709 o_ptr->bpval = 0 - (o_ptr->bpval);
4710 }
4711 break;
4712
4713 /* Ring of Speed! */
4714 case SV_RING_SPEED:
4715 /* Base speed (1 to 10) */
4716 o_ptr->bpval = randint(5) + m_bonus(5, level);
4717
4718 /* Super-charge the ring */
4719 while (rand_int(100) < 50 && o_ptr->bpval < 15) o_ptr->bpval++;
4720
4721 /* Paranoia - Limit */
4722 if (o_ptr->bpval > 15) o_ptr->bpval = 15;
4723
4724 /* Cursed Ring */
4725 if (power < 0) {
4726 /* Cursed */
4727 o_ptr->ident |= (ID_CURSED);
4728
4729 /* Reverse bpval */
4730 o_ptr->bpval = 0 - (o_ptr->bpval);
4731
4732 break;
4733 }
4734
4735 break;
4736
4737 case SV_RING_LORDLY:
4738 #if 0 /* lordly pfft ring.. */
4739 do {
4740 random_resistance(o_ptr, FALSE, ((randint(20))+18));
4741 } while (randint(4) == 1);
4742 #endif
4743
4744 /* Bonus to armor class */
4745 o_ptr->to_a = 10 + randint(5) + m_bonus(10, level);
4746 break;
4747
4748 /* Flames, Acid, Ice */
4749 case SV_RING_FLAMES:
4750 case SV_RING_ACID:
4751 case SV_RING_ICE:
4752 case SV_RING_ELEC:
4753 /* Bonus to armor class */
4754 o_ptr->to_a = 5 + randint(5) + m_bonus(10, level);
4755 break;
4756
4757 /* Weakness, Stupidity */
4758 case SV_RING_WEAKNESS:
4759 case SV_RING_STUPIDITY:
4760 /* Cursed */
4761 o_ptr->ident |= (ID_CURSED);
4762
4763 /* Penalize */
4764 o_ptr->bpval = 0 - (1 + m_bonus(5, level));
4765
4766 break;
4767
4768 /* WOE, Stupidity */
4769 case SV_RING_WOE:
4770 /* Cursed */
4771 o_ptr->ident |= (ID_CURSED);
4772
4773 /* Penalize */
4774 o_ptr->to_a = 0 - (5 + m_bonus(10, level));
4775 o_ptr->bpval = 0 - (1 + m_bonus(5, level));
4776 break;
4777
4778 /* Ring of damage */
4779 case SV_RING_DAMAGE:
4780 /* Bonus to damage */
4781 o_ptr->to_d = 5 + randint(8) + m_bonus(10, level);
4782
4783 /* Cursed */
4784 if (power < 0) {
4785 /* Cursed */
4786 o_ptr->ident |= (ID_CURSED);
4787
4788 /* Reverse bonus */
4789 o_ptr->to_d = 0 - (o_ptr->to_d);
4790 }
4791 break;
4792
4793 /* Ring of Accuracy */
4794 case SV_RING_ACCURACY:
4795 /* Bonus to hit */
4796 // o_ptr->to_h = 5 + randint(8) + m_bonus(10, level);
4797 o_ptr->to_h = 10 + rand_int(11) + m_bonus(5, level);
4798
4799 /* Cursed */
4800 if (power < 0) {
4801 /* Cursed */
4802 o_ptr->ident |= (ID_CURSED);
4803
4804 /* Reverse tohit */
4805 o_ptr->to_h = 0 - (o_ptr->to_h);
4806 }
4807 break;
4808
4809 /* Ring of Protection */
4810 case SV_RING_PROTECTION:
4811 /* Bonus to armor class */
4812 o_ptr->to_a = 5 + randint(8) + m_bonus(10, level);
4813
4814 /* Cursed */
4815 if (power < 0) {
4816 /* Cursed */
4817 o_ptr->ident |= (ID_CURSED);
4818
4819 /* Reverse toac */
4820 o_ptr->to_a = 0 - (o_ptr->to_a);
4821 }
4822
4823 break;
4824
4825 /* Ring of Slaying */
4826 case SV_RING_SLAYING:
4827 /* Bonus to damage and to hit */
4828 o_ptr->to_h = 3 + randint(6) + m_bonus(10, level);
4829 o_ptr->to_d = 3 + randint(5) + m_bonus(9, level);
4830
4831 /* Cursed */
4832 if (power < 0) {
4833 /* Cursed */
4834 o_ptr->ident |= (ID_CURSED);
4835
4836 /* Reverse bonuses */
4837 o_ptr->to_h = 0 - (o_ptr->to_h);
4838 o_ptr->to_d = 0 - (o_ptr->to_d);
4839 }
4840 break;
4841 }
4842 break;
4843
4844 case TV_AMULET:
4845 /* Analyze */
4846 switch (o_ptr->sval) {
4847 /* Old good Mangband ones */
4848 /* Amulet of Terken -- never cursed */
4849 case SV_AMULET_TERKEN:
4850 o_ptr->bpval = randint(5) + m_bonus(5, level);
4851 //o_ptr->to_h = randint(5);
4852 //o_ptr->to_d = randint(5);
4853
4854 /* Sorry.. */
4855 // o_ptr->xtra1 = EGO_XTRA_ABILITY;
4856 // o_ptr->xtra2 = randint(256);
4857 break;
4858
4859 /* Amulet of the Moon -- never cursed */
4860 case SV_AMULET_THE_MOON:
4861 o_ptr->bpval = randint(5) + m_bonus(5, level);
4862 o_ptr->to_h = randint(5);
4863 o_ptr->to_d = randint(5);
4864
4865 // o_ptr->xtra1 = EGO_XTRA_ABILITY;
4866 //o_ptr->xtra2 = randint(256);
4867 break;
4868
4869 /* Amulet of the Magi -- never cursed */
4870 case SV_AMULET_THE_MAGI:
4871 // if (randint(3) == 1) o_ptr->art_flags3 |= TR3_SLOW_DIGEST;
4872 case SV_AMULET_TRICKERY:
4873 case SV_AMULET_DEVOTION:
4874 o_ptr->bpval = 1 + m_bonus(3, level);
4875 break;
4876
4877 case SV_AMULET_WEAPONMASTERY:
4878 o_ptr->bpval = 1 + m_bonus(2, level);
4879 o_ptr->to_a = 1 + m_bonus(4, level);
4880 o_ptr->to_h = 1 + m_bonus(5, level);
4881 o_ptr->to_d = 1 + m_bonus(5, level);
4882 break;
4883
4884 /* Amulet of wisdom/charisma */
4885 case SV_AMULET_BRILLANCE:
4886 case SV_AMULET_CHARISMA:
4887 case SV_AMULET_WISDOM:
4888 case SV_AMULET_INFRA:
4889 o_ptr->bpval = 1 + m_bonus(5, level);
4890
4891 /* Cursed */
4892 if (power < 0) {
4893 /* Cursed */
4894 o_ptr->ident |= (ID_CURSED);
4895
4896 /* Reverse bonuses */
4897 o_ptr->bpval = 0 - (o_ptr->bpval);
4898 }
4899
4900 break;
4901
4902 /* Amulet of the Serpents */
4903 case SV_AMULET_SERPENT:
4904 o_ptr->bpval = 1 + m_bonus(5, level);
4905 o_ptr->to_a = 1 + m_bonus(6, level);
4906
4907 /* Cursed */
4908 if (power < 0) {
4909 /* Cursed */
4910 o_ptr->ident |= (ID_CURSED);
4911
4912 /* Reverse bonuses */
4913 o_ptr->bpval = 0 - (o_ptr->bpval);
4914 }
4915
4916 break;
4917
4918 case SV_AMULET_NO_MAGIC:
4919 /* Never cursed - C. Blue */
4920 break;
4921 case SV_AMULET_NO_TELE:
4922 if (power < 0) o_ptr->ident |= (ID_CURSED);
4923 break;
4924
4925 case SV_AMULET_RESISTANCE:
4926 #if 0
4927 if (randint(3) == 1) random_resistance(o_ptr, FALSE, ((randint(34)) + 4));
4928 if (randint(5) == 1) o_ptr->art_flags2 |= TR2_RES_POIS;
4929 #endif // 0
4930 break;
4931
4932 /* Amulet of searching */
4933 case SV_AMULET_SEARCHING:
4934 o_ptr->bpval = randint(5) + m_bonus(5, level);
4935
4936 /* Cursed */
4937 if (power < 0) {
4938 /* Cursed */
4939 o_ptr->ident |= (ID_CURSED);
4940
4941 /* Reverse bonuses */
4942 o_ptr->bpval = 0 - (o_ptr->bpval);
4943 }
4944
4945 break;
4946
4947 /* Amulet of Doom -- always cursed */
4948 case SV_AMULET_DOOM:
4949 /* Cursed */
4950 o_ptr->ident |= (ID_CURSED);
4951
4952 /* Penalize */
4953 o_ptr->bpval = 0 - (randint(5) + m_bonus(5, level));
4954 o_ptr->to_a = 0 - (randint(5) + m_bonus(5, level));
4955
4956 break;
4957
4958 /* Amulet of Rage, formerly 'Suspicion' */
4959 case SV_AMULET_RAGE:
4960 o_ptr->bpval = 1 + m_bonus(2, level);
4961 o_ptr->to_a = -1 - m_bonus(13, level);
4962 o_ptr->to_h = -1 - m_bonus(10, level);
4963 o_ptr->to_d = 1 + m_bonus(8, level);//was 15,..
4964 if (rand_int(100) < 33) {
4965 // o_ptr->xtra1 = EGO_XTRA_POWER;
4966 // o_ptr->xtra2 = rand_int(255);
4967 }
4968 break;
4969
4970 /* Amulet of speed */
4971 case SV_AMULET_SPEED:
4972 // o_ptr->bpval = randint(5);1/2*1/4
4973
4974 /* chances:
4975 o_ptr->bpval = rand_int(4) + randint(randint(2));
4976 +1: 1/2*1/4 + 1/2*1/2*1/4 = 3/16
4977 +2: 1/2*1/2*1/4 + 1/2*1/2*1/4 + 1/2*1/4 = 4/16
4978 +3: 1/2*1/2*1/4 + 1/2*1/2*1/4 + 1/2*1/4 = 4/16
4979 +4: 1/2*1/2*1/4 + 1/2*1/2*1/4 + 1/2*1/4 = 4/16
4980 +5: 1/2*1/2*1/4 = 1/16
4981 */
4982
4983 /* chances:
4984 o_ptr->bpval = rand_int(3) + randint(3);
4985 +1: 1/3*1/3 = 1/9
4986 +2: 1/3*1/3 + 1/3*1/3 = 2/9
4987 +3: 1/3*1/3 + 1/3*1/3 + 1/3*1/3 = 3/9
4988 +4: 1/3*1/3 + 1/3*1/3 = 2/9
4989 +5: 1/3*1/3 = 1/9
4990 */
4991
4992 o_ptr->bpval = randint(3 + randint(2));
4993 /* chances:
4994 +1: 1/2*1/4 + 1/2*1/5 = 9/40
4995 +2: 1/2*1/4 + 1/2*1/5 = 9/40
4996 +3: 1/2*1/4 + 1/2*1/5 = 9/40
4997 +4: 1/2*1/4 + 1/2*1/5 = 9/40
4998 +5: 1/2*1/5 = 4/40
4999 */
5000
5001 /* Cursed */
5002 if (power < 0) {
5003 /* Broken */
5004 o_ptr->ident |= ID_BROKEN;
5005
5006 /* Cursed */
5007 o_ptr->ident |= ID_CURSED;
5008
5009 /* Reverse bonuses */
5010 o_ptr->bpval = 0 - (o_ptr->bpval);
5011 }
5012
5013 break;
5014
5015 /* Talisman (Amulet of Luck) */
5016 case SV_AMULET_LUCK:
5017 o_ptr->bpval = magik(40)?randint(3):(magik(40)?randint(4):randint(5));
5018
5019 /* Cursed */
5020 if (power < 0) {
5021 /* Broken */
5022 o_ptr->ident |= ID_BROKEN;
5023
5024 /* Cursed */
5025 o_ptr->ident |= ID_CURSED;
5026
5027 /* Reverse bonuses */
5028 o_ptr->bpval = 0 - (o_ptr->bpval);
5029 }
5030
5031 break;
5032
5033 case SV_AMULET_REFLECTION:
5034 o_ptr->to_a = 5 + rand_int(11);
5035
5036 /* Cursed */
5037 if (power < 0) {
5038 /* Broken */
5039 o_ptr->ident |= ID_BROKEN;
5040 /* Cursed */
5041 o_ptr->ident |= ID_CURSED;
5042 /* Reverse bonuses */
5043 o_ptr->to_a = -o_ptr->to_a;
5044 }
5045 break;
5046 }
5047 break;
5048 }
5049 }
5050
5051
5052 /*
5053 * Apply magic to an item known to be "boring"
5054 *
5055 * Hack -- note the special code for various items
5056 */
5057 static void a_m_aux_4(object_type *o_ptr, int level, int power, u32b resf) {
5058 u32b f1, f2, f3, f4, f5, f6, esp;
5059
5060 /* Very good */
5061 if (power > 1) {
5062 /* Make ego item */
5063 // if (!rand_int(RANDART_JEWEL) && (o_ptr->tval == TV_LITE)) create_artifact(o_ptr, FALSE, TRUE); else
5064 make_ego_item(level, o_ptr, TRUE, resf);
5065 } else if (power < -1) {
5066 /* Make ego item */
5067 make_ego_item(level, o_ptr, FALSE, resf);
5068 }
5069
5070 object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
5071
5072 /* Apply magic (good or bad) according to type */
5073 switch (o_ptr->tval) {
5074 case TV_BOOK:
5075 /* Randomize random books */
5076 if (o_ptr->sval == SV_SPELLBOOK) {
5077 int i = 0, tries = 1000;
5078
5079 while (tries) {
5080 tries--;
5081
5082 /* Pick a spell */
5083 i = rand_int(max_spells);
5084
5085 /* Only random ones */
5086 // if (exec_lua(format("return can_spell_random(%d)", i)) == FALSE)
5087 // continue;
5088
5089 /* Test if it passes the level check */
5090 if (rand_int(school_spells[i].skill_level * 3) <= level) {
5091 /* Ok */
5092 break;
5093 }
5094 }
5095 /* Use globe of light(or the first one) */
5096 if (!tries)
5097 o_ptr->pval = 0;
5098 else
5099 o_ptr->pval = i;
5100 }
5101
5102 break;
5103
5104 case TV_LITE:
5105
5106 o_ptr->to_h = o_ptr->to_d = o_ptr->to_a = 0;
5107
5108 /* Hack -- Torches -- random fuel */
5109 if (f4 & TR4_FUEL_LITE) {
5110 if (o_ptr->sval == SV_LITE_TORCH) {
5111 // if (o_ptr->pval) o_ptr->pval = randint(o_ptr->pval);
5112 o_ptr->timeout = randint(FUEL_TORCH);
5113 }
5114
5115 /* Hack -- Lanterns -- random fuel */
5116 else if (o_ptr->sval == SV_LITE_LANTERN) {
5117 o_ptr->timeout = randint(FUEL_LAMP);
5118 // if (o_ptr->pval) o_ptr->pval = randint(o_ptr->pval);
5119 }
5120 }
5121
5122 break;
5123
5124
5125 case TV_WAND:
5126 /* Hack -- charge wands */
5127 charge_wand(o_ptr);
5128 break;
5129
5130 case TV_STAFF:
5131 /* Hack -- charge staffs */
5132 charge_staff(o_ptr);
5133 break;
5134
5135 case TV_CHEST:
5136 /* Hack -- skip ruined chests */
5137 if (k_info[o_ptr->k_idx].level <= 0) break;
5138
5139 /* Pick a trap */
5140 place_trap_object(o_ptr);
5141
5142 break;
5143
5144 case TV_GOLEM:
5145 switch (o_ptr->sval) {
5146 case SV_GOLEM_ARM:
5147 o_ptr->pval = 1 + m_bonus(15, level);
5148 break;
5149 case SV_GOLEM_LEG:
5150 o_ptr->pval = 1 + m_bonus(8, level);
5151 break;
5152 }
5153 break;
5154
5155 /* Hack -- consider using 'timeout' inplace */
5156 case TV_ROD:
5157 /* Hack -- charge rods */
5158 o_ptr->pval = 0;
5159 break;
5160 }
5161 }
5162
5163
5164 /*
5165 * Complete the "creation" of an object by applying "magic" to the item
5166 *
5167 * This includes not only rolling for random bonuses, but also putting the
5168 * finishing touches on ego-items and artifacts, giving charges to wands and
5169 * staffs, giving fuel to lites, and placing traps on chests.
5170 *
5171 * In particular, note that "Instant Artifacts", if "created" by an external
5172 * routine, must pass through this function to complete the actual creation.
5173 *
5174 * The base "chance" of the item being "good" increases with the "level"
5175 * parameter, which is usually derived from the dungeon level, being equal
5176 * to the level plus 10, up to a maximum of 75. If "good" is true, then
5177 * the object is guaranteed to be "good". If an object is "good", then
5178 * the chance that the object will be "great" (ego-item or artifact), also
5179 * increases with the "level", being equal to half the level, plus 5, up to
5180 * a maximum of 20. If "great" is true, then the object is guaranteed to be
5181 * "great". At dungeon level 65 and below, 15/100 objects are "great".
5182 *
5183 * If the object is not "good", there is a chance it will be "cursed", and
5184 * if it is "cursed", there is a chance it will be "broken". These chances
5185 * are related to the "good" / "great" chances above.
5186 *
5187 * Otherwise "normal" rings and amulets will be "good" half the time and
5188 * "cursed" half the time, unless the ring/amulet is always good or cursed.
5189 *
5190 * If "okay" is true, and the object is going to be "great", then there is
5191 * a chance that an artifact will be created. This is true even if both the
5192 * "good" and "great" arguments are false. As a total hack, if "great" is
5193 * true, then the item gets 3 extra "attempts" to become an artifact.
5194 *
5195 * Added "true_art" to disallow true artifacts in case a king/queen kills a
5196 * monster, they cannot carry true artifacts anyways (but they would usually
5197 * find heaps of them..) - C. Blue
5198 *
5199 * 'wpos' only has effect for calculating 'verygreat' minimum value and for
5200 * ood checks of true artifacts created here.
5201 * "verygreat" makes sure that ego items aren't just resist fire etc.
5202 * Has no influence on artifacts. - C. Blue
5203 */
5204 void apply_magic(struct worldpos *wpos, object_type *o_ptr, int lev, bool okay, bool good, bool great, bool verygreat, u32b resf) {
5205 /* usually lev = dungeonlevel (sometimes more, if in vault) */
5206 object_type forge_bak, forge_highest, forge_lowest;
5207 object_type *o_ptr_bak = NULL, *o_ptr_highest = &forge_highest;
5208 object_type *o_ptr_lowest = &forge_lowest;
5209 bool resf_fallback = TRUE;
5210 s32b ego_value1, ego_value2, ovr, fc;
5211 long depth = ABS(getlevel(wpos)), depth_value;
5212 int i, rolls, chance1, chance2, power; //, j;
5213 char o_name[ONAME_LEN];
5214 u32b f1, f2, f3, f4, f5, f6, esp; /* for RESF checks */
5215
5216 /* Fix for reasonable level reqs on DROP_CHOSEN/SPECIAL_GENE items -C. Blue */
5217 if (lev == -2) lev = getlevel(wpos);
5218
5219 /* Maximum "level" for various things */
5220 if (lev > MAX_DEPTH_OBJ - 1) lev = MAX_DEPTH_OBJ - 1;
5221
5222
5223 /* Base chance of being "good" */
5224 /* Hack: Way too many fire/waterproof books in high level towns! */
5225 if (o_ptr->tval == TV_BOOK) chance1 = 10;
5226 else chance1 = lev + 10;
5227
5228 /* Maximal chance of being "good" */
5229 if (chance1 > 75) chance1 = 75;
5230
5231 /* Base chance of being "great" */
5232 chance2 = chance1 / 2;
5233
5234 /* Maximal chance of being "great" */
5235 if (chance2 > 20) chance2 = 20;
5236
5237
5238 /* Assume normal */
5239 power = 0;
5240
5241 /* Roll for "good" */
5242 if (good || magik(chance1)) {
5243 /* Assume "good" */
5244 power = 1;
5245
5246 /* Higher chance2 for super heavy armours are already very rare */
5247 if (k_info[o_ptr->k_idx].flags5 & TR5_WINNERS_ONLY) chance2 += 10;
5248
5249 /* Roll for "great" */
5250 if (great || magik(chance2)) power = 2;
5251 }
5252
5253 /* Roll for "cursed" */
5254 else if (magik(chance1)) {
5255 /* Assume "cursed" */
5256 power = -1;
5257
5258 /* Roll for "broken" */
5259 if (magik(chance2)) power = -2;
5260 }
5261
5262 /* insta-ego items can never be random artifacts */
5263 if ((k_info[o_ptr->k_idx].flags6 & TR6_INSTA_EGO)) {
5264 if (power < 0) power = -2; //cursed ego
5265 else power = 2; //great ego
5266 resf &= ~RESF_FORCERANDART;
5267 resf |= RESF_NORANDART;
5268 }
5269
5270
5271 /* Assume no rolls */
5272 rolls = 0;
5273
5274 /* Get one roll if excellent */
5275 if (power >= 2) rolls = 1;
5276
5277 /* Hack -- Get four rolls if forced great */
5278 if (great) rolls = 2; // 4
5279
5280 /* Hack -- Get no rolls if not allowed */
5281 if (!okay || o_ptr->name1) rolls = 0;
5282
5283
5284 /* virgin */
5285 o_ptr->owner = 0;
5286
5287
5288 /* Hack for possible randarts, to be created in next for loop:
5289 Jewelry can keep +hit,+dam,+ac through artifying process!
5290 That means, it must be applied before arting it, because the
5291 o_ptr->name1 check below will exit apply_magic() via return().
5292 Won't affect normal items that fail randart check anyway. ----------------------- */
5293 if ((o_ptr->tval == TV_RING || o_ptr->tval == TV_AMULET)
5294 && !o_ptr->name1) { /* if already art, do not reroll hit/dam/ac! */
5295 o_ptr_bak = &forge_bak;
5296 object_copy(o_ptr_bak, o_ptr);
5297 a_m_aux_3(o_ptr_bak, lev, 1, resf); /* create a good, non-ego version for arting */
5298 }
5299 /* --------------------------------------------------------------------------------- */
5300
5301 if ((resf & RESF_FORCERANDART)) rolls = 2;
5302
5303 /* Roll for artifacts if allowed */
5304 for (i = 0; i < rolls; i++) {
5305 /* Roll for an artifact -
5306 on original object, since rings/amulets might already have gotten
5307 an ego power from a_m_aux_3() above. */
5308 if (make_artifact(wpos, o_ptr_bak ? o_ptr_bak : o_ptr, resf)) {
5309 if (o_ptr_bak) object_copy(o_ptr, o_ptr_bak);
5310 break;
5311 }
5312 }
5313 /* Hack -- analyze artifacts */
5314 if (o_ptr->name1) {
5315 artifact_type *a_ptr;
5316
5317 /* Randart */
5318 if (o_ptr->name1 == ART_RANDART) {
5319 /* generate it finally, after those preparations above */
5320 a_ptr = randart_make(o_ptr);
5321 }
5322 /* Normal artifacts */
5323 else a_ptr = &a_info[o_ptr->name1];
5324
5325 /* ?catch impossible randart types? */
5326 if (a_ptr == (artifact_type*)NULL) {
5327 o_ptr->name1 = 0;
5328 s_printf("RANDART_FAIL in apply_magic().\n");
5329 return;
5330 }
5331
5332 /* determine level-requirement */
5333 determine_level_req(lev, o_ptr);
5334
5335 /* Override level requirements? */
5336 if ((o_ptr->name1 == ART_RANDART) &&
5337 (cfg.arts_level_req >= 3))
5338 o_ptr->level = 0;
5339 else if ((a_ptr->flags4 & TR4_SPECIAL_GENE) &&
5340 (cfg.arts_level_req >= 1))
5341 o_ptr->level = 0;
5342 else if (cfg.arts_level_req >= 2)
5343 o_ptr->level = 0;
5344
5345 /* Hack -- Mark the artifact as "created" */
5346 handle_art_inumpara(o_ptr->name1);
5347
5348 /* Info */
5349 /* s_printf("Created artifact %d.\n", o_ptr->name1); */
5350
5351 /* Extract the other fields */
5352 o_ptr->pval = a_ptr->pval;
5353 o_ptr->ac = a_ptr->ac;
5354 o_ptr->dd = a_ptr->dd;
5355 o_ptr->ds = a_ptr->ds;
5356 o_ptr->to_a = a_ptr->to_a;
5357 o_ptr->to_h = a_ptr->to_h;
5358 o_ptr->to_d = a_ptr->to_d;
5359 o_ptr->weight = a_ptr->weight;
5360
5361 /* Hack -- no bundled arts (esp.missiles) */
5362 o_ptr->number = 1;
5363 o_ptr->timeout = 0;
5364
5365 /* clear flags from pre-artified item, simulating
5366 generation of a brand new object. */
5367 o_ptr->ident &= ~(ID_MENTAL | ID_BROKEN | ID_CURSED);
5368
5369 /* Hack -- extract the "broken" flag */
5370 if (!a_ptr->cost) o_ptr->ident |= ID_BROKEN;
5371
5372 /* Hack -- extract the "cursed" flag */
5373 if (a_ptr->flags3 & TR3_CURSED) o_ptr->ident |= ID_CURSED;
5374
5375 /* Done */
5376 return;
5377 } else if ((resf & RESF_FORCERANDART)) {
5378 invwipe(o_ptr);
5379 return; /* failed to generate */
5380 }
5381
5382 /* Hack - for NO_MORGUL_IN_IDDC check in a_m_aux_1(). - C. Blue
5383 (Usually, o_ptr->wpos is only set in drop_near(), which happens _afterwards_.) */
5384 wpcopy(&o_ptr->wpos, wpos);
5385
5386 /* In case we get an ego item, check "verygreat" flag and retry a few times if needed */
5387 if (verygreat) s_printf("verygreat apply_magic:\n");
5388 /* for other items: */
5389 o_ptr_bak = &forge_bak;
5390 object_copy(o_ptr_bak, o_ptr);
5391 object_copy(o_ptr_highest, o_ptr);
5392
5393 depth_value = (depth < 60 ? depth * 150 : 9000) + randint(depth) * 100;
5394 // for (i = 0; i < (!is_ammo(o_ptr->tval) ? 2 + depth / 7 : 4 + depth / 5); i++) {
5395 // for (i = 0; i < (!is_ammo(o_ptr->tval) ? 2 + depth / 5 : 4 + depth / 5); i++) {
5396 for (i = 0; i < 25; i++) {
5397 object_copy(o_ptr, o_ptr_bak);
5398
5399 /* Apply magic */
5400 switch (o_ptr->tval) {
5401 case TV_TRAPKIT:
5402 if (!is_firearm_trapkit(o_ptr->sval)) break;
5403 case TV_DIGGING:
5404 case TV_BLUNT:
5405 case TV_POLEARM:
5406 case TV_SWORD:
5407 case TV_BOW:
5408 case TV_SHOT:
5409 case TV_ARROW:
5410 case TV_BOLT:
5411 case TV_BOOMERANG:
5412 case TV_AXE:
5413 case TV_MSTAFF:
5414 if (power) a_m_aux_1(o_ptr, lev, power, resf);
5415 break;
5416
5417 case TV_DRAG_ARMOR:
5418 case TV_HARD_ARMOR:
5419 case TV_SOFT_ARMOR:
5420 case TV_SHIELD:
5421 case TV_HELM:
5422 case TV_CROWN:
5423 case TV_CLOAK:
5424 case TV_GLOVES:
5425 case TV_BOOTS:
5426 // Power is no longer required since things such as
5427 // Kollas need magic applied to finish their normal
5428 // generation.
5429 //if (power) a_m_aux_2(o_ptr, lev, power, resf);
5430 a_m_aux_2(o_ptr, lev, power, resf);
5431 break;
5432
5433 case TV_RING:
5434 case TV_AMULET:
5435 a_m_aux_3(o_ptr, lev, power, resf);
5436 break;
5437
5438 case TV_CHEST:
5439 /* Traps (placed in a_m_aux_4) won't be placed on a level 0 object */
5440 determine_level_req(lev, o_ptr); /* usually lev == dungeonlevel (+ x for vaults) */
5441 a_m_aux_4(o_ptr, lev, power, resf);
5442 /* that's it already */
5443 return;
5444
5445 default:
5446 a_m_aux_4(o_ptr, lev, power, resf);
5447 break;
5448 }
5449
5450 /* Bad hack: Un-ego mindcrafter spell scrolls if they got fireproof/waterproof ego,
5451 since they (by another bad hack) already ignore those. */
5452 if (o_ptr->tval == TV_BOOK && o_ptr->sval == SV_SPELLBOOK &&
5453 get_spellbook_name_colour(o_ptr->pval) == TERM_YELLOW) {
5454 if (o_ptr->name2 == EGO_FIREPROOF_BOOK || o_ptr->name2 == EGO_WATERPROOF_BOOK) o_ptr->name2 = 0;
5455 if (o_ptr->name2b == EGO_FIREPROOF_BOOK || o_ptr->name2b == EGO_WATERPROOF_BOOK) o_ptr->name2b = 0;
5456 }
5457
5458 #if 1 // tweaked pernA ego..
5459 /* Hack -- analyze ego-items */
5460 //else if (o_ptr->name2)
5461 if (o_ptr->name2 && !o_ptr->name1) {
5462 artifact_type *a_ptr;
5463 a_ptr = ego_make(o_ptr);
5464
5465 /* Extract the other fields */
5466 if ((o_ptr->tval == TV_RING && o_ptr->sval == SV_RING_POLYMORPH)
5467 || o_ptr->tval == TV_BOOK
5468 || is_ammo(o_ptr->tval))
5469 ; /* keep o_ptr->pval! */
5470 else if (!is_magic_device(o_ptr->tval)) /* don't kill charges on EGO (of plenty) devices! */
5471 o_ptr->pval = a_ptr->pval; /* paranoia?-> pval might've been limited in ego_make(), so set it here, instead of adding it */
5472 else
5473 o_ptr->pval += a_ptr->pval;
5474
5475 o_ptr->ac += a_ptr->ac;
5476 o_ptr->dd += a_ptr->dd;
5477 o_ptr->ds += a_ptr->ds;
5478 if (a_ptr->to_a < 0) o_ptr->to_a = a_ptr->to_a; /* <- special for 'bad' ego powers, vs high-ac armour such as DSM */
5479 else o_ptr->to_a += a_ptr->to_a;
5480 o_ptr->to_h += a_ptr->to_h;
5481 o_ptr->to_d += a_ptr->to_d;
5482
5483 apply_enchantment_limits(o_ptr); /* new: paranoia? worked fine without so far */
5484
5485 /* Reduce enchantment boni for ego Dark Swords - C. Blue
5486 (since they're no more (dis)enchantable, make work easier for unbelievers..) */
5487 if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_DARK_SWORD)) {
5488 /* Don't reduce negative boni, of *Defender*s for example */
5489 if ((o_ptr->to_h > 0) && (o_ptr-> to_d > 0)) {
5490 o_ptr->to_h /= 2;
5491 o_ptr->to_d /= 2;
5492 }
5493 }
5494
5495 /* Hack -- acquire "cursed" flag */
5496 // if (f3 & TR3_CURSED) o_ptr->ident |= (ID_CURSED); // this should be done here!
5497 if (a_ptr->flags3 & TR3_CURSED) o_ptr->ident |= (ID_CURSED);
5498 }
5499 #endif // 1
5500
5501 /* Hack: determine level-requirement - here AGAIN because ego-item
5502 routine wasnt called before we called det_l_r the first time */
5503 determine_level_req(lev, o_ptr);
5504
5505 /* Examine real objects */
5506 if (o_ptr->k_idx) {
5507 object_kind *k_ptr = &k_info[o_ptr->k_idx];
5508 /* Hack -- acquire "broken" flag */
5509 if (!k_ptr->cost) o_ptr->ident |= ID_BROKEN;
5510 /* Hack -- acquire "cursed" flag */
5511 if (k_ptr->flags3 & TR3_CURSED) o_ptr->ident |= ID_CURSED;
5512 }
5513
5514 /* Pick the lowest value item */
5515 if (i == 0)
5516 object_copy(o_ptr_lowest, o_ptr);
5517 else if (object_value_real(0, o_ptr) < object_value_real(0, o_ptr_lowest))
5518 object_copy(o_ptr_lowest, o_ptr);
5519
5520 object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
5521 if ((resf & RESF_LOWVALUE) && (object_value_real(0, o_ptr) > 35000)) continue;
5522 if ((resf & RESF_MIDVALUE) && (object_value_real(0, o_ptr) > 50000)) continue;
5523 if ((resf & RESF_NOHIVALUE) && (object_value_real(0, o_ptr) > 100000)) continue;
5524 if ((resf & RESF_LOWSPEED) && (f1 & TR1_SPEED) && (o_ptr->bpval > 4 || o_ptr->pval > 4)) continue;
5525 if ((resf & RESF_NOHISPEED) && (f1 & TR1_SPEED) && (o_ptr->bpval > 6 || o_ptr->pval > 6)) continue;
5526
5527 /* "verygreat" check: */
5528 /* 2000 to exclude res, light, reg, etc */
5529 /* 5000+objval to exclude brands/slays */
5530 //NO: if (!verygreat || object_value_real(0, o_ptr) >= 7000) break; <- arrows (+36,+42) -> lol. - C. Blue
5531 if (!verygreat) break;
5532
5533 if (o_ptr->name2) ego_value1 = e_info[o_ptr->name2].cost; else ego_value1 = 0;
5534 if (o_ptr->name2b) ego_value2 = e_info[o_ptr->name2b].cost; else ego_value2 = 0;
5535
5536 object_desc(0, o_name, o_ptr, FALSE, 3);
5537 ovr = object_value_real(0, o_ptr);
5538 fc = flag_cost(o_ptr, o_ptr->pval);
5539
5540 /* remember most expensive object we rolled, in case we don't find any better we can fallback to it */
5541 if (ovr > object_value_real(0, o_ptr_highest)) {
5542 object_copy(o_ptr_highest, o_ptr);
5543 /* No fallback because of resf necessary */
5544 resf_fallback = FALSE;
5545 } else continue;
5546
5547 s_printf("dpt %d, dptval %d, egoval %d / %d, realval %d, flags %d (%s)\n",
5548 depth, depth_value, ego_value1, ego_value2, ovr, fc, o_name);
5549
5550 if (!is_ammo(o_ptr->tval)) {
5551 if ((ego_value1 >= depth_value) || (ego_value2 >= depth_value) ||
5552 (object_value_real(0, o_ptr) >= depth * 300)) break;
5553 } else {
5554 /* Ammo amount is increased in place_object */
5555 if (object_value_real(0, o_ptr) >= depth + 150) break;
5556 }
5557 } /* verygreat-loop end */
5558
5559 /* verify! (could fail if drop is forced 'great' but only ego power
5560 available is a bad one (0 value) or vice versa.. */
5561 if ((k_info[o_ptr->k_idx].flags6 & TR6_INSTA_EGO) && !o_ptr->name2 && !o_ptr->name2b) {
5562 invwipe(o_ptr);
5563 return; /* failed to generate */
5564 }
5565
5566 if (verygreat) {
5567 if (resf_fallback) {
5568 /* Fallback to lowest value item in case resf proved too strict - mikaelh */
5569 s_printf("lowest value fallback used in apply_magic (resf = %#x)\n", resf);
5570
5571 object_copy(o_ptr, o_ptr_lowest);
5572
5573 if (o_ptr->name2) ego_value1 = e_info[o_ptr->name2].cost; else ego_value1 = 0;
5574 if (o_ptr->name2b) ego_value2 = e_info[o_ptr->name2b].cost; else ego_value2 = 0;
5575
5576 object_desc(0, o_name, o_ptr, FALSE, 3);
5577 ovr = object_value_real(0, o_ptr);
5578 fc = flag_cost(o_ptr, o_ptr->pval);
5579
5580 /* Dump information about the item */
5581 s_printf("dpt %d, dptval %d, egoval %d / %d, realval %d, flags %d (%s)\n",
5582 depth, depth_value, ego_value1, ego_value2, ovr, fc, o_name);
5583
5584 s_printf("taken\n");
5585 } else {
5586 s_printf("taken\n");
5587 object_copy(o_ptr, o_ptr_highest);
5588 }
5589 }
5590 }
5591
5592 /*
5593 * This 'utter hack' function is to allow item-generation w/o specifing
5594 * worldpos.
5595 */
5596 void apply_magic_depth(int Depth, object_type *o_ptr, int lev, bool okay, bool good, bool great, bool verygreat, u32b resf) {
5597 worldpos wpos;
5598
5599 /* CHANGEME */
5600 wpos.wx = cfg.town_x;
5601 wpos.wy = cfg.town_y;
5602 wpos.wz = Depth > 0 ? 0 - Depth : Depth;
5603 apply_magic(&wpos, o_ptr, lev, okay, good, great, verygreat, resf);
5604 }
5605
5606
5607 /*
5608 * determine level requirement.
5609 * based on C.Blue's idea. - Jir -
5610 */
5611 //#ifndef TEST_SERVER /* cloned the function below, for reworking - C. Blue */
5612 #if 1
5613 void determine_level_req(int level, object_type *o_ptr) {
5614 int i, j, klev = k_info[o_ptr->k_idx].level, base = klev / 2;
5615 artifact_type *a_ptr = NULL;
5616
5617
5618 /* -------------------- Dungeon level hacks -------------------- */
5619
5620
5621 switch (o_ptr->tval) {
5622 case TV_RING:
5623 switch (o_ptr->sval) {
5624 case SV_RING_SPEED:
5625 if (level < 75) level = 75;
5626 break;
5627 case SV_RING_MIGHT:
5628 case SV_RING_TOUGHNESS:
5629 case SV_RING_READYWIT:
5630 case SV_RING_CUNNINGNESS:
5631 if (level < 25) level = 25;
5632 break;
5633 }
5634 break;
5635 case TV_DRAG_ARMOR:
5636 if (o_ptr->sval == SV_DRAGON_POWER && level < 100) level = 100;
5637 break;
5638 case TV_POTION:
5639 switch (o_ptr->sval) {
5640 case SV_POTION_INC_STR:
5641 case SV_POTION_INC_INT:
5642 case SV_POTION_INC_WIS:
5643 case SV_POTION_INC_DEX:
5644 case SV_POTION_INC_CON:
5645 case SV_POTION_INC_CHR:
5646 if (level < 20) level = 20;
5647 break;
5648 }
5649 break;
5650 }
5651
5652
5653 /* -------------------- Exceptions -------------------- */
5654
5655
5656 if (o_ptr->tval == TV_RING && o_ptr->sval == SV_RING_POLYMORPH) {
5657 o_ptr->level = ring_of_polymorph_level(r_info[o_ptr->pval].level);
5658 return;
5659 }
5660 if (o_ptr->tval == TV_SOFT_ARMOR && o_ptr->sval == SV_COSTUME) return;
5661
5662 /* Unowned yet */
5663 // o_ptr->owner = 0;
5664
5665 /* artifact */
5666 if (o_ptr->name1) {
5667 /* Randart */
5668 if (o_ptr->name1 == ART_RANDART) {
5669 a_ptr = randart_make(o_ptr);
5670 if (a_ptr == (artifact_type*)NULL){
5671 o_ptr->name1 = 0;
5672 o_ptr->level = 0;
5673 return;
5674 }
5675
5676 /* level of randarts tends to be outrageous */
5677 base = a_ptr->level / 1;/* was 2*/
5678 }
5679 /* Normal artifacts */
5680 else {
5681 a_ptr = &a_info[o_ptr->name1];
5682 base = a_ptr->level;
5683 base += 30; /*general increase for artifacts! */
5684 }
5685 }
5686
5687
5688 if (o_ptr->tval == TV_CHEST) {
5689 o_ptr->level = base + (level * 2) / 4; /* chest level is base for calculating the item level,
5690 so it must be like a dungeon level - C. Blue
5691 (base = k_info level / 2, level = dungeonlevel usually) */
5692 return;
5693 }
5694
5695
5696 /* ---------- Base level boost depending on item type ---------- */
5697
5698
5699 /* stat/heal potions harder to cheeze-transfer */
5700 if (o_ptr->tval == TV_POTION) {
5701 switch(o_ptr->sval) {
5702 case SV_POTION_HEALING:
5703 base += 15 + 10;
5704 break;
5705 case SV_POTION_RESTORE_MANA:
5706 base += 10 + 10;
5707 break;
5708 case SV_POTION_INC_STR:
5709 case SV_POTION_INC_INT:
5710 case SV_POTION_INC_WIS:
5711 case SV_POTION_INC_DEX:
5712 case SV_POTION_INC_CON:
5713 case SV_POTION_INC_CHR:
5714 base += 40 + 30;
5715 break;
5716 case SV_POTION_AUGMENTATION:
5717 base += 45 + 20;
5718 break;
5719 case SV_POTION_EXPERIENCE:
5720 base += 20 + 20;
5721 break;
5722 }
5723 }
5724 /* Certain items harder to cheeze-transfer */
5725 if ((o_ptr->tval == TV_RING) && (o_ptr->bpval > 0)) {
5726 switch(o_ptr->sval) {
5727 case SV_RING_CRIT:
5728 case SV_RING_SPEED:
5729 base += o_ptr->bpval * 2;
5730 break;
5731 case SV_RING_ATTACKS:
5732 base += o_ptr->bpval * 5;
5733 break;
5734 case SV_RING_MIGHT:
5735 case SV_RING_READYWIT:
5736 case SV_RING_TOUGHNESS:
5737 case SV_RING_CUNNINGNESS:
5738 base += o_ptr->bpval * 9;
5739 break;
5740 }
5741 }
5742
5743 /* jewelry shop has too low levels on powerful amulets */
5744 if (o_ptr->tval == TV_AMULET) {
5745 switch (o_ptr->sval) {
5746 case SV_AMULET_SPEED:
5747 base += 20 + o_ptr->bpval * 2;
5748 break;
5749 case SV_AMULET_TRICKERY:
5750 case SV_AMULET_THE_MAGI:
5751 case SV_AMULET_DEVOTION:
5752 base += 16 + o_ptr->bpval * 3;
5753 break;
5754 }
5755 }
5756
5757 if (o_ptr->tval == TV_DRAG_ARMOR) {
5758 switch(o_ptr->sval) {
5759 case SV_DRAGON_MULTIHUED:
5760 case SV_DRAGON_SHINING:
5761 case SV_DRAGON_DEATH:
5762 base += 20;
5763 break;
5764 case SV_DRAGON_POWER:
5765 base += 20;
5766 break;
5767 default:
5768 base += 20;//was 5, but then chaos dsm had level 28
5769 }
5770 }
5771
5772 /* prevent exorbitantly high-level lamp randarts:
5773 (base item targets were: dwarven ~20+ , fean ~32+) */
5774 if (o_ptr->tval == TV_LITE && o_ptr->name1 != ART_RANDART) {
5775 switch (o_ptr->sval) {
5776 case SV_LITE_DWARVEN: base += 35; break;
5777 case SV_LITE_FEANORIAN: base += 55; break;
5778 default: if (o_ptr->name2) base += 20;
5779 }
5780 }
5781
5782 /* Hack -- analyze ego-items */
5783 if (o_ptr->name2 || o_ptr->name2b) {
5784 if (o_ptr->name2) base += e_info[o_ptr->name2].rating;
5785 if (o_ptr->name2b) base += e_info[o_ptr->name2b].rating;
5786 /* general level boost for ego items!
5787 except very basic ones */
5788 switch (o_ptr->name2) {
5789 case EGO_LEPROUS:
5790 case EGO_STUPIDITY: case EGO_NAIVETY:
5791 case EGO_UGLINESS: case EGO_SICKLINESS:
5792 case EGO_ENVELOPING: case EGO_VULNERABILITY:
5793 case EGO_IRRITATION:
5794 case EGO_WEAKNESS: case EGO_CLUMSINESS:
5795 case EGO_PEACE:
5796 case EGO_NOISE: case EGO_SLOWNESS:
5797 case EGO_ANNOYANCE:
5798 case EGO_MORGUL: case EGO_NOTHINGNESS:
5799 case EGO_BACKBITING: case EGO_SHATTERED:
5800 case EGO_BLASTED:
5801 case EGO_LFADING:
5802 case EGO_INDESTRUCTIBLE:case EGO_CURSED:
5803 case EGO_FIREPROOF: case EGO_WATERPROOF:
5804 case EGO_FIREPROOF_BOOK:case EGO_WATERPROOF_BOOK:
5805 case EGO_PLENTY:
5806 case EGO_TOBVIOUS:
5807 case EGO_VULNERABILITY2:case EGO_VULNERABILITY3:
5808 case EGO_BUDWEISER: case EGO_HEINEKEN:
5809 case EGO_GUINNESS:
5810 break;
5811
5812 case EGO_RESIST_ACID: case EGO_RESIST_ELEC:
5813 case EGO_RESIST_FIRE: case EGO_RESIST_COLD:
5814 case EGO_ENDURE_ACID: case EGO_ENDURE_ELEC:
5815 case EGO_ENDURE_FIRE: case EGO_ENDURE_COLD:
5816 case EGO_NOLDOR: case EGO_WISDOM:
5817 case EGO_BEAUTY: case EGO_INFRAVISION:
5818 case EGO_REGENERATION: case EGO_TELEPORTATION:
5819 case EGO_PROTECTION: case EGO_STEALTH:
5820 case EGO_CHARMING:
5821 case EGO_SLOW_DESCENT: case EGO_QUIET:
5822 case EGO_DIGGING:
5823 case EGO_RQUICKNESS: case EGO_RCHARGING:
5824 case EGO_LBOLDNESS: case EGO_LBRIGHTNESS:
5825 case EGO_LSTAR_BRIGHTNESS: case EGO_LINFRAVISION:
5826 case EGO_RSIMPLICITY:
5827 case EGO_CONCENTRATION:
5828 base += 5;
5829 break;
5830
5831 case EGO_FREE_ACTION:
5832 case EGO_SLAYING: case EGO_AGILITY:
5833 case EGO_MOTION:
5834 case EGO_RISTARI:
5835 case EGO_AURA_COLD2: case EGO_AURA_FIRE2: case EGO_AURA_ELEC2:
5836 base += 10;
5837 break;
5838
5839 case EGO_KILL_EVIL:
5840 case EGO_HA: /* 'Aman' */
5841 case EGO_GONDOLIN:
5842 base += 25;
5843 break;
5844
5845 case EGO_ELVENKIND:
5846 base += o_ptr->bpval * 2 + 15;
5847 break;
5848 case EGO_SPEED:
5849 base += o_ptr->bpval * 2 + 15;
5850 break;
5851 case EGO_TELEPATHY:
5852 base += 25;
5853 break;
5854
5855 case EGO_IMMUNE:
5856 /* only occurs on mithril/adamantite plate, which is already quite
5857 high level -> need reduction (usually like level 56 without it) */
5858 base -= 10;
5859 break;
5860
5861 default:
5862 base += 15;
5863 }
5864 }
5865
5866 /* '17/72' == 0.2361... < 1/4 :) */
5867 base >>= 1;
5868
5869
5870 /* --------------- Adjust, randomize and sanitize --------------- */
5871
5872
5873 #if 0 /* would need rework in conjunction with ego powers I'm afraid - C. Blue ;/ */
5874 /* increase plain items' levels -> no more level 21 red dsm or level 18 thunder axe! - C. Blue */
5875 if (klev <= 40) base += (klev / 10);
5876 else if (klev <= 50) base += (klev / 6);
5877 else if (klev <= 60) base += (klev / 7);
5878 else if (klev <= 70) base += (klev / 6);
5879 else if (klev <= 80) base += (klev / 5);
5880 else if (klev <= 90) base += (klev / 4);
5881 else base += (klev / 3);
5882 #endif
5883
5884 /* Hack: level -9999 means: use unmodified base value and don't use randomizer: */
5885 if (level == -9999) {
5886 i = 0;
5887 j = base;
5888 } else {
5889 i = level - base;
5890 j = (((i * (i > 0 ? 2 : 2)) / 12 + base) * rand_range(95,105)) / 100;/* was 1:2 / 4 */
5891 }
5892
5893 /* Level must be between 1 and 100 inclusively */
5894 o_ptr->level = (j < 100) ? ((j > 1) ? j : 1) : 100;
5895
5896
5897 /* --------------- Final bottom limits --------------- */
5898
5899
5900 /* Anti-cheeze hacks */
5901 if ((o_ptr->tval == TV_POTION) && ( /* potions that mustn't be transferred, otherwise resulting in 1 out-of-line char */
5902 (o_ptr->sval == SV_POTION_EXPERIENCE) ||
5903 (o_ptr->sval == SV_POTION_LEARNING) ||
5904 (o_ptr->sval == SV_POTION_INVULNERABILITY))) o_ptr->level = 0;
5905 if ((o_ptr->tval == TV_SCROLL) && (o_ptr->sval == SV_SCROLL_TRAP_CREATION) && (o_ptr->level < 20)) o_ptr->level = 20;
5906 if ((o_ptr->tval == TV_SCROLL) && (o_ptr->sval == SV_SCROLL_FIRE) && (o_ptr->level < 30)) o_ptr->level = 30;
5907 if ((o_ptr->tval == TV_SCROLL) && (o_ptr->sval == SV_SCROLL_ICE) && (o_ptr->level < 30)) o_ptr->level = 30;
5908 if ((o_ptr->tval == TV_SCROLL) && (o_ptr->sval == SV_SCROLL_CHAOS) && (o_ptr->level < 30)) o_ptr->level = 30;
5909 if (o_ptr->tval == TV_RING && o_ptr->sval == SV_RING_SPEED && (o_ptr->level < 30 + o_ptr->bpval - 1) && (o_ptr->bpval > 0))
5910 o_ptr->level = 30 + o_ptr->bpval - 1 + rand_int(3);
5911 if ((o_ptr->tval == TV_DRAG_ARMOR) && (o_ptr->sval == SV_DRAGON_POWER) && (o_ptr->level < 45)) o_ptr->level = 44 + randint(5);
5912
5913 if (o_ptr->tval == TV_LITE) {
5914 if (o_ptr->name1 == ART_RANDART) {
5915 switch (o_ptr->sval) {
5916 case SV_LITE_DWARVEN: if (o_ptr->level < 30) o_ptr->level = 30; break;//ego powered lower limit is ~28, going slightly above that..
5917 case SV_LITE_FEANORIAN: if (o_ptr->level < 38) o_ptr->level = 38; break;
5918 }
5919 } else {
5920 switch (o_ptr->sval) {
5921 case SV_LITE_DWARVEN: if (o_ptr->level < 20) o_ptr->level = 20; break;
5922 case SV_LITE_FEANORIAN: if (o_ptr->level < 32) o_ptr->level = 32; break;
5923 }
5924 }
5925 }
5926
5927 /* Fix cheap but high +dam weaponry: */
5928 if (o_ptr->level * 10 < o_ptr->to_d * 12) o_ptr->level = (o_ptr->to_d * 12) / 10;
5929
5930
5931 /* --------------- Reduce excessive level --------------- */
5932
5933
5934 /* Slightly reduce high levels */
5935 if (o_ptr->level > 55) o_ptr->level--;
5936 if (o_ptr->level > 50) o_ptr->level--;
5937 if (o_ptr->level > 45) o_ptr->level--;
5938 if (o_ptr->level > 40) o_ptr->level--;
5939
5940 #if 0
5941 /* tone down deep randarts a bit to allow winner-trading */
5942 if (o_ptr->name1 == ART_RANDART) {
5943 if (o_ptr->level > 51) o_ptr->level = 51 + ((o_ptr->level - 51) / 3);
5944 }
5945
5946 /* tone down deep winners_only items to allow winner-trading */
5947 else if (k_info[o_ptr->k_idx].flags5 & TR5_WINNERS_ONLY) {
5948 if (o_ptr->level > 51) o_ptr->level = 51 + ((o_ptr->level - 51) / 2);
5949 }
5950
5951 /* done above instead, where EGO_ are tested */
5952 /* Reduce outrageous ego item levels (double-ego adamantite of immunity for example */
5953 else if (o_ptr->name2) {
5954 if (o_ptr->level > 51) o_ptr->level = 48 + rand_int(4);
5955 else if (o_ptr->level > 48) o_ptr->level = 48 + rand_int(2);
5956 }
5957 #else /* unify.. */
5958 /* tone down very-high-level items for trading */
5959 if (o_ptr->level > 51) o_ptr->level = 51 + ((o_ptr->level - 51) / 3);
5960 /* further tone down if no randart and no winners-only */
5961 if (o_ptr->level > 50 &&
5962 o_ptr->name1 != ART_RANDART && !(k_info[o_ptr->k_idx].flags5 & TR5_WINNERS_ONLY))
5963 o_ptr->level -= rand_int(3);
5964 #endif
5965
5966 /* Special limit for +LIFE randarts */
5967 if ((o_ptr->name1 == ART_RANDART) &&
5968 (a_ptr->flags1 & TR1_LIFE) && (o_ptr->level <= 50))
5969 o_ptr->level = 51 + rand_int(2);
5970
5971 /* Special limit for WINNERS_ONLY items */
5972 if ((k_info[o_ptr->k_idx].flags5 & TR5_WINNERS_ONLY) && (o_ptr->level <= 50))
5973 o_ptr->level = 51 + rand_int(5);
5974 }
5975 #else /* new way, quite reworked */
5976 void determine_level_req(int level, object_type *o_ptr) {
5977 }
5978 #endif
5979
5980 /* Purpose: fix old items' level requirements.
5981 What it does: Check current level against theoretical minimum level of
5982 that item according to current determine_level_req() values.
5983 Fix if below, by applying bottom cap value. */
5984 void verify_level_req(object_type *o_ptr) {
5985 int lv = o_ptr->level;
5986
5987 if (!lv) return;
5988
5989 determine_level_req(0, o_ptr);
5990 if (lv > o_ptr->level) o_ptr->level = lv;
5991 }
5992
5993 /* Set level req for polymorph ring on its creation - C. Blue */
5994 int ring_of_polymorph_level(int r_lev) {
5995 #if 0
5996 if (r_lev == 0) return 5;
5997 /* 0->5..1->6..30->26..60->42..80->51..85->53..100->58 */
5998 //return 5 + (1600 / ((2000 / (r_lev + 1)) + 10));
5999 //return 10 + (1000 / ((2000 / r_lev) + 10));
6000 //return 5 + (1000 / ((1500 / r_lev) + 5));
6001 //return 5 + (1000 / ((1500 / r_lev) + 7));
6002 #else /* use two curves, low-lev and rest */
6003 if (r_lev < 7) return 5;
6004 else if (r_lev < 30) return (850 / (1170 / r_lev)); /* 7 -> 5, 15 -> 10, 23 -> 16, 29 -> _21_ */
6005 else return 5 + (1000 / ((1500 / r_lev) + 7)); /* 30 -> _22_, 60 -> 36, 80 -> 43, 100 -> 50 */
6006 #endif
6007 }
6008
6009 /*
6010 * Object-theme codes borrowed from ToME. - Jir -
6011 */
6012
6013 /* The themed objects to use */
6014 static obj_theme match_theme;
6015
6016 /*
6017 * XXX XXX XXX It relies on the fact that obj_theme is a four byte structure
6018 * for its efficient operation. A horrendous hack, I'd say.
6019 */
6020 void init_match_theme(obj_theme theme)
6021 {
6022 /* Save the theme */
6023 match_theme = theme;
6024 }
6025
6026 #if 0
6027 /*
6028 * Ditto XXX XXX XXX
6029 */
6030 static bool theme_changed(obj_theme theme)
6031 {
6032 /* Any of the themes has been changed */
6033 if (theme.treasure != match_theme.treasure) return (TRUE);
6034 if (theme.combat != match_theme.combat) return (TRUE);
6035 if (theme.magic != match_theme.magic) return (TRUE);
6036 if (theme.tools != match_theme.tools) return (TRUE);
6037
6038 /* No changes */
6039 return (FALSE);
6040 }
6041 #endif // 0
6042
6043
6044 /*
6045 * Maga-Hack -- match certain types of object only.
6046 */
6047 static int kind_is_theme(int k_idx)
6048 {
6049 object_kind *k_ptr = &k_info[k_idx];
6050
6051 int p = 0;
6052
6053 /*
6054 * Paranoia -- Prevent accidental "(Nothing)"
6055 * that are results of uninitialised theme structs.
6056 *
6057 * Caution: Junks go into the allocation table.
6058 */
6059 if (match_theme.treasure + match_theme.combat +
6060 match_theme.magic + match_theme.tools == 0) return (TRUE);
6061
6062
6063 /* Pick probability to use */
6064 switch (k_ptr->tval) {
6065 case TV_SKELETON:
6066 case TV_BOTTLE:
6067 case TV_JUNK:
6068 case TV_FIRESTONE:
6069 case TV_CORPSE:
6070 case TV_EGG:
6071 /* hm, this was missing here, for a long time - C. Blue */
6072 case TV_GOLEM:
6073 /*
6074 * Degree of junk is defined in terms of the other
6075 * 4 quantities XXX XXX XXX
6076 * The type of prob should be *signed* as well as
6077 * larger than theme components, or we would see
6078 * unexpected, well, junks.
6079 */
6080 p = 100 - (match_theme.treasure + match_theme.combat +
6081 match_theme.magic + match_theme.tools);
6082 break;
6083 case TV_CHEST: p = match_theme.treasure; break;
6084 case TV_CROWN: p = match_theme.treasure; break;
6085 case TV_DRAG_ARMOR: p = match_theme.treasure; break;
6086 case TV_AMULET: p = match_theme.treasure; break;
6087 case TV_RING: p = match_theme.treasure; break;
6088
6089 case TV_SHOT: p = match_theme.combat; break;
6090 case TV_ARROW: p = match_theme.combat; break;
6091 case TV_BOLT: p = match_theme.combat; break;
6092 case TV_BOOMERANG: p = match_theme.combat; break;
6093 case TV_BOW: p = match_theme.combat; break;
6094 case TV_BLUNT: p = match_theme.combat; break;
6095 case TV_POLEARM: p = match_theme.combat; break;
6096 case TV_SWORD: p = match_theme.combat; break;
6097 case TV_AXE: p = match_theme.combat; break;
6098 case TV_GLOVES: p = match_theme.combat; break;
6099 case TV_HELM: p = match_theme.combat; break;
6100 case TV_SHIELD: p = match_theme.combat; break;
6101 case TV_SOFT_ARMOR: p = match_theme.combat; break;
6102 case TV_HARD_ARMOR: p = match_theme.combat; break;
6103
6104 case TV_MSTAFF: p = match_theme.magic; break;
6105 case TV_STAFF: p = match_theme.magic; break;
6106 case TV_WAND: p = match_theme.magic; break;
6107 case TV_ROD: p = match_theme.magic; break;
6108 case TV_ROD_MAIN: p = match_theme.magic; break;
6109 case TV_SCROLL: p = match_theme.magic; break;
6110 case TV_PARCHMENT: p = match_theme.magic; break;
6111 case TV_POTION: p = match_theme.magic; break;
6112 case TV_POTION2: p = match_theme.magic; break;
6113
6114 case TV_RUNE: p = match_theme.magic; break;
6115 #if 0
6116 case TV_BATERIE: p = match_theme.magic; break;
6117 case TV_RANDART: p = match_theme.magic; break;
6118 case TV_BOOK: p = match_theme.magic; break;
6119 case TV_SYMBIOTIC_BOOK: p = match_theme.magic; break;
6120 case TV_MUSIC_BOOK: p = match_theme.magic; break;
6121 case TV_DRUID_BOOK: p = match_theme.magic; break;
6122 case TV_DAEMON_BOOK: p = match_theme.magic; break;
6123 #endif // 0
6124 case TV_BOOK: p = match_theme.magic; break;
6125 case TV_LITE: p = match_theme.tools; break;
6126 case TV_CLOAK: p = match_theme.tools; break;
6127 case TV_BOOTS: p = match_theme.tools; break;
6128 case TV_SPIKE: p = match_theme.tools; break;
6129 case TV_DIGGING: p = match_theme.tools; break;
6130 case TV_FLASK: p = match_theme.tools; break;
6131 case TV_FOOD: p = match_theme.tools; break;
6132 case TV_TOOL: p = match_theme.tools; break;
6133 case TV_INSTRUMENT: p = match_theme.tools; break;
6134 case TV_TRAPKIT: p = match_theme.tools; break;
6135 }
6136
6137 /* Return the percentage */
6138 return p;
6139 }
6140
6141 /*
6142 * Determine if an object must not be generated.
6143 */
6144 int kind_is_legal_special = -1;
6145 int kind_is_legal(int k_idx, u32b resf) {
6146 object_kind *k_ptr = &k_info[k_idx];
6147 int p = kind_is_theme(k_idx);
6148
6149 /* Used only for the Nazgul rings */
6150 if ((k_ptr->tval == TV_RING) && (k_ptr->sval == SV_RING_SPECIAL)) p = 0;
6151
6152 /* Are we forced to one tval ? */
6153 if ((kind_is_legal_special != -1) && (kind_is_legal_special != k_ptr->tval)) p = 0;
6154
6155 /* If legal store item and 'flat', make it equal to all other items */
6156 if (p && (resf & RESF_STOREFLAT)) p = 100;
6157
6158 /* Return the percentage */
6159 return p;
6160 }
6161
6162
6163
6164
6165 /*
6166 * Hack -- determine if a template is "good"
6167 * ugh, this is pretty bad hard-coding, and probably not even needed anymore?
6168 * note: Removing the speed-ring hardcode will probably lower their drop rate from wyrms and other good-droppers!
6169 */
6170 static int kind_is_good(int k_idx, u32b resf) {
6171 object_kind *k_ptr = &k_info[k_idx];
6172
6173 /* Analyze the item type */
6174 switch (k_ptr->tval) {
6175 /* Armor -- Good unless damaged */
6176 case TV_HARD_ARMOR:
6177 case TV_SOFT_ARMOR:
6178 case TV_DRAG_ARMOR:
6179 case TV_SHIELD:
6180 case TV_CLOAK:
6181 case TV_BOOTS:
6182 case TV_GLOVES:
6183 case TV_HELM:
6184 case TV_CROWN:
6185 if (k_ptr->to_a < 0) return 0;
6186 return 100;
6187
6188 /* Weapons -- Good unless damaged */
6189 case TV_BOW:
6190 case TV_SWORD:
6191 case TV_BLUNT:
6192 case TV_POLEARM:
6193 case TV_DIGGING:
6194 case TV_AXE:
6195 case TV_BOOMERANG:
6196 if (k_ptr->to_h < 0) return 0;
6197 if (k_ptr->to_d < 0) return 0;
6198 return 100;
6199
6200 /* Ammo -- Arrows/Bolts are good */
6201 case TV_BOLT:
6202 case TV_ARROW:
6203 case TV_SHOT: /* are Shots bad? */
6204 if (k_ptr->sval == SV_AMMO_CHARRED) return 0;
6205 case TV_MSTAFF:
6206 return 100;
6207
6208 /* Trap kits are good now, since weapons are, too (required for dungeon keeper reward sval generation..) */
6209 #if 0 /* disabled them again, because _every_ monster would drop them like weapons/armour, ie way too high frequency! - instead, added kind_is_good_reward() */
6210 case TV_TRAPKIT:
6211 return 100;
6212 #endif
6213
6214 /* Rings -- Rings of Speed are good */
6215 case TV_RING:
6216 if (k_ptr->sval == SV_RING_SPEED) return 100;
6217 if (k_ptr->sval == SV_RING_BARAHIR) return 100;
6218 if (k_ptr->sval == SV_RING_TULKAS) return 100;
6219 if (k_ptr->sval == SV_RING_NARYA) return 100;
6220 if (k_ptr->sval == SV_RING_NENYA) return 100;
6221 if (k_ptr->sval == SV_RING_VILYA) return 100;
6222 if (k_ptr->sval == SV_RING_POWER) return 100;
6223 return 0;
6224
6225 /* Amulets -- Amulets of the Magi are good */
6226 case TV_AMULET:
6227 #if 0
6228 if (k_ptr->sval == SV_AMULET_THE_MAGI) return 100;
6229 if (k_ptr->sval == SV_AMULET_THE_MOON) return 100;
6230 if (k_ptr->sval == SV_AMULET_SPEED) return 100;
6231 if (k_ptr->sval == SV_AMULET_TERKEN) return 100;
6232 #endif
6233 return 0;
6234 }
6235
6236 /* Assume not good */
6237 return 0;
6238 }
6239
6240 /* Variant of kind_is_good() that includes trap kits,
6241 specifically made for create_reward(). */
6242 static int kind_is_good_reward(int k_idx, u32b resf) {
6243 object_kind *k_ptr = &k_info[k_idx];
6244
6245 /* Analyze the item type */
6246 switch (k_ptr->tval) {
6247 /* Armor -- Good unless damaged */
6248 case TV_HARD_ARMOR:
6249 case TV_SOFT_ARMOR:
6250 case TV_DRAG_ARMOR:
6251 case TV_SHIELD:
6252 case TV_CLOAK:
6253 case TV_BOOTS:
6254 case TV_GLOVES:
6255 case TV_HELM:
6256 case TV_CROWN:
6257 if (k_ptr->to_a < 0) return 0;
6258 return 100;
6259
6260 /* Weapons -- Good unless damaged */
6261 case TV_BOW:
6262 case TV_SWORD:
6263 case TV_BLUNT:
6264 case TV_POLEARM:
6265 case TV_DIGGING:
6266 case TV_AXE:
6267 case TV_BOOMERANG:
6268 if (k_ptr->to_h < 0) return 0;
6269 if (k_ptr->to_d < 0) return 0;
6270 return 100;
6271
6272 /* Ammo -- Arrows/Bolts are good */
6273 case TV_BOLT:
6274 case TV_ARROW:
6275 case TV_SHOT: /* are Shots bad? */
6276 if (k_ptr->sval == SV_AMMO_CHARRED) return 0;
6277 case TV_MSTAFF:
6278 return 100;
6279
6280 /* Trap kits are good now, since weapons are, too (required for dungeon keeper reward sval generation..) */
6281 case TV_TRAPKIT:
6282 return 100;
6283 }
6284
6285 /* Assume not good */
6286 return 0;
6287 }
6288
6289
6290 /* Hack -- inscribe items that a unique drops */
6291 s16b unique_quark = 0;
6292
6293 /* Restrict the type of placed objects */
6294 u32b place_object_restrictor = RESF_NONE;
6295
6296 /*
6297 * Attempt to place an object (normal or good/great) at the given location.
6298 *
6299 * This routine plays nasty games to generate the "special artifacts".
6300 *
6301 * This routine uses "object_level" for the "generation level".
6302 *
6303 * This routine requires a clean floor grid destination.
6304 */
6305 //void place_object(struct worldpos *wpos, int y, int x, bool good, bool great)
6306 void place_object(struct worldpos *wpos, int y, int x, bool good, bool great, bool verygreat, u32b resf, obj_theme theme, int luck, byte removal_marker) {
6307 int prob, base, tmp_luck, i, dlev;
6308 int tries = 0, k_idx, debug_k_idx = 0;
6309
6310 object_type forge;
6311 dun_level *l_ptr = getfloor(wpos);
6312 dungeon_type *d_ptr;
6313 cave_type **zcave;
6314 if (!(zcave = getcave(wpos))) return;
6315 dlev = getlevel(wpos);
6316 d_ptr = getdungeon(wpos);
6317
6318 /* Paranoia -- check bounds */
6319 if (!in_bounds(y, x)) return;
6320
6321 /* Hack - No l00t in Valinor */
6322 if (in_valinor(wpos)) return;
6323
6324 #ifdef RPG_SERVER /* no objects are generated in Training Tower */
6325 if (in_trainingtower(wpos)) return;
6326 #endif
6327
6328 /* Require clean floor space */
6329 // if (!cave_clean_bold(zcave, y, x)) return;
6330
6331 if (resf & RESF_DEBUG_ITEM) {
6332 debug_k_idx = luck;
6333 luck = 0;
6334 }
6335
6336 /* place_object_restrictor overrides resf */
6337 resf |= place_object_restrictor;
6338
6339 /* Luck does not affect items placed at level creation time */
6340 if (!level_generation_time) {
6341 luck += global_luck;
6342 if (d_ptr) {
6343 if ((d_ptr->flags3 & DF3_LUCK_PROG_IDDC)) {
6344 /* progressive luck bonus past Menegroth */
6345 luck += dlev > 40 ? dlev / 20 + 1 : 0;
6346 }
6347 if ((d_ptr->flags3 & DF3_LUCK_1)) luck++;
6348 if ((d_ptr->flags3 & DF3_LUCK_5)) luck += 5;
6349 if ((d_ptr->flags3 & DF3_LUCK_20)) luck += 20;
6350 }
6351 }
6352
6353 if (luck < -10) luck = -10;
6354 if (luck > 40) luck = 40;
6355
6356 //200-(8000/(luck+40)) old way (0..100)
6357 //(2000-(11250/(5+1)))*4/70 ->0..100
6358 //(1125-(11250/(10+40)))/10 ->0..90 (only prob is, low luck values result in too high factors: 4->32 instead of 19
6359 //(1125-(11250/(10+40)))/20 ->0..45 ^problem solved, but no diffs 0->1 and 39->40
6360 //(1125-(11250/(10+40)))/15 ->0..60 ^all solved. low luck values are a bit more effective now than they originally were ('old way'), seems ok.
6361 if (luck > 0) {
6362 /* max luck = 40 */
6363 tmp_luck = (1125 - (11250 / (luck + 10))) / 15;
6364 if (!good && !great && magik(tmp_luck / 6)) good = TRUE;
6365 else if (good && !great && magik(tmp_luck / 20)) {great = TRUE; good = TRUE;}
6366 } else if (luck < 0) {
6367 /* min luck = -10 */
6368 tmp_luck = 200 - (2000 / (-luck + 10));
6369 if (great && magik(tmp_luck / 3)) {great = FALSE; good = TRUE;}
6370 else if (!great && good && magik(tmp_luck / 2)) good = FALSE;
6371 }
6372
6373 /* Chance of "special object" */
6374 prob = (good || great ? 300 : 10000); // 10 : 1000; 30 : 1000
6375
6376 /* Base level for the object */
6377 base = (good || great ? (object_level + 10) : object_level);
6378
6379
6380 /* Hack -- clear out the forgery */
6381 invwipe(&forge);
6382
6383 if (resf & RESF_DEBUG_ITEM) {
6384 k_idx = debug_k_idx;
6385
6386 /* Prepare the object */
6387 invcopy(&forge, k_idx);
6388 forge.number = 1;
6389 }
6390 /* Generate a special object, or a normal object */
6391 else if ((rand_int(prob) != 0) || !make_artifact_special(wpos, &forge, resf)) {
6392 /* Check global variable, if some base types are forbidden */
6393 do {
6394 tries++;
6395 k_idx = 0;
6396
6397 /* Good objects */
6398 if (good) {
6399 /* Activate restriction */
6400 get_obj_num_hook = kind_is_good;
6401
6402 /* Prepare allocation table */
6403 get_obj_num_prep(resf);
6404 }
6405 /* Normal objects */
6406 else {
6407 /* Select items based on "theme" */
6408 init_match_theme(theme);
6409
6410 /* Activate normal restriction */
6411 get_obj_num_hook = kind_is_legal;
6412
6413 /* Prepare allocation table */
6414 get_obj_num_prep(resf);
6415
6416 /* The table is synchronised */
6417 // alloc_kind_table_valid = TRUE;
6418 }
6419
6420
6421 /* Pick a random object */
6422 /* Magic arrows from DROP_GREAT monsters are annoying.. - C. Blue */
6423 /* Added lines for the other magic ammos - the_sandman */
6424 if (great)
6425 for (i = 0; i < 20; i++) {
6426 k_idx = get_obj_num(base, resf);
6427 if (is_ammo(k_info[k_idx].tval) && k_info[k_idx].sval == SV_AMMO_MAGIC) continue;
6428 break;
6429 }
6430 else
6431 k_idx = get_obj_num(base, resf);
6432
6433 /* Good objects */
6434 #if 0 // commented out for efficiency
6435 if (good) {
6436 /* Clear restriction */
6437 get_obj_num_hook = NULL;
6438
6439 /* Prepare allocation table */
6440 get_obj_num_prep(resf);
6441 }
6442 #endif // 0
6443
6444 if ((resf & RESF_NOHIDSM) && (k_info[k_idx].tval == TV_DRAG_ARMOR) &&
6445 !sv_dsm_low(k_info[k_idx].sval) && !sv_dsm_mid(k_info[k_idx].sval))
6446 continue;
6447
6448 if ((resf & RESF_LOWVALUE) && (k_info[k_idx].cost > 35000)) continue;
6449 if ((resf & RESF_MIDVALUE) && (k_info[k_idx].cost > 50000)) continue;
6450 if ((resf & RESF_NOHIVALUE) && (k_info[k_idx].cost > 100000)) continue;
6451
6452 if ((resf & RESF_NOTRUEART) && (k_info[k_idx].flags3 & TR3_INSTA_ART)) continue;
6453
6454 if (!(resf & RESF_WINNER) && k_info[k_idx].flags5 & TR5_WINNERS_ONLY) continue;
6455
6456 if ((k_info[k_idx].flags5 & TR5_FORCE_DEPTH) && dlev < k_info[k_idx].level) continue;
6457
6458 /* Allow all other items here - mikaelh */
6459 break;
6460 } while(tries < 10);
6461
6462 /* Note that if we run out of 'tries', the last tested object WILL be used,
6463 except if we clear k_idx now. */
6464 if (tries == 10) k_idx = 0;
6465
6466 /* Handle failure */
6467 if (!k_idx) return;
6468
6469 /* Prepare the object */
6470 invcopy(&forge, k_idx);
6471 }
6472
6473 /* Apply magic (allow artifacts) */
6474 apply_magic(wpos, &forge, object_level, TRUE, good, great, verygreat, resf);
6475
6476 /* Hack -- generate multiple spikes/missiles */
6477 if (!forge.name1)
6478 switch (forge.tval) {
6479 case TV_SPIKE:
6480 forge.number = damroll(6, 7);
6481 break;
6482 case TV_SHOT:
6483 case TV_ARROW:
6484 case TV_BOLT:
6485 /* luck has influence on ammo stack size, heh */
6486 if (luck >= 0)
6487 forge.number = damroll(6, (forge.sval == SV_AMMO_MAGIC) ? 2 : (7 * (40 + randint(luck)) / 40));
6488 else
6489 forge.number = damroll(6, (forge.sval == SV_AMMO_MAGIC) ? 2 : (7 * (20 - randint(-luck)) / 20));
6490 /* Stacks of ethereal ammo are smaller */
6491 if (forge.name2 == EGO_ETHEREAL || forge.name2b == EGO_ETHEREAL) forge.number /= ETHEREAL_AMMO_REDUCTION;
6492 /* Ammo from acquirement scrolls comes in more generous numbers :) */
6493 if (verygreat) forge.number *= 2;
6494 if (forge.sval == SV_AMMO_CHARRED) forge.number = randint(6);
6495 break;
6496 }
6497
6498 /* Hack -- inscribe items that a unique drops */
6499 if (unique_quark) {
6500 forge.note = unique_quark;
6501 forge.note_utag = strlen(quark_str(unique_quark)); /* mark this note as 'unique monster quark' */
6502 }
6503
6504 if (opening_chest) {
6505 forge.owner = opening_chest_owner;
6506 forge.mode = opening_chest_mode;
6507 if (true_artifact_p(&forge)) determine_artifact_timeout(forge.name1, wpos);
6508 }
6509
6510 forge.marked2 = removal_marker;
6511 forge.discount = object_discount; /* usually 0, except for creation from stolen acquirement scrolls */
6512 drop_near(&forge, -1, wpos, y, x);
6513
6514 /* for now ignore live-spawns. change that maybe? */
6515 if (level_generation_time) {
6516 /* Check that we're in a dungeon */
6517 if (l_ptr) {
6518 if (forge.name1) l_ptr->flags2 |= LF2_ARTIFACT;
6519 if (k_info[forge.k_idx].level >= dlev + 8) l_ptr->flags2 |= LF2_ITEM_OOD;
6520 }
6521 }
6522
6523 }
6524
6525 /* Like place_object(), but doesn't actually drop the object to the floor - C. Blue */
6526 void generate_object(object_type *o_ptr, struct worldpos *wpos, bool good, bool great, bool verygreat, u32b resf, obj_theme theme, int luck) {
6527 int prob, base, tmp_luck, i, dlev;;
6528 int tries = 0, k_idx;
6529 dungeon_type *d_ptr;
6530
6531 cave_type **zcave;
6532 if (!(zcave = getcave(wpos))) return;
6533 dlev = getlevel(wpos);
6534 d_ptr = getdungeon(wpos);
6535
6536 /* Hack - No l00t in Valinor */
6537 if (in_valinor(wpos)) return;
6538
6539 /* place_object_restrictor overrides resf */
6540 resf |= place_object_restrictor;
6541
6542 /* Luck does not affect items placed at level creation time */
6543 if (!level_generation_time) {
6544 luck += global_luck;
6545 if (d_ptr) {
6546 if ((d_ptr->flags3 & DF3_LUCK_PROG_IDDC)) {
6547 /* progressive luck bonus past Menegroth */
6548 luck += dlev > 40 ? dlev / 20 + 1 : 0;
6549 }
6550 if ((d_ptr->flags3 & DF3_LUCK_1)) luck++;
6551 if ((d_ptr->flags3 & DF3_LUCK_5)) luck += 5;
6552 if ((d_ptr->flags3 & DF3_LUCK_20)) luck += 20;
6553 }
6554 }
6555
6556 if (luck < -10) luck = -10;
6557 if (luck > 40) luck = 40;
6558
6559 if (luck > 0) {
6560 /* max luck = 40 */
6561 tmp_luck = (1125 - (11250 / (luck + 10))) / 15;
6562 if (!good && !great && magik(tmp_luck / 6)) good = TRUE;
6563 else if (good && !great && magik(tmp_luck / 20)) {great = TRUE; good = TRUE;}
6564 } else if (luck < 0) {
6565 /* min luck = -10 */
6566 tmp_luck = 200 - (2000 / (-luck + 10));
6567 if (great && magik(tmp_luck / 3)) {great = FALSE; good = TRUE;}
6568 else if (!great && good && magik(tmp_luck / 2)) good = FALSE;
6569 }
6570
6571 /* Chance of "special object" */
6572 prob = (good || great ? 300 : 10000); // 10 : 1000; 30 : 1000
6573
6574 /* Base level for the object */
6575 base = (good || great ? (object_level + 10) : object_level);
6576
6577
6578 /* Hack -- clear out the forgery */
6579 invwipe(o_ptr);
6580
6581 /* Generate a special object, or a normal object */
6582 if ((rand_int(prob) != 0) || !make_artifact_special(wpos, o_ptr, resf)) {
6583 /* Check global variable, if some base types are forbidden */
6584 do {
6585 tries++;
6586 k_idx = 0;
6587
6588 /* Good objects */
6589 if (good) {
6590 /* Activate restriction */
6591 get_obj_num_hook = kind_is_good;
6592
6593 /* Prepare allocation table */
6594 get_obj_num_prep(resf);
6595 }
6596 /* Normal objects */
6597 else {
6598 /* Select items based on "theme" */
6599 init_match_theme(theme);
6600
6601 /* Activate normal restriction */
6602 get_obj_num_hook = kind_is_legal;
6603
6604 /* Prepare allocation table */
6605 get_obj_num_prep(resf);
6606
6607 /* The table is synchronised */
6608 // alloc_kind_table_valid = TRUE;
6609 }
6610
6611
6612 /* Pick a random object */
6613 /* Magic arrows from DROP_GREAT monsters are annoying.. - C. Blue */
6614 /* Added lines for the other magic ammos - the_sandman */
6615 if (great)
6616 for (i = 0; i < 20; i++) {
6617 k_idx = get_obj_num(base, resf);
6618 if (is_ammo(k_info[k_idx].tval) && k_info[k_idx].sval == SV_AMMO_MAGIC) continue;
6619 break;
6620 }
6621 else
6622 k_idx = get_obj_num(base, resf);
6623
6624 /* Good objects */
6625 #if 0 // commented out for efficiency
6626
6627 if (good)
6628 {
6629 /* Clear restriction */
6630 get_obj_num_hook = NULL;
6631
6632 /* Prepare allocation table */
6633 get_obj_num_prep(resf);
6634 }
6635 #endif // 0
6636
6637 if ((resf & RESF_NOHIDSM) && (k_info[k_idx].tval == TV_DRAG_ARMOR) &&
6638 !sv_dsm_low(k_info[k_idx].sval) && !sv_dsm_mid(k_info[k_idx].sval))
6639 continue;
6640
6641 if ((resf & RESF_LOWVALUE) && (k_info[k_idx].cost > 35000)) continue;
6642 if ((resf & RESF_MIDVALUE) && (k_info[k_idx].cost > 50000)) continue;
6643 if ((resf & RESF_NOHIVALUE) && (k_info[k_idx].cost > 100000)) continue;
6644
6645 if ((resf & RESF_NOTRUEART) && (k_info[k_idx].flags3 & TR3_INSTA_ART)) continue;
6646
6647 if (!(resf & RESF_WINNER) && k_info[k_idx].flags5 & TR5_WINNERS_ONLY) continue;
6648
6649 /* Allow all other items here - mikaelh */
6650 break;
6651 } while(tries < 1000);
6652
6653 /* Note that if we run out of 'tries', the last tested object WILL be used,
6654 except if we clear k_idx now. */
6655 if (tries == 1000) k_idx = 0;
6656
6657 /* Handle failure */
6658 if (!k_idx) { /* always generate a reward. in case of failure, make a lamp for now.. */
6659 switch (rand_int(3)){
6660 case 0: k_idx = 527; /* everburning torch */
6661 case 1: k_idx = 525; /* dwarven lantern */
6662 case 2: k_idx = 530; /* feanorian lamp */
6663 }
6664 }
6665
6666 /* Prepare the object */
6667 invcopy(o_ptr, k_idx);
6668 }
6669
6670 /* Apply magic (allow artifacts) */
6671 apply_magic(wpos, o_ptr, object_level, TRUE, good, great, verygreat, resf);
6672
6673 /* Hack -- generate multiple spikes/missiles */
6674 if (!o_ptr->name1)
6675 switch (o_ptr->tval)
6676 {
6677 case TV_SPIKE:
6678 o_ptr->number = damroll(6, 7);
6679 break;
6680 case TV_SHOT:
6681 case TV_ARROW:
6682 case TV_BOLT:
6683 /* luck has influence on ammo stack size, heh */
6684 if (luck >= 0)
6685 o_ptr->number = damroll(6, (o_ptr->sval == SV_AMMO_MAGIC) ? 2 : (7 * (40 + randint(luck)) / 40));
6686 else
6687 o_ptr->number = damroll(6, (o_ptr->sval == SV_AMMO_MAGIC) ? 2 : (7 * (20 - randint(-luck)) / 20));
6688 /* Stacks of ethereal ammo are smaller */
6689 if (o_ptr->name2 == EGO_ETHEREAL || o_ptr->name2b == EGO_ETHEREAL) o_ptr->number /= ETHEREAL_AMMO_REDUCTION;
6690 /* Ammo from acquirement scrolls comes in more generous numbers :) */
6691 if (verygreat) o_ptr->number *= 2;
6692 if (o_ptr->sval == SV_AMMO_CHARRED) o_ptr->number = randint(6);
6693 break;
6694 }
6695
6696 /* Hack -- inscribe items that a unique drops */
6697 if (unique_quark) {
6698 o_ptr->note = unique_quark;
6699 o_ptr->note_utag = strlen(quark_str(unique_quark)); /* mark this note as 'unique monster quark' */
6700 }
6701 //s_printf("object generated %d,%d,%d\n", o_ptr->tval, o_ptr->sval, o_ptr->k_idx);
6702 }
6703
6704
6705 /*
6706 * Scatter some "great" objects near the player
6707 */
6708 void acquirement(struct worldpos *wpos, int y1, int x1, int num, bool great, bool verygreat, u32b resf)
6709 {
6710 // int y, x, i, d;
6711 cave_type **zcave;
6712 if (!(zcave = getcave(wpos))) return;
6713
6714 /* Scatter some objects */
6715 for (; num > 0; --num) {
6716 /* Place a good (or great) object */
6717 place_object_restrictor = RESF_NONE;
6718 place_object(wpos, y1, x1, TRUE, great, verygreat, resf, default_obj_theme, 0, ITEM_REMOVAL_NORMAL);
6719 /* Notice */
6720 note_spot_depth(wpos, y1, x1);
6721 /* Redraw */
6722 everyone_lite_spot(wpos, y1, x1);
6723 }
6724 }
6725 /*
6726 * Same as acquirement, except it doesn't drop the item to the floor. Creates one "great" object.
6727 */
6728 void acquirement_direct(object_type *o_ptr, struct worldpos *wpos, bool great, bool verygreat, u32b resf)
6729 {
6730 cave_type **zcave;
6731 if (!(zcave = getcave(wpos))) return;
6732
6733 /* Place a good (or great) object */
6734 place_object_restrictor = RESF_NONE;
6735 //s_printf("generating object...");
6736 generate_object(o_ptr, wpos, TRUE, great, verygreat, resf, default_obj_theme, 0);
6737 //s_printf("object acquired %d,%d,%d\n", o_ptr->tval, o_ptr->sval, o_ptr->k_idx);
6738 }
6739
6740
6741
6742 /* for create_reward() ... */
6743 static int reward_melee_check(player_type *p_ptr, long int treshold) {
6744 long int rnd_result = 0, selection = 0;
6745 long int choice1 = 0, choice2 = 0, choice3 = 0, choice4 = 0, choice5 = 0;
6746 if (p_ptr->s_info[SKILL_SWORD].value >= treshold
6747 /* hack: critical-hits skill only affects swords! */
6748 || p_ptr->s_info[SKILL_CRITS].value >= treshold)
6749 choice1 = p_ptr->s_info[SKILL_SWORD].value;
6750 if (p_ptr->s_info[SKILL_BLUNT].value >= treshold) choice2 = p_ptr->s_info[SKILL_BLUNT].value;
6751 if (p_ptr->s_info[SKILL_AXE].value >= treshold) choice3 = p_ptr->s_info[SKILL_AXE].value;
6752 if (p_ptr->s_info[SKILL_POLEARM].value >= treshold) choice4 = p_ptr->s_info[SKILL_POLEARM].value;
6753 if (p_ptr->s_info[SKILL_MARTIAL_ARTS].value >= treshold) choice5 = p_ptr->s_info[SKILL_MARTIAL_ARTS].value;
6754 rnd_result = randint(choice1 + choice2 + choice3 + choice4 + choice5);
6755 /* manipulation concerning magic/melee hybrids but also priests:
6756 melee takes precedence over magic, since someone wouldn't skill melee otherwise */
6757 /* TV_MSTAFF */
6758 if (!rnd_result) return 0;
6759 /* TV_SWORD
6760 TV_BLUNT
6761 TV_AXE
6762 TV_POLEARM
6763 TV_SHIELD */
6764 if (rnd_result <= choice1) selection = 1;
6765 else if (rnd_result - choice1 <= choice2) selection = 2;
6766 else if (rnd_result - choice1 - choice2 <= choice3) selection = 3;
6767 else if (rnd_result - choice1 - choice2 - choice3 <= choice4) selection = 4;
6768 /* Martial Arts - will get some light armor or any misc item instead! */
6769 else if (rnd_result - choice1 - choice2 - choice3 - choice4 <= choice5) selection = 5;
6770
6771 /* Receive a shield instead of a weapon? Depends on actual weapon type! */
6772 /* ..not if we're dual-wielding */
6773 if (p_ptr->inventory[INVEN_WIELD].k_idx &&
6774 p_ptr->inventory[INVEN_ARM].k_idx && p_ptr->inventory[INVEN_ARM].tval != TV_SHIELD) return selection;
6775 /* ..not if we're rogues anyway */
6776 if (p_ptr->pclass == CLASS_ROGUE) return selection;
6777 /* player's form cannot equip shields? */
6778 if (!item_tester_hook_wear(p_ptr->Ind, INVEN_ARM)) return selection;
6779 //Nope, they can! if (p_ptr->pclass == CLASS_SHAMAN) return(selection); /* shamans cannot cast magic well with shield. */
6780 switch (selection) {
6781 case 1: if magik(50) selection = 6; break;
6782 case 2: if magik(35) selection = 6; break;
6783 case 3: if magik(15) selection = 6; break;
6784 case 4: if magik(10) selection = 6; break;
6785 }
6786 return (selection);
6787 }
6788 static int reward_ranged_check(player_type *p_ptr, long int treshold) {
6789 long int rnd_result = 0, selection = 0;
6790 long int choice1 = 0, choice2 = 0, choice3 = 0, choice4 = 0;
6791 if (p_ptr->s_info[SKILL_BOW].value >= treshold) choice1 = p_ptr->s_info[SKILL_BOW].value;
6792 if (p_ptr->s_info[SKILL_XBOW].value >= treshold) choice2 = p_ptr->s_info[SKILL_XBOW].value;
6793 if (p_ptr->s_info[SKILL_SLING].value >= treshold) choice3 = p_ptr->s_info[SKILL_SLING].value;
6794 if (p_ptr->s_info[SKILL_BOOMERANG].value >= treshold) choice4 = p_ptr->s_info[SKILL_BOOMERANG].value;
6795 rnd_result = randint(choice1 + choice2 + choice3 + choice4);
6796 if (!rnd_result) return 0;
6797 /* TV_BOW:
6798 SV_SHORT_BOW, SV_LONG_BOW
6799 SV_LIGHT_XBOW, SV_HEAVY_XBOW
6800 SV_SLING
6801 TV_BOOMERANG */
6802 if (rnd_result <= choice1) selection = 1;
6803 else if (rnd_result - choice1 <= choice2) selection = 2;
6804 else if (rnd_result - choice1 - choice2 <= choice3) selection = 3;
6805 else if (rnd_result - choice1 - choice2 - choice3 <= choice4) selection = 4;
6806 /* For now no shooter reward for unskilled players (not necessarily needed though..everyone wants a good shooter!) */
6807 if (!(choice1 + choice2 + choice3 + choice4)) selection = 0;
6808 return (selection);
6809 }
6810 static int reward_armor_check(player_type *p_ptr, bool mha, bool rha) {
6811 // int maxweight = (adj_str_hold[p_ptr->stat_ind[A_STR]] - 10) * 10;
6812 int maxweight = adj_str_armor[p_ptr->stat_ind[A_STR]] * 10;
6813 long int rnd_result = 0, selection = 0;
6814 int choice1 = 0, choice2 = 0, choice3 = 0, choice4 = 0, choice5 = 0, choice6 = 0, choice7 = 0, choice8 = 0;
6815 /* TV_SOFT_ARMOR
6816 TV_HARD_ARMOR
6817 TV_DRAG_ARMOR
6818 TV_BOOTS
6819 TV_GLOVES
6820 TV_HELM
6821 TV_CROWN
6822 TV_CLOAK */
6823 if (maxweight < 240 || mha || rha) choice1 = 10;
6824 if (maxweight >= 240 && !mha && !rha) {
6825 choice2 = 30; /* If player can make good use of heavy armour, make him likely to get one! */
6826 choice1 = 0; /* ..and don't give him too light armour */
6827 }
6828 if (maxweight >= 200 && !mha && !rha) choice3 = 4; /* Only slim chance to get a Dragon Scale Mail! */
6829 choice4 = 10;
6830 choice5 = 10;
6831 choice6 = 10;
6832 /* actually funny to give the "Highlander Tournament" winner a crown ;) */
6833 if (maxweight <= 50) choice7 = 10;//magic classes (aka 'low STR' a bit more likely to get one
6834 else choice7 = 5;
6835 choice8 = 10;
6836 rnd_result = randint(choice1 + choice2 + choice3 + choice4 + choice5 + choice6 + choice7 + choice8);
6837 if (!rnd_result) return 0;
6838 if (rnd_result <= choice1) selection = 1;
6839 else if (rnd_result - choice1 <= choice2) selection = 2;
6840 else if (rnd_result - choice1 - choice2 <= choice3) selection = 3;
6841 else if (rnd_result - choice1 - choice2 - choice3 <= choice4) selection = 4;
6842 else if (rnd_result - choice1 - choice2 - choice3 - choice4 <= choice5) selection = 5;
6843 else if (rnd_result - choice1 - choice2 - choice3 - choice4 - choice5 <= choice6) selection = 6;
6844 else if (rnd_result - choice1 - choice2 - choice3 - choice4 - choice5 - choice6 <= choice7) selection = 7;
6845 else selection = 8;
6846 return (selection);
6847 }
6848 static int reward_spell_check(player_type *p_ptr, long int treshold) {
6849 int selection = 0;
6850 s32b value = 0, mod = 0;
6851
6852 /* get base value of MAGIC skill */
6853 compute_skills(p_ptr, &value, &mod, SKILL_MAGIC);
6854 /* check whether player increased magic skill above its base value */
6855 if (p_ptr->s_info[SKILL_MAGIC].value > value) selection = 1;
6856
6857 return (selection);
6858 }
6859 static int reward_misc_check(player_type *p_ptr, long int treshold) {
6860 /* TV_TRAPKIT */
6861 if (p_ptr->s_info[SKILL_TRAPPING].value >= treshold) return 4;
6862
6863 /* TV_LITE
6864 TV_AMULET
6865 TV_RING */
6866 return (randint(3));
6867 }
6868
6869 /*
6870 * Create a reward (form quests etc) for the player //UNFINISHED, just started to code a few lines, o laziness
6871 * <min_lv> and <max_lv> restrict the object's base level when choosing from k_info.txt.
6872 * currently, they are just averaged to form a 'base object level' for get_obj_num() though.
6873 * <treshold> is the skill treshold a player must have for a skill to be considered for choosing a reward. - C. Blue
6874 */
6875 void create_reward(int Ind, object_type *o_ptr, int min_lv, int max_lv, bool great, bool verygreat, u32b resf, long int treshold) {
6876 player_type *p_ptr = Players[Ind];
6877 bool good = TRUE;
6878 int base = (min_lv + max_lv) / 2; /* base object level */
6879 // int base = 100;
6880 int tries = 0, i = 0, j = 0;
6881 char o_name[ONAME_LEN];
6882 u32b f1, f2, f3, f4, f5, f6, esp;
6883 bool mha, rha; /* monk heavy armor, rogue heavy armor */
6884 bool go_heavy = TRUE; /* new special thingy: don't pick super light cloth armour if we're not specifically light-armour oriented */
6885
6886 /* for analysis functions and afterwards for determining concrete reward */
6887 int maxweight_melee = adj_str_hold[p_ptr->stat_ind[A_STR]] * 10;
6888 int maxweight_ranged = adj_str_hold[p_ptr->stat_ind[A_STR]] * 10;
6889 int maxweight_shield = ((adj_str_hold[p_ptr->stat_ind[A_STR]] / 7) + 4) * 10;
6890 // int maxweight_armor = (adj_str_hold[p_ptr->stat_ind[A_STR]] - 10) * 10; /* not really directly calculatable, since cumber_armor uses TOTAL armor weight, so just estimate something.. pft */
6891 int maxweight_armor = adj_str_armor[p_ptr->stat_ind[A_STR]] * 10;
6892 object_type tmp_obj;
6893 int wearable[5], wearables; /* 5 pure (no shields) armour slots, 3 misc slots (tools omitted) */
6894
6895 /* analysis results: */
6896 int melee_choice, ranged_choice, armor_choice, spell_choice, misc_choice;
6897 int final_choice = 0; /* 1 = melee, 2 = ranged, 3 = armor, 4 = misc item */
6898
6899 /* concrete reward */
6900 int reward_tval = 0, reward_sval = 0, k_idx = 0, reward_maxweight = 500;
6901
6902 invwipe(o_ptr);
6903
6904 /* fix reasonable limits */
6905 if (maxweight_armor < 30) maxweight_armor = 30;
6906
6907 /* analyze skills */
6908 if (p_ptr->skill_points != (p_ptr->max_plv - 1) * SKILL_NB_BASE) {
6909 melee_choice = reward_melee_check(p_ptr, treshold);
6910 mha = (melee_choice == 5); /* monk heavy armor */
6911 rha = (get_skill(p_ptr, SKILL_DODGE)); /* rogue heavy armor; pclass == rogue or get_skill(SKILL_CRITS) are implied by this one due to current tables.c. dual_wield is left out on purpose. */
6912 /* analyze current setup (for reward_armor_check) */
6913 if (p_ptr->inventory[INVEN_WIELD].k_idx &&
6914 p_ptr->inventory[INVEN_ARM].k_idx && p_ptr->inventory[INVEN_ARM].tval != TV_SHIELD)
6915 rha = TRUE; /* we're dual-wielding */
6916 /* make choices */
6917 ranged_choice = reward_ranged_check(p_ptr, treshold);
6918 armor_choice = reward_armor_check(p_ptr, mha, rha);
6919 spell_choice = reward_spell_check(p_ptr, treshold);
6920 misc_choice = reward_misc_check(p_ptr, treshold);
6921 /* martial arts -> no heavy armor (paranoia, shouldn't happen, already cought in reward_armor_check) */
6922 if (melee_choice == 5 &&
6923 (armor_choice == 2 || armor_choice == 3))
6924 armor_choice = 1;
6925 } else { /* player didn't distribute ANY skill points, sigh */
6926 melee_choice = 0;
6927 mha = FALSE;
6928 rha = FALSE;
6929 ranged_choice = 0;
6930 spell_choice = 0;
6931 switch (p_ptr->pclass) {
6932 case CLASS_WARRIOR:
6933 case CLASS_MIMIC:
6934 case CLASS_PALADIN:
6935 case CLASS_MINDCRAFTER:
6936 if (!rand_int(4)) melee_choice = 6;
6937 break;
6938 case CLASS_ADVENTURER:
6939 case CLASS_PRIEST:
6940 case CLASS_DRUID:
6941 mha = TRUE;
6942 break;
6943 case CLASS_ROGUE:
6944 melee_choice = 1;
6945 rha = TRUE;
6946 break;
6947 case CLASS_ARCHER:
6948 case CLASS_RANGER:
6949 ranged_choice = 1;
6950 break;
6951 case CLASS_MAGE:
6952 case CLASS_RUNEMASTER:
6953 case CLASS_SHAMAN:
6954 spell_choice = 1;
6955 break;
6956 }
6957 /* analyze current setup (for reward_armor_check) */
6958 if (p_ptr->inventory[INVEN_WIELD].k_idx &&
6959 p_ptr->inventory[INVEN_ARM].k_idx && p_ptr->inventory[INVEN_ARM].tval != TV_SHIELD)
6960 rha = TRUE; /* we're dual-wielding */
6961 /* make choices */
6962 armor_choice = reward_armor_check(p_ptr, mha, rha);
6963 misc_choice = randint(3);
6964 }
6965
6966 /* Special low limits for Martial Arts or Rogue-skill users: */
6967 if (rha) {
6968 switch (armor_choice) {
6969 case 1: maxweight_armor = 100; break;
6970 case 2: /* cannot happen */ break;
6971 case 3: /* cannot happen */ break;
6972 case 4: maxweight_armor = 40; break;
6973 case 5: maxweight_armor = 25; break;
6974 case 6: maxweight_armor = 40; break;//4.0 helmets don't exist (jewel encrusted crown has it though, so we just pretend..)
6975 case 7: maxweight_armor = 30; break;
6976 case 8: maxweight_armor = 15; break;
6977 }
6978 go_heavy = FALSE;
6979 }
6980 if (mha) {
6981 switch (armor_choice) {
6982 case 1: maxweight_armor = 30; break;
6983 case 2: /* cannot happen */ break;
6984 case 3: /* cannot happen */ break;
6985 case 4: maxweight_armor = 20; break;
6986 case 5: maxweight_armor = 20; break;
6987 case 6: maxweight_armor = 40; break;//4.0 helmets don't exist (jewel encrusted crown has it though, so we just pretend..)
6988 case 7: maxweight_armor = 30; break;
6989 case 8: maxweight_armor = 15; break;
6990 }
6991 go_heavy = FALSE;
6992 }
6993 if (spell_choice) {
6994 /* no heavy boots/gauntlets/helmets for casters */
6995 switch (armor_choice) {
6996 case 4: maxweight_armor = 40; break;
6997 case 5: maxweight_armor = 15; break;//1.5 gloves don't exist, so it's just leather+elven here
6998 case 6: maxweight_armor = 40; break;//4.0 helmets don't exist (jewel encrusted crown has it though, so we just pretend..)
6999 }
7000 go_heavy = FALSE;
7001 }
7002 if (p_ptr->s_info[SKILL_CRITS].value >= treshold) maxweight_melee = 100;
7003
7004 /* Choose between possible rewards we gathered from analyzing so far */
7005 /* Priority: Weapon -> Ranged -> Armor -> Misc */
7006 if (!melee_choice && spell_choice && ((!armor_choice && !ranged_choice) || magik(50))) final_choice = 4;
7007 if (melee_choice && ((!armor_choice && !ranged_choice) || magik(50))) final_choice = 1;
7008 if (ranged_choice && !final_choice && (!armor_choice || magik(50))) final_choice = 2;
7009 if (melee_choice == 5) final_choice = 3;
7010 if (misc_choice == 4 && (!final_choice || (final_choice && magik(75))) && (!armor_choice || magik(50))) final_choice = 6;
7011 if (armor_choice && !final_choice) final_choice = 3;
7012 /* if (final_choice == 3 && magik(25)) final_choice = 5; <- no misc items for now, won't be good if not (rand)arts anyway! */
7013 /* to catch cases where NO result has been chosen at all (paranoia): */
7014 if (!final_choice) final_choice = 5;
7015
7016 /* Generate TV_ from raw final choice, and choose an appropriate SV_ sub-type now */
7017 switch (final_choice) {
7018 case 1: reward_maxweight = maxweight_melee;
7019 switch (melee_choice) {
7020 case 1: reward_tval = TV_SWORD;
7021 /* Antimagic-users with Sword-skill? Let's be nice and generate a Dark Sword :/ */
7022 if (get_skill(p_ptr, SKILL_ANTIMAGIC)) reward_sval = SV_DARK_SWORD;
7023 break;
7024 case 2: reward_tval = TV_BLUNT; break;
7025 case 3: reward_tval = TV_AXE; break;
7026 case 4: reward_tval = TV_POLEARM; break;
7027 /* 5 -> Martial Arts, handled above */
7028 case 6: reward_tval = TV_SHIELD; reward_maxweight = maxweight_shield; break;
7029 }
7030 break;
7031 case 2: reward_tval = TV_BOW;
7032 reward_maxweight = maxweight_ranged;
7033 switch (ranged_choice) {
7034 case 1: if (magik(50)) reward_sval = SV_SHORT_BOW; else reward_sval = SV_LONG_BOW; break;
7035 case 2: if (magik(50) || maxweight_ranged < 200) reward_sval = SV_LIGHT_XBOW; else reward_sval = SV_HEAVY_XBOW; break;
7036 case 3: reward_sval = SV_SLING; break;
7037 case 4: reward_tval = TV_BOOMERANG; break;
7038 }
7039 break;
7040 case 3: reward_maxweight = maxweight_armor;
7041 switch (armor_choice) {
7042 case 1: reward_tval = TV_SOFT_ARMOR; break;
7043 case 2: reward_tval = TV_HARD_ARMOR; break;
7044 case 3: reward_tval = TV_DRAG_ARMOR; break;
7045 case 4: reward_tval = TV_BOOTS; break;
7046 case 5: reward_tval = TV_GLOVES; break;
7047 case 6: reward_tval = TV_HELM; break;
7048 case 7: reward_tval = TV_CROWN; break;
7049 case 8: reward_tval = TV_CLOAK; break;
7050 /* to catch cases where NO result has been chosen at all (paranoia): */
7051 // default: reward_tval = TV_CROWN; reward_maxweight = 40; break;
7052 }
7053 break;
7054 case 4: reward_maxweight = 500;
7055 reward_tval = TV_MSTAFF; reward_sval = SV_MSTAFF; break;
7056 case 5: reward_maxweight = 500; /* no use, so just use any high value.. */
7057 switch (misc_choice) {
7058 case 1: reward_tval = TV_LITE; break;
7059 case 2: reward_tval = TV_AMULET; break;
7060 case 3: reward_tval = TV_RING; break;
7061 }
7062 break;
7063 case 6: reward_maxweight = 500;
7064 reward_tval = TV_TRAPKIT;
7065 break;
7066 }
7067
7068 /* respect unusuable slots depending on monster form */
7069 invwipe(&tmp_obj);
7070 tmp_obj.tval = reward_tval;
7071 /* we cannot equip the selected reward? */
7072 if (!item_tester_hook_wear(Ind, i = wield_slot(Ind, &tmp_obj))) {
7073 /* for weapons and TV_SHIELD: this shouldn't happen */
7074 if (is_weapon(tmp_obj.tval) || tmp_obj.tval == TV_MSTAFF || is_ranged_weapon(tmp_obj.tval)) {
7075 /* shouldn't happen, but.. */
7076 invcopy(o_ptr, lookup_kind(TV_SPECIAL, SV_CUSTOM_OBJECT));
7077 o_ptr->note = quark_add("a Cake");
7078 o_ptr->xtra1 = 15;
7079 s_printf("REWARD_CREATED: (%s) a Cake (1)\n", p_ptr->name);
7080 /* serious alternatives: digger, magic device, a set of consumables */
7081 return;
7082 }
7083
7084 /* for armour being selected */
7085 else if (is_armour(tmp_obj.tval)) {
7086 wearables = 0;
7087 wearable[0] = item_tester_hook_wear(Ind, INVEN_BODY) ? 10 + 30 + 3 : 0;
7088 wearable[1] = item_tester_hook_wear(Ind, INVEN_OUTER) ? 10 : 0;
7089 wearable[2] = item_tester_hook_wear(Ind, INVEN_HEAD) ? 10 + 5 : 0;
7090 wearable[3] = item_tester_hook_wear(Ind, INVEN_HANDS) ? 10 : 0;
7091 wearable[4] = item_tester_hook_wear(Ind, INVEN_FEET) ? 10 : 0;
7092 wearables = wearable[0] + wearable[1] + wearable[2] + wearable[3] + wearable[4];
7093
7094 /* we cannot wear ANY armour? */
7095 if (!wearables) {
7096 /* select a different item class */
7097 wearables = 0;
7098 wearable[0] = item_tester_hook_wear(Ind, INVEN_LITE) ? 1 : 0;
7099 wearable[1] = item_tester_hook_wear(Ind, INVEN_NECK) ? 1 : 0;
7100 wearable[2] = item_tester_hook_wear(Ind, INVEN_RIGHT) ? 1 : 0;
7101 wearables = wearable[0] + wearable[1] + wearable[2];
7102
7103 /* we cannot wear ANY item? =P */
7104 if (!wearables) {
7105 /* this is silly, someone polymorphed into limbless form to turn in the reward deed?.. */
7106 invcopy(o_ptr, lookup_kind(TV_SPECIAL, SV_CUSTOM_OBJECT));
7107 o_ptr->note = quark_add("a Cake");
7108 o_ptr->xtra1 = 15;
7109 s_printf("REWARD_CREATED: (%s) a Cake (2)\n", p_ptr->name);
7110 /* serious alternatives: digger, magic device, a set of consumables */
7111 return;
7112 }
7113
7114 i = randint(wearables);
7115 if (i <= wearable[0]) reward_tval = TV_LITE;
7116 else if (i <= wearable[0] + wearable[1]) reward_tval = TV_AMULET;
7117 else if (i <= wearable[0] + wearable[1] + wearable[2]) reward_tval = TV_RING;
7118 s_printf("REWARD_CANNOT_WEAR: changed to %d\n", reward_tval);
7119 } else { /* we can wear some sort of armour */
7120 i = randint(wearables);
7121 if (i <= wearable[0]) {
7122 wearables = 0;
7123 wearable[0] = (reward_maxweight < 240 || mha || rha) ? 10 : 0;
7124 wearable[1] = (reward_maxweight >= 240 && !mha && !rha) ? 30 : 0;
7125 wearable[2] = (reward_maxweight >= 200 && !mha && !rha) ? 3 : 0;
7126 wearables = wearable[0] + wearable[1] + wearable[2];
7127 i = randint(wearables);
7128 if (i <= wearable[0]) reward_tval = TV_SOFT_ARMOR;
7129 else if (i <= wearable[0] + wearable[1]) reward_tval = TV_HARD_ARMOR;
7130 else if (i <= wearable[0] + wearable[1] + wearable[2]) reward_tval = TV_DRAG_ARMOR;
7131 }
7132 else if (i <= wearable[0] + wearable[1]) reward_tval = TV_CLOAK;
7133 else if (i <= wearable[0] + wearable[1] + wearable[2]) reward_tval = (rand_int(3) ? TV_HELM : TV_CROWN);
7134 else if (i <= wearable[0] + wearable[1] + wearable[2] + wearable[3]) reward_tval = TV_GLOVES;
7135 else if (i <= wearable[0] + wearable[1] + wearable[2] + wearable[3] + wearable[4]) reward_tval = TV_BOOTS;
7136 s_printf("REWARD_CANNOT_WEAR: changed to %d\n", reward_tval);
7137 }
7138 }
7139
7140 /* of course we cannot wield trapping kits, nothing to do here */
7141 else if (tmp_obj.tval == TV_TRAPKIT) ;
7142
7143 /* for other items: */
7144 else {
7145 /* shouldn't happen, but.. */
7146 invcopy(o_ptr, lookup_kind(TV_SPECIAL, SV_CUSTOM_OBJECT));
7147 o_ptr->note = quark_add("a Cake");
7148 o_ptr->xtra1 = 15;
7149 s_printf("REWARD_CREATED: (%s) a Cake (3)\n", p_ptr->name);
7150 /* serious alternatives: digger, magic device, a set of consumables */
7151 return;
7152 }
7153 }
7154
7155 /* In case no SVAL has been defined yet:
7156 Choose a random SVAL while paying attention to maxweight limit! */
7157 if (!reward_sval) {
7158 int weapon_bpr = 0; /* try that the reward weapon does not reduce bpr compared to current bpr */
7159 bool weapon_2h = FALSE; /* make the reward weapon 2-handed if we're using 2-handed */
7160
7161 if (is_weapon(reward_tval)) { /* melee weapon */
7162 if (p_ptr->inventory[INVEN_WIELD].k_idx) {
7163 i = calc_blows_obj(Ind, &p_ptr->inventory[INVEN_WIELD]);
7164
7165 /* If player purposedly uses 2h weapon, give him one.
7166 We ignore 1.5h weapons (TR4_SHOULD2H) for now, since player might
7167 just be using such a startup weapon without deeper thought */
7168 if ((k_info[p_ptr->inventory[INVEN_WIELD].k_idx].flags4 & TR4_MUST2H)) weapon_2h = TRUE;
7169 }
7170 if (p_ptr->inventory[INVEN_ARM].k_idx && p_ptr->inventory[INVEN_ARM].tval != TV_SHIELD) j = calc_blows_obj(Ind, &p_ptr->inventory[INVEN_ARM]);
7171 if (j > i) i = j; /* for dual-wielders, use the faster one */
7172 if (!i) i = 3; /* if player doesn't hold a weapon atm (why!?) just start trying for 3 bpr */
7173 weapon_bpr = i;
7174 }
7175
7176 /* Check global variable, if some base types are forbidden */
7177 do {
7178 tries++;
7179 k_idx = 0;
7180
7181 /* rings (except speed) and amulets don't count as good so they won't be generated (see kind_is_good) */
7182 if (reward_tval != TV_AMULET && reward_tval != TV_RING) {
7183 get_obj_num_hook = kind_is_good_reward;
7184 get_obj_num_prep_tval(reward_tval, resf);
7185 } else {
7186 get_obj_num_hook = NULL;
7187 get_obj_num_prep_tval(reward_tval, resf);
7188 }
7189
7190 /* Pick a random object */
7191 /* Magic arrows from DROP_GREAT monsters are annoying.. - C. Blue */
7192 /* Added lines for the other magic ammos - the_sandman */
7193 if (great)
7194 for (i = 0; i < 20; i++) {
7195 k_idx = get_obj_num(base, resf);
7196 if (is_ammo(k_info[k_idx].tval) && k_info[k_idx].sval == SV_AMMO_MAGIC) continue;
7197 break;
7198 }
7199 else
7200 k_idx = get_obj_num(base, resf);
7201
7202 /* Prepare the object */
7203 invcopy(o_ptr, k_idx);
7204 reward_sval = o_ptr->sval;
7205
7206 /* HACK - Kollas won't pass RESF_LOWVALUE or RESF_MIDVALUE checks in apply_magic - mikaelh */
7207 if ((reward_tval == TV_CLOAK) && (reward_sval == SV_KOLLA) && ((resf & (RESF_LOWVALUE | RESF_MIDVALUE)))) {
7208 continue;
7209 }
7210
7211 /* Note that in theory the item's weight might change depending on it's
7212 apply_magic_depth outcome, we're ignoring that here for now though. */
7213
7214 /* Check for weight limit! */
7215 if (o_ptr->weight > reward_maxweight) continue;
7216
7217 /* No weapon that reduces bpr compared to what weapon the person currently holds! */
7218 if (weapon_bpr) {
7219 if (calc_blows_obj(Ind, o_ptr) < weapon_bpr) {
7220 if (tries < 70) continue; /* try hard to not lose a single bpr at first */
7221 if (weapon_bpr < 4 && tries < 90) continue; /* try to at least not lose a bpr if it drops us below 3 */
7222 if (weapon_bpr < 3) continue; /* 1 bpr is simply the worst, gotta keep trying */
7223 }
7224
7225 /* new: try to stay with 2h weapons if we're using one
7226 (except if the only available choices keep giving less bpr for some reason after 50 tries huh) */
7227 if (weapon_2h && !(k_info[k_idx].flags4 & TR4_MUST2H) && (tries < 50)) continue;
7228 }
7229
7230 if ((resf & RESF_NOHIDSM) &&
7231 (reward_tval == TV_DRAG_ARMOR) &&
7232 !sv_dsm_low(reward_sval) && !sv_dsm_mid(reward_sval))
7233 continue;
7234
7235 /* avoid super light caster armour? */
7236 if (go_heavy)
7237 switch (reward_tval) {
7238 case TV_HELM:
7239 if (reward_sval == SV_CLOTH_CAP) continue;
7240 break;
7241 case TV_SOFT_ARMOR:
7242 /* Note: we allow SV_ROBE because it could be permanence! always great to have.
7243 Could potentially add: SV_LEATHER_FROCK (3.0), SV_PAPER_ARMOR (4.0) */
7244 if (reward_sval == SV_GOWN || reward_sval == SV_TUNIC || reward_sval == SV_FROCK) continue;
7245 }
7246
7247 /* success! */
7248 break;
7249 } while (tries < 100); /* need more tries here than in place_object() because of additional weight limit check */
7250
7251 #if 0 /* Let's just take the last attempt then. We NEED a reward. */
7252 /* Note that if we run out of 'tries', the last tested object WILL be used,
7253 except if we clear k_idx now. */
7254 if (tries == 100) k_idx = 0;
7255 /* Handle failure */
7256 if (!k_idx) {
7257 invwipe(o_ptr);
7258 return;
7259 }
7260 #endif
7261
7262 } else {
7263 /* Prepare the object */
7264 invcopy(o_ptr, lookup_kind(reward_tval, reward_sval));
7265 }
7266
7267 /* debug log */
7268 s_printf("REWARD_RAW: final_choice %d, reward_tval %d, k_idx %d, tval %d, sval %d, weight %d(%d%s)\n", final_choice, reward_tval, k_idx, o_ptr->tval, o_ptr->sval, o_ptr->weight, reward_maxweight, go_heavy ? " go_heavy" : "");
7269 if (is_admin(p_ptr))
7270 msg_format(Ind, "Reward: final_choice %d, reward_tval %d, k_idx %d, tval %d, sval %d, weight %d(%d%s)", final_choice, reward_tval, k_idx, o_ptr->tval, o_ptr->sval, o_ptr->weight, reward_maxweight, go_heavy ? " go_heavy" : "");
7271
7272 /* hack - fix the shit with an ugly workaround for now (shouldn't happen anymore) */
7273 if (!o_ptr->sval) {
7274 for (i = 1; i < max_k_idx; i++)
7275 if (k_info[i].tval == reward_tval && k_info[k_idx].weight <= reward_maxweight) {
7276 reward_sval = k_info[i].sval;
7277 break;
7278 }
7279 invcopy(o_ptr, lookup_kind(reward_tval, reward_sval));
7280 s_printf("REWARD_UGLY (%d,%d)\n", o_ptr->tval, o_ptr->sval);
7281 }
7282
7283 /* apply_magic to that item, until we find a fitting one */
7284 tries = 0;
7285 i = o_ptr->k_idx;
7286 do {
7287 tries++;
7288 invwipe(o_ptr);
7289 invcopy(o_ptr, i);
7290
7291 /* Apply magic (allow artifacts) */
7292 apply_magic_depth(base, o_ptr, base, TRUE, good, great, verygreat, resf);
7293 s_printf("REWARD_REAL: final_choice %d, reward_tval %d, k_idx %d, tval %d, sval %d, weight %d(%d)\n", final_choice, reward_tval, k_idx, o_ptr->tval, o_ptr->sval, o_ptr->weight, reward_maxweight);
7294 object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
7295
7296 /* This should have already been checked in apply_magic_depth above itself,
7297 but atm it seems not to work: */
7298 if ((o_ptr->name1 == ART_RANDART) && (resf & RESF_NORANDART)) continue;
7299 if (o_ptr->name1 && (o_ptr->name1 != ART_RANDART) && (resf & RESF_NOTRUEART)) continue;
7300 if ((o_ptr->name2 && o_ptr->name2b) && (resf & RESF_NODOUBLEEGO)) continue;
7301 if ((resf & RESF_LOWSPEED) && (f1 & TR1_SPEED) && (o_ptr->bpval > 4 || o_ptr->pval > 4)) continue;
7302 if ((resf & RESF_NOHISPEED) && (f1 & TR1_SPEED) && (o_ptr->bpval > 6 || o_ptr->pval > 6)) continue;
7303 if (!(f1 & TR1_SPEED)) {
7304 if ((resf & RESF_LOWVALUE) && (object_value_real(0, o_ptr) > 35000)) continue;
7305 if ((resf & RESF_MIDVALUE) && (object_value_real(0, o_ptr) > 50000)) continue;
7306 if ((resf & RESF_NOHIVALUE) && (object_value_real(0, o_ptr) > 100000)) continue;
7307 } else {
7308 if ((resf & RESF_LOWVALUE) && (object_value_real(0, o_ptr) > 200000)) continue;
7309 if ((resf & RESF_MIDVALUE) && (object_value_real(0, o_ptr) > 200000)) continue;
7310 if ((resf & RESF_NOHIVALUE) && (object_value_real(0, o_ptr) > 250000)) continue;
7311 }
7312
7313 /* Don't generate cursed randarts.. */
7314 if (cursed_p(o_ptr)) continue;
7315
7316 if (o_ptr->name2 == EGO_COMBAT)
7317 switch (p_ptr->pclass) {
7318 case CLASS_WARRIOR:
7319 case CLASS_MIMIC:
7320 case CLASS_RANGER:
7321 case CLASS_ROGUE:
7322 case CLASS_MINDCRAFTER:
7323 case CLASS_PRIEST:
7324 case CLASS_PALADIN:
7325 case CLASS_DRUID:
7326 break;
7327 default:
7328 continue;
7329 }
7330
7331 /* analyze class (so far nothing is done here, but everything is determined by skills instead) */
7332 switch (p_ptr->pclass) {
7333 case CLASS_WARRIOR:
7334 case CLASS_ARCHER:
7335 break;
7336 case CLASS_ADVENTURER:
7337 case CLASS_SHAMAN:
7338 if ((p_ptr->stat_max[A_INT] > p_ptr->stat_max[A_WIS]) &&
7339 (o_ptr->name2 == EGO_WISDOM && !o_ptr->name2b)) continue;
7340 if ((p_ptr->stat_max[A_WIS] > p_ptr->stat_max[A_INT]) &&
7341 (o_ptr->name2 == EGO_INTELLIGENCE && !o_ptr->name2b)) continue;
7342 break;
7343 case CLASS_MAGE:
7344 case CLASS_RANGER:
7345 case CLASS_ROGUE:
7346 case CLASS_RUNEMASTER:
7347 case CLASS_MINDCRAFTER:
7348 if (o_ptr->name2 == EGO_WISDOM && !o_ptr->name2b) continue;
7349 break;
7350 case CLASS_PRIEST:
7351 case CLASS_PALADIN:
7352 case CLASS_DRUID:
7353 if (o_ptr->name2 == EGO_INTELLIGENCE && !o_ptr->name2b) continue;
7354 break;
7355 }
7356
7357 /* analyze race */
7358 if (p_ptr->prace == RACE_VAMPIRE && anti_undead(o_ptr)) continue;
7359
7360 /* Don't generate NO_MAGIC or DRAIN_MANA items if we do use magic */
7361 if (spell_choice) {
7362 if (f5 & TR5_DRAIN_MANA) continue;
7363 if (f3 & TR3_NO_MAGIC) continue;
7364 }
7365
7366 /* Don't generate mage-only benefitting reward if we don't use magic */
7367 if (!spell_choice && !o_ptr->name2b) { /* as _double ego_, it should be acceptable :-p */
7368 switch (o_ptr->name2) {
7369 //case EGO_MAGI: /* crown of magi, it's not bad for anyone actually */
7370 //case EGO_CLOAK_MAGI: /* well, it does provide speed.. */
7371 case EGO_INTELLIGENCE:
7372 case EGO_WISDOM:
7373 case EGO_BRILLIANCE:
7374 case EGO_OFTHEMAGI:
7375 case EGO_ISTARI:
7376 continue;
7377 }
7378 }
7379 /* don't generate too worthless magi-specific items,
7380 prevented by simply hacking the pval up! */
7381 else if (spell_choice) {
7382 switch (o_ptr->name2) {
7383 case EGO_INTELLIGENCE:
7384 case EGO_WISDOM:
7385 if (o_ptr->pval < 4) o_ptr->pval = 4;
7386 break;
7387 case EGO_BRILLIANCE:
7388 if (o_ptr->pval < 3) o_ptr->pval = 3;
7389 break;
7390 case EGO_OFTHEMAGI:
7391 if (o_ptr->pval < 5) o_ptr->pval = 5;
7392 break;
7393 }
7394 /* as _double ego_, it should be acceptable :-p */
7395 if (!o_ptr->name2) switch (o_ptr->name2b) {
7396 case EGO_INTELLIGENCE:
7397 case EGO_WISDOM:
7398 if (o_ptr->pval < 4) o_ptr->pval = 4;
7399 break;
7400 case EGO_BRILLIANCE:
7401 if (o_ptr->pval < 3) o_ptr->pval = 3;
7402 break;
7403 case EGO_OFTHEMAGI:
7404 if (o_ptr->pval < 5) o_ptr->pval = 5;
7405 break;
7406 }
7407 }
7408
7409 /* Don't generate (possibly expensive due to high bpval, hence passed up till here) crap */
7410 if (!o_ptr->name2b)
7411 switch (o_ptr->name2) {
7412 case EGO_CONCENTRATION:
7413 case EGO_INFRAVISION:
7414 case EGO_BEAUTY:
7415 case EGO_CHARMING: continue;
7416 default: break;
7417 }
7418
7419 /* a reward should have some value: */
7420 if (object_value_real(0, o_ptr) < 5000) continue;
7421 if (o_ptr->name2) { /* should always be true actually! just paranoia */
7422 if (e_info[o_ptr->name2].cost <= 2000) {
7423 if (o_ptr->name2b) {
7424 if (e_info[o_ptr->name2b].cost <= 2000) continue;
7425 } else continue;
7426 }
7427 }
7428
7429 /* a reward should have some use - prevent +1 speed boots! */
7430 if ((o_ptr->name2 == EGO_SPEED || o_ptr->name2b == EGO_SPEED) && o_ptr->pval == 1) continue;
7431
7432 /* specialty: for runemasters, if it's armour, make sure it resists (backlash) at least one of the elements we can cast :) */
7433 if (p_ptr->pclass == CLASS_RUNEMASTER && is_armour(o_ptr->tval)) {
7434 bool rlite = (p_ptr->s_info[SKILL_R_LITE].value > 0);
7435 bool rdark = (p_ptr->s_info[SKILL_R_DARK].value > 0);
7436 bool rnexu = (p_ptr->s_info[SKILL_R_NEXU].value > 0);
7437 bool rneth = (p_ptr->s_info[SKILL_R_NETH].value > 0);
7438 bool rchao = (p_ptr->s_info[SKILL_R_CHAO].value > 0);
7439 bool rmana = (p_ptr->s_info[SKILL_R_MANA].value > 0);
7440 bool rconf = (rlite && rdark);
7441 bool relec = (rlite && rneth);
7442 bool rfire = (rlite && rchao);
7443 bool rcold = (rdark && rneth);
7444 bool racid = (rdark && rchao);
7445 bool rpois = (rdark && rmana);
7446 bool rsoun = (rnexu && rchao);
7447 bool rshar = (rnexu && rmana);
7448 bool rdise = (rneth && rchao);
7449 u32b relem2, relem5;
7450
7451 if (p_ptr->resist_fire || p_ptr->immune_fire) rfire = FALSE;
7452 if (p_ptr->resist_cold || p_ptr->immune_cold) rcold = FALSE;
7453 if (p_ptr->resist_acid || p_ptr->immune_acid) racid = FALSE;
7454 if (p_ptr->resist_elec || p_ptr->immune_elec) relec = FALSE;
7455 if (p_ptr->resist_pois || p_ptr->immune_poison) rpois = FALSE;
7456 if (p_ptr->resist_lite) rlite = FALSE;
7457 if (p_ptr->resist_dark) rdark = FALSE;
7458 if (p_ptr->resist_nexus) rnexu = FALSE;
7459 if (p_ptr->resist_neth) rneth = FALSE;
7460 if (p_ptr->resist_chaos) rchao = rconf = FALSE;
7461 if (p_ptr->resist_conf) rconf = FALSE;
7462 if (p_ptr->resist_sound) rsoun = FALSE;
7463 if (p_ptr->resist_shard) rshar = FALSE;
7464 if (p_ptr->resist_disen) rdise = FALSE;
7465
7466 /* note: skip hard/impossible to acquire elements */
7467 relem2 = ((rlite ? TR2_RES_LITE : 0x0) | (rdark ? TR2_RES_DARK : 0x0) |
7468 (rnexu ? TR2_RES_NEXUS : 0x0) | (rneth ? TR2_RES_NETHER : 0x0) |
7469 (rchao ? TR2_RES_CHAOS : 0x0) |
7470 (rfire ? TR2_RES_FIRE | TR2_IM_FIRE : 0x0) | (rcold ? TR2_RES_COLD | TR2_IM_COLD : 0x0) |
7471 (relec ? TR2_RES_ELEC | TR2_IM_ELEC : 0x0) | (racid ? TR2_RES_ACID | TR2_IM_ACID : 0x0) |
7472 (rpois ? TR2_RES_POIS : 0x0) |
7473 (rconf ? TR2_RES_CONF | TR2_RES_CHAOS : 0x0) | (rsoun ? TR2_RES_SOUND : 0x0) |
7474 (rshar ? TR2_RES_SHARDS : 0x0) | (rdise ? TR2_RES_DISEN : 0x0));
7475 relem5 = (rpois ? TR5_IM_POISON : 0x0);
7476
7477 if ((relem2 || relem5) && !(f2 & relem2) && !(f5 & relem5)) continue;
7478 }
7479
7480 /* If the item only has high resistance, and no immunity, make sure that we don't already resist it. */
7481 if (!(f2 & (TR2_IM_FIRE | TR2_IM_COLD | TR2_IM_ACID | TR2_IM_ELEC)) && !(f5 & TR5_IM_POISON)) {
7482 int hres = 0;
7483 int pres = 0;
7484
7485 if (f2 & TR2_RES_LITE) {
7486 hres++;
7487 if (p_ptr->resist_lite) pres++;
7488 }
7489 if (f2 & TR2_RES_DARK) {
7490 hres++;
7491 if (p_ptr->resist_dark) pres++;
7492 }
7493 if (f2 & TR2_RES_NEXUS) {
7494 hres++;
7495 if (p_ptr->resist_nexus) pres++;
7496 }
7497 if (f2 & TR2_RES_NETHER) {
7498 hres++;
7499 if (p_ptr->resist_neth) pres++;
7500 }
7501 if (f2 & TR2_RES_CHAOS) {
7502 hres++;
7503 if (p_ptr->resist_chaos) pres++;
7504 }
7505 if (f2 & TR2_RES_POIS) {
7506 hres++;
7507 if (p_ptr->resist_pois) pres++;
7508 }
7509 if (f2 & TR2_RES_SOUND) {
7510 hres++;
7511 if (p_ptr->resist_sound) pres++;
7512 }
7513 if (f2 & TR2_RES_SHARDS) {
7514 hres++;
7515 if (p_ptr->resist_shard) pres++;
7516 }
7517 if (f2 & TR2_RES_DISEN) {
7518 hres++;
7519 if (p_ptr->resist_disen) pres++;
7520 }
7521
7522 if (f2 & TR2_RES_CONF) {
7523 hres++;
7524 if (p_ptr->resist_conf) pres++;
7525 }
7526 if (f2 & TR2_RES_BLIND) {
7527 hres++;
7528 if (p_ptr->resist_blind) pres++;
7529 }
7530 //if (f5 & TR5_RES_WATER) hres++;
7531 //PLASMA, MANA, TIME, FEAR
7532
7533 if (hres && pres == hres) continue;
7534 }
7535
7536 break;
7537 } while (tries < (verygreat ? 20 : 100));
7538
7539 /* more loggin' */
7540 object_desc(0, o_name, o_ptr, TRUE, 2+8+16);
7541 s_printf("REWARD_CREATED: (%s) %s\n", p_ptr->name, o_name);
7542
7543 /* Give the object to the player who is to be rewarded */
7544 /* inven_carry(Ind, o_ptr); <- not neccessarily >;) */
7545 }
7546
7547 /* shorten the process of creating a standard-parm reward */
7548 void give_reward(int Ind, u32b resf, cptr quark, int level, int discount) {
7549 object_type forge, *o_ptr = &forge;
7550 create_reward(Ind, o_ptr, 95, 95, TRUE, TRUE, resf, 3000);
7551 object_aware(Ind, o_ptr);
7552 object_known(o_ptr);
7553 if (o_ptr->tval != TV_SPECIAL) o_ptr->discount = discount;
7554 o_ptr->level = level;
7555 o_ptr->ident |= ID_MENTAL;
7556 if (quark && !o_ptr->note) o_ptr->note = quark_add(quark);
7557 inven_carry(Ind, o_ptr);
7558 }
7559
7560
7561 /*
7562 * XXX XXX XXX Do not use these hard-coded values.
7563 */
7564 #if 0 // ok so I don't use them :)
7565 #define OBJ_GOLD_LIST 480 /* First "gold" entry */
7566 #define MAX_GOLD 18 /* Number of "gold" entries */
7567 #endif // 0
7568
7569 /*
7570 * Places a treasure (Gold or Gems) at given location
7571 * The location must be a valid, empty, floor grid.
7572 */
7573 /*note: This function uses completely bad values for picking a gold 'colour' at first and should be rewritten.
7574 I added a hack that resets the colour to something feasible so not almost every high level pile is adamantite. */
7575 void place_gold(struct worldpos *wpos, int y, int x, int bonus) {
7576 int i, k_idx;
7577 s32b base;
7578 object_type forge;
7579 cave_type **zcave;
7580
7581 if (!(zcave = getcave(wpos))) return;
7582
7583 /* Paranoia -- check bounds */
7584 if (!in_bounds(y, x)) return;
7585
7586 /* not in Valinor */
7587 if (in_valinor(wpos)) return;
7588
7589 /* Require clean floor grid */
7590 // if (!cave_clean_bold(zcave, y, x)) return;
7591
7592 /* Hack -- Pick a Treasure variety */
7593 i = ((randint(object_level + 2) + 2) / 2);
7594
7595 /* Apply "extra" magic */
7596 if (rand_int(GREAT_OBJ) == 0)
7597 i += randint(object_level + 1);
7598
7599 /* Hack -- Creeping Coins only generate "themselves" */
7600 if (coin_type) i = coin_type;
7601
7602 //s_printf("pg: ol=%d,i=%d,ct=%d\n", object_level, i, coin_type);
7603 /* Do not create "illegal" Treasure Types */
7604 if (i > SV_GOLD_MAX) i = SV_GOLD_MAX;
7605
7606 k_idx = lookup_kind(TV_GOLD, i);
7607 invcopy(&forge, k_idx);
7608
7609 /* Hack -- Base coin cost */
7610 // base = k_info[OBJ_GOLD_LIST+i].cost;
7611 base = k_info[k_idx].cost;
7612
7613 /* Determine how much the treasure is "worth" */
7614 forge.pval = (base + (8L * randint(base)) + randint(8)) + bonus;
7615
7616 /* hacking this mess of an outdated function: pick a 'colour' */
7617 /* hack -- Creeping Coins only generate "themselves" */
7618 if (coin_type) {
7619 forge.sval = coin_type;
7620 forge.xtra2 = 1; //mark as "don't change colour on stacking up"
7621 } else {
7622 forge.k_idx = gold_colour(forge.pval, TRUE, FALSE);
7623 forge.sval = k_info[forge.k_idx].sval;
7624 }
7625
7626 if (opening_chest) {
7627 forge.owner = opening_chest_owner;
7628 forge.mode = opening_chest_mode;
7629 }
7630
7631 /* Drop it */
7632 drop_near(&forge, -1, wpos, y, x);
7633 }
7634
7635
7636
7637 /* Test whether The One Ring just got dropped into lava in Mt. Doom.
7638 If so, erase it and weaken Sauron for his next encounter. - C. Blue
7639
7640 A bit silly side effect: If the ring gets dropped by a monster,
7641 the same thing happens :-p.
7642
7643 (Note that an 'item crash' ie an art destroying everything below it
7644 can only happen at !wpos->wz && CAVE_ICKY ie in actual houses, so we
7645 don't need to check for it in any way.)
7646 */
7647 static bool dropped_the_one_ring(struct worldpos *wpos, cave_type *c_ptr) {
7648 /* not in Mt Doom? */
7649 dungeon_type *d_ptr = getdungeon(wpos);
7650 if (in_irondeepdive(wpos)) {
7651 if (iddc[ABS(wpos->wz)].type != DI_MT_DOOM) return FALSE;
7652 } else if (d_ptr->type != DI_MT_DOOM) return FALSE;
7653
7654 /* grid isn't lava or 'fire'? */
7655 switch (c_ptr->feat) {
7656 case FEAT_SHAL_LAVA:
7657 case FEAT_DEEP_LAVA:
7658 case FEAT_FIRE:
7659 case FEAT_GREAT_FIRE:
7660 break;
7661 default:
7662 return FALSE;
7663 }
7664
7665 /* lands safely on top of a loot pile? :-p */
7666 if (c_ptr->o_idx) return FALSE;
7667
7668 /* destroy it and weaken Sauron! */
7669 handle_art_d(ART_POWER);
7670 msg_broadcast(0, "\374\377f** \377oSauron, the Sorceror has been greatly weakened! \377f**");
7671 #ifdef USE_SOUND_2010
7672 /* :-o double sfx! */
7673 sound_floor_vol(wpos, "thunder", NULL, SFX_TYPE_MISC, 100);
7674 sound_floor_vol(wpos, "detonation", NULL, SFX_TYPE_MISC, 100);
7675 #endif
7676 if (in_irondeepdive(wpos)) {
7677 /* check if Sauron is already spawned */
7678 int k;
7679 bool found = FALSE;
7680 monster_type *m_ptr;
7681
7682 for (k = m_top - 1; k >= 0; k--) {
7683 m_ptr = &m_list[m_fast[k]];
7684 if (m_ptr->r_idx != RI_SAURON) continue;
7685
7686 found = TRUE;
7687 m_ptr->speed -= 5;
7688 m_ptr->mspeed -= 5;
7689 m_ptr->hp = (m_ptr->hp * 1) / 2;
7690 m_ptr->maxhp = (m_ptr->maxhp * 1) / 2;
7691 break;
7692 }
7693 if (!found) sauron_weakened_iddc = TRUE;
7694 } else {
7695 /* check if Sauron is already spawned */
7696 int k;
7697 bool found = FALSE;
7698 monster_type *m_ptr;
7699
7700 for (k = m_top - 1; k >= 0; k--) {
7701 m_ptr = &m_list[m_fast[k]];
7702 if (m_ptr->r_idx != RI_SAURON) continue;
7703
7704 found = TRUE;
7705 m_ptr->speed -= 5;
7706 m_ptr->mspeed -= 5;
7707 m_ptr->hp = (m_ptr->hp * 1) / 2;
7708 m_ptr->maxhp = (m_ptr->maxhp * 1) / 2;
7709 break;
7710 }
7711 if (!found) sauron_weakened = TRUE;
7712 }
7713 return TRUE;
7714 }
7715
7716 /*
7717 * Let an item 'o_ptr' fall to the ground at or near (y,x).
7718 * The initial location is assumed to be "in_bounds()".
7719 *
7720 * This function takes a parameter "chance". This is the percentage
7721 * chance that the item will "disappear" instead of drop. If the object
7722 * has been thrown, then this is the chance of disappearance on contact.
7723 *
7724 * Hack -- this function uses "chance" to determine if it should produce
7725 * some form of "description" of the drop event (under the player).
7726 *
7727 * This function should probably be broken up into a function to determine
7728 * a "drop location", and several functions to actually "drop" an object.
7729 *
7730 * XXX XXX XXX Consider allowing objects to combine on the ground.
7731 */
7732 /* XXX XXX XXX DIRTY! DIRTY! DIRTY! - Jir - */
7733 //#define DROP_KILL_NOTE /* todo: needs adjustments - see below */
7734 #define DROP_ON_STAIRS_IN_EMERGENCY
7735 s16b drop_near(object_type *o_ptr, int chance, struct worldpos *wpos, int y, int x) {
7736 int k, d, ny, nx, i, s; // , y1, x1
7737 int bs, bn;
7738 int by, bx;
7739 //int ty, tx;
7740 int o_idx = -1;
7741 int flag = 0; // 1 = normal, 2 = combine, 3 = crash
7742
7743 cave_type *c_ptr;
7744
7745 bool comb;
7746 /* for destruction checks */
7747 bool do_kill = FALSE;
7748 #ifdef DROP_KILL_NOTE
7749 bool is_potion = FALSE, plural = FALSE;
7750 cptr note_kill = NULL;
7751 #endif
7752 #ifdef DROP_ON_STAIRS_IN_EMERGENCY
7753 bool allow_stairs = FALSE;
7754 #endif
7755 u32b f1, f2, f3, f4, f5, f6, esp;
7756
7757 bool arts = artifact_p(o_ptr), crash;
7758 u16b this_o_idx, next_o_idx = 0;
7759
7760 cave_type **zcave;
7761 monster_race *r_ptr;
7762
7763
7764 if (!(zcave = getcave(wpos))) return(-1);
7765
7766 /* Handle normal "breakage" */
7767 if (!arts && magik(chance)) {
7768 /* Failure */
7769 return (-1);
7770 }
7771
7772 /* Score */
7773 bs = -1;
7774
7775 /* Picker */
7776 bn = 0;
7777
7778 /* Default */
7779 by = y;
7780 bx = x;
7781
7782 d = 0;
7783
7784 /* Scan local grids */
7785 for (i = 0; i < tdi[3]; i++) {
7786 comb = FALSE;
7787
7788 if (i >= tdi[d]) {
7789 #ifdef DROP_ON_STAIRS_IN_EMERGENCY
7790 /* New hack for vaults that have mountain separators:
7791 If player spawns in them on a staircase he took and gets disarmed right away,
7792 the weapon can't drop onto the staircase and will get erased!
7793 Similar happens for emerging from an enclosed void jump gate.
7794 So allow dropping items onto stairs in emergency cases. */
7795
7796 /* Scan once more in rad 0 and 1, but this time allow staircase grids too */
7797 if (d == 1) {
7798 if (!flag && !allow_stairs) {
7799 allow_stairs = TRUE;
7800 d = 0;
7801 i = tdi[d] - 1;
7802 continue;
7803 }
7804 allow_stairs = FALSE;
7805 }
7806 #endif
7807 d++;
7808 }
7809
7810 /* Location */
7811 ny = y + tdy[i];
7812 nx = x + tdx[i];
7813
7814 /* Skip illegal grids */
7815 if (!in_bounds(ny, nx)) continue;
7816
7817 /* Require line of sight */
7818 if (!los(wpos, y, x, ny, nx)) continue;
7819
7820 /* Obtain grid */
7821 c_ptr = &zcave[ny][nx];
7822
7823 /* Require floor space (or shallow terrain) -KMW- */
7824 // if (!(f_info[c_ptr->feat].flags1 & FF1_FLOOR)) continue;
7825 if (!cave_floor_bold(zcave, ny, nx) ||
7826 /* Usually cannot drop items on permanent features,
7827 exception for stairs/gates though in case of emergency */
7828 (cave_perma_bold(zcave, ny, nx)
7829 #ifdef DROP_ON_STAIRS_IN_EMERGENCY
7830 && !(allow_stairs && is_stair(c_ptr->feat))
7831 #endif
7832 ))
7833 continue;
7834
7835 /* not on open house doors! -
7836 added this to prevent items landing ON an open door of a list house,
7837 making it impossible to pick up the item again because the character
7838 would enter the house when trying to step onto the grid with the item. - C. Blue */
7839 if (zcave[ny][nx].feat == FEAT_HOME_OPEN) continue;
7840
7841 /* Hack: Don't drop items below immovable unkillable monsters aka the
7842 Target Dummy, so players can get their items (ammo) back - C. Blue */
7843 if (c_ptr->m_idx > 0) {
7844 r_ptr = race_inf(&m_list[c_ptr->m_idx]);
7845 if (((r_ptr->flags1 & RF1_NEVER_MOVE) ||
7846 (r_ptr->flags7 & RF7_NEVER_ACT)) &&
7847 (r_ptr->flags7 & RF7_NO_DEATH))
7848 continue;
7849 }
7850
7851 /* No traps */
7852 // if (c_ptr->t_idx) continue;
7853
7854 /* No objects */
7855 k = 0;
7856
7857 /* Scan objects in that grid */
7858 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) {
7859 object_type *j_ptr;
7860
7861 /* Acquire object */
7862 j_ptr = &o_list[this_o_idx];
7863
7864 /* Acquire next object */
7865 next_o_idx = j_ptr->next_o_idx;
7866
7867 /* Check for possible combination */
7868 if (object_similar(0, o_ptr, j_ptr, 0x4)) comb = TRUE;
7869
7870 /* Count objects */
7871 k++;
7872 }
7873
7874 /* Add new object */
7875 if (!comb) k++;
7876
7877 /* No stacking (allow combining) */
7878 // if (!testing_stack && (k > 1)) continue;
7879
7880 /* Hack -- no stacking inside houses */
7881 /* XXX this can cause 'arts crashes arts' */
7882 crash = (!wpos->wz && k > 1 && !comb && (c_ptr->info & CAVE_ICKY));
7883 if (!arts && crash) continue;
7884
7885 /* Paranoia */
7886 if (k > 99) continue;
7887
7888 /* Calculate score */
7889 s = 10000 - (d + k * 5 + (crash ? 2000 : 0));
7890
7891 /* Skip bad values */
7892 if (s < bs) continue;
7893
7894 /* New best value */
7895 if (s > bs) bn = 0;
7896
7897 /* Apply the randomizer to equivalent values */
7898 if ((++bn >= 2) && (rand_int(bn) != 0)) continue;
7899
7900 /* Keep score */
7901 bs = s;
7902
7903 /* Track it */
7904 by = ny;
7905 bx = nx;
7906
7907 /* Okay */
7908 flag = crash ? 3 : (comb ? 2 : 1);
7909 }
7910
7911 /* Poor little object */
7912 if (!flag) {
7913 /* Describe */
7914 /*object_desc(o_name, o_ptr, FALSE, 0);*/
7915
7916 /* Message */
7917 /*msg_format("The %s disappear%s.",
7918 o_name, ((o_ptr->number == 1) ? "s" : ""));*/
7919
7920 if (true_artifact_p(o_ptr)) handle_art_d(o_ptr->name1);
7921 questitem_d(o_ptr, o_ptr->number);
7922 return (-1);
7923 }
7924
7925 ny = by;
7926 nx = bx;
7927 c_ptr = &zcave[ny][nx];
7928
7929 if (o_ptr->name1 == ART_POWER && dropped_the_one_ring(wpos, c_ptr)) return -1;
7930
7931 /* some objects get destroyed by falling on certain floor type - C. Blue */
7932 object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
7933 #ifdef DROP_KILL_NOTE
7934 if (o_ptr->tval == TV_POTION) is_potion = TRUE;
7935 if (o_ptr->number > 1) plural = TRUE;
7936 #endif
7937 switch (c_ptr->feat) {
7938 case FEAT_SHAL_WATER:
7939 case FEAT_DEEP_WATER:
7940 case FEAT_GLIT_WATER:
7941 // case FEAT_WATER:
7942 // case FEAT_TAINTET_WATER:
7943 if (hates_water(o_ptr)) {
7944 do_kill = TRUE;
7945 #ifdef DROP_KILL_NOTE
7946 note_kill = (plural ? " are soaked!" : " is soaked!");
7947 #endif
7948 if (f5 & TR5_IGNORE_WATER) do_kill = FALSE;
7949 }
7950 break;
7951 case FEAT_SHAL_LAVA:
7952 case FEAT_DEEP_LAVA:
7953 case FEAT_FIRE:
7954 case FEAT_GREAT_FIRE:
7955 if (hates_fire(o_ptr)) {
7956 do_kill = TRUE;
7957 #ifdef DROP_KILL_NOTE
7958 note_kill = is_potion ? (plural ? " evaporate!" : " evaporates!") : (plural ? " burn up!" : " burns up!");
7959 #endif
7960 if (f3 & TR3_IGNORE_FIRE) do_kill = FALSE;
7961 }
7962 break;
7963 }
7964
7965 if (do_kill) {
7966 #ifdef DROP_KILL_NOTE //needs adjustments
7967 /* Effect "observed" */
7968 if (!quiet && p_ptr->obj_vis[this_o_idx]) obvious = TRUE;
7969 /* Artifacts, and other objects, get to resist */
7970 if (is_art || ignore) {
7971 /* Observe the resist */
7972 if (!quiet && p_ptr->obj_vis[this_o_idx]) {
7973 msg_format(Ind, "The %s %s unaffected!",
7974 o_name, (plural ? "are" : "is"));
7975 }
7976 /* Kill it */
7977 } else {
7978 /* Describe if needed */
7979 if (!quiet && p_ptr->obj_vis[this_o_idx] && note_kill)
7980 msg_format(Ind, "\377oThe %s%s", o_name, note_kill);
7981 /* Potions produce effects when 'shattered' */
7982 if (is_potion) (void)potion_smash_effect(who, wpos, ny, nx, o_sval);
7983 if (!quiet) everyone_lite_spot(wpos, ny, nx);
7984 }
7985 #endif
7986 if (true_artifact_p(o_ptr)) handle_art_d(o_ptr->name1); /* just paranoia here */
7987 questitem_d(o_ptr, o_ptr->number);
7988 return (-1);
7989 }
7990
7991 /* Artifact always disappears, depending on tomenet.cfg flags */
7992 /* this should be in drop_near_severe, would be cleaner sometime in the future.. */
7993 if (wpos->wz == 0) { /* Assume houses are always on surface */
7994 if (undepositable_artifact_p(o_ptr) && cfg.anti_arts_house && inside_house(wpos, nx, ny)) {
7995 // char o_name[ONAME_LEN];
7996 // object_desc(Ind, o_name, o_ptr, TRUE, 0);
7997 // msg_format(Ind, "%s fades into the air!", o_name);
7998 handle_art_d(o_ptr->name1);
7999 return (-1);
8000 }
8001 }
8002
8003 /* Scan objects in that grid for combination */
8004 if (flag == 2) for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) {
8005 object_type *q_ptr;
8006
8007 /* Acquire object */
8008 q_ptr = &o_list[this_o_idx];
8009
8010 /* Acquire next object */
8011 next_o_idx = q_ptr->next_o_idx;
8012
8013 /* Check for combination */
8014 if (object_similar(0, q_ptr, o_ptr, 0x4)) {
8015 /* Combine the items */
8016 object_absorb(0, q_ptr, o_ptr);
8017
8018 /* for player-store 'offer' check */
8019 o_idx = this_o_idx;
8020
8021 /* Done */
8022 break;
8023 }
8024 }
8025
8026 /* Successful drop */
8027 // if (flag)
8028 else {
8029 /* Assume fails */
8030 // flag = FALSE;
8031
8032 /* XXX XXX XXX */
8033
8034 // c_ptr = &zcave[ny][nx];
8035
8036 /* Crush anything under us (for artifacts) */
8037 if (flag == 3) delete_object(wpos, ny, nx, TRUE);
8038
8039
8040 #ifdef MAX_ITEMS_STACKING
8041 /* limit max stack size */
8042 if (c_ptr->o_idx &&
8043 MAX_ITEMS_STACKING != 0 &&
8044 o_list[c_ptr->o_idx].stack_pos >= MAX_ITEMS_STACKING - 1) {
8045 /* unique monster drops get priority and 'crash' all previous objects.
8046 This should be preferable over just deleting the top object, if the
8047 unique monster drops multiple objects, which is true in most cases. */
8048 #if 0 /* rough way */
8049 //TODO: better handling of unique loot: pick one normal item and destroy it, to make room for one unique boss item.
8050 if (o_ptr->note_utag &&
8051 o_list[c_ptr->o_idx].note_utag == 0) { /* hold back a bit if we'd have to destroy other unique loot;
8052 note: this ignores cases of unique loot below a normal item though. */
8053 delete_object(wpos, ny, nx, TRUE);
8054 }
8055 /* can't drop! */
8056 else
8057 #else /* more refined way */
8058 /* if we drop unique monster loot, look for a normal item and destroy it to make room */
8059 do_kill = TRUE;
8060 if (o_ptr->note_utag) {
8061 /* scan pile from top to bottom */
8062 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) {
8063 /* found a non-unique-loot item? */
8064 if (!o_list[this_o_idx].note_utag) {
8065 /* erase it */
8066 delete_object_idx(this_o_idx, TRUE);
8067 /* done */
8068 do_kill = FALSE;
8069 break;
8070 }
8071 /* Acquire next object */
8072 next_o_idx = o_list[this_o_idx].next_o_idx;
8073 }
8074 }
8075 if (do_kill)
8076 #endif
8077 {
8078 if (true_artifact_p(o_ptr)) handle_art_d(o_ptr->name1); /* just paranoia here */
8079 questitem_d(o_ptr, o_ptr->number);
8080 return (-1);
8081 }
8082 }
8083 #endif
8084
8085
8086 /* Make a new object */
8087 o_idx = o_pop();
8088
8089 /* Sigil (reset it) */
8090 if (o_ptr->sigil) {
8091 //msg_print(Ind, "The sigil fades away.");
8092 o_ptr->sigil = 0;
8093 o_ptr->sseed = 0;
8094 }
8095
8096 /* Success */
8097 if (o_idx) {
8098 /* Structure copy */
8099 o_list[o_idx] = *o_ptr;
8100
8101 /* Access */
8102 o_ptr = &o_list[o_idx];
8103
8104 /* Locate */
8105 o_ptr->iy = ny;
8106 o_ptr->ix = nx;
8107 wpcopy(&o_ptr->wpos, wpos);
8108
8109 /* reset scan_objs timer */
8110 o_ptr->marked = 0;
8111
8112 /* Keep game pieces from disappearing */
8113 if (o_ptr->tval == TV_GAME) o_ptr->marked2 = ITEM_REMOVAL_NEVER;
8114
8115 /* items dropped into a house (well or a vault
8116 on surface if such exists) are marked to not
8117 get removed by timeout check, allowing us to
8118 additionally check and delete objects on
8119 unallocated levels - C. Blue */
8120 if (o_ptr->marked2 != ITEM_REMOVAL_NEVER) {
8121 if (wpos->wz == 0 && (c_ptr->info & CAVE_ICKY)) {
8122 /* mark as 'inside a house' */
8123 o_ptr->marked2 = ITEM_REMOVAL_HOUSE;
8124 } else if (o_ptr->marked2 != ITEM_REMOVAL_DEATH_WILD &&
8125 o_ptr->marked2 != ITEM_REMOVAL_LONG_WILD) {
8126 /* clear possible previous ITEM_REMOVAL_HOUSE mark */
8127 o_ptr->marked2 = ITEM_REMOVAL_NORMAL;
8128 }
8129 }
8130
8131 /* items dropped in pvp arena are deleted quickly - C. Blue */
8132 if (wpos->wz == WPOS_PVPARENA_Z && wpos->wy == WPOS_PVPARENA_Y && wpos->wx == WPOS_PVPARENA_X)
8133 o_ptr->marked2 = ITEM_REMOVAL_QUICK;
8134
8135 #ifdef ALLOW_NR_CROSS_ITEMS
8136 /* Allow the item to be traded as long as it doesn't leave the Nether Realm - C. Blue */
8137 if (!o_ptr->owner && in_netherrealm(wpos)) o_ptr->NR_tradable = TRUE;
8138 #endif
8139
8140 /* No monster */
8141 o_ptr->held_m_idx = 0;
8142
8143 /* Build a stack */
8144 o_ptr->next_o_idx = c_ptr->o_idx;
8145 #ifdef MAX_ITEMS_STACKING
8146 if (c_ptr->o_idx && MAX_ITEMS_STACKING != 0)
8147 o_ptr->stack_pos = o_list[c_ptr->o_idx].stack_pos + 1;
8148 else
8149 #endif
8150 o_ptr->stack_pos = 0; /* first object on this grid */
8151
8152 /* Place */
8153 // c_ptr = &zcave[ny][nx];
8154 c_ptr->o_idx = o_idx;
8155
8156 /* Clear visibility flags */
8157 for (k = 1; k <= NumPlayers; k++) {
8158 /* This player cannot see it */
8159 Players[k]->obj_vis[o_idx] = FALSE;
8160 }
8161
8162 /* Note the spot */
8163 note_spot_depth(wpos, ny, nx);
8164
8165 /* Draw the spot */
8166 everyone_lite_spot(wpos, ny, nx);
8167
8168 #ifdef USE_SOUND_2010
8169 /* done in do_cmd_drop() atm */
8170 #else
8171 /*sound(SOUND_DROP);*/
8172 #endif
8173
8174 /* Mega-Hack -- no message if "dropped" by player */
8175 /* Message when an object falls under the player */
8176 /*if (chance && (ny == py) && (nx == px))
8177 {
8178 msg_print("You feel something roll beneath your feet.");
8179 }*/
8180
8181 if (chance && c_ptr->m_idx < 0) {
8182 msg_print(0 - c_ptr->m_idx, "You feel something roll beneath your feet.");
8183 }
8184
8185 /* Success */
8186 // flag = TRUE;
8187 } else /* paranoia: couldn't allocate a new object */ {
8188 if (true_artifact_p(o_ptr)) handle_art_d(o_ptr->name1);
8189 questitem_d(o_ptr, o_ptr->number);
8190 }
8191 }
8192
8193 /* Result */
8194 return (o_idx);
8195 }
8196 /* This function make the artifact disapper at once (cept randarts),
8197 * and call the normal dropping function otherwise.
8198 */
8199
8200 s16b drop_near_severe(int Ind, object_type *o_ptr, int chance, struct worldpos *wpos, int y, int x) {
8201 player_type *p_ptr = Players[Ind];
8202
8203 /* Items dropped by admins never disappear by 'time out' */
8204 if (is_admin(p_ptr)) o_ptr->marked2 = ITEM_REMOVAL_NEVER;
8205
8206 /* Artifact always disappears, depending on tomenet.cfg flags */
8207 /* hm for now we also allow ring of phasing to be traded between winners. not needed though. */
8208 if (true_artifact_p(o_ptr) && !is_admin(p_ptr) &&
8209 ((cfg.anti_arts_hoard && undepositable_artifact_p(o_ptr)) || (p_ptr->total_winner && !winner_artifact_p(o_ptr) && cfg.kings_etiquette)))
8210 //(cfg.anti_arts_hoard || (cfg.anti_arts_house && 0)) would be cleaner sometime in the future..
8211 {
8212 char o_name[ONAME_LEN];
8213 object_desc(Ind, o_name, o_ptr, TRUE, 0);
8214
8215 msg_format(Ind, "%s fades into the air!", o_name);
8216 handle_art_d(o_ptr->name1);
8217 return -1;
8218 }
8219 else return (drop_near(o_ptr, chance, wpos, y, x));
8220 }
8221
8222
8223
8224 /*
8225 * Hack -- instantiate a trap
8226 *
8227 * XXX XXX XXX This routine should be redone to reflect trap "level".
8228 * That is, it does not make sense to have spiked pits at 50 feet.
8229 * Actually, it is not this routine, but the "trap instantiation"
8230 * code, which should also check for "trap doors" on quest levels.
8231 */
8232 /* The note above is completely obsoleted. - Jir - */
8233 void pick_trap(struct worldpos *wpos, int y, int x)
8234 {
8235 // int feat;
8236 // int tries = 100;
8237
8238 cave_type **zcave;
8239 cave_type *c_ptr;
8240 struct c_special *cs_ptr;
8241 if (!(zcave = getcave(wpos))) return;
8242 c_ptr = &zcave[y][x];
8243
8244 /* Paranoia */
8245 if (!(cs_ptr = GetCS(c_ptr, CS_TRAPS))) return;
8246
8247 cs_ptr->sc.trap.found = TRUE;
8248
8249 /* Notice */
8250 note_spot_depth(wpos, y, x);
8251
8252 /* Redraw */
8253 everyone_lite_spot(wpos, y, x);
8254 }
8255
8256 /*
8257 * Divide 'stacked' wands. - Jir -
8258 * o_ptr->number is not changed here!
8259 */
8260 int divide_charged_item(object_type *o_ptr, int amt)
8261 {
8262 int charge = 0;
8263
8264 /* Paranoia */
8265 if (o_ptr->number < amt) return (-1);
8266
8267 if (o_ptr->tval == TV_WAND) {
8268 charge = (o_ptr->pval * amt) / o_ptr->number;
8269 if (amt < o_ptr->number) o_ptr->pval -= charge;
8270 }
8271
8272 return (charge);
8273 }
8274
8275
8276 /*
8277 * Describe the charges on an item in the inventory.
8278 */
8279 void inven_item_charges(int Ind, int item)
8280 {
8281 player_type *p_ptr = Players[Ind];
8282
8283 object_type *o_ptr = &p_ptr->inventory[item];
8284
8285 /* Require staff/wand */
8286 if ((o_ptr->tval != TV_STAFF) && (o_ptr->tval != TV_WAND)) return;
8287
8288 /* Require known item */
8289 if (!object_known_p(Ind, o_ptr)) return;
8290
8291 /* Multiple charges */
8292 if (o_ptr->pval != 1)
8293 {
8294 /* Print a message */
8295 msg_format(Ind, "You have %d charges remaining.", o_ptr->pval);
8296 }
8297
8298 /* Single charge */
8299 else
8300 {
8301 /* Print a message */
8302 msg_format(Ind, "You have %d charge remaining.", o_ptr->pval);
8303 }
8304 }
8305
8306
8307 /*
8308 * Describe an item in the inventory.
8309 */
8310 void inven_item_describe(int Ind, int item)
8311 {
8312 player_type *p_ptr = Players[Ind];
8313
8314 object_type *o_ptr = &p_ptr->inventory[item];
8315
8316 char o_name[ONAME_LEN];
8317
8318 /* Hack -- suppress msg */
8319 if (p_ptr->taciturn_messages) return;
8320
8321 /* Get a description */
8322 object_desc(Ind, o_name, o_ptr, TRUE, 3);
8323
8324 /* Print a message */
8325 msg_format(Ind, "You have %s.", o_name);
8326 }
8327
8328
8329 /*
8330 * Increase the "number" of an item in the inventory
8331 */
8332 void inven_item_increase(int Ind, int item, int num) {
8333 player_type *p_ptr = Players[Ind];
8334 object_type *o_ptr = &p_ptr->inventory[item];
8335
8336 /* Apply */
8337 num += o_ptr->number;
8338
8339 /* Bounds check */
8340 if (num > 255) num = 255;
8341 else if (num < 0) num = 0;
8342
8343 /* Un-apply */
8344 num -= o_ptr->number;
8345
8346 /* Change the number and weight */
8347 if (num) {
8348 /* Add the number */
8349 o_ptr->number += num;
8350
8351 /* Add the weight */
8352 p_ptr->total_weight += (num * o_ptr->weight);
8353
8354 /* Recalculate bonuses */
8355 p_ptr->update |= (PU_BONUS);
8356
8357 /* Recalculate mana XXX */
8358 p_ptr->update |= (PU_MANA);
8359
8360 /* Combine the pack */
8361 p_ptr->notice |= (PN_COMBINE);
8362
8363 /* Window stuff */
8364 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
8365 }
8366
8367 /* If losing quest items, the quest goal might get unset again! */
8368 if ((p_ptr->quest_any_r || p_ptr->quest_any_r_target) && num < 0) quest_check_ungoal_r(Ind, o_ptr, -num);
8369 }
8370
8371
8372 /*
8373 * Erase an inventory slot if it has no more items
8374 * WARNING: Since this slides down following items, DON'T use this in a loop that
8375 * processes items and goes from lower value upwards to higher value if you don't
8376 * intend that result for some reason!! - C. Blue
8377 */
8378 bool inven_item_optimize(int Ind, int item)
8379 {
8380 player_type *p_ptr = Players[Ind];
8381
8382 object_type *o_ptr = &p_ptr->inventory[item];
8383
8384 /* Only optimize real items */
8385 if (!o_ptr->k_idx) {
8386 invwipe(o_ptr); /* hack just for paranoia: make sure it's erased */
8387 return (FALSE);
8388 }
8389
8390 /* Only optimize empty items */
8391 if (o_ptr->number) return (FALSE);
8392
8393 /* The item is in the pack */
8394 if (item < INVEN_WIELD)
8395 {
8396 int i;
8397
8398 /* One less item */
8399 p_ptr->inven_cnt--;
8400
8401 /* Slide everything down */
8402 for (i = item; i < INVEN_PACK; i++)
8403 {
8404 /* Structure copy */
8405 p_ptr->inventory[i] = p_ptr->inventory[i+1];
8406 }
8407
8408 /* Update inventory indeces - mikaelh */
8409 inven_index_erase(Ind, item);
8410 inven_index_slide(Ind, item + 1, -1, INVEN_PACK);
8411
8412 /* Erase the "final" slot */
8413 invwipe(&p_ptr->inventory[i]);
8414 }
8415
8416 /* The item is being wielded */
8417 else
8418 {
8419 /* One less item */
8420 p_ptr->equip_cnt--;
8421
8422 /* Erase the empty slot */
8423 invwipe(&p_ptr->inventory[item]);
8424
8425 /* Recalculate bonuses */
8426 p_ptr->update |= (PU_BONUS);
8427
8428 /* Recalculate torch */
8429 p_ptr->update |= (PU_TORCH);
8430
8431 /* Recalculate mana XXX */
8432 p_ptr->update |= (PU_MANA);
8433 }
8434
8435 /* Window stuff */
8436 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
8437
8438 return (TRUE);
8439 }
8440
8441
8442 /*
8443 * Describe the charges on an item on the floor.
8444 */
8445 void floor_item_charges(int item)
8446 {
8447 object_type *o_ptr = &o_list[item];
8448
8449 /* Require staff/wand */
8450 if ((o_ptr->tval != TV_STAFF) && (o_ptr->tval != TV_WAND)) return;
8451
8452 /* Require known item */
8453 /*if (!object_known_p(o_ptr)) return;*/
8454
8455 /* Multiple charges */
8456 if (o_ptr->pval != 1)
8457 {
8458 /* Print a message */
8459 /*msg_format("There are %d charges remaining.", o_ptr->pval);*/
8460 }
8461
8462 /* Single charge */
8463 else
8464 {
8465 /* Print a message */
8466 /*msg_format("There is %d charge remaining.", o_ptr->pval);*/
8467 }
8468 }
8469
8470
8471
8472 /*
8473 * Describe an item in the inventory.
8474 */
8475 void floor_item_describe(int item)
8476 {
8477 /* Get a description */
8478 /*object_desc(o_name, o_ptr, TRUE, 3);*/
8479
8480 /* Print a message */
8481 /*msg_format("You see %s.", o_name);*/
8482 }
8483
8484
8485 /*
8486 * Increase the "number" of an item on the floor
8487 */
8488 void floor_item_increase(int item, int num)
8489 {
8490 object_type *o_ptr = &o_list[item];
8491
8492 /* Apply */
8493 num += o_ptr->number;
8494
8495 /* Bounds check */
8496 if (num > 255) num = 255;
8497 else if (num < 0) num = 0;
8498
8499 /* Un-apply */
8500 num -= o_ptr->number;
8501
8502 /* Change the number */
8503 o_ptr->number += num;
8504 }
8505
8506
8507 /*
8508 * Optimize an item on the floor (destroy "empty" items)
8509 */
8510 void floor_item_optimize(int item)
8511 {
8512 object_type *o_ptr = &o_list[item];
8513
8514 /* Paranoia -- be sure it exists */
8515 if (!o_ptr->k_idx) return;
8516
8517 /* Only optimize empty items */
8518 if (o_ptr->number) return;
8519
8520 /* Delete it */
8521 delete_object_idx(item, TRUE);
8522 }
8523
8524
8525 /*
8526 * Inscribe the items automatically. - Jir -
8527 * if 'flags' is non-0, overwrite existing inscriptions.
8528 *
8529 * TODO: inscribe item's power like {+StCo[FiAc;FASI}
8530 */
8531 void auto_inscribe(int Ind, object_type *o_ptr, int flags)
8532 {
8533 player_type *p_ptr = Players[Ind];
8534 #if 0
8535 char c[] = "@m ";
8536 #endif
8537
8538 if (!o_ptr->tval) return;
8539
8540 /* skip inscribed items */
8541 if (!flags && o_ptr->note &&
8542 strcmp(quark_str(o_ptr->note), "on sale") &&
8543 strcmp(quark_str(o_ptr->note), "stolen"))
8544 return;
8545
8546 if (!p_ptr->obj_aware[o_ptr->k_idx]) return;
8547
8548 if (o_ptr->tval == TV_SCROLL &&
8549 o_ptr->sval == SV_SCROLL_WORD_OF_RECALL) {
8550 o_ptr->note = quark_add("@r3@R");
8551 return;
8552 } else if (o_ptr->tval == TV_ROD &&
8553 o_ptr->sval == SV_ROD_RECALL) {
8554 o_ptr->note = quark_add("@z3@R");
8555 return;
8556 }
8557 else if (o_ptr->tval == TV_SCROLL) {
8558 if (o_ptr->sval == SV_SCROLL_PHASE_DOOR) {
8559 o_ptr->note = quark_add("@r1");
8560 return;
8561 }
8562 if (o_ptr->sval == SV_SCROLL_TELEPORT) {
8563 o_ptr->note = quark_add("@r2");
8564 return;
8565 }
8566 if (o_ptr->sval == SV_SCROLL_IDENTIFY) {
8567 o_ptr->note = quark_add("@r5");//@r5!X
8568 return;
8569 }
8570 if (o_ptr->sval == SV_SCROLL_TRAP_DOOR_DESTRUCTION) {
8571 o_ptr->note = quark_add("@r8");
8572 return;
8573 }
8574 if (o_ptr->sval == SV_SCROLL_MAPPING) {
8575 o_ptr->note = quark_add("@r9");
8576 return;
8577 }
8578 if (o_ptr->sval == SV_SCROLL_SATISFY_HUNGER) {
8579 o_ptr->note = quark_add("@r0");
8580 return;
8581 }
8582 }
8583 else if (o_ptr->tval == TV_POTION) {
8584 if (o_ptr->sval == SV_POTION_HEALING) {
8585 o_ptr->note = quark_add("@q1");
8586 return;
8587 }
8588 if (o_ptr->sval == SV_POTION_SPEED) {
8589 o_ptr->note = quark_add("@q2");
8590 return;
8591 }
8592 if (o_ptr->sval == SV_POTION_RESISTANCE) {
8593 o_ptr->note = quark_add("@q3");
8594 return;
8595 }
8596 if (o_ptr->sval == SV_POTION_RESTORE_EXP) {
8597 o_ptr->note = quark_add("@q4");
8598 return;
8599 }
8600 }
8601
8602 #if 0 /* disabled till new spell system is done */
8603 if (!is_realm_book(o_ptr) && o_ptr->tval != TV_BOOK) return;
8604
8605 /* XXX though it's ok with 'm' for everything.. */
8606 c[2] = o_ptr->sval +1 +48;
8607 o_ptr->note = quark_add(c);
8608 #endif
8609 }
8610
8611
8612
8613 /*
8614 * Check if we have space for an item in the pack without overflow
8615 */
8616 bool inven_carry_okay(int Ind, object_type *o_ptr, byte tolerance)
8617 {
8618 player_type *p_ptr = Players[Ind];
8619
8620 int i;
8621
8622 /* Empty slot? */
8623 if (p_ptr->inven_cnt < INVEN_PACK) return (TRUE);
8624
8625 /* Similar slot? */
8626 for (i = 0; i < INVEN_PACK; i++)
8627 {
8628 /* Get that item */
8629 object_type *j_ptr = &p_ptr->inventory[i];
8630
8631 /* Check if the two items can be combined */
8632 if (object_similar(Ind, j_ptr, o_ptr, tolerance)) return (TRUE);
8633 }
8634
8635 /* Hack -- try quiver slot (see inven_carry) */
8636 // if (object_similar(Ind, &p_ptr->inventory[INVEN_AMMO], o_ptr, 0x0)) return (TRUE);
8637
8638 /* Nope */
8639 return (FALSE);
8640 }
8641
8642
8643 /*
8644 * Add an item to the players inventory, and return the slot used.
8645 *
8646 * If the new item can combine with an existing item in the inventory,
8647 * it will do so, using "object_similar()" and "object_absorb()", otherwise,
8648 * the item will be placed into the "proper" location in the inventory.
8649 *
8650 * This function can be used to "over-fill" the player's pack, but only
8651 * once, and such an action must trigger the "overflow" code immediately.
8652 * Note that when the pack is being "over-filled", the new item must be
8653 * placed into the "overflow" slot, and the "overflow" must take place
8654 * before the pack is reordered, but (optionally) after the pack is
8655 * combined. This may be tricky. See "dungeon.c" for info.
8656 */
8657 s16b inven_carry(int Ind, object_type *o_ptr) {
8658 player_type *p_ptr = Players[Ind];
8659
8660 int i, j, k;
8661 int n = -1;
8662
8663 object_type *j_ptr;
8664 u32b f1 = 0, f2 = 0, f3 = 0, f4 = 0, f5, f6 = 0, esp = 0;
8665
8666 /* Check for combining */
8667 for (j = 0; j < INVEN_PACK; j++) {
8668 j_ptr = &p_ptr->inventory[j];
8669
8670 /* Skip empty items */
8671 if (!j_ptr->k_idx) continue;
8672
8673 /* Hack -- track last item */
8674 n = j;
8675
8676 /* Check if the two items can be combined */
8677 if (object_similar(Ind, j_ptr, o_ptr, 0x0)) {
8678 /* Check whether this item was requested by an item-retrieval quest.
8679 Note about quest_credited check: inven_carry() is also called by carry(),
8680 resulting in double crediting otherwise! */
8681 if (p_ptr->quest_any_r_within_target && !o_ptr->quest_credited) quest_check_goal_r(Ind, o_ptr);
8682
8683 /* Combine the items */
8684 object_absorb(Ind, j_ptr, o_ptr);
8685
8686 /* Increase the weight */
8687 p_ptr->total_weight += (o_ptr->number * o_ptr->weight);
8688
8689 /* Recalculate bonuses */
8690 p_ptr->update |= (PU_BONUS);
8691
8692 /* Window stuff */
8693 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
8694
8695 /* Success */
8696 p_ptr->inventory[j].auto_insc = TRUE;
8697 #ifdef USE_SOUND_2010
8698 sound_item(Ind, o_ptr->tval, o_ptr->sval, "pickup_");
8699 #endif
8700 return (j);
8701 }
8702 }
8703
8704
8705 /* Paranoia */
8706 if (p_ptr->inven_cnt > INVEN_PACK) return (-1);
8707
8708
8709 /* Find an empty slot */
8710 for (j = 0; j < INVEN_PACK; j++) {
8711 j_ptr = &p_ptr->inventory[j];
8712
8713 /* Use it if found */
8714 if (!j_ptr->k_idx) break;
8715 }
8716
8717 /* Check if if the overflow slot is already occupied */
8718 if (j == INVEN_PACK && p_ptr->inventory[INVEN_PACK].k_idx) {
8719 /* Force a pack overflow now to clear the overflow slot */
8720 s_printf("WARNING: Forcing a pack overflow for player %s.\n", p_ptr->name);
8721 pack_overflow(Ind);
8722 }
8723
8724 /* Use that slot */
8725 i = j;
8726
8727
8728 /* Hack -- pre-reorder the pack */
8729 if (i < INVEN_PACK) {
8730 s64b o_value, j_value;
8731
8732 /* Get the "value" of the item */
8733 o_value = object_value(Ind, o_ptr);
8734
8735 /* Scan every occupied slot */
8736 for (j = 0; j < INVEN_PACK; j++) {
8737 j_ptr = &p_ptr->inventory[j];
8738
8739 /* Use empty slots */
8740 if (!j_ptr->k_idx) break;
8741
8742 /* Objects sort by decreasing type */
8743 if (o_ptr->tval > j_ptr->tval) break;
8744 if (o_ptr->tval < j_ptr->tval) continue;
8745
8746 /* Hack: Don't sort ammo any further, to allow players
8747 a custom order of usage for !L inscription - C. Blue */
8748 if (is_ammo(o_ptr->tval)) continue;
8749
8750 /* Non-aware (flavored) items always come last */
8751 if (!object_aware_p(Ind, o_ptr)) continue;
8752 if (!object_aware_p(Ind, j_ptr)) break;
8753
8754 /* Objects sort by increasing sval */
8755 if (o_ptr->sval < j_ptr->sval) break;
8756 if (o_ptr->sval > j_ptr->sval) continue;
8757
8758 /* Level 0 items owned by the player come first */
8759 if (o_ptr->level == 0 && o_ptr->owner == p_ptr->id && j_ptr->level != 0) break;
8760 if (j_ptr->level == 0 && j_ptr->owner == p_ptr->id && o_ptr->level != 0) continue;
8761
8762 /* Level 0 items owned by other players always come last */
8763 if (o_ptr->level == 0 && o_ptr->owner && o_ptr->owner != p_ptr->id && !(j_ptr->level == 0 && j_ptr->owner && j_ptr->owner != p_ptr->id)) continue;
8764 if (j_ptr->level == 0 && j_ptr->owner && j_ptr->owner != p_ptr->id && !(o_ptr->level == 0 && o_ptr->owner && o_ptr->owner != p_ptr->id)) break;
8765
8766 /* Unidentified objects always come last */
8767 if (!object_known_p(Ind, o_ptr)) continue;
8768 if (!object_known_p(Ind, j_ptr)) break;
8769
8770 /* Determine the "value" of the pack item */
8771 j_value = object_value(Ind, j_ptr);
8772
8773 /* Objects sort by decreasing value */
8774 if (o_value > j_value) break;
8775 if (o_value < j_value) continue;
8776 }
8777
8778 /* Use that slot */
8779 i = j;
8780
8781 /* Structure slide (make room) */
8782 for (k = n; k >= i; k--) {
8783 /* Hack -- Slide the item */
8784 p_ptr->inventory[k+1] = p_ptr->inventory[k];
8785 }
8786
8787 /* Update inventory indeces - mikaelh */
8788 inven_index_slide(Ind, i, 1, n);
8789
8790 /* Paranoia -- Wipe the new slot */
8791 invwipe(&p_ptr->inventory[i]);
8792 }
8793
8794 /* Check whether this item was requested by an item-retrieval quest
8795 Note about quest_credited check: inven_carry() is also called by carry(),
8796 resulting in double crediting otherwise! */
8797 if (p_ptr->quest_any_r_within_target && !o_ptr->quest_credited) quest_check_goal_r(Ind, o_ptr);
8798
8799 if (!o_ptr->owner && !p_ptr->admin_dm) {
8800 o_ptr->owner = p_ptr->id;
8801 o_ptr->mode = p_ptr->mode;
8802 if (true_artifact_p(o_ptr)) determine_artifact_timeout(o_ptr->name1, &o_ptr->wpos); /* paranoia? */
8803 }
8804
8805 /* Auto id ? */
8806 if (p_ptr->auto_id) {
8807 object_aware(Ind, o_ptr);
8808 object_known(o_ptr);
8809 }
8810
8811 /* Auto-inscriber */
8812 #ifdef AUTO_INSCRIBER
8813 if (p_ptr->auto_inscribe) auto_inscribe(Ind, o_ptr, 0);
8814 #endif
8815
8816 object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
8817
8818 /* Auto Curse */
8819 if (f3 & TR3_AUTO_CURSE) {
8820 /* The object recurse itself ! */
8821 if (!(o_ptr->ident & ID_CURSED)) {
8822 o_ptr->ident |= ID_CURSED;
8823 o_ptr->ident |= ID_SENSE | ID_SENSED_ONCE;
8824 note_toggle_cursed(o_ptr, TRUE);
8825 }
8826 }
8827
8828 /* Structure copy to insert the new item */
8829 p_ptr->inventory[i] = (*o_ptr);
8830
8831 /* Forget the old location */
8832 p_ptr->inventory[i].iy = p_ptr->inventory[i].ix = 0;
8833 p_ptr->inventory[i].wpos.wx = 0;
8834 p_ptr->inventory[i].wpos.wy = 0;
8835 p_ptr->inventory[i].wpos.wz = 0;
8836 /* Clean out unused fields */
8837 p_ptr->inventory[i].next_o_idx = 0;
8838 p_ptr->inventory[i].held_m_idx = 0;
8839
8840
8841 /* Increase the weight, prepare to redraw */
8842 p_ptr->total_weight += (o_ptr->number * o_ptr->weight);
8843
8844 /* Count the items */
8845 p_ptr->inven_cnt++;
8846
8847 /* Recalculate bonuses */
8848 p_ptr->update |= (PU_BONUS);
8849
8850 /* Reorder pack */
8851 p_ptr->notice |= (PN_REORDER);
8852
8853 /* Window stuff */
8854 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
8855
8856 /* Return the slot */
8857 p_ptr->inventory[i].auto_insc = TRUE;
8858
8859 #ifdef USE_SOUND_2010
8860 sound_item(Ind, o_ptr->tval, o_ptr->sval, "pickup_");
8861 #endif
8862
8863 return (i);
8864 }
8865
8866
8867
8868
8869 /*
8870 * Combine items in the pack
8871 *
8872 * Note special handling of the "overflow" slot
8873 */
8874 void combine_pack(int Ind) {
8875 player_type *p_ptr = Players[Ind];
8876
8877 int i, j, k;
8878
8879 object_type *o_ptr;
8880 object_type *j_ptr;
8881
8882 bool flag = FALSE;
8883
8884
8885 /* Combine the pack (backwards) */
8886 for (i = INVEN_PACK; i > 0; i--) {
8887 /* Get the item */
8888 o_ptr = &p_ptr->inventory[i];
8889
8890 /* Skip empty items */
8891 if (!o_ptr->k_idx) continue;
8892
8893
8894 /* Auto id ? */
8895 if (p_ptr->auto_id) {
8896 object_aware(Ind, o_ptr);
8897 object_known(o_ptr);
8898
8899 /* Window stuff */
8900 p_ptr->window |= (PW_INVEN | PW_EQUIP);
8901 }
8902
8903 /* Scan the items above that item */
8904 for (j = 0; j < i; j++) {
8905 /* Get the item */
8906 j_ptr = &p_ptr->inventory[j];
8907
8908 /* Skip empty items */
8909 if (!j_ptr->k_idx) continue;
8910
8911 /* Can we drop "o_ptr" onto "j_ptr"? */
8912 if (object_similar(Ind, j_ptr, o_ptr, p_ptr->current_force_stack - 1 == i ? 0x2 : 0x0)) {
8913 /* clear if used */
8914 if (p_ptr->current_force_stack - 1 == i) p_ptr->current_force_stack = 0;
8915
8916 /* Take note */
8917 flag = TRUE;
8918
8919 /* Add together the item counts */
8920 object_absorb(Ind, j_ptr, o_ptr);
8921
8922 /* One object is gone */
8923 p_ptr->inven_cnt--;
8924
8925 /* Slide everything down */
8926 for (k = i; k < INVEN_PACK; k++) {
8927 /* Structure copy */
8928 p_ptr->inventory[k] = p_ptr->inventory[k+1];
8929 }
8930
8931 /* Update inventory indeces - mikaelh */
8932 inven_index_move(Ind, j, i);
8933 inven_index_slide(Ind, i + 1, -1, INVEN_PACK);
8934
8935 /* Erase the "final" slot */
8936 invwipe(&p_ptr->inventory[k]);
8937
8938 /* Window stuff */
8939 p_ptr->window |= (PW_INVEN | PW_EQUIP);
8940
8941 if (p_ptr->inventory[j].auto_insc) {
8942 p_ptr->inventory[i].auto_insc = TRUE;
8943 p_ptr->inventory[j].auto_insc = FALSE;
8944 }
8945
8946 /* Done */
8947 break;
8948 }
8949 }
8950 }
8951
8952 /* Message */
8953 if (flag) msg_print(Ind, "You combine some items in your pack.");
8954
8955 /* clear */
8956 if (p_ptr->current_force_stack) {
8957 if (!flag) msg_print(Ind, "Nothing to combine.");
8958 p_ptr->current_force_stack = 0;
8959 }
8960 }
8961
8962
8963 /*
8964 * Reorder items in the pack
8965 *
8966 * Note special handling of the "overflow" slot
8967 *
8968 * Note special handling of empty slots XXX XXX XXX XXX
8969 */
8970 void reorder_pack(int Ind) {
8971 player_type *p_ptr = Players[Ind];
8972
8973 int i, j, k;
8974
8975 s64b o_value;
8976 s64b j_value;
8977
8978 object_type *o_ptr;
8979 object_type *j_ptr;
8980
8981 object_type temp;
8982
8983 bool flag = FALSE;
8984
8985
8986 /* Re-order the pack (forwards) */
8987 for (i = 0; i < INVEN_PACK; i++) {
8988 /* Mega-Hack -- allow "proper" over-flow */
8989 if ((i == INVEN_PACK) && (p_ptr->inven_cnt == INVEN_PACK)) break;
8990
8991 /* Get the item */
8992 o_ptr = &p_ptr->inventory[i];
8993
8994 /* Skip empty slots */
8995 if (!o_ptr->k_idx) continue;
8996
8997 /* Get the "value" of the item */
8998 o_value = object_value(Ind, o_ptr);
8999
9000 /* Scan every occupied slot */
9001 for (j = 0; j < INVEN_PACK; j++) {
9002 /* Get the item already there */
9003 j_ptr = &p_ptr->inventory[j];
9004
9005 /* Use empty slots */
9006 if (!j_ptr->k_idx) break;
9007
9008 /* Objects sort by decreasing type */
9009 if (o_ptr->tval > j_ptr->tval) break;
9010 if (o_ptr->tval < j_ptr->tval) continue;
9011
9012 /* Hack: Don't sort ammo any further, to allow players
9013 a custom order of usage for !L inscription - C. Blue */
9014 if (is_ammo(o_ptr->tval)) continue;
9015
9016 /* Non-aware (flavored) items always come last */
9017 if (!object_aware_p(Ind, o_ptr)) continue;
9018 if (!object_aware_p(Ind, j_ptr)) break;
9019
9020 /* Objects sort by increasing sval */
9021 if (o_ptr->sval < j_ptr->sval) break;
9022 if (o_ptr->sval > j_ptr->sval) continue;
9023
9024 /* Level 0 items owned by the player come first */
9025 if (o_ptr->level == 0 && o_ptr->owner == p_ptr->id && j_ptr->level != 0) break;
9026 if (j_ptr->level == 0 && j_ptr->owner == p_ptr->id && o_ptr->level != 0) continue;
9027
9028 /* Level 0 items owned by other players always come last */
9029 if (o_ptr->level == 0 && o_ptr->owner && o_ptr->owner != p_ptr->id && !(j_ptr->level == 0 && j_ptr->owner && j_ptr->owner != p_ptr->id)) continue;
9030 if (j_ptr->level == 0 && j_ptr->owner && j_ptr->owner != p_ptr->id && !(o_ptr->level == 0 && o_ptr->owner && o_ptr->owner != p_ptr->id)) break;
9031
9032 /* Unidentified objects always come last */
9033 if (!object_known_p(Ind, o_ptr)) continue;
9034 if (!object_known_p(Ind, j_ptr)) break;
9035
9036 /* Determine the "value" of the pack item */
9037 j_value = object_value(Ind, j_ptr);
9038
9039 /* Objects sort by decreasing value */
9040 if (o_value > j_value) break;
9041 if (o_value < j_value) continue;
9042 }
9043
9044 /* Never move down */
9045 if (j >= i) continue;
9046
9047 /* Take note */
9048 flag = TRUE;
9049
9050 /* Save the moving item */
9051 temp = p_ptr->inventory[i];
9052
9053 /* Structure slide (make room) */
9054 for (k = i; k > j; k--) {
9055 /* Slide the item */
9056 p_ptr->inventory[k] = p_ptr->inventory[k-1];
9057 }
9058
9059 /* Insert the moved item */
9060 p_ptr->inventory[j] = temp;
9061
9062 /* Update inventory indeces - mikaelh */
9063 inven_index_slide(Ind, j, 1, i - 1);
9064 inven_index_move(Ind, i, j);
9065
9066 /* Window stuff */
9067 p_ptr->window |= (PW_INVEN | PW_EQUIP);
9068
9069 if (p_ptr->inventory[i].auto_insc) {
9070 p_ptr->inventory[j].auto_insc = TRUE;
9071 p_ptr->inventory[i].auto_insc = FALSE;
9072 }
9073 }
9074
9075 /* Message */
9076 if (flag) msg_print(Ind, "You reorder some items in your pack.");
9077 }
9078
9079
9080
9081
9082 /*
9083 * Hack -- process the objects
9084 */
9085 /* TODO: terrain effects (lava burns scrolls etc) */
9086 void process_objects(void)
9087 {
9088 int i, k;
9089
9090 object_type *o_ptr;
9091
9092
9093 /* Hack -- only every ten game turns */
9094 // if ((turn % 10) != 5) return;
9095
9096
9097 /* Process objects */
9098 for (k = o_top - 1; k >= 0; k--) {
9099 /* Access index */
9100 i = o_fast[k];
9101
9102 /* Access object */
9103 o_ptr = &o_list[i];
9104
9105 /* Excise dead objects */
9106 if (!o_ptr->k_idx) {
9107 /* Excise it */
9108 o_fast[k] = o_fast[--o_top];
9109
9110 /* Skip */
9111 continue;
9112 }
9113
9114 /* Recharge rods on the ground */
9115 if ((o_ptr->tval == TV_ROD) && (o_ptr->pval)) o_ptr->pval--;
9116
9117 /* Recharge rod trap kits */
9118 if (o_ptr->tval == TV_TRAPKIT && o_ptr->sval == SV_TRAPKIT_DEVICE &&
9119 o_ptr->timeout) o_ptr->timeout--;
9120 }
9121 }
9122
9123 /*
9124 * Set the "o_idx" fields in the cave array to correspond
9125 * to the objects in the "o_list".
9126 */
9127 void setup_objects(void)
9128 {
9129 int i;
9130 cave_type **zcave;
9131 object_type *o_ptr;
9132
9133 for (i = 0; i < o_max; i++)
9134 {
9135 o_ptr = &o_list[i];
9136
9137 /* Skip dead objects */
9138 if (!o_ptr->k_idx) continue;
9139
9140 /* Skip objects on depths that aren't allocated */
9141 if (!(zcave = getcave(&o_ptr->wpos))) continue;
9142
9143 /* Skip carried objects */
9144 if (o_ptr->held_m_idx) continue;
9145
9146 // if (!in_bounds2(&o_ptr->wpos, o_ptr->iy, o_ptr->ix)) continue;
9147 if (in_bounds_array(o_ptr->iy, o_ptr->ix))
9148
9149 #if 0 // excise_object_idx() should do this
9150 /* Build the stack */
9151 if (j = zcave[o_ptr->iy][o_ptr->ix].o_idx)
9152 o_ptr->next_o_idx = j;
9153 else o_ptr->next_o_idx = 0;
9154 #endif // 0
9155
9156 /* Set the o_idx correctly */
9157 zcave[o_ptr->iy][o_ptr->ix].o_idx = i;
9158 }
9159 }
9160
9161
9162
9163 /*
9164 * Wipe an object clean.
9165 */
9166 void object_wipe(object_type *o_ptr) {
9167 /* Wipe the structure */
9168 o_ptr = WIPE(o_ptr, object_type);
9169 }
9170
9171
9172 /*
9173 * Prepare an object based on an existing object: dest, src
9174 */
9175 void object_copy(object_type *o_ptr, object_type *j_ptr) {
9176 /* Copy the structure */
9177 COPY(o_ptr, j_ptr, object_type);
9178 }
9179
9180
9181 /* ToME function -- not used for now */
9182 #if 0
9183 /*
9184 * Let the floor carry an object
9185 */
9186 s16b floor_carry(worldpos *wpos, int y, int x, object_type *j_ptr)
9187 {
9188 int n = 0;
9189
9190 s16b o_idx;
9191
9192 s16b this_o_idx, next_o_idx = 0;
9193
9194
9195 /* Scan objects in that grid for combination */
9196 for (this_o_idx = cave[y][x].o_idx; this_o_idx; this_o_idx = next_o_idx)
9197 {
9198 object_type *o_ptr;
9199
9200 /* Acquire object */
9201 o_ptr = &o_list[this_o_idx];
9202
9203 /* Acquire next object */
9204 next_o_idx = o_ptr->next_o_idx;
9205
9206 /* Check for combination */
9207 if (object_similar(o_ptr, j_ptr, 0x0))
9208 {
9209 /* Combine the items */
9210 object_absorb(o_ptr, j_ptr);
9211
9212 /* Result */
9213 return (this_o_idx);
9214 }
9215
9216 /* Count objects */
9217 n++;
9218 }
9219
9220
9221 /* Make an object */
9222 o_idx = o_pop();
9223
9224 /* Success */
9225 if (o_idx)
9226 {
9227 object_type *o_ptr;
9228
9229 /* Acquire object */
9230 o_ptr = &o_list[o_idx];
9231
9232 /* Structure Copy */
9233 object_copy(o_ptr, j_ptr);
9234
9235 /* Location */
9236 o_ptr->iy = y;
9237 o_ptr->ix = x;
9238
9239 /* Forget monster */
9240 o_ptr->held_m_idx = 0;
9241
9242 /* Build a stack */
9243 o_ptr->next_o_idx = cave[y][x].o_idx;
9244
9245 /* Place the object */
9246 cave[y][x].o_idx = o_idx;
9247
9248 /* Notice */
9249 note_spot(y, x);
9250
9251 /* Redraw */
9252 lite_spot(y, x);
9253 }
9254
9255 /* Result */
9256 return (o_idx);
9257 }
9258 #endif // 0
9259
9260 /* Easier unified artifact handling */
9261 void handle_art_i(int aidx) {
9262 if (a_info[aidx].cur_num < 255) a_info[aidx].cur_num++;
9263 a_info[aidx].known = TRUE;
9264 }
9265 void handle_art_ipara(int aidx) { /* only for paranoia.. could be removed basically (except for the known=TRUE part) */
9266 if (!a_info[aidx].cur_num && (a_info[aidx].cur_num < 255)) a_info[aidx].cur_num++;
9267 a_info[aidx].known = TRUE;
9268 }
9269 void handle_art_inum(int aidx) {
9270 if (a_info[aidx].cur_num < 255) a_info[aidx].cur_num++;
9271 }
9272 void handle_art_inumpara(int aidx) {
9273 if (!a_info[aidx].cur_num && (a_info[aidx].cur_num < 255)) a_info[aidx].cur_num++;
9274 }
9275 void handle_art_dnum(int aidx) {
9276 if (a_info[aidx].cur_num > 0) a_info[aidx].cur_num--;
9277 #ifdef FLUENT_ARTIFACT_RESETS
9278 if (a_info[aidx].cur_num == 0) a_info[aidx].timeout = 0;
9279 #endif
9280 }
9281 void handle_art_d(int aidx) {
9282 if (a_info[aidx].cur_num > 0) {
9283 a_info[aidx].cur_num--;
9284 if (!a_info[aidx].cur_num) {
9285 a_info[aidx].known = FALSE;
9286 #ifdef FLUENT_ARTIFACT_RESETS
9287 a_info[aidx].timeout = 0;
9288 #endif
9289 }
9290 } else {
9291 a_info[aidx].cur_num = 0;
9292 a_info[aidx].known = FALSE;//semi-paranoia: fixes old arts from before fluent reset mechanism!
9293 #ifdef FLUENT_ARTIFACT_RESETS
9294 a_info[aidx].timeout = 0;
9295 #endif
9296 }
9297 }
9298
9299 /* Check whether an item causes HP drain on an undead player (vampire) who wears/wields it */
9300 bool anti_undead(object_type *o_ptr) {
9301 u32b f1, f2, f3, f4, f5, f6, esp;
9302 int l = 0;
9303
9304 if (cursed_p(o_ptr)) return(FALSE);
9305
9306 /* hack: it's carried by the wight-king! */
9307 if (o_ptr->name1 == ART_STONE_LORE) return FALSE;
9308
9309 object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
9310 if (f3 & TR3_LITE1) l++;
9311 if (f4 & TR4_LITE2) l += 2;
9312 if (f4 & TR4_LITE3) l += 3;
9313 if ((f4 & TR4_FUEL_LITE) && (o_ptr->timeout < 1)) l = 0;
9314
9315 /* powerful lights and anti-undead/evil items damage vampires */
9316 if (l) { /* light sources, or other items that provide light */
9317 if ((l > 2) || o_ptr->name1 || (f3 & TR3_BLESSED) ||
9318 (f1 & TR1_SLAY_EVIL) || (f1 & TR1_SLAY_UNDEAD) || (f1 & TR1_KILL_UNDEAD))
9319 return(TRUE);
9320 } else {
9321 if ((f3 & TR3_BLESSED) || (f1 & TR1_KILL_UNDEAD))
9322 return(TRUE);
9323 }
9324
9325 return(FALSE);
9326 }
9327
9328 /*
9329 * Generate default item-generation restriction flags for a given player - C. Blue
9330 */
9331 u32b make_resf(player_type *p_ptr) {
9332 u32b f = RESF_NONE;
9333 if (p_ptr == NULL) return(f);
9334
9335 /* winner handling */
9336 if (p_ptr->total_winner) {
9337 f |= RESF_WINNER; /* allow generation of WINNERS_ONLY items */
9338 f |= RESF_LIFE; /* allowed to find +LIFE artifacts; hack: and WINNERS_ONLY artifacts too */
9339 if (cfg.kings_etiquette) f |= RESF_NOTRUEART; /* player is currently a winner? Then don't find true arts! */
9340 }
9341
9342 /* fallen winner handling */
9343 if (p_ptr->once_winner) {
9344 if (cfg.fallenkings_etiquette) {
9345 f |= RESF_NOTRUEART; /* player is a fallen winner? Then don't find true arts! */
9346 /* since fallen kings are already kinda punished by their status, cut them some slack here?: */
9347 if (p_ptr->lev >= 50) {
9348 // f |= RESF_WINNER; /* allow generation of WINNERS_ONLY items, if player won once but can't get true arts */
9349 // f |= RESF_LIFE; /* allowed to find +LIFE artifacts; hack: and WINNERS_ONLY artifacts too */
9350 }
9351 }
9352 }
9353
9354 /* anyone who cannot use true arts can still _find_ them? (should usually be disabled) */
9355 if (!cfg.winners_find_randarts) f &= ~RESF_NOTRUEART; /* monsters killed by [fallen] winners can drop no true arts but randarts only instead? */
9356
9357 /* special mode handling */
9358 if (p_ptr->mode & MODE_PVP) f |= RESF_NOTRUEART; /* PvP mode chars can't find true arts, since true arts are for kinging! */
9359
9360 return (f);
9361 }
9362
9363 /*
9364 * Items have been slided in the inventory - mikaelh
9365 */
9366 void inven_index_slide(int Ind, s16b begin, s16b mod, s16b end)
9367 {
9368 player_type *p_ptr = Players[Ind];
9369 inventory_change_type *inv_change, *list;
9370
9371 /* Update index numbers for p_ptr->current_* items when sliding items in the inventory */
9372
9373 if (p_ptr->current_rod != -1 && p_ptr->current_rod >= begin && p_ptr->current_rod <= end)
9374 p_ptr->current_rod += mod;
9375
9376 if (p_ptr->current_activation != -1 && p_ptr->current_activation >= begin && p_ptr->current_activation <= end)
9377 p_ptr->current_activation += mod;
9378
9379 /* Record the change if the client supports inventory IDs */
9380 if (is_newer_than(&p_ptr->version, 4, 4, 2, 1, 0, 0)) {
9381 MAKE(inv_change, inventory_change_type);
9382 inv_change->revision = ++p_ptr->inventory_revision;
9383 inv_change->type = INVENTORY_CHANGE_SLIDE;
9384 inv_change->begin = begin;
9385 inv_change->end = end;
9386 inv_change->mod = mod;
9387
9388 /* Add it to the end of the list */
9389 list = p_ptr->inventory_changes;
9390 if (list) {
9391 while (list->next) list = list->next;
9392 list->next = inv_change;
9393 } else {
9394 p_ptr->inventory_changes = inv_change;
9395 }
9396
9397 p_ptr->inventory_changed = TRUE;
9398 }
9399 }
9400
9401 /*
9402 * Items have been moved in the inventory - mikaelh
9403 */
9404 void inven_index_move(int Ind, s16b slot, s16b new_slot)
9405 {
9406 player_type *p_ptr = Players[Ind];
9407 inventory_change_type *inv_change, *list;
9408
9409 /* Update index numbers for p_ptr->current_* items when moving items in the inventory */
9410
9411 if (p_ptr->current_rod == slot) p_ptr->current_rod = new_slot;
9412 if (p_ptr->current_activation == slot) p_ptr->current_activation = new_slot;
9413
9414 /* Record the change if the client supports inventory IDs */
9415 if (is_newer_than(&p_ptr->version, 4, 4, 2, 1, 0, 0)) {
9416 MAKE(inv_change, inventory_change_type);
9417 inv_change->revision = ++p_ptr->inventory_revision;
9418 inv_change->type = INVENTORY_CHANGE_MOVE;
9419 inv_change->begin = slot;
9420 inv_change->end = new_slot;
9421 inv_change->mod = 0;
9422
9423 /* Add it to the end of the list */
9424 list = p_ptr->inventory_changes;
9425 if (list) {
9426 while (list->next) list = list->next;
9427 list->next = inv_change;
9428 } else {
9429 p_ptr->inventory_changes = inv_change;
9430 }
9431
9432 p_ptr->inventory_changed = TRUE;
9433 }
9434 }
9435
9436 /*
9437 * Items have been erased from the inventory - mikaelh
9438 */
9439 void inven_index_erase(int Ind, s16b slot)
9440 {
9441 player_type *p_ptr = Players[Ind];
9442 inventory_change_type *inv_change, *list;
9443
9444 /* Update index numbers for p_ptr->current_* items when erasing items in the inventory */
9445
9446 if (p_ptr->current_rod == slot) p_ptr->current_rod = -1;
9447 if (p_ptr->current_activation == slot) p_ptr->current_activation = -1;
9448
9449 /* Record the change if the client supports inventory IDs */
9450 if (is_newer_than(&p_ptr->version, 4, 4, 2, 1, 0, 0)) {
9451 MAKE(inv_change, inventory_change_type);
9452 inv_change->revision = ++p_ptr->inventory_revision;
9453 inv_change->type = INVENTORY_CHANGE_ERASE;
9454 inv_change->begin = slot;
9455 inv_change->end = -1;
9456 inv_change->mod = 0;
9457
9458 /* Add it to the end of the list */
9459 list = p_ptr->inventory_changes;
9460 if (list) {
9461 while (list->next) list = list->next;
9462 list->next = inv_change;
9463 } else {
9464 p_ptr->inventory_changes = inv_change;
9465 }
9466
9467 p_ptr->inventory_changed = TRUE;
9468 }
9469 }
9470
9471 /*
9472 * Apply recorded changes to an inventory slot number - mikaelh
9473 */
9474 s16b replay_inven_changes(int Ind, s16b slot)
9475 {
9476 player_type *p_ptr = Players[Ind];
9477 inventory_change_type *inv_change;
9478
9479 inv_change = p_ptr->inventory_changes;
9480 while (inv_change) {
9481 switch (inv_change->type) {
9482 case INVENTORY_CHANGE_SLIDE:
9483 if (slot >= inv_change->begin && slot <= inv_change->end)
9484 slot += inv_change->mod;
9485 break;
9486 case INVENTORY_CHANGE_MOVE:
9487 if (slot == inv_change->begin) slot = inv_change->end;
9488 break;
9489 case INVENTORY_CHANGE_ERASE:
9490 if (slot == inv_change->begin) return 0xFF;
9491 break;
9492 }
9493 inv_change = inv_change->next;
9494 }
9495
9496 return slot;
9497 }
9498
9499 /*
9500 * Client is now aware of the inventory changes so they can be removed - mikaelh
9501 */
9502 void inven_confirm_revision(int Ind, int revision)
9503 {
9504 player_type *p_ptr = Players[Ind];
9505 inventory_change_type *inv_change, *prev_change, *next_change;
9506
9507 inv_change = p_ptr->inventory_changes;
9508 prev_change = NULL;
9509 while (inv_change) {
9510 /* Don't delete everything in case of an overflow */
9511 if (((revision > 0 && inv_change->revision > 0) || (revision <= 0)) &&
9512 inv_change->revision <= revision) {
9513 /* Delete the record */
9514
9515 if (prev_change) prev_change->next = inv_change->next;
9516 else p_ptr->inventory_changes = inv_change->next;
9517
9518 next_change = inv_change->next;
9519 KILL(inv_change, inventory_change_type);
9520 inv_change = next_change;
9521 }
9522 else {
9523 prev_change = inv_change;
9524 inv_change = inv_change->next;
9525 }
9526 }
9527 }
9528
9529 /* Set timeout for a newly found artifact, for fluent artifact reset system
9530 to counter long-time hoarding of artifacts. - C. Blue */
9531 void determine_artifact_timeout(int a_idx, struct worldpos *wpos) {
9532 #ifndef FLUENT_ARTIFACT_RESETS
9533 a_info[a_idx].timeout = -2; /* marker for when it gets reactivated */
9534 #else
9535 object_type forge;
9536 int i;
9537
9538 i = lookup_kind(a_info[a_idx].tval, a_info[a_idx].sval);
9539 if (i) invcopy(&forge, i);
9540 else { /* paranoia */
9541 s_printf("DETERMINE_ARTIFACT_TIMEOUT: Cannot find item %d,%d (aidx %d)!\n", a_info[a_idx].tval, a_info[a_idx].sval, a_idx);
9542 /* try to hack it manually, really paranoid */
9543 forge.k_idx = 0;
9544 a_idx = 0; //artifact #0 has tval,sval = 0,0 - for the paranoid code below.. (side note: true_artifact_p() doesn't return true for aidx 0 ^^ but who cares..)
9545 /* atm this code has no actual effect.. */
9546 forge.tval = a_info[a_idx].tval;
9547 forge.sval = a_info[a_idx].sval;
9548 }
9549 forge.name1 = a_idx;
9550
9551 #ifdef RING_OF_PHASING_NO_TIMEOUT
9552 if (a_idx == ART_PHASING) {
9553 /* special treatment: it's pseudo-permanent, but gets erased when someone else kills Zu-Aon */
9554 a_info[a_idx].timeout = -1;
9555 } else
9556 #endif
9557 if (multiple_artifact_p(&forge)) {
9558 a_info[a_idx].timeout = -1; /* grond/crown don't expire */
9559 return;
9560 } else if (winner_artifact_p(&forge)) a_info[a_idx].timeout = FLUENT_ARTIFACT_WEEKS * 10080 * 2; /* mirror of glory */
9561 else if (a_idx != ART_RANDART) a_info[a_idx].timeout = FLUENT_ARTIFACT_WEEKS * 10080;
9562 else {
9563 /* paranoia */
9564 s_printf("DETERMINE_ARTIFACT_TIMEOUT: For some reason a randart was specified!\n");
9565 return;
9566 }
9567
9568 #ifdef RPG_SERVER
9569 a_info[a_idx].timeout *= 2;
9570 #endif
9571 #endif
9572 //for IDDC_ARTIFACT_FAST_TIMEOUT
9573 if (wpos) a_info[a_idx].iddc = in_irondeepdive(wpos);
9574
9575 /* assume winner-artifact or non-winner, for WINNER_ARTIFACT_FAST_TIMEOUT */
9576 a_info[a_idx].winner = FALSE;
9577 }
9578
9579 /* Similarly to erase_guild_key() this function searches *everywhere* for a
9580 true artifact to erase it. Used for FLUENT_ARTIFACT_RESETS. - C. Blue */
9581 void erase_artifact(int a_idx) {
9582 int i, this_o_idx, next_o_idx;
9583 monster_type *m_ptr;
9584 object_type *o_ptr, *q_ptr;
9585 char m_name[MNAME_LEN], o_name[ONAME_LEN], o_name_short[ONAME_LEN];
9586
9587 int slot;
9588 hash_entry *ptr;
9589 player_type *p_ptr;
9590
9591 object_type forge;
9592 i = lookup_kind(a_info[a_idx].tval, a_info[a_idx].sval);
9593 if (i) invcopy(&forge, i);
9594 forge.name1 = a_idx;
9595 object_desc(0, o_name, &forge, TRUE, 0);//fixed diz for admins
9596 object_desc(0, o_name_short, &forge, TRUE, 256);//short name for telling people
9597
9598 /* objects on the floor/in monster inventories */
9599 for (i = 0; i < o_max; i++) {
9600 o_ptr = &o_list[i];
9601 /* Skip dead objects */
9602 if (!o_ptr->k_idx) continue;
9603 /* Look for specific true artifact */
9604 if (o_ptr->name1 != a_idx) continue;
9605
9606 /* in monster inventory */
9607 if (o_ptr->held_m_idx) {
9608 m_ptr = &m_list[o_ptr->held_m_idx];
9609 /* 1st object held is the artifact? */
9610 if (m_ptr->hold_o_idx == i) {
9611 m_ptr->hold_o_idx = o_ptr->next_o_idx;
9612 monster_desc(0, m_name, o_ptr->held_m_idx, 0);
9613 s_printf("FLUENT_ARTIFACT_RESETS: %d - monster inventory (%d, '%s', #1)\n '%s'\n", a_idx, o_ptr->held_m_idx, m_name, o_name);
9614 delete_object_idx(i, TRUE);
9615 msg_broadcast_format(0, "\374\377M* \377U%s has been lost once more. \377M*", o_name_short);
9616 return;
9617 } else {
9618 i = 1;
9619 q_ptr = &o_list[m_ptr->hold_o_idx];//compiler warning
9620 for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) {
9621 if (this_o_idx == i) {
9622 q_ptr->next_o_idx = o_list[this_o_idx].next_o_idx;
9623 monster_desc(0, m_name, o_ptr->held_m_idx, 0);
9624 s_printf("FLUENT_ARTIFACT_RESETS: %d - monster inventory (%d, '%s', #%d)\n '%s'\n", a_idx, o_ptr->held_m_idx, m_name, i, o_name);
9625 delete_object_idx(this_o_idx, TRUE);
9626 msg_broadcast_format(0, "\374\377M* \377U%s has been lost once more. \377M*", o_name_short);
9627 return;
9628 }
9629 q_ptr = &o_list[this_o_idx];
9630 next_o_idx = q_ptr->next_o_idx;
9631 i++;
9632 }
9633 /* paranoid fail */
9634 s_printf("FLUENT_ARTIFACT_RESETS_ERROR: %d - monster inventory (%d, '%s', #%d)\n '%s'\n", a_idx, o_ptr->held_m_idx, m_name, i, o_name);
9635 return;
9636 }
9637 }
9638
9639 #ifdef PLAYER_STORES
9640 /* Log removal of player store items - this code only applies if server rules allow dropping true artifacts in houses.
9641 In case the cave wasn't allocated, the delete_object_idx() call below won't remove it from pstore lists, so we have to do it now.
9642 Note: This can be a false alarm in case the item is inscribed '@S' but is not actually inside a player house. */
9643 if (!getcave(&o_ptr->wpos) &&
9644 o_ptr->note && strstr(quark_str(o_ptr->note), "@S")) {
9645 //char o_name[ONAME_LEN];//, p_name[NAME_LEN];
9646 //object_desc(0, o_name, o_ptr, TRUE, 3);
9647 //s_printf("PLAYER_STORE_REMOVED (maybe): %s - %s (%d,%d,%d; %d,%d).\n",
9648 s_printf("PLAYER_STORE_REMOVED (maybe): %s (%d,%d,%d; %d,%d).\n",
9649 //p_name, o_name, wpos->wx, wpos->wy, wpos->wz,
9650 o_name, o_ptr->wpos.wx, o_ptr->wpos.wy, o_ptr->wpos.wz,
9651 o_ptr->ix, o_ptr->iy);
9652 }
9653 #endif
9654
9655 s_printf("FLUENT_ARTIFACT_RESETS: %d - floor '%s'\n", a_idx, o_name);
9656 delete_object_idx(i, TRUE);
9657 msg_broadcast_format(0, "\374\377M* \377U%s has been lost once more. \377M*", o_name_short);
9658 return;
9659 }
9660
9661 /* Players online */
9662 for (this_o_idx = 1; this_o_idx <= NumPlayers; this_o_idx++) {
9663 p_ptr = Players[this_o_idx];
9664 /* scan his inventory */
9665 for (i = 0; i < INVEN_TOTAL; i++) {
9666 o_ptr = &p_ptr->inventory[i];
9667 if (!o_ptr->k_idx) continue;
9668
9669 if (o_ptr->name1 == a_idx) {
9670 s_printf("FLUENT_ARTIFACT_RESETS: %d - player '%s'\n '%s'\n", a_idx, p_ptr->name, o_name);
9671 //object_desc(this_o_idx, o_name, o_ptr, FALSE, 3);
9672 msg_format(this_o_idx, "\374\377R%s bids farewell to you...", o_name_short);
9673 handle_art_d(a_idx);
9674 inven_item_increase(this_o_idx, i, -99);
9675 inven_item_describe(this_o_idx, i);
9676 inven_item_optimize(this_o_idx, i);
9677 msg_broadcast_format(this_o_idx, "\374\377M* \377U%s has been lost once more. \377M*", o_name_short);
9678 return;
9679 }
9680 }
9681 }
9682
9683 /* hack */
9684 NumPlayers++;
9685 MAKE(Players[NumPlayers], player_type);
9686 p_ptr = Players[NumPlayers];
9687 p_ptr->inventory = C_NEW(INVEN_TOTAL, object_type);
9688 for (slot = 0; slot < NUM_HASH_ENTRIES; slot++) {
9689 ptr = hash_table[slot];
9690 while (ptr) {
9691 /* not the holder of the artifact? */
9692 if (ptr->id != a_info[a_idx].carrier) {
9693 /* advance to next character */
9694 ptr = ptr->next;
9695 continue;
9696 }
9697
9698 /* clear his data (especially inventory) */
9699 o_ptr = p_ptr->inventory;
9700 WIPE(p_ptr, player_type);
9701 p_ptr->inventory = o_ptr;
9702 p_ptr->Ind = NumPlayers;
9703 C_WIPE(p_ptr->inventory, INVEN_TOTAL, object_type);
9704 /* set his supposed name */
9705 strcpy(p_ptr->name, ptr->name);
9706 /* generate savefile name */
9707 process_player_name(NumPlayers, TRUE);
9708 /* try to load him! */
9709 if (!load_player(NumPlayers)) {
9710 /* bad fail */
9711 s_printf("FLUENT_ARTIFACT_RESETS_ERROR: %d - load_player '%s' failed\n '%s'\n", a_idx, p_ptr->name, o_name);
9712 /* unhack */
9713 C_FREE(p_ptr->inventory, INVEN_TOTAL, object_type);
9714 KILL(p_ptr, player_type);
9715 NumPlayers--;
9716 return;
9717 }
9718 /* scan his inventory */
9719 for (i = 0; i < INVEN_TOTAL; i++) {
9720 o_ptr = &p_ptr->inventory[i];
9721 if (!o_ptr->k_idx) continue;
9722
9723 if (o_ptr->name1 == a_idx) {
9724 s_printf("FLUENT_ARTIFACT_RESETS: %d - savegame '%s'\n '%s'\n", a_idx, p_ptr->name, o_name);
9725 handle_art_d(a_idx);
9726 o_ptr->tval = o_ptr->sval = o_ptr->k_idx = o_ptr->name1 = 0;
9727 p_ptr->fluent_artifact_reset = TRUE; /* hack to notify him next time he logs on */
9728 /* write savegame back */
9729 save_player(NumPlayers);
9730 /* unhack */
9731 C_FREE(p_ptr->inventory, INVEN_TOTAL, object_type);
9732 KILL(p_ptr, player_type);
9733 NumPlayers--;
9734 msg_broadcast_format(0, "\374\377M* \377U%s has been lost once more. \377M*", o_name_short);
9735 return;
9736 }
9737 }
9738
9739 /* exit with failure */
9740 slot = NUM_HASH_ENTRIES;
9741 break;
9742 }
9743 }
9744 /* unhack */
9745 C_FREE(p_ptr->inventory, INVEN_TOTAL, object_type);
9746 KILL(p_ptr, player_type);
9747 NumPlayers--;
9748
9749 /* Paranoia: Failed to locate the artifact. Shouldn't happen! */
9750 s_printf("FLUENT_ARTIFACT_RESETS_ERROR: %d - not found '%s'\n", a_idx, o_name);
9751
9752 /* It can actually happen if the savegame was deleted manually.
9753 In such cases, free the artifact again. This might cause problems
9754 with duplicate artifacts if the savegames are reinstantiated, so
9755 on loading a character, the artifact owner should be compared. */
9756 handle_art_d(a_idx);
9757 msg_broadcast_format(0, "\374\377M* \377U%s has been lost once more. \377M*", o_name_short);
9758 }
9759
9760 /* Modify a particular existing type of item in the whole game world. - C. Blue
9761 (added for Living Lightning drop 'Sky DSM of Imm' to become a canonical randart Sky DSM instead) */
9762 /* Helper function - hard-coded stuff - replacement item parameters */
9763 static void hack_particular_item_aux(object_type *qq_ptr, struct worldpos xwpos) {
9764 int tries;
9765 artifact_type *xa_ptr;
9766
9767 object_wipe(qq_ptr);
9768 invcopy(qq_ptr, lookup_kind(TV_DRAG_ARMOR, SV_DRAGON_SKY));
9769 qq_ptr->number = 1;
9770 qq_ptr->name1 = ART_RANDART;
9771 tries = 500;
9772 while (tries) {
9773 /* Piece together a 32-bit random seed */
9774 qq_ptr->name3 = rand_int(0xFFFF) << 16;
9775 qq_ptr->name3 += rand_int(0xFFFF);
9776 apply_magic(&xwpos, qq_ptr, 150, TRUE, TRUE, TRUE, TRUE, RESF_FORCERANDART | RESF_NOTRUEART | RESF_LIFE);
9777
9778 xa_ptr = randart_make(qq_ptr);
9779 if (artifact_power(xa_ptr) >= 105 + 5 && /* at least +1 new mod gained; and +extra bonus boost */
9780 qq_ptr->to_a > 0 && /* not cursed */
9781 !(xa_ptr->flags3 & (TR3_AGGRAVATE | TR3_NO_MAGIC)))
9782 break;
9783 tries--;
9784 }
9785 qq_ptr->level = 0;
9786 if (!tries) s_printf("hack_particular_item_aux: Re-rolling out of tries!\n");
9787 }
9788 static void hack_particular_item_prepare_wpos(struct worldpos *xwpos) {
9789 int x, y;
9790 dungeon_type *d_ptr;
9791
9792 for (y = 0; y < MAX_WILD_Y; y++)
9793 for (x = 0; x < MAX_WILD_X; x++) {
9794 if ((d_ptr = wild_info[y][x].tower)) {
9795 if (d_ptr->type == DI_CLOUD_PLANES) {
9796 xwpos->wx = x;
9797 xwpos->wy = y;
9798 xwpos->wz = 20;
9799 }
9800 }
9801 if ((d_ptr = wild_info[y][x].dungeon)) {
9802 if (d_ptr->type == DI_CLOUD_PLANES) {
9803 xwpos->wx = x;
9804 xwpos->wy = y;
9805 xwpos->wz = 20;
9806 }
9807 }
9808 }
9809 }
9810 static bool hack_particular_item_cmp(object_type *o_ptr) {
9811 //return (o_ptr->tval != TV_DRAG_ARMOR || o_ptr->sval != SV_DRAGON_SKY || o_ptr->name2 != EGO_IMMUNE);
9812 return (o_ptr->tval != TV_DRAG_ARMOR || o_ptr->sval != SV_DRAGON_SKY || o_ptr->name1 != ART_RANDART || o_ptr->level != 0);
9813 }
9814 void hack_particular_item(void) {
9815 int i, this_o_idx, next_o_idx;
9816 monster_type *m_ptr;
9817 object_type *o_ptr, *q_ptr;
9818
9819 int slot;
9820 hash_entry *ptr;
9821 player_type *p_ptr;
9822
9823 int found = 0;
9824
9825 struct worldpos xwpos;
9826
9827 xwpos.wx = xwpos.wy = xwpos.wz = 0;
9828 hack_particular_item_prepare_wpos(&xwpos);
9829 if (!xwpos.wz) {
9830 s_printf("hack_particular_item(): failed to prepare wpos!\n");
9831 return;
9832 }
9833
9834 s_printf("hack_particular_item(): commencing check..\n");
9835
9836 /* objects on the floor/in monster inventories */
9837 for (i = 0; i < o_max; i++) {
9838 o_ptr = &o_list[i];
9839 /* Skip dead objects */
9840 if (!o_ptr->k_idx) continue;
9841 /* Look for specific item */
9842 if (hack_particular_item_cmp(o_ptr)) continue;
9843
9844 /* in monster inventory */
9845 if (o_ptr->held_m_idx) {
9846 m_ptr = &m_list[o_ptr->held_m_idx];
9847 /* 1st object held matches? */
9848 q_ptr = &o_list[m_ptr->hold_o_idx];
9849 if (!hack_particular_item_cmp(q_ptr)) {
9850 s_printf(" found in monster inventory (1st)\n");
9851 hack_particular_item_aux(q_ptr, xwpos);
9852 found++;
9853 } else {
9854 i = 1;
9855 q_ptr = &o_list[m_ptr->hold_o_idx];//compiler warning
9856 for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) {
9857 q_ptr = &o_list[this_o_idx];
9858 if (!hack_particular_item_cmp(q_ptr)) {
9859 s_printf(" found in monster inventory\n");
9860 hack_particular_item_aux(&o_list[this_o_idx], xwpos);
9861 found++;
9862 }
9863 next_o_idx = q_ptr->next_o_idx;
9864 i++;
9865 }
9866 }
9867 } else {
9868 q_ptr = &o_list[i];
9869 s_printf(" found on the floor\n");
9870 hack_particular_item_aux(q_ptr, xwpos);
9871 found++;
9872 }
9873 }
9874
9875 /* Players online */
9876 for (this_o_idx = 1; this_o_idx <= NumPlayers; this_o_idx++) {
9877 p_ptr = Players[this_o_idx];
9878 /* scan his inventory */
9879 for (i = 0; i < INVEN_TOTAL; i++) {
9880 o_ptr = &p_ptr->inventory[i];
9881 if (!o_ptr->k_idx) continue;
9882
9883 if (!hack_particular_item_cmp(o_ptr)) {
9884 s_printf(" found in live player '%s'\n", p_ptr->name);
9885 hack_particular_item_aux(o_ptr, xwpos);
9886 found++;
9887 }
9888 }
9889 }
9890
9891 /* hack */
9892 NumPlayers++;
9893 MAKE(Players[NumPlayers], player_type);
9894 p_ptr = Players[NumPlayers];
9895 p_ptr->inventory = C_NEW(INVEN_TOTAL, object_type);
9896 for (slot = 0; slot < NUM_HASH_ENTRIES; slot++) {
9897 ptr = hash_table[slot];
9898 while (ptr) {
9899 /* clear his data (especially inventory) */
9900 o_ptr = p_ptr->inventory;
9901 WIPE(p_ptr, player_type);
9902 p_ptr->inventory = o_ptr;
9903 p_ptr->Ind = NumPlayers;
9904 C_WIPE(p_ptr->inventory, INVEN_TOTAL, object_type);
9905 /* set his supposed name */
9906 strcpy(p_ptr->name, ptr->name);
9907 /* generate savefile name */
9908 process_player_name(NumPlayers, TRUE);
9909 /* try to load him! */
9910 if (!load_player(NumPlayers)) {
9911 /* bad fail */
9912 s_printf(" load_player '%s' failed\n", p_ptr->name);
9913 /* unhack */
9914 C_FREE(p_ptr->inventory, INVEN_TOTAL, object_type);
9915 KILL(p_ptr, player_type);
9916 NumPlayers--;
9917 return;
9918 }
9919 /* scan his inventory */
9920 for (i = 0; i < INVEN_TOTAL; i++) {
9921 o_ptr = &p_ptr->inventory[i];
9922 if (!o_ptr->k_idx) continue;
9923
9924 if (!hack_particular_item_cmp(o_ptr)) {
9925 s_printf(" found in load_player '%s'\n", p_ptr->name);
9926 hack_particular_item_aux(o_ptr, xwpos);
9927 found++;
9928 /* write savegame back */
9929 save_player(NumPlayers);
9930 }
9931 }
9932 ptr = ptr->next;
9933 }
9934 }
9935 /* unhack */
9936 C_FREE(p_ptr->inventory, INVEN_TOTAL, object_type);
9937 KILL(p_ptr, player_type);
9938 NumPlayers--;
9939
9940 s_printf("hack_particular_item: found+replaced %d occurances\n", found);
9941 }
9942