Exemplo n.º 1
0
        /// <summary>
        /// Prep work before screen is painted
        /// </summary>
        /// <param name="gd"></param>
        /// <param name="state"></param>
        public void PreDraw(GraphicsDevice gd, WorldState state)
        {
            var pxOffset = -state.WorldSpace.GetScreenOffset();
            var damage   = Blueprint.Damage;
            var _2d      = state._2D;

            /**
             * Tasks:
             *  If zoom or rotation has changed, redraw all static layers
             *  If scroll has changed, redraw static layer if the scroll is outwith the buffered region
             *  If architecture has changed, redraw appropriate static layer
             *  If there is a new object in the static layer, redraw the static layer
             *  If an objects in the static layer has changed, redraw the static layer and move the object to the dynamic layer
             *  If wall visibility has changed, redraw wall layer (should think about how this works with breakthrough wall mode
             */

            var redrawStaticObjects = false;
            var redrawFloor         = false;
            var redrawWall          = false;

            var recacheWalls   = false;
            var recacheFloors  = false;
            var recacheTerrain = false;
            var recacheObjects = false;

            if (TicksSinceLight++ > 60 * 4)
            {
                damage.Add(new BlueprintDamage(BlueprintDamageType.LIGHTING_CHANGED));
            }

            WorldObjectRenderInfo info = null;

            foreach (var item in damage)
            {
                switch (item.Type)
                {
                case BlueprintDamageType.ROTATE:
                case BlueprintDamageType.ZOOM:
                case BlueprintDamageType.LEVEL_CHANGED:
                    recacheObjects = true;
                    recacheWalls   = true;
                    recacheFloors  = true;
                    recacheTerrain = true;
                    break;

                case BlueprintDamageType.SCROLL:
                    if (StaticObjects == null || StaticObjects.PxOffset != GetScrollIncrement(pxOffset))
                    {
                        redrawFloor         = true;
                        redrawWall          = true;
                        redrawStaticObjects = true;
                    }
                    break;

                case BlueprintDamageType.LIGHTING_CHANGED:
                    redrawFloor         = true;
                    redrawWall          = true;
                    redrawStaticObjects = true;

                    Blueprint.GenerateRoomLights();
                    state.OutsideColor   = Blueprint.RoomColors[1];
                    state._3D.RoomLights = Blueprint.RoomColors;
                    state._2D.AmbientLight.SetData(Blueprint.RoomColors);
                    TicksSinceLight = 0;
                    break;

                case BlueprintDamageType.OBJECT_MOVE:
                    /** Redraw if its in static layer **/
                    info = GetRenderInfo(item.Component);
                    if (info.Layer == WorldObjectRenderLayer.STATIC)
                    {
                        recacheObjects = true;
                        info.Layer     = WorldObjectRenderLayer.DYNAMIC;
                    }
                    if (item.Component is ObjectComponent)
                    {
                        ((ObjectComponent)item.Component).DynamicCounter = 0;
                    }
                    break;

                case BlueprintDamageType.OBJECT_GRAPHIC_CHANGE:
                    /** Redraw if its in static layer **/
                    info = GetRenderInfo(item.Component);
                    if (info.Layer == WorldObjectRenderLayer.STATIC)
                    {
                        recacheObjects = true;
                        info.Layer     = WorldObjectRenderLayer.DYNAMIC;
                    }
                    if (item.Component is ObjectComponent)
                    {
                        ((ObjectComponent)item.Component).DynamicCounter = 0;
                    }
                    break;

                case BlueprintDamageType.OBJECT_RETURN_TO_STATIC:
                    info = GetRenderInfo(item.Component);
                    if (info.Layer == WorldObjectRenderLayer.DYNAMIC)
                    {
                        recacheObjects = true;
                        info.Layer     = WorldObjectRenderLayer.STATIC;
                    }
                    break;

                case BlueprintDamageType.WALL_CUT_CHANGED:
                    recacheWalls = true;
                    break;

                case BlueprintDamageType.ROOF_STYLE_CHANGED:
                    Blueprint.RoofComp.StyleDirty = true;
                    break;

                case BlueprintDamageType.FLOOR_CHANGED:
                case BlueprintDamageType.WALL_CHANGED:
                    recacheTerrain = true;
                    recacheFloors  = true;
                    recacheWalls   = true;
                    Blueprint.RoofComp.ShapeDirty = true;
                    break;
                }
                if (recacheFloors || recacheTerrain)
                {
                    redrawFloor = true;
                }
                if (recacheWalls)
                {
                    redrawWall = true;
                }
                if (recacheObjects)
                {
                    redrawStaticObjects = true;
                }
            }
            damage.Clear();

            var tileOffset = state.WorldSpace.GetTileFromScreen(-pxOffset);
            //scroll buffer loads in increments of SCROLL_BUFFER
            var newOff    = GetScrollIncrement(pxOffset);
            var oldCenter = state.CenterTile;

            state.CenterTile += state.WorldSpace.GetTileFromScreen(newOff - pxOffset); //offset the scroll to the position of the scroll buffer.
            tileOffset        = state.CenterTile;

            pxOffset = newOff;

            if (recacheTerrain)
            {
                Blueprint.Terrain.RegenTerrain(gd, state, Blueprint);
            }

            if (recacheWalls)
            {
                _2d.Pause();
                _2d.Resume(); //clear the sprite buffer before we begin drawing what we're going to cache
                Blueprint.WallComp.Draw(gd, state);
                ClearDrawBuffer(StaticWallCache);
                _2d.End(StaticWallCache, true);
            }

            if (recacheFloors)
            {
                _2d.Pause();
                _2d.Resume(); //clear the sprite buffer before we begin drawing what we're going to cache
                Blueprint.FloorComp.Draw(gd, state);
                ClearDrawBuffer(StaticFloorCache);
                _2d.End(StaticFloorCache, true);
            }

            if (redrawFloor)
            {
                /** Draw archetecture to a texture **/
                Promise <Texture2D> bufferTexture = null;
                Promise <Texture2D> depthTexture  = null;
                using (var buffer = state._2D.WithBuffer(BUFFER_FLOOR_PIXEL, ref bufferTexture, BUFFER_FLOOR_DEPTH, ref depthTexture))
                {
                    _2d.SetScroll(pxOffset);
                    while (buffer.NextPass())
                    {
                        _2d.RenderCache(StaticFloorCache);
                        Blueprint.Terrain.DepthMode = _2d.OutputDepth;
                        Blueprint.Terrain.Draw(gd, state);
                    }
                }
                StaticFloor = new ScrollBuffer(bufferTexture.Get(), depthTexture.Get(), pxOffset, new Vector3(tileOffset, 0));
            }

            if (redrawWall)
            {
                Promise <Texture2D> bufferTexture = null;
                Promise <Texture2D> depthTexture  = null;
                using (var buffer = state._2D.WithBuffer(BUFFER_WALL_PIXEL, ref bufferTexture, BUFFER_WALL_DEPTH, ref depthTexture))
                {
                    _2d.SetScroll(pxOffset);
                    while (buffer.NextPass())
                    {
                        _2d.RenderCache(StaticWallCache);
                    }
                }
                StaticWall = new ScrollBuffer(bufferTexture.Get(), depthTexture.Get(), pxOffset, new Vector3(tileOffset, 0));
            }

            if (recacheObjects)
            {
                _2d.Pause();
                _2d.Resume();

                foreach (var obj in Blueprint.Objects)
                {
                    if (obj.Level > state.Level)
                    {
                        continue;
                    }
                    var renderInfo = GetRenderInfo(obj);
                    if (renderInfo.Layer == WorldObjectRenderLayer.STATIC)
                    {
                        var tilePosition = obj.Position;
                        _2d.OffsetPixel(state.WorldSpace.GetScreenFromTile(tilePosition));
                        _2d.OffsetTile(tilePosition);
                        _2d.SetObjID(obj.ObjectID);
                        obj.Draw(gd, state);
                    }
                }
                ClearDrawBuffer(StaticObjectsCache);
                _2d.End(StaticObjectsCache, true);
            }

            if (redrawStaticObjects)
            {
                /** Draw static objects to a texture **/
                Promise <Texture2D> bufferTexture = null;
                Promise <Texture2D> depthTexture  = null;
                using (var buffer = state._2D.WithBuffer(BUFFER_STATIC_OBJECTS_PIXEL, ref bufferTexture, BUFFER_STATIC_OBJECTS_DEPTH, ref depthTexture))
                {
                    _2d.SetScroll(pxOffset);
                    while (buffer.NextPass())
                    {
                        _2d.RenderCache(StaticObjectsCache);
                    }
                }
                StaticObjects = new ScrollBuffer(bufferTexture.Get(), depthTexture.Get(), pxOffset, new Vector3(tileOffset, 0));
            }
            state.CenterTile = oldCenter; //revert to our real scroll position
        }