Exemple #1
0
        /**
         * Helper function used with ranged_helper by do_cmd_fire.
         */
        public static attack_result make_ranged_shot(Object.Object o_ptr, int y, int x)
        {
            attack_result result = new attack_result(false, 0, 0, "hit");

            Object.Object j_ptr = Misc.p_ptr.inventory[Misc.INVEN_BOW];

            Monster.Monster m_ptr = Cave.cave_monster(Cave.cave, Cave.cave.m_idx[y][x]);
            Monster_Race    r_ptr = Misc.r_info[m_ptr.r_idx];

            int bonus   = Misc.p_ptr.state.to_h + o_ptr.to_h + j_ptr.to_h;
            int chance  = Misc.p_ptr.state.skills[(int)Skill.TO_HIT_BOW] + bonus * Misc.BTH_PLUS_ADJ;
            int chance2 = chance - Cave.distance(Misc.p_ptr.py, Misc.p_ptr.px, y, x);

            int  multiplier = Misc.p_ptr.state.ammo_mult;
            Slay best_s_ptr = null;

            /* Did we hit it (penalize distance travelled) */
            if (!test_hit(chance2, r_ptr.ac, m_ptr.ml))
            {
                return(result);
            }

            result.success = true;

            Slay.improve_attack_modifier(o_ptr, m_ptr, ref best_s_ptr, true, false);
            Slay.improve_attack_modifier(j_ptr, m_ptr, ref best_s_ptr, true, false);

            /* If we have a slay, modify the multiplier appropriately */
            if (best_s_ptr != null)
            {
                result.hit_verb = best_s_ptr.range_verb;
                multiplier     += best_s_ptr.mult;
            }

            /* Apply damage: multiplier, slays, criticals, bonuses */
            result.dmg  = Random.damroll(o_ptr.dd, o_ptr.ds);
            result.dmg += o_ptr.to_d + j_ptr.to_d;
            result.dmg *= multiplier;
            result.dmg  = critical_shot(o_ptr.weight, o_ptr.to_h, result.dmg, ref result.msg_type);

            Misc.p_ptr.inventory[Misc.INVEN_BOW].notice_attack_plusses();

            return(result);
        }
Exemple #2
0
        /**
         * Attack the monster at the given location with a single blow.
         */
        static bool py_attack_real(int y, int x, ref bool fear)
        {
            /* Information about the target of the attack */
            Monster.Monster m_ptr = Cave.cave_monster(Cave.cave, Cave.cave.m_idx[y][x]);
            Monster_Race    r_ptr = Misc.r_info[m_ptr.r_idx];
            //char m_name[80];
            string m_name;
            bool   stop = false;

            /* The weapon used */
            Object.Object o_ptr = Misc.p_ptr.inventory[Misc.INVEN_WIELD];

            /* Information about the attack */
            int  bonus    = Misc.p_ptr.state.to_h + o_ptr.to_h;
            int  chance   = Misc.p_ptr.state.skills[(int)Skill.TO_HIT_MELEE] + bonus * Misc.BTH_PLUS_ADJ;
            bool do_quake = false;
            bool success  = false;

            /* Default to punching for one damage */
            string       hit_verb = "punch";
            int          dmg      = 1;
            Message_Type msg_type = Message_Type.MSG_HIT;

            /* Extract monster name (or "it") */
            m_name = m_ptr.monster_desc(0);

            /* Auto-Recall if possible and visible */
            if (m_ptr.ml)
            {
                Cave.monster_race_track(m_ptr.r_idx);
            }

            /* Track a new monster */
            if (m_ptr.ml)
            {
                Cave.health_track(Misc.p_ptr, Cave.cave.m_idx[y][x]);
            }

            /* Handle player fear (only for invisible monsters) */
            if (Misc.p_ptr.check_state(Object_Flag.AFRAID, Misc.p_ptr.state.flags))
            {
                Utilities.msgt(Message_Type.MSG_AFRAID, "You are too afraid to attack {0}!", m_name);
                return(false);
            }

            /* Disturb the monster */
            Monster.Monster.mon_clear_timed(Cave.cave.m_idx[y][x], (int)Misc.MON_TMD.SLEEP, Misc.MON_TMD_FLG_NOMESSAGE, false);

            /* See if the player hit */
            success = test_hit(chance, (int)r_ptr.ac, m_ptr.ml);

            /* If a miss, skip this hit */
            if (!success)
            {
                Utilities.msgt(Message_Type.MSG_MISS, "You miss {0}.", m_name);
                return(false);
            }

            /* Handle normal weapon */
            if (o_ptr.kind != null)
            {
                int  i;
                Slay best_s_ptr = null;

                hit_verb = "hit";

                /* Get the best attack from all slays or
                 * brands on all non-launcher equipment */
                for (i = Misc.INVEN_LEFT; i < Misc.INVEN_TOTAL; i++)
                {
                    Object.Object obj = Misc.p_ptr.inventory[i];
                    if (obj.kind != null)
                    {
                        Slay.improve_attack_modifier(obj, m_ptr, ref best_s_ptr, true, false);
                    }
                }

                Slay.improve_attack_modifier(o_ptr, m_ptr, ref best_s_ptr, true, false);
                if (best_s_ptr != null)
                {
                    hit_verb = best_s_ptr.melee_verb;
                }

                dmg  = Random.damroll(o_ptr.dd, o_ptr.ds);
                dmg *= (best_s_ptr == null) ? 1 : best_s_ptr.mult;

                dmg += o_ptr.to_d;
                dmg  = critical_norm(o_ptr.weight, o_ptr.to_h, dmg, ref msg_type);

                /* Learn by use for the weapon */
                o_ptr.notice_attack_plusses();

                if (Misc.p_ptr.check_state(Object_Flag.IMPACT, Misc.p_ptr.state.flags) && dmg > 50)
                {
                    do_quake = true;
                    Object.Object.wieldeds_notice_flag(Misc.p_ptr, Object_Flag.IMPACT.value);
                }
            }

            /* Learn by use for other equipped items */
            Object.Object.wieldeds_notice_on_attack();

            /* Apply the player damage bonuses */
            dmg += Misc.p_ptr.state.to_d;

            /* No negative damage */
            if (dmg <= 0)
            {
                dmg = 0;
            }

            /* Tell the player what happened */
            if (dmg <= 0)
            {
                Utilities.msgt(Message_Type.MSG_MISS, "You fail to harm {0}.", m_name);
            }
            else if (msg_type == Message_Type.MSG_HIT)
            {
                Utilities.msgt(Message_Type.MSG_HIT, "You {0} {1}.", hit_verb, m_name);
            }
            else if (msg_type == Message_Type.MSG_HIT_GOOD)
            {
                Utilities.msgt(Message_Type.MSG_HIT_GOOD, "You {0} {1}. {2}", hit_verb, m_name, "It was a good hit!");
            }
            else if (msg_type == Message_Type.MSG_HIT_GREAT)
            {
                Utilities.msgt(Message_Type.MSG_HIT_GREAT, "You {0} {1}. {2}", hit_verb, m_name, "It was a great hit!");
            }
            else if (msg_type == Message_Type.MSG_HIT_SUPERB)
            {
                Utilities.msgt(Message_Type.MSG_HIT_SUPERB, "You {0} {1}. {2}", hit_verb, m_name, "It was a superb hit!");
            }
            else if (msg_type == Message_Type.MSG_HIT_HI_GREAT)
            {
                Utilities.msgt(Message_Type.MSG_HIT_HI_GREAT, "You {0} {1}. {2}", hit_verb, m_name, "It was a *GREAT* hit!");
            }
            else if (msg_type == Message_Type.MSG_HIT_HI_SUPERB)
            {
                Utilities.msgt(Message_Type.MSG_HIT_HI_SUPERB, "You {0} {1}. {2}", hit_verb, m_name, "It was a *SUPERB* hit!");
            }

            /* Complex message */
            if (Misc.p_ptr.wizard)
            {
                Utilities.msg("You do {0} (out of {1}) damage.", dmg, m_ptr.hp);
            }

            /* Confusion attack */
            if (Misc.p_ptr.confusing != 0)
            {
                Misc.p_ptr.confusing = 0;                //false;
                Utilities.msg("Your hands stop glowing.");

                Monster.Monster.mon_inc_timed(Cave.cave.m_idx[y][x], Misc.MON_TMD.CONF,
                                              (10 + Random.randint0(Misc.p_ptr.lev) / 10), Misc.MON_TMD_FLG_NOTIFY, false);
            }

            /* Damage, check for fear and death */
            stop = Monster.Monster_Make.mon_take_hit(Cave.cave.m_idx[y][x], dmg, ref fear, null);

            if (stop)
            {
                fear = false;
            }

            /* Apply earthquake brand */
            if (do_quake)
            {
                throw new NotImplementedException();
                //earthquake(Misc.p_ptr.py, Misc.p_ptr.px, 10);
                //if (Cave.cave.m_idx[y][x] == 0) stop = true;
            }

            return(stop);
        }