Changeset 1014

Show
Ignore:
Timestamp:
10/01/08 19:39:28 (3 months ago)
Author:
takkaria
Message:

Move monster hit/death stuff to a more appropriate place (xtra2.c->monster2.c).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/externs.h

    r996 r1014  
    409409extern void message_pain(int m_idx, int dam); 
    410410extern void update_smart_learn(int m_idx, int what); 
     411void monster_death(int m_idx); 
     412bool mon_take_hit(int m_idx, int dam, bool *fear, cptr note); 
    411413 
    412414/* pathfind.c */ 
     
    648650void gain_exp(s32b amount); 
    649651void lose_exp(s32b amount); 
    650 void monster_death(int m_idx); 
    651 bool mon_take_hit(int m_idx, int dam, bool *fear, cptr note); 
    652652bool modify_panel(term *t, int wy, int wx); 
    653653bool adjust_panel(int y, int x); 
  • trunk/src/monster/monster2.c

    r999 r1014  
    1818#include "angband.h" 
    1919 
     20#include "object/tvalsval.h" 
    2021 
    2122 
     
    25262527 
    25272528 
     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 */ 
     2536static 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 */ 
     2566static 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 */ 
     2615void 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 */ 
     2838bool 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 
  • trunk/src/xtra2.c

    r999 r1014  
    11411141 
    11421142 
    1143  
    1144  
    1145 /* 
    1146  * Hack -- Return the "automatic coin type" of a monster race 
    1147  * Used to allocate proper treasure when "Creeping coins" die 
    1148  * 
    1149  * Note the use of actual "monster names".  XXX XXX XXX 
    1150  */ 
    1151 static int get_coin_type(const monster_race *r_ptr) 
    1152 { 
    1153         cptr name = (r_name + r_ptr->name); 
    1154  
    1155         /* Analyze "coin" monsters */ 
    1156         if (r_ptr->d_char == '$') 
    1157         { 
    1158                 /* Look for textual clues */ 
    1159                 if (strstr(name, " copper ")) return (SV_COPPER); 
    1160                 if (strstr(name, " silver ")) return (SV_SILVER); 
    1161                 if (strstr(name, " gold ")) return (SV_GOLD); 
    1162                 if (strstr(name, " mithril ")) return (SV_MITHRIL); 
    1163                 if (strstr(name, " adamantite ")) return (SV_ADAMANTITE); 
    1164  
    1165                 /* Look for textual clues */ 
    1166                 if (strstr(name, "Copper ")) return (SV_COPPER); 
    1167                 if (strstr(name, "Silver ")) return (SV_SILVER); 
    1168                 if (strstr(name, "Gold ")) return (SV_GOLD); 
    1169                 if (strstr(name, "Mithril ")) return (SV_MITHRIL); 
    1170                 if (strstr(name, "Adamantite ")) return (SV_ADAMANTITE); 
    1171         } 
    1172  
    1173         /* Assume nothing */ 
    1174         return (SV_GOLD_ANY); 
    1175 } 
    1176  
    1177  
    1178 /* 
    1179  * Create magical stairs after finishing a quest monster. 
    1180  */ 
    1181 static void build_quest_stairs(int y, int x) 
    1182 { 
    1183         int ny, nx; 
    1184  
    1185  
    1186         /* Stagger around */ 
    1187         while (!cave_valid_bold(y, x)) 
    1188         { 
    1189                 int d = 1; 
    1190  
    1191                 /* Pick a location */ 
    1192                 scatter(&ny, &nx, y, x, d, 0); 
    1193  
    1194                 /* Stagger */ 
    1195                 y = ny; x = nx; 
    1196         } 
    1197  
    1198         /* Destroy any objects */ 
    1199         delete_object(y, x); 
    1200  
    1201         /* Explain the staircase */ 
    1202         msg_print("A magical staircase appears..."); 
    1203  
    1204         /* Create stairs down */ 
    1205         cave_set_feat(y, x, FEAT_MORE); 
    1206  
    1207         /* Update the visuals */ 
    1208         p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); 
    1209  
    1210         /* Fully update the flow */ 
    1211         p_ptr->update |= (PU_FORGET_FLOW | PU_UPDATE_FLOW); 
    1212 } 
    1213  
    1214  
    1215 /* 
    1216  * Handle the "death" of a monster. 
    1217  * 
    1218  * Disperse treasures centered at the monster location based on the 
    1219  * various flags contained in the monster flags fields. 
    1220  * 
    1221  * Check for "Quest" completion when a quest monster is killed. 
    1222  * 
    1223  * Note that only the player can induce "monster_death()" on Uniques. 
    1224  * Thus (for now) all Quest monsters should be Uniques. 
    1225  * 
    1226  * Note that monsters can now carry objects, and when a monster dies, 
    1227  * it drops all of its objects, which may disappear in crowded rooms. 
    1228  */ 
    1229 void monster_death(int m_idx) 
    1230 { 
    1231         int i, j, y, x, level; 
    1232  
    1233         int dump_item = 0; 
    1234         int dump_gold = 0; 
    1235  
    1236         int number = 0; 
    1237         int total = 0; 
    1238  
    1239         s16b this_o_idx, next_o_idx = 0; 
    1240  
    1241         monster_type *m_ptr = &mon_list[m_idx]; 
    1242  
    1243         monster_race *r_ptr = &r_info[m_ptr->r_idx]; 
    1244  
    1245         bool visible = (m_ptr->ml || (r_ptr->flags[0] & (RF0_UNIQUE))); 
    1246  
    1247         bool great = (r_ptr->flags[0] & (RF0_DROP_GREAT)) ? TRUE : FALSE; 
    1248         bool good = ((r_ptr->flags[0] & (RF0_DROP_GOOD)) ? TRUE : FALSE) || great; 
    1249  
    1250         bool gold_ok = (!(r_ptr->flags[0] & (RF0_ONLY_ITEM))); 
    1251         bool item_ok = (!(r_ptr->flags[0] & (RF0_ONLY_GOLD))); 
    1252  
    1253         int force_coin = get_coin_type(r_ptr); 
    1254  
    1255         object_type *i_ptr; 
    1256         object_type object_type_body; 
    1257  
    1258  
    1259         /* Get the location */ 
    1260         y = m_ptr->fy; 
    1261         x = m_ptr->fx; 
    1262  
    1263  
    1264         /* Drop objects being carried */ 
    1265         for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) 
    1266         { 
    1267                 object_type *o_ptr; 
    1268  
    1269                 /* Get the object */ 
    1270                 o_ptr = &o_list[this_o_idx]; 
    1271  
    1272                 /* Get the next object */ 
    1273                 next_o_idx = o_ptr->next_o_idx; 
    1274  
    1275                 /* Paranoia */ 
    1276                 o_ptr->held_m_idx = 0; 
    1277  
    1278                 /* Get local object */ 
    1279                 i_ptr = &object_type_body; 
    1280  
    1281                 /* Copy the object */ 
    1282                 object_copy(i_ptr, o_ptr); 
    1283  
    1284                 /* Delete the object */ 
    1285                 delete_object_idx(this_o_idx); 
    1286  
    1287                 /* Drop it */ 
    1288                 drop_near(i_ptr, -1, y, x); 
    1289         } 
    1290  
    1291         /* Forget objects */ 
    1292         m_ptr->hold_o_idx = 0; 
    1293  
    1294  
    1295         /* Mega-Hack -- drop "winner" treasures */ 
    1296         if (r_ptr->flags[0] & (RF0_DROP_CHOSEN)) 
    1297         { 
    1298                 /* Get local object */ 
    1299                 i_ptr = &object_type_body; 
    1300  
    1301                 /* Mega-Hack -- Prepare to make "Grond" */ 
    1302                 object_prep(i_ptr, lookup_kind(TV_HAFTED, SV_GROND)); 
    1303  
    1304                 /* Mega-Hack -- Mark this item as "Grond" */ 
    1305                 i_ptr->name1 = ART_GROND; 
    1306  
    1307                 /* Mega-Hack -- Actually create "Grond" */ 
    1308                 apply_magic(i_ptr, -1, TRUE, TRUE, TRUE); 
    1309                 i_ptr->origin = ORIGIN_DROP; 
    1310                 i_ptr->origin_depth = p_ptr->depth; 
    1311                 i_ptr->origin_xtra = m_ptr->r_idx; 
    1312  
    1313                 /* Drop it in the dungeon */ 
    1314                 drop_near(i_ptr, -1, y, x); 
    1315  
    1316  
    1317                 /* Get local object */ 
    1318                 i_ptr = &object_type_body; 
    1319  
    1320                 /* Mega-Hack -- Prepare to make "Morgoth" */ 
    1321                 object_prep(i_ptr, lookup_kind(TV_CROWN, SV_MORGOTH)); 
    1322                 i_ptr->origin = ORIGIN_DROP; 
    1323                 i_ptr->origin_depth = p_ptr->depth; 
    1324                 i_ptr->origin_xtra = m_ptr->r_idx; 
    1325  
    1326                 /* Mega-Hack -- Mark this item as "Morgoth" */ 
    1327                 i_ptr->name1 = ART_MORGOTH; 
    1328  
    1329                 /* Mega-Hack -- Actually create "Morgoth" */ 
    1330                 apply_magic(i_ptr, -1, TRUE, TRUE, TRUE); 
    1331  
    1332                 /* Drop it in the dungeon */ 
    1333                 drop_near(i_ptr, -1, y, x); 
    1334         } 
    1335  
    1336  
    1337         /* Determine how much we can drop */ 
    1338         if ((r_ptr->flags[0] & RF0_DROP_20) && (randint0(100) < 20)) number++; 
    1339         if ((r_ptr->flags[0] & RF0_DROP_40) && (randint0(100) < 40)) number++; 
    1340         if ((r_ptr->flags[0] & RF0_DROP_60) && (randint0(100) < 60)) number++; 
    1341  
    1342         if (r_ptr->flags[0] & RF0_DROP_4) number += rand_range(2, 6); 
    1343         if (r_ptr->flags[0] & RF0_DROP_3) number += rand_range(2, 4); 
    1344         if (r_ptr->flags[0] & RF0_DROP_2) number += rand_range(1, 3); 
    1345         if (r_ptr->flags[0] & RF0_DROP_1) number++; 
    1346  
    1347         /* Average monster level and current depth */ 
    1348         level = (p_ptr->depth + r_ptr->level) / 2; 
    1349  
    1350         /* Drop some objects */ 
    1351         for (j = 0; j < number; j++) 
    1352         { 
    1353                 /* Get local object */ 
    1354                 i_ptr = &object_type_body; 
    1355  
    1356                 /* Wipe the object */ 
    1357                 object_wipe(i_ptr); 
    1358  
    1359                 /* Make Gold */ 
    1360                 if (gold_ok && (!item_ok || (randint0(100) < 50))) 
    1361                 { 
    1362                         /* Make some gold */ 
    1363                         make_gold(i_ptr, level, force_coin); 
    1364                         dump_gold++; 
    1365                 } 
    1366  
    1367                 /* Make Object */ 
    1368                 else 
    1369                 { 
    1370                         /* Make an object */ 
    1371                         if (!make_object(i_ptr, level, good, great)) continue; 
    1372                         dump_item++; 
    1373                 } 
    1374  
    1375                 /* Set origin */ 
    1376                 i_ptr->origin = visible ? ORIGIN_DROP : ORIGIN_DROP_UNKNOWN; 
    1377                 i_ptr->origin_depth = p_ptr->depth; 
    1378                 i_ptr->origin_xtra = m_ptr->r_idx; 
    1379  
    1380                 /* Drop it in the dungeon */ 
    1381                 drop_near(i_ptr, -1, y, x); 
    1382         } 
    1383  
    1384         /* Take note of any dropped treasure */ 
    1385         if (visible && (dump_item || dump_gold)) 
    1386         { 
    1387                 /* Take notes on treasure */ 
    1388                 lore_treasure(m_idx, dump_item, dump_gold); 
    1389         } 
    1390  
    1391         /* Update monster list window */ 
    1392         p_ptr->redraw |= PR_MONLIST; 
    1393  
    1394         /* Only process "Quest Monsters" */ 
    1395         if (!(r_ptr->flags[0] & (RF0_QUESTOR))) return; 
    1396  
    1397         /* Hack -- Mark quests as complete */ 
    1398         for (i = 0; i < MAX_Q_IDX; i++) 
    1399         { 
    1400                 /* Hack -- note completed quests */ 
    1401                 if (q_list[i].level == r_ptr->level) q_list[i].level = 0; 
    1402  
    1403                 /* Count incomplete quests */ 
    1404                 if (q_list[i].level) total++; 
    1405         } 
    1406  
    1407         /* Build magical stairs */ 
    1408         build_quest_stairs(y, x); 
    1409  
    1410         /* Nothing left, game over... */ 
    1411         if (total == 0) 
    1412         { 
    1413                 /* Total winner */ 
    1414                 p_ptr->total_winner = TRUE; 
    1415  
    1416                 /* Redraw the "title" */ 
    1417                 p_ptr->redraw |= (PR_TITLE); 
    1418  
    1419                 /* Congratulations */ 
    1420                 msg_print("*** CONGRATULATIONS ***"); 
    1421                 msg_print("You have won the game!"); 
    1422                 msg_print("You may retire (commit suicide) when you are ready."); 
    1423         } 
    1424 } 
    1425  
    1426  
    1427  
    1428  
    1429 /* 
    1430  * Decrease a monster's hit points, handle monster death. 
    1431  * 
    1432  * We return TRUE if the monster has been killed (and deleted). 
    1433  * 
    1434  * We announce monster death (using an optional "death message" 
    1435  * if given, and a otherwise a generic killed/destroyed message). 
    1436  * 
    1437  * Only "physical attacks" can induce the "You have slain" message. 
    1438  * Missile and Spell attacks will induce the "dies" message, or 
    1439  * various "specialized" messages.  Note that "You have destroyed" 
    1440  * and "is destroyed" are synonyms for "You have slain" and "dies". 
    1441  * 
    1442  * Invisible monsters induce a special "You have killed it." message. 
    1443  * 
    1444  * Hack -- we "delay" fear messages by passing around a "fear" flag. 
    1445  * 
    1446  * Consider decreasing monster experience over time, say, by using 
    1447  * "(m_exp * m_lev * (m_lev)) / (p_lev * (m_lev + n_killed))" instead 
    1448  * of simply "(m_exp * m_lev) / (p_lev)", to make the first monster 
    1449  * worth more than subsequent monsters.  This would also need to 
    1450  * induce changes in the monster recall code.  XXX XXX XXX 
    1451  */ 
    1452 bool mon_take_hit(int m_idx, int dam, bool *fear, cptr note) 
    1453 { 
    1454         monster_type *m_ptr = &mon_list[m_idx]; 
    1455  
    1456         monster_race *r_ptr = &r_info[m_ptr->r_idx]; 
    1457  
    1458         monster_lore *l_ptr = &l_list[m_ptr->r_idx]; 
    1459  
    1460         s32b div, new_exp, new_exp_frac; 
    1461  
    1462  
    1463         /* Redraw (later) if needed */ 
    1464         if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH); 
    1465  
    1466  
    1467         /* Wake it up */ 
    1468         m_ptr->csleep = 0; 
    1469  
    1470         /* Hurt it */ 
    1471         m_ptr->hp -= dam; 
    1472  
    1473         /* It is dead now */ 
    1474         if (m_ptr->hp < 0) 
    1475         { 
    1476                 char m_name[80]; 
    1477                 char buf[80]; 
    1478  
    1479                 /* Assume normal death sound */ 
    1480                 int soundfx = MSG_KILL; 
    1481  
    1482                 /* Play a special sound if the monster was unique */ 
    1483                 if (r_ptr->flags[0] & RF0_UNIQUE)  
    1484                 { 
    1485                         /* Mega-Hack -- Morgoth -- see monster_death() */ 
    1486                         if (r_ptr->flags[0] & RF0_DROP_CHOSEN) 
    1487                                 soundfx = MSG_KILL_KING; 
    1488                         else 
    1489                                 soundfx = MSG_KILL_UNIQUE; 
    1490                 } 
    1491  
    1492                 /* Extract monster name */ 
    1493                 monster_desc(m_name, sizeof(m_name), m_ptr, 0); 
    1494  
    1495                 /* Death by Missile/Spell attack */ 
    1496                 if (note) 
    1497                 { 
    1498                         message_format(soundfx, m_ptr->r_idx, "%^s%s", m_name, note); 
    1499                 } 
    1500  
    1501                 /* Death by physical attack -- invisible monster */ 
    1502                 else if (!m_ptr->ml) 
    1503                 { 
    1504                         message_format(soundfx, m_ptr->r_idx, "You have killed %s.", m_name); 
    1505                 } 
    1506  
    1507                 /* Death by Physical attack -- non-living monster */ 
    1508                 else if ((r_ptr->flags[2] & (RF2_DEMON | RF2_UNDEAD)) || 
    1509                          (r_ptr->flags[1] & (RF1_STUPID)) || 
    1510                          (strchr("Evg", r_ptr->d_char))) 
    1511                 { 
    1512                         message_format(soundfx, m_ptr->r_idx, "You have destroyed %s.", m_name); 
    1513                 } 
    1514  
    1515                 /* Death by Physical attack -- living monster */ 
    1516                 else 
    1517                 { 
    1518                         message_format(soundfx, m_ptr->r_idx, "You have slain %s.", m_name); 
    1519                 } 
    1520  
    1521                 /* Player level */ 
    1522                 div = p_ptr->lev; 
    1523  
    1524                 /* Give some experience for the kill */ 
    1525                 new_exp = ((long)r_ptr->mexp * r_ptr->level) / div; 
    1526  
    1527                 /* Handle fractional experience */ 
    1528                 new_exp_frac = ((((long)r_ptr->mexp * r_ptr->level) % div) 
    1529                                 * 0x10000L / div) + p_ptr->exp_frac; 
    1530  
    1531                 /* Keep track of experience */ 
    1532                 if (new_exp_frac >= 0x10000L) 
    1533                 { 
    1534                         new_exp++; 
    1535                         p_ptr->exp_frac = (u16b)(new_exp_frac - 0x10000L); 
    1536                 } 
    1537                 else 
    1538                 { 
    1539                         p_ptr->exp_frac = (u16b)new_exp_frac; 
    1540                 } 
    1541  
    1542                 /* When the player kills a Unique, it stays dead */ 
    1543                 if (r_ptr->flags[0] & (RF0_UNIQUE)) 
    1544                 { 
    1545                         char unique_name[80]; 
    1546                         r_ptr->max_num = 0; 
    1547  
    1548                         /* This gets the correct name if we slay an invisible unique and don't have See Invisible. */ 
    1549                         monster_desc(unique_name, sizeof(unique_name), m_ptr, MDESC_SHOW | MDESC_IND2); 
    1550  
    1551                         /* Log the slaying of a unique */ 
    1552                         strnfmt(buf, sizeof(buf), "Killed %s", unique_name); 
    1553                         history_add(buf, HISTORY_SLAY_UNIQUE, 0); 
    1554                 } 
    1555  
    1556                 /* Gain experience */ 
    1557                 gain_exp(new_exp); 
    1558  
    1559                 /* Generate treasure */ 
    1560                 monster_death(m_idx); 
    1561  
    1562                 /* Recall even invisible uniques or winners */ 
    1563                 if (m_ptr->ml || (r_ptr->flags[0] & (RF0_UNIQUE))) 
    1564                 { 
    1565                         /* Count kills this life */ 
    1566                         if (l_ptr->pkills < MAX_SHORT) l_ptr->pkills++; 
    1567  
    1568                         /* Count kills in all lives */ 
    1569                         if (l_ptr->tkills < MAX_SHORT) l_ptr->tkills++; 
    1570  
    1571                         /* Hack -- Auto-recall */ 
    1572                         monster_race_track(m_ptr->r_idx); 
    1573                 } 
    1574  
    1575                 /* Delete the monster */ 
    1576