| | 2529 | |
|---|
| | 2530 | /* |
|---|
| | 2531 | * Hack -- Return the "automatic coin type" of a monster race |
|---|
| | 2532 | * Used to allocate proper treasure when "Creeping coins" die |
|---|
| | 2533 | * |
|---|
| | 2534 | * Note the use of actual "monster names". XXX XXX XXX |
|---|
| | 2535 | */ |
|---|
| | 2536 | static int get_coin_type(const monster_race *r_ptr) |
|---|
| | 2537 | { |
|---|
| | 2538 | cptr name = (r_name + r_ptr->name); |
|---|
| | 2539 | |
|---|
| | 2540 | /* Analyze "coin" monsters */ |
|---|
| | 2541 | if (r_ptr->d_char == '$') |
|---|
| | 2542 | { |
|---|
| | 2543 | /* Look for textual clues */ |
|---|
| | 2544 | if (strstr(name, " copper ")) return (SV_COPPER); |
|---|
| | 2545 | if (strstr(name, " silver ")) return (SV_SILVER); |
|---|
| | 2546 | if (strstr(name, " gold ")) return (SV_GOLD); |
|---|
| | 2547 | if (strstr(name, " mithril ")) return (SV_MITHRIL); |
|---|
| | 2548 | if (strstr(name, " adamantite ")) return (SV_ADAMANTITE); |
|---|
| | 2549 | |
|---|
| | 2550 | /* Look for textual clues */ |
|---|
| | 2551 | if (strstr(name, "Copper ")) return (SV_COPPER); |
|---|
| | 2552 | if (strstr(name, "Silver ")) return (SV_SILVER); |
|---|
| | 2553 | if (strstr(name, "Gold ")) return (SV_GOLD); |
|---|
| | 2554 | if (strstr(name, "Mithril ")) return (SV_MITHRIL); |
|---|
| | 2555 | if (strstr(name, "Adamantite ")) return (SV_ADAMANTITE); |
|---|
| | 2556 | } |
|---|
| | 2557 | |
|---|
| | 2558 | /* Assume nothing */ |
|---|
| | 2559 | return (SV_GOLD_ANY); |
|---|
| | 2560 | } |
|---|
| | 2561 | |
|---|
| | 2562 | |
|---|
| | 2563 | /* |
|---|
| | 2564 | * Create magical stairs after finishing a quest monster. |
|---|
| | 2565 | */ |
|---|
| | 2566 | static void build_quest_stairs(int y, int x) |
|---|
| | 2567 | { |
|---|
| | 2568 | int ny, nx; |
|---|
| | 2569 | |
|---|
| | 2570 | |
|---|
| | 2571 | /* Stagger around */ |
|---|
| | 2572 | while (!cave_valid_bold(y, x)) |
|---|
| | 2573 | { |
|---|
| | 2574 | int d = 1; |
|---|
| | 2575 | |
|---|
| | 2576 | /* Pick a location */ |
|---|
| | 2577 | scatter(&ny, &nx, y, x, d, 0); |
|---|
| | 2578 | |
|---|
| | 2579 | /* Stagger */ |
|---|
| | 2580 | y = ny; x = nx; |
|---|
| | 2581 | } |
|---|
| | 2582 | |
|---|
| | 2583 | /* Destroy any objects */ |
|---|
| | 2584 | delete_object(y, x); |
|---|
| | 2585 | |
|---|
| | 2586 | /* Explain the staircase */ |
|---|
| | 2587 | msg_print("A magical staircase appears..."); |
|---|
| | 2588 | |
|---|
| | 2589 | /* Create stairs down */ |
|---|
| | 2590 | cave_set_feat(y, x, FEAT_MORE); |
|---|
| | 2591 | |
|---|
| | 2592 | /* Update the visuals */ |
|---|
| | 2593 | p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); |
|---|
| | 2594 | |
|---|
| | 2595 | /* Fully update the flow */ |
|---|
| | 2596 | p_ptr->update |= (PU_FORGET_FLOW | PU_UPDATE_FLOW); |
|---|
| | 2597 | } |
|---|
| | 2598 | |
|---|
| | 2599 | |
|---|
| | 2600 | |
|---|
| | 2601 | /* |
|---|
| | 2602 | * Handle the "death" of a monster. |
|---|
| | 2603 | * |
|---|
| | 2604 | * Disperse treasures centered at the monster location based on the |
|---|
| | 2605 | * various flags contained in the monster flags fields. |
|---|
| | 2606 | * |
|---|
| | 2607 | * Check for "Quest" completion when a quest monster is killed. |
|---|
| | 2608 | * |
|---|
| | 2609 | * Note that only the player can induce "monster_death()" on Uniques. |
|---|
| | 2610 | * Thus (for now) all Quest monsters should be Uniques. |
|---|
| | 2611 | * |
|---|
| | 2612 | * Note that monsters can now carry objects, and when a monster dies, |
|---|
| | 2613 | * it drops all of its objects, which may disappear in crowded rooms. |
|---|
| | 2614 | */ |
|---|
| | 2615 | void monster_death(int m_idx) |
|---|
| | 2616 | { |
|---|
| | 2617 | int i, j, y, x, level; |
|---|
| | 2618 | |
|---|
| | 2619 | int dump_item = 0; |
|---|
| | 2620 | int dump_gold = 0; |
|---|
| | 2621 | |
|---|
| | 2622 | int number = 0; |
|---|
| | 2623 | int total = 0; |
|---|
| | 2624 | |
|---|
| | 2625 | s16b this_o_idx, next_o_idx = 0; |
|---|
| | 2626 | |
|---|
| | 2627 | monster_type *m_ptr = &mon_list[m_idx]; |
|---|
| | 2628 | |
|---|
| | 2629 | monster_race *r_ptr = &r_info[m_ptr->r_idx]; |
|---|
| | 2630 | |
|---|
| | 2631 | bool visible = (m_ptr->ml || (r_ptr->flags[0] & (RF0_UNIQUE))); |
|---|
| | 2632 | |
|---|
| | 2633 | bool great = (r_ptr->flags[0] & (RF0_DROP_GREAT)) ? TRUE : FALSE; |
|---|
| | 2634 | bool good = ((r_ptr->flags[0] & (RF0_DROP_GOOD)) ? TRUE : FALSE) || great; |
|---|
| | 2635 | |
|---|
| | 2636 | bool gold_ok = (!(r_ptr->flags[0] & (RF0_ONLY_ITEM))); |
|---|
| | 2637 | bool item_ok = (!(r_ptr->flags[0] & (RF0_ONLY_GOLD))); |
|---|
| | 2638 | |
|---|
| | 2639 | int force_coin = get_coin_type(r_ptr); |
|---|
| | 2640 | |
|---|
| | 2641 | object_type *i_ptr; |
|---|
| | 2642 | object_type object_type_body; |
|---|
| | 2643 | |
|---|
| | 2644 | |
|---|
| | 2645 | /* Get the location */ |
|---|
| | 2646 | y = m_ptr->fy; |
|---|
| | 2647 | x = m_ptr->fx; |
|---|
| | 2648 | |
|---|
| | 2649 | |
|---|
| | 2650 | /* Drop objects being carried */ |
|---|
| | 2651 | for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) |
|---|
| | 2652 | { |
|---|
| | 2653 | object_type *o_ptr; |
|---|
| | 2654 | |
|---|
| | 2655 | /* Get the object */ |
|---|
| | 2656 | o_ptr = &o_list[this_o_idx]; |
|---|
| | 2657 | |
|---|
| | 2658 | /* Get the next object */ |
|---|
| | 2659 | next_o_idx = o_ptr->next_o_idx; |
|---|
| | 2660 | |
|---|
| | 2661 | /* Paranoia */ |
|---|
| | 2662 | o_ptr->held_m_idx = 0; |
|---|
| | 2663 | |
|---|
| | 2664 | /* Get local object */ |
|---|
| | 2665 | i_ptr = &object_type_body; |
|---|
| | 2666 | |
|---|
| | 2667 | /* Copy the object */ |
|---|
| | 2668 | object_copy(i_ptr, o_ptr); |
|---|
| | 2669 | |
|---|
| | 2670 | /* Delete the object */ |
|---|
| | 2671 | delete_object_idx(this_o_idx); |
|---|
| | 2672 | |
|---|
| | 2673 | /* Drop it */ |
|---|
| | 2674 | drop_near(i_ptr, -1, y, x); |
|---|
| | 2675 | } |
|---|
| | 2676 | |
|---|
| | 2677 | /* Forget objects */ |
|---|
| | 2678 | m_ptr->hold_o_idx = 0; |
|---|
| | 2679 | |
|---|
| | 2680 | |
|---|
| | 2681 | /* Mega-Hack -- drop "winner" treasures */ |
|---|
| | 2682 | if (r_ptr->flags[0] & (RF0_DROP_CHOSEN)) |
|---|
| | 2683 | { |
|---|
| | 2684 | /* Get local object */ |
|---|
| | 2685 | i_ptr = &object_type_body; |
|---|
| | 2686 | |
|---|
| | 2687 | /* Mega-Hack -- Prepare to make "Grond" */ |
|---|
| | 2688 | object_prep(i_ptr, lookup_kind(TV_HAFTED, SV_GROND)); |
|---|
| | 2689 | |
|---|
| | 2690 | /* Mega-Hack -- Mark this item as "Grond" */ |
|---|
| | 2691 | i_ptr->name1 = ART_GROND; |
|---|
| | 2692 | |
|---|
| | 2693 | /* Mega-Hack -- Actually create "Grond" */ |
|---|
| | 2694 | apply_magic(i_ptr, -1, TRUE, TRUE, TRUE); |
|---|
| | 2695 | i_ptr->origin = ORIGIN_DROP; |
|---|
| | 2696 | i_ptr->origin_depth = p_ptr->depth; |
|---|
| | 2697 | i_ptr->origin_xtra = m_ptr->r_idx; |
|---|
| | 2698 | |
|---|
| | 2699 | /* Drop it in the dungeon */ |
|---|
| | 2700 | drop_near(i_ptr, -1, y, x); |
|---|
| | 2701 | |
|---|
| | 2702 | |
|---|
| | 2703 | /* Get local object */ |
|---|
| | 2704 | i_ptr = &object_type_body; |
|---|
| | 2705 | |
|---|
| | 2706 | /* Mega-Hack -- Prepare to make "Morgoth" */ |
|---|
| | 2707 | object_prep(i_ptr, lookup_kind(TV_CROWN, SV_MORGOTH)); |
|---|
| | 2708 | i_ptr->origin = ORIGIN_DROP; |
|---|
| | 2709 | i_ptr->origin_depth = p_ptr->depth; |
|---|
| | 2710 | i_ptr->origin_xtra = m_ptr->r_idx; |
|---|
| | 2711 | |
|---|
| | 2712 | /* Mega-Hack -- Mark this item as "Morgoth" */ |
|---|
| | 2713 | i_ptr->name1 = ART_MORGOTH; |
|---|
| | 2714 | |
|---|
| | 2715 | /* Mega-Hack -- Actually create "Morgoth" */ |
|---|
| | 2716 | apply_magic(i_ptr, -1, TRUE, TRUE, TRUE); |
|---|
| | 2717 | |
|---|
| | 2718 | /* Drop it in the dungeon */ |
|---|
| | 2719 | drop_near(i_ptr, -1, y, x); |
|---|
| | 2720 | } |
|---|
| | 2721 | |
|---|
| | 2722 | |
|---|
| | 2723 | /* Determine how much we can drop */ |
|---|
| | 2724 | if ((r_ptr->flags[0] & RF0_DROP_20) && (randint0(100) < 20)) number++; |
|---|
| | 2725 | if ((r_ptr->flags[0] & RF0_DROP_40) && (randint0(100) < 40)) number++; |
|---|
| | 2726 | if ((r_ptr->flags[0] & RF0_DROP_60) && (randint0(100) < 60)) number++; |
|---|
| | 2727 | |
|---|
| | 2728 | if (r_ptr->flags[0] & RF0_DROP_4) number += rand_range(2, 6); |
|---|
| | 2729 | if (r_ptr->flags[0] & RF0_DROP_3) number += rand_range(2, 4); |
|---|
| | 2730 | if (r_ptr->flags[0] & RF0_DROP_2) number += rand_range(1, 3); |
|---|
| | 2731 | if (r_ptr->flags[0] & RF0_DROP_1) number++; |
|---|
| | 2732 | |
|---|
| | 2733 | /* Average monster level and current depth */ |
|---|
| | 2734 | level = (p_ptr->depth + r_ptr->level) / 2; |
|---|
| | 2735 | |
|---|
| | 2736 | /* Drop some objects */ |
|---|
| | 2737 | for (j = 0; j < number; j++) |
|---|
| | 2738 | { |
|---|
| | 2739 | /* Get local object */ |
|---|
| | 2740 | i_ptr = &object_type_body; |
|---|
| | 2741 | |
|---|
| | 2742 | /* Wipe the object */ |
|---|
| | 2743 | object_wipe(i_ptr); |
|---|
| | 2744 | |
|---|
| | 2745 | /* Make Gold */ |
|---|
| | 2746 | if (gold_ok && (!item_ok || (randint0(100) < 50))) |
|---|
| | 2747 | { |
|---|
| | 2748 | /* Make some gold */ |
|---|
| | 2749 | make_gold(i_ptr, level, force_coin); |
|---|
| | 2750 | dump_gold++; |
|---|
| | 2751 | } |
|---|
| | 2752 | |
|---|
| | 2753 | /* Make Object */ |
|---|
| | 2754 | else |
|---|
| | 2755 | { |
|---|
| | 2756 | /* Make an object */ |
|---|
| | 2757 | if (!make_object(i_ptr, level, good, great)) continue; |
|---|
| | 2758 | dump_item++; |
|---|
| | 2759 | } |
|---|
| | 2760 | |
|---|
| | 2761 | /* Set origin */ |
|---|
| | 2762 | i_ptr->origin = visible ? ORIGIN_DROP : ORIGIN_DROP_UNKNOWN; |
|---|
| | 2763 | i_ptr->origin_depth = p_ptr->depth; |
|---|
| | 2764 | i_ptr->origin_xtra = m_ptr->r_idx; |
|---|
| | 2765 | |
|---|
| | 2766 | /* Drop it in the dungeon */ |
|---|
| | 2767 | drop_near(i_ptr, -1, y, x); |
|---|
| | 2768 | } |
|---|
| | 2769 | |
|---|
| | 2770 | /* Take note of any dropped treasure */ |
|---|
| | 2771 | if (visible && (dump_item || dump_gold)) |
|---|
| | 2772 | { |
|---|
| | 2773 | /* Take notes on treasure */ |
|---|
| | 2774 | lore_treasure(m_idx, dump_item, dump_gold); |
|---|
| | 2775 | } |
|---|
| | 2776 | |
|---|
| | 2777 | /* Update monster list window */ |
|---|
| | 2778 | p_ptr->redraw |= PR_MONLIST; |
|---|
| | 2779 | |
|---|
| | 2780 | /* Only process "Quest Monsters" */ |
|---|
| | 2781 | if (!(r_ptr->flags[0] & (RF0_QUESTOR))) return; |
|---|
| | 2782 | |
|---|
| | 2783 | /* Hack -- Mark quests as complete */ |
|---|
| | 2784 | for (i = 0; i < MAX_Q_IDX; i++) |
|---|
| | 2785 | { |
|---|
| | 2786 | /* Hack -- note completed quests */ |
|---|
| | 2787 | if (q_list[i].level == r_ptr->level) q_list[i].level = 0; |
|---|
| | 2788 | |
|---|
| | 2789 | /* Count incomplete quests */ |
|---|
| | 2790 | if (q_list[i].level) total++; |
|---|
| | 2791 | } |
|---|
| | 2792 | |
|---|
| | 2793 | /* Build magical stairs */ |
|---|
| | 2794 | build_quest_stairs(y, x); |
|---|
| | 2795 | |
|---|
| | 2796 | /* Nothing left, game over... */ |
|---|
| | 2797 | if (total == 0) |
|---|
| | 2798 | { |
|---|
| | 2799 | /* Total winner */ |
|---|
| | 2800 | p_ptr->total_winner = TRUE; |
|---|
| | 2801 | |
|---|
| | 2802 | /* Redraw the "title" */ |
|---|
| | 2803 | p_ptr->redraw |= (PR_TITLE); |
|---|
| | 2804 | |
|---|
| | 2805 | /* Congratulations */ |
|---|
| | 2806 | msg_print("*** CONGRATULATIONS ***"); |
|---|
| | 2807 | msg_print("You have won the game!"); |
|---|
| | 2808 | msg_print("You may retire (commit suicide) when you are ready."); |
|---|
| | 2809 | } |
|---|
| | 2810 | } |
|---|
| | 2811 | |
|---|
| | 2812 | |
|---|
| | 2813 | |
|---|
| | 2814 | |
|---|
| | 2815 | /* |
|---|
| | 2816 | * Decrease a monster's hit points, handle monster death. |
|---|
| | 2817 | * |
|---|
| | 2818 | * We return TRUE if the monster has been killed (and deleted). |
|---|
| | 2819 | * |
|---|
| | 2820 | * We announce monster death (using an optional "death message" |
|---|
| | 2821 | * if given, and a otherwise a generic killed/destroyed message). |
|---|
| | 2822 | * |
|---|
| | 2823 | * Only "physical attacks" can induce the "You have slain" message. |
|---|
| | 2824 | * Missile and Spell attacks will induce the "dies" message, or |
|---|
| | 2825 | * various "specialized" messages. Note that "You have destroyed" |
|---|
| | 2826 | * and "is destroyed" are synonyms for "You have slain" and "dies". |
|---|
| | 2827 | * |
|---|
| | 2828 | * Invisible monsters induce a special "You have killed it." message. |
|---|
| | 2829 | * |
|---|
| | 2830 | * Hack -- we "delay" fear messages by passing around a "fear" flag. |
|---|
| | 2831 | * |
|---|
| | 2832 | * Consider decreasing monster experience over time, say, by using |
|---|
| | 2833 | * "(m_exp * m_lev * (m_lev)) / (p_lev * (m_lev + n_killed))" instead |
|---|
| | 2834 | * of simply "(m_exp * m_lev) / (p_lev)", to make the first monster |
|---|
| | 2835 | * worth more than subsequent monsters. This would also need to |
|---|
| | 2836 | * induce changes in the monster recall code. XXX XXX XXX |
|---|
| | 2837 | */ |
|---|
| | 2838 | bool mon_take_hit(int m_idx, int dam, bool *fear, cptr note) |
|---|
| | 2839 | { |
|---|
| | 2840 | monster_type *m_ptr = &mon_list[m_idx]; |
|---|
| | 2841 | |
|---|
| | 2842 | monster_race *r_ptr = &r_info[m_ptr->r_idx]; |
|---|
| | 2843 | |
|---|
| | 2844 | monster_lore *l_ptr = &l_list[m_ptr->r_idx]; |
|---|
| | 2845 | |
|---|
| | 2846 | s32b div, new_exp, new_exp_frac; |
|---|
| | 2847 | |
|---|
| | 2848 | |
|---|
| | 2849 | /* Redraw (later) if needed */ |
|---|
| | 2850 | if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH); |
|---|
| | 2851 | |
|---|
| | 2852 | |
|---|
| | 2853 | /* Wake it up */ |
|---|
| | 2854 | m_ptr->csleep = 0; |
|---|
| | 2855 | |
|---|
| | 2856 | /* Hurt it */ |
|---|
| | 2857 | m_ptr->hp -= dam; |
|---|
| | 2858 | |
|---|
| | 2859 | /* It is dead now */ |
|---|
| | 2860 | if (m_ptr->hp < 0) |
|---|
| | 2861 | { |
|---|
| | 2862 | char m_name[80]; |
|---|
| | 2863 | char buf[80]; |
|---|
| | 2864 | |
|---|
| | 2865 | /* Assume normal death sound */ |
|---|
| | 2866 | int soundfx = MSG_KILL; |
|---|
| | 2867 | |
|---|
| | 2868 | /* Play a special sound if the monster was unique */ |
|---|
| | 2869 | if (r_ptr->flags[0] & RF0_UNIQUE) |
|---|
| | 2870 | { |
|---|
| | 2871 | /* Mega-Hack -- Morgoth -- see monster_death() */ |
|---|
| | 2872 | if (r_ptr->flags[0] & RF0_DROP_CHOSEN) |
|---|
| | 2873 | soundfx = MSG_KILL_KING; |
|---|
| | 2874 | else |
|---|
| | 2875 | soundfx = MSG_KILL_UNIQUE; |
|---|
| | 2876 | } |
|---|
| | 2877 | |
|---|
| | 2878 | /* Extract monster name */ |
|---|
| | 2879 | monster_desc(m_name, sizeof(m_name), m_ptr, 0); |
|---|
| | 2880 | |
|---|
| | 2881 | /* Death by Missile/Spell attack */ |
|---|
| | 2882 | if (note) |
|---|
| | 2883 | { |
|---|
| | 2884 | message_format(soundfx, m_ptr->r_idx, "%^s%s", m_name, note); |
|---|
| | 2885 | } |
|---|
| | 2886 | |
|---|
| | 2887 | /* Death by physical attack -- invisible monster */ |
|---|
| | 2888 | else if (!m_ptr->ml) |
|---|
| | 2889 | { |
|---|
| | 2890 | message_format(soundfx, m_ptr->r_idx, "You have killed %s.", m_name); |
|---|
| | 2891 | } |
|---|
| | 2892 | |
|---|
| | 2893 | /* Death by Physical attack -- non-living monster */ |
|---|
| | 2894 | else if ((r_ptr->flags[2] & (RF2_DEMON | RF2_UNDEAD)) || |
|---|
| | 2895 | (r_ptr->flags[1] & (RF1_STUPID)) || |
|---|
| | 2896 | (strchr("Evg", r_ptr->d_char))) |
|---|
| | 2897 | { |
|---|
| | 2898 | message_format(soundfx, m_ptr->r_idx, "You have destroyed %s.", m_name); |
|---|
| | 2899 | } |
|---|
| | 2900 | |
|---|
| | 2901 | /* Death by Physical attack -- living monster */ |
|---|
| | 2902 | else |
|---|
| | 2903 | { |
|---|
| | 2904 | message_format(soundfx, m_ptr->r_idx, "You have slain %s.", m_name); |
|---|
| | 2905 | } |
|---|
| | 2906 | |
|---|
| | 2907 | /* Player level */ |
|---|
| | 2908 | div = p_ptr->lev; |
|---|
| | 2909 | |
|---|
| | 2910 | /* Give some experience for the kill */ |
|---|
| | 2911 | new_exp = ((long)r_ptr->mexp * r_ptr->level) / div; |
|---|
| | 2912 | |
|---|
| | 2913 | /* Handle fractional experience */ |
|---|
| | 2914 | new_exp_frac = ((((long)r_ptr->mexp * r_ptr->level) % div) |
|---|
| | 2915 | * 0x10000L / div) + p_ptr->exp_frac; |
|---|
| | 2916 | |
|---|
| | 2917 | /* Keep track of experience */ |
|---|
| | 2918 | if (new_exp_frac >= 0x10000L) |
|---|
| | 2919 | { |
|---|
| | 2920 | new_exp++; |
|---|
| | 2921 | p_ptr->exp_frac = (u16b)(new_exp_frac - 0x10000L); |
|---|
| | 2922 | } |
|---|
| | 2923 | else |
|---|
| | 2924 | { |
|---|
| | 2925 | p_ptr->exp_frac = (u16b)new_exp_frac; |
|---|
| | 2926 | } |
|---|
| | 2927 | |
|---|
| | 2928 | /* When the player kills a Unique, it stays dead */ |
|---|
| | 2929 | if (r_ptr->flags[0] & (RF0_UNIQUE)) |
|---|
| | 2930 | { |
|---|
| | 2931 | char unique_name[80]; |
|---|
| | 2932 | r_ptr->max_num = 0; |
|---|
| | 2933 | |
|---|
| | 2934 | /* This gets the correct name if we slay an invisible unique and don't have See Invisible. */ |
|---|
| | 2935 | monster_desc(unique_name, sizeof(unique_name), m_ptr, MDESC_SHOW | MDESC_IND2); |
|---|
| | 2936 | |
|---|
| | 2937 | /* Log the slaying of a unique */ |
|---|
| | 2938 | strnfmt(buf, sizeof(buf), "Killed %s", unique_name); |
|---|
| | 2939 | history_add(buf, HISTORY_SLAY_UNIQUE, 0); |
|---|
| | 2940 | } |
|---|
| | 2941 | |
|---|
| | 2942 | /* Gain experience */ |
|---|
| | 2943 | gain_exp(new_exp); |
|---|
| | 2944 | |
|---|
| | 2945 | /* Generate treasure */ |
|---|
| | 2946 | monster_death(m_idx); |
|---|
| | 2947 | |
|---|
| | 2948 | /* Recall even invisible uniques or winners */ |
|---|
| | 2949 | if (m_ptr->ml || (r_ptr->flags[0] & (RF0_UNIQUE))) |
|---|
| | 2950 | { |
|---|
| | 2951 | /* Count kills this life */ |
|---|
| | 2952 | if (l_ptr->pkills < MAX_SHORT) l_ptr->pkills++; |
|---|
| | 2953 | |
|---|
| | 2954 | /* Count kills in all lives */ |
|---|
| | 2955 | if (l_ptr->tkills < MAX_SHORT) l_ptr->tkills++; |
|---|
| | 2956 | |
|---|
| | 2957 | /* Hack -- Auto-recall */ |
|---|
| | 2958 | monster_race_track(m_ptr->r_idx); |
|---|
| | 2959 | } |
|---|
| | 2960 | |
|---|
| | 2961 | /* Delete the monster */ |
|---|
| | 2962 | delete_monster_idx(m_idx); |
|---|
| | 2963 | |
|---|
| | 2964 | /* Not afraid */ |
|---|
| | 2965 | (*fear) = FALSE; |
|---|
| | 2966 | |
|---|
| | 2967 | /* Monster is dead */ |
|---|
| | 2968 | return (TRUE); |
|---|
| | 2969 | } |
|---|
| | 2970 | |
|---|
| | 2971 | |
|---|
| | 2972 | /* Mega-Hack -- Pain cancels fear */ |
|---|
| | 2973 | if (m_ptr->monfear && (dam > 0)) |
|---|
| | 2974 | { |
|---|
| | 2975 | int tmp = randint1(dam); |
|---|
| | 2976 | |
|---|
| | 2977 | /* Cure a little fear */ |
|---|
| | 2978 | if (tmp < m_ptr->monfear) |
|---|
| | 2979 | { |
|---|
| | 2980 | /* Reduce fear */ |
|---|
| | 2981 | m_ptr->monfear -= tmp; |
|---|
| | 2982 | } |
|---|
| | 2983 | |
|---|
| | 2984 | /* Cure all the fear */ |
|---|
| | 2985 | else |
|---|
| | 2986 | { |
|---|
| | 2987 | /* Cure fear */ |
|---|
| | 2988 | m_ptr->monfear = 0; |
|---|
| | 2989 | |
|---|
| | 2990 | /* No more fear */ |
|---|
| | 2991 | (*fear) = FALSE; |
|---|
| | 2992 | } |
|---|
| | 2993 | } |
|---|
| | 2994 | |
|---|
| | 2995 | /* Sometimes a monster gets scared by damage */ |
|---|
| | 2996 | if (!m_ptr->monfear && !(r_ptr->flags[2] & (RF2_NO_FEAR)) && (dam > 0)) |
|---|
| | 2997 | { |
|---|
| | 2998 | int percentage; |
|---|
| | 2999 | |
|---|
| | 3000 | /* Percentage of fully healthy */ |
|---|
| | 3001 | percentage = (100L * m_ptr->hp) / m_ptr->maxhp; |
|---|
| | 3002 | |
|---|
| | 3003 | /* |
|---|
| | 3004 | * Run (sometimes) if at 10% or less of max hit points, |
|---|
| | 3005 | * or (usually) when hit for half its current hit points |
|---|
| | 3006 | */ |
|---|
| | 3007 | if ((randint1(10) >= percentage) || |
|---|
| | 3008 | ((dam >= m_ptr->hp) && (randint0(100) < 80))) |
|---|
| | 3009 | { |
|---|
| | 3010 | /* Hack -- note fear */ |
|---|
| | 3011 | (*fear) = TRUE; |
|---|
| | 3012 | |
|---|
| | 3013 | /* Hack -- Add some timed fear */ |
|---|
| | 3014 | m_ptr->monfear = (randint1(10) + |
|---|
| | 3015 | (((dam >= m_ptr->hp) && (percentage > 7)) ? |
|---|
| | 3016 | 20 : ((11 - percentage) * 5))); |
|---|
| | 3017 | } |
|---|
| | 3018 | } |
|---|
| | 3019 | |
|---|
| | 3020 | |
|---|
| | 3021 | /* Not dead yet */ |
|---|
| | 3022 | return (FALSE); |
|---|
| | 3023 | } |
|---|
| | 3024 | |
|---|