Пример #1
0
        /*
         * Let the given monster attempt to reproduce.
         *
         * Note that "reproduction" REQUIRES empty space.
         */
        public static bool multiply_monster(int m_idx)
        {
            Monster m_ptr = Cave.cave_monster(Cave.cave, m_idx);

            int i, y, x;

            bool result = false;

            /* Try up to 18 times */
            for (i = 0; i < 18; i++)
            {
                int d = 1;

                /* Pick a location */
                Cave.scatter(out y, out x, m_ptr.fy, m_ptr.fx, d, 0);

                /* Require an "empty" floor grid */
                if (!Cave.cave_empty_bold(y, x))
                {
                    continue;
                }

                /* Create a new monster (awake, no groups) */
                result = Monster_Make.place_new_monster(Cave.cave, y, x, m_ptr.r_idx, false, false,
                                                        Origin.DROP_BREED);

                /* Done */
                break;
            }

            /* Result */
            return(result);
        }
Пример #2
0
        /**
         * This is a helper function used by do_cmd_throw and do_cmd_fire.
         *
         * It abstracts out the projectile path, display code, identify and clean up
         * logic, while using the 'attack' parameter to do work particular to each
         * kind of attack.
         */
        public static void ranged_helper(int item, int dir, int range, int shots, ranged_attack attack)
        {
            /* Get the ammo */
            Object.Object o_ptr = Object.Object.object_from_item_idx(item);

            int          i, j;
            ConsoleColor missile_attr = o_ptr.object_attr();
            char         missile_char = o_ptr.object_char();

            //object_type object_type_body;
            Object.Object i_ptr = new Object.Object();            //&object_type_body;

            //char o_name[80];
            string o_name;

            int           path_n;
            List <ushort> path_g = new List <ushort>();          //[256];

            int msec = Player.Player_Other.instance.delay_factor;

            /* Start at the player */
            int x = Misc.p_ptr.px;
            int y = Misc.p_ptr.py;

            /* Predict the "target" location */
            short ty = (short)(y + 99 * Misc.ddy[dir]);
            short tx = (short)(x + 99 * Misc.ddx[dir]);

            bool hit_target = false;

            /* Check for target validity */
            if ((dir == 5) && Target.okay())
            {
                int taim;
                //char msg[80];
                string msg;
                Target.get(out tx, out ty);
                taim = Cave.distance(y, x, ty, tx);
                if (taim > range)
                {
                    msg = String.Format("Target out of range by {0} squares. Fire anyway? ", taim - range);
                    if (!Utilities.get_check(msg))
                    {
                        return;
                    }
                }
            }

            /* Sound */
            //sound(MSG_SHOOT); //later

            o_ptr.notice_on_firing();

            /* Describe the object */
            o_name = o_ptr.object_desc(Object.Object.Detail.FULL | Object.Object.Detail.SINGULAR);

            /* Actually "fire" the object -- Take a partial turn */
            Misc.p_ptr.energy_use = (short)(100 / shots);

            /* Calculate the path */
            path_n = Cave.project_path(out path_g, range, y, x, ty, tx, 0);

            /* Hack -- Handle stuff */
            Misc.p_ptr.handle_stuff();

            /* Start at the player */
            x = Misc.p_ptr.px;
            y = Misc.p_ptr.py;

            /* Project along the path */
            for (i = 0; i < path_n; ++i)
            {
                int ny = Cave.GRID_Y(path_g[i]);
                int nx = Cave.GRID_X(path_g[i]);

                /* Hack -- Stop before hitting walls */
                if (!Cave.cave_floor_bold(ny, nx))
                {
                    break;
                }

                /* Advance */
                x = nx;
                y = ny;

                /* Only do visuals if the player can "see" the missile */
                if (Cave.player_can_see_bold(y, x))
                {
                    Cave.print_rel(missile_char, missile_attr, y, x);
                    Cave.move_cursor_relative(y, x);

                    Term.fresh();
                    if (Misc.p_ptr.redraw != 0)
                    {
                        Misc.p_ptr.redraw_stuff();
                    }

                    Term.xtra(TERM_XTRA.DELAY, msec);
                    Cave.cave_light_spot(Cave.cave, y, x);

                    Term.fresh();
                    if (Misc.p_ptr.redraw != 0)
                    {
                        Misc.p_ptr.redraw_stuff();
                    }
                }
                else
                {
                    /* Delay anyway for consistency */
                    Term.xtra(TERM_XTRA.DELAY, msec);
                }

                /* Handle monster */
                if (Cave.cave.m_idx[y][x] > 0)
                {
                    break;
                }
            }

            /* Try the attack on the monster at (x, y) if any */
            if (Cave.cave.m_idx[y][x] > 0)
            {
                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];
                bool            visible = m_ptr.ml;

                bool fear = false;
                //char m_name[80];
                string m_name;
                string note_dies = r_ptr.monster_is_unusual() ? " is destroyed." : " dies.";

                attack_result result   = attack(o_ptr, y, x);
                int           dmg      = result.dmg;
                Message_Type  msg_type = result.msg_type;
                string        hit_verb = result.hit_verb;

                if (result.success)
                {
                    hit_target = true;

                    /* Get "the monster" or "it" */
                    m_name = m_ptr.monster_desc(0);

                    o_ptr.notice_attack_plusses();

                    /* No negative damage; change verb if no damage done */
                    if (dmg <= 0)
                    {
                        dmg      = 0;
                        hit_verb = "fail to harm";
                    }

                    if (!visible)
                    {
                        /* Invisible monster */
                        Utilities.msgt(Message_Type.MSG_SHOOT_HIT, "The {0} finds a mark.", o_name);
                    }
                    else
                    {
                        /* Visible monster */
                        if ((Message_Type)msg_type == Message_Type.MSG_SHOOT_HIT)
                        {
                            Utilities.msgt(Message_Type.MSG_SHOOT_HIT, "The {0} {1} {2}.", o_name, hit_verb, m_name);
                        }
                        else if ((Message_Type)msg_type == Message_Type.MSG_HIT_GOOD)
                        {
                            Utilities.msgt(Message_Type.MSG_HIT_GOOD, "The {0} {1} {2}. {3}", o_name, hit_verb, m_name,
                                           "It was a good hit!");
                        }
                        else if ((Message_Type)msg_type == Message_Type.MSG_HIT_GREAT)
                        {
                            Utilities.msgt(Message_Type.MSG_HIT_GREAT, "The {0} {1} {2}. {3}", o_name, hit_verb, m_name,
                                           "It was a great hit!");
                        }
                        else if ((Message_Type)msg_type == Message_Type.MSG_HIT_SUPERB)
                        {
                            Utilities.msgt(Message_Type.MSG_HIT_SUPERB, "The {0} {1} {2}. {3}", o_name, hit_verb, m_name,
                                           "It was a superb hit!");
                        }

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

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

                    /* Hit the monster, check for death */
                    if (!Monster_Make.mon_take_hit(Cave.cave.m_idx[y][x], dmg, ref fear, note_dies))
                    {
                        Monster_Message.message_pain(Cave.cave.m_idx[y][x], dmg);
                        if (fear && m_ptr.ml)
                        {
                            Monster_Message.add_monster_message(m_name, Cave.cave.m_idx[y][x], MON_MSG.FLEE_IN_TERROR, true);
                        }
                    }
                }
            }

            /* Obtain a local object */
            i_ptr = o_ptr.copy();
            i_ptr.split(o_ptr, 1);

            /* See if the ammunition broke or not */
            j = i_ptr.breakage_chance(hit_target);

            /* Drop (or break) near that location */
            Object.Object.drop_near(Cave.cave, i_ptr, j, y, x, true);

            if (item >= 0)
            {
                /* The ammo is from the inventory */
                Object.Object.inven_item_increase(item, -1);
                Object.Object.inven_item_describe(item);
                Object.Object.inven_item_optimize(item);
            }
            else
            {
                /* The ammo is from the floor */
                Object.Object.floor_item_increase(0 - item, -1);
                Object.Object.floor_item_optimize(0 - item);
            }
        }
Пример #3
0
        /*
         * Write the current dungeon
         */
        public static void wr_dungeon()
        {
            int y, x;

            byte tmp8u;

            byte count;
            byte prev_char;


            if (Misc.p_ptr.is_dead)
            {
                return;
            }

            /*** Basic info ***/

            /* Dungeon specific info follows */
            wr_u16b((ushort)Misc.p_ptr.depth);
            wr_u16b(Misc.daycount);
            wr_u16b((ushort)Misc.p_ptr.py);
            wr_u16b((ushort)Misc.p_ptr.px);
            wr_u16b((ushort)Cave.cave.height);
            wr_u16b((ushort)Cave.cave.width);
            wr_u16b(0);
            wr_u16b(0);


            /*** Simple "Run-Length-Encoding" of cave ***/

            /* Note that this will induce two wasted bytes */
            count     = 0;
            prev_char = 0;

            /* Dump the cave */
            for (y = 0; y < Cave.DUNGEON_HGT; y++)
            {
                for (x = 0; x < Cave.DUNGEON_WID; x++)
                {
                    /* Extract the important cave.info flags */
                    tmp8u = (byte)(Cave.cave.info[y][x] & (IMPORTANT_FLAGS));

                    /* If the run is broken, or too full, flush it */
                    if ((tmp8u != prev_char) || (count == byte.MaxValue))
                    {
                        wr_byte((byte)count);
                        wr_byte((byte)prev_char);
                        prev_char = tmp8u;
                        count     = 1;
                    }

                    /* Continue the run */
                    else
                    {
                        count++;
                    }
                }
            }

            /* Flush the data (if any) */
            if (count != 0)
            {
                wr_byte((byte)count);
                wr_byte((byte)prev_char);
            }

            /** Now dump the cave.info2[][] stuff **/

            /* Note that this will induce two wasted bytes */
            count     = 0;
            prev_char = 0;

            /* Dump the cave */
            for (y = 0; y < Cave.DUNGEON_HGT; y++)
            {
                for (x = 0; x < Cave.DUNGEON_WID; x++)
                {
                    /* Keep all the information from info2 */
                    tmp8u = (byte)Cave.cave.info2[y][x];

                    /* If the run is broken, or too full, flush it */
                    if ((tmp8u != prev_char) || (count == byte.MaxValue))
                    {
                        wr_byte((byte)count);
                        wr_byte((byte)prev_char);
                        prev_char = tmp8u;
                        count     = 1;
                    }

                    /* Continue the run */
                    else
                    {
                        count++;
                    }
                }
            }

            /* Flush the data (if any) */
            if (count != 0)
            {
                wr_byte((byte)count);
                wr_byte((byte)prev_char);
            }


            /*** Simple "Run-Length-Encoding" of cave ***/

            /* Note that this will induce two wasted bytes */
            count     = 0;
            prev_char = 0;

            /* Dump the cave */
            for (y = 0; y < Cave.DUNGEON_HGT; y++)
            {
                for (x = 0; x < Cave.DUNGEON_WID; x++)
                {
                    /* Extract a byte */
                    tmp8u = Cave.cave.feat[y][x];

                    /* If the run is broken, or too full, flush it */
                    if ((tmp8u != prev_char) || (count == byte.MaxValue))
                    {
                        wr_byte((byte)count);
                        wr_byte((byte)prev_char);
                        prev_char = tmp8u;
                        count     = 1;
                    }

                    /* Continue the run */
                    else
                    {
                        count++;
                    }
                }
            }

            /* Flush the data (if any) */
            if (count != 0)
            {
                wr_byte((byte)count);
                wr_byte((byte)prev_char);
            }


            /*** Compact ***/

            /* Compact the objects */
            Object.Object.compact_objects(0);

            /* Compact the monsters */
            Monster_Make.compact_monsters(0);
        }