Ejemplo n.º 1
0
        private void DrawEntities(Map map, Position3D center, MousePicking mousePicking, out Vector2 renderOffset)
        {
            if (center == null)
            {
                renderOffset = new Vector2();
                return;
            }

            // reset the spritebatch Z
            m_SpriteBatch.Reset();
            // set the lighting variables.
            m_SpriteBatch.SetLightIntensity(Lighting.IsometricLightLevel);
            m_SpriteBatch.SetLightDirection(Lighting.IsometricLightDirection);

            // get variables that describe the tiles drawn in the viewport: the first tile to draw,
            // the offset to that tile, and the number of tiles drawn in the x and y dimensions.
            Point firstTile, renderDimensions;
            int   overDrawTilesOnSides            = 3;
            int   overDrawTilesAtTopAndBottom     = 6;
            int   overDrawAdditionalTilesOnBottom = 10;

            CalculateViewport(center, overDrawTilesOnSides, overDrawTilesAtTopAndBottom, out firstTile, out renderOffset, out renderDimensions);

            CountEntitiesRendered = 0;                                         // Count of objects rendered for statistics and debug

            MouseOverList  overList         = new MouseOverList(mousePicking); // List of entities mouse is over.
            List <AEntity> deferredToRemove = new List <AEntity>();

            for (int y = 0; y < renderDimensions.Y * 2 + 1 + overDrawAdditionalTilesOnBottom; y++)
            {
                Vector3 drawPosition = new Vector3();
                drawPosition.X = (firstTile.X - firstTile.Y + (y % 2)) * TILE_SIZE_FLOAT_HALF + renderOffset.X;
                drawPosition.Y = (firstTile.X + firstTile.Y + y) * TILE_SIZE_FLOAT_HALF + renderOffset.Y;

                Point firstTileInRow = new Point(firstTile.X + ((y + 1) / 2), firstTile.Y + (y / 2));

                for (int x = 0; x < renderDimensions.X + 1; x++)
                {
                    MapTile tile = map.GetMapTile(firstTileInRow.X - x, firstTileInRow.Y + x);
                    if (tile == null)
                    {
                        drawPosition.X -= TILE_SIZE_FLOAT;
                        continue;
                    }

                    List <AEntity> entities = tile.Entities;
                    bool           draw     = true;
                    for (int i = 0; i < entities.Count; i++)
                    {
                        if (entities[i] is DeferredEntity)
                        {
                            deferredToRemove.Add(entities[i]);
                        }

                        if (!m_DrawTerrain)
                        {
                            if ((entities[i] is Ground) || (entities[i].Z > tile.Ground.Z))
                            {
                                draw = false;
                            }
                        }

                        if ((entities[i].Z >= m_DrawMaxItemAltitude || (m_DrawMaxItemAltitude != 255 && entities[i] is Item && (entities[i] as Item).ItemData.IsRoof)) && !(entities[i] is Ground))
                        {
                            continue;
                        }

                        if (draw)
                        {
                            AEntityView view = entities[i].GetView();
                            if (view != null)
                            {
                                if (view.Draw(m_SpriteBatch, drawPosition, overList, map, !m_UnderSurface))
                                {
                                    CountEntitiesRendered++;
                                }
                            }
                        }
                    }

                    foreach (AEntity deferred in deferredToRemove)
                    {
                        tile.OnExit(deferred);
                    }
                    deferredToRemove.Clear();

                    drawPosition.X -= TILE_SIZE_FLOAT;
                }
            }

            OverheadsView.Render(m_SpriteBatch, overList, map, m_UnderSurface);

            // Update the MouseOver objects
            mousePicking.UpdateOverEntities(overList, mousePicking.Position);

            // Draw the objects we just send to the spritebatch.
            m_SpriteBatch.GraphicsDevice.SetRenderTarget(m_RenderTargetSprites);
            m_SpriteBatch.GraphicsDevice.Clear(Color.Black);
            m_SpriteBatch.FlushSprites(true);
            m_SpriteBatch.GraphicsDevice.SetRenderTarget(null);
        }
Ejemplo n.º 2
0
        private void InternalDrawEntities(Map map, Position3D center, MousePicking mousePick, out Vector2 renderOffset)
        {
            if (center == null)
            {
                renderOffset = new Vector2();
                return;
            }

            const int renderDimensionY          = 16; // the number of tiles that are drawn for half the screen (doubled to fill the entire screen).
            const int renderDimensionX          = 18; // the number of tiles that are drawn in the x-direction ( + renderExtraColumnsAtSides * 2 ).
            const int renderExtraColumnsAtSides = 2;  // the client draws additional tiles at the edge to make wide objects that are mostly offscreen visible.


            // when the player entity is higher (z) in the world, we must offset the first row drawn. This variable MUST be a multiple of 2.
            int renderZOffset = (center.Z / 14) * 2 + 4;
            // this is used to draw tall objects that would otherwise not be visible until their ground tile was on screen. This may still skip VERY tall objects (those weird jungle trees?)
            int renderExtraRowsAtBottom = renderZOffset + 10;

            Point firstTile = new Point(
                center.X + renderExtraColumnsAtSides - ((renderZOffset + 1) / 2),
                center.Y - renderDimensionY - renderExtraColumnsAtSides - (renderZOffset / 2));

            renderOffset.X  = ((Settings.Game.Resolution.Width + ((renderDimensionY) * 44)) / 2) - 22 + renderExtraColumnsAtSides * 44;
            renderOffset.X -= (int)((center.X_offset - center.Y_offset) * 22);
            renderOffset.X -= (firstTile.X - firstTile.Y) * 22;

            renderOffset.Y  = ((Settings.Game.Resolution.Height - (renderDimensionY * 44)) / 2);
            renderOffset.Y += (center.Z * 4) + (int)(center.Z_offset * 4);
            renderOffset.Y -= (int)((center.X_offset + center.Y_offset) * 22);
            renderOffset.Y -= (firstTile.X + firstTile.Y) * 22;
            renderOffset.Y -= (renderZOffset) * 22;

            ObjectsRendered = 0;                                                                           // Count of objects rendered for statistics and debug

            MouseOverList  overList         = new MouseOverList(_input.MousePosition, mousePick.PickOnly); // List of entities mouse is over.
            List <AEntity> deferredToRemove = new List <AEntity>();

            for (int col = 0; col < renderDimensionY * 2 + renderExtraRowsAtBottom; col++)
            {
                Vector3 drawPosition = new Vector3();
                drawPosition.X = (firstTile.X - firstTile.Y + (col % 2)) * 22 + renderOffset.X;
                drawPosition.Y = (firstTile.X + firstTile.Y + col) * 22 + renderOffset.Y;

                Point index = new Point(firstTile.X + ((col + 1) / 2), firstTile.Y + (col / 2));

                for (int row = 0; row < renderDimensionX + renderExtraColumnsAtSides * 2; row++)
                {
                    var maptile = map.GetMapTile(index.X - row, index.Y + row);
                    if (maptile == null)
                    {
                        continue;
                    }

                    foreach (var entity in maptile.Entities)
                    {
                        if (!DrawTerrain)
                        {
                            if (entity is Ground)
                            {
                                break;
                            }
                            if (entity.Z > maptile.Ground.Z)
                            {
                                break;
                            }
                        }

                        if (entity.Z >= _maxItemAltitude)
                        {
                            continue;
                        }

                        var view = entity.GetView();

                        if (view != null)
                        {
                            if (view.Draw(_spriteBatch, drawPosition, overList, map))
                            {
                                ObjectsRendered++;
                            }
                        }

                        if (entity is DeferredEntity)
                        {
                            deferredToRemove.Add(entity);
                        }
                    }

                    foreach (var deferred in deferredToRemove)
                    {
                        maptile.OnExit(deferred);
                    }
                    deferredToRemove.Clear();

                    drawPosition.X -= 44f;
                }
            }

            OverheadRenderer.Render(_spriteBatch, overList, map);

            // Update the MouseOver objects
            mousePick.UpdateOverEntities(overList, _input.MousePosition);

            // Draw the objects we just send to the spritebatch.
            _spriteBatch.Prepare(true, true);
            _spriteBatch.Flush();
        }