Ejemplo n.º 1
0
        public void DrawScrollBuffer(ScrollBuffer buffer, Vector2 offset, Vector3 tileOffset, WorldState state)
        {
            var offsetDiff = buffer.PxOffset - offset;
            var tOff       = buffer.WorldPosition - tileOffset;
            var spr        = new _2DSprite
            {
                RenderMode = (buffer.Depth == null) ? _2DBatchRenderMode.NO_DEPTH : _2DBatchRenderMode.RESTORE_DEPTH,
                Pixel      = buffer.Pixel,
                Depth      = buffer.Depth,
                SrcRect    = new Rectangle(0, 0, buffer.Pixel.Width, buffer.Pixel.Height),
                DestRect   = new Rectangle((int)offsetDiff.X - 2, (int)offsetDiff.Y, buffer.Pixel.Width, buffer.Pixel.Height),
            };

            this.Draw(spr);
            spr.AbsoluteWorldPosition = tOff * new Vector3(1, 1.23f, 1) * WorldSpace.WorldUnitsPerTile;
            if (state.Rotation == WorldRotation.TopRight || state.Rotation == WorldRotation.BottomRight)
            {
                spr.AbsoluteWorldPosition.Y *= -1;
            }
            //why does this even work???
            //i added the 1.23 scaling factor on the y direction because at 1 it was shifting slightly
            //it's still not perfect, which leads me to believe there is a bigger problem...
            //after that I flip the offset if we're looking at it the other way, which inverts the z offset and corrects it somehow...
            //i mean, techically this should work with NO multipliers at all!
        }
Ejemplo n.º 2
0
        public void PreDraw(GraphicsDevice gd, WorldState state)
        {
            var changes = state.Changes;

            if (changes.DrawImmediate)
            {
                return;
            }
            if (changes.StaticSurfaceDirty)
            {
                var pxOffset  = -state.WorldSpace.GetScreenOffset();
                var newOff    = GetScrollIncrement(pxOffset, state);
                var oldCenter = state.CenterTile;
                state.CenterTile += state.WorldSpace.GetTileFromScreen(newOff - pxOffset); //offset the scroll to the position of the scroll buffer.
                var tileOffset = state.CenterTile;

                /** Draw static objects to a texture **/
                Promise <Texture2D> bufferTexture = null;
                Promise <Texture2D> depthTexture  = null;
                using (var buffer = state._2D.WithBuffer(BUFFER_STATIC, ref bufferTexture, BUFFER_STATIC_DEPTH, ref depthTexture))
                {
                    while (buffer.NextPass())
                    {
                        World.Architecture.StaticDraw(gd, state, newOff);
                        World.Entities.StaticDraw(gd, state, newOff);
                    }
                }
                StaticSurface = new ScrollBuffer(bufferTexture.Get(), depthTexture.Get(), newOff, new Vector3(tileOffset, 0));
                changes.StaticSurfaceDirty = false; //static surface has been updated!
                state.CenterTile           = oldCenter;
            }
            changes.StaticSurface = StaticSurface; //copy so changes can keep track of when we leave this buffer range
        }
Ejemplo n.º 3
0
        public void DrawScrollBuffer(ScrollBuffer buffer, Vector2 offset, Vector3 tileOffset, WorldState state)
        {
            var offsetDiff = (buffer.PxOffset - offset) * state.PreciseZoom;
            var tOff       = buffer.WorldPosition - tileOffset;
            var spr        = new _2DSprite
            {
                RenderMode = (buffer.Depth == null) ? _2DBatchRenderMode.NO_DEPTH : _2DBatchRenderMode.RESTORE_DEPTH,
                Pixel      = buffer.Pixel,
                Depth      = buffer.Depth,
                SrcRect    = new Rectangle(0, 0, buffer.Pixel.Width, buffer.Pixel.Height),
                DestRect   = new Rectangle((int)offsetDiff.X - 2, (int)offsetDiff.Y, buffer.Pixel.Width, buffer.Pixel.Height),
            };

            this.Draw(spr);
            spr.AbsoluteWorldPosition = tOff * WorldSpace.WorldUnitsPerTile;
            var y = spr.AbsoluteWorldPosition.Z;

            spr.AbsoluteWorldPosition.Z = spr.AbsoluteWorldPosition.Y;
            spr.AbsoluteWorldPosition.Y = y;
        }
Ejemplo n.º 4
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
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Prep work before screen is painted
        /// </summary>
        /// <param name="gd"></param>
        /// <param name="state"></param>
        public virtual void PreDraw(GraphicsDevice gd, WorldState state)
        {
            //var oht = state.BaseHeight;
            //state.BaseHeight = 0;
            var pxOffset = -state.WorldSpace.GetScreenOffset();
            //state.BaseHeight = oht;
            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 im = state.ThisFrameImmediate;
            var redrawStaticObjects = im;
            var redrawFloor         = im;
            var redrawWall          = im;

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

            var lightChangeType = 0;

            if (TicksSinceLight++ > 60 * 4)
            {
                damage.Add(new BlueprintDamage(BlueprintDamageType.OUTDOORS_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, state))
                    {
                        redrawFloor         = true;
                        redrawWall          = true;
                        redrawStaticObjects = true;
                    }
                    break;

                case BlueprintDamageType.PRECISE_ZOOM:
                    drawImmediate = true;
                    redrawFloor   = redrawWall = redrawStaticObjects = true;
                    break;

                case BlueprintDamageType.LIGHTING_CHANGED:
                    if (lightChangeType >= 2)
                    {
                        break;
                    }
                    var room = (ushort)item.TileX;
                    redrawFloor         = true;
                    redrawWall          = true;
                    redrawStaticObjects = true;

                    state.Light?.InvalidateRoom(room);
                    Blueprint.GenerateRoomLights();
                    state.OutsideColor   = Blueprint.RoomColors[1];
                    state._3D.RoomLights = Blueprint.RoomColors;
                    state.OutsidePx.SetData(new Color[] { new Color(Blueprint.OutsideColor, (Blueprint.OutsideColor.R + Blueprint.OutsideColor.G + Blueprint.OutsideColor.B) / (255 * 3f)) });
                    if (state.AmbientLight != null)
                    {
                        state.AmbientLight.SetData(Blueprint.RoomColors);
                    }
                    TicksSinceLight = 0;
                    break;

                case BlueprintDamageType.OUTDOORS_LIGHTING_CHANGED:
                    if (lightChangeType >= 1)
                    {
                        break;
                    }
                    lightChangeType     = 1;
                    redrawFloor         = true;
                    redrawWall          = true;
                    redrawStaticObjects = true;

                    Blueprint.GenerateRoomLights();
                    state.OutsideColor   = Blueprint.RoomColors[1];
                    state._3D.RoomLights = Blueprint.RoomColors;
                    state.OutsidePx.SetData(new Color[] { new Color(Blueprint.OutsideColor, (Blueprint.OutsideColor.R + Blueprint.OutsideColor.G + Blueprint.OutsideColor.B) / (255 * 3f)) });
                    if (state.AmbientLight != null)
                    {
                        state.AmbientLight.SetData(Blueprint.RoomColors);
                    }
                    state.Light?.InvalidateOutdoors();

                    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:
                    recacheCutaway = true;
                    break;

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

                case BlueprintDamageType.ROOM_CHANGED:
                    for (sbyte i = 0; i < Blueprint.RoomMap.Length; i++)
                    {
                        state.Rooms.SetRoomMap(i, Blueprint.RoomMap[i]);
                    }
                    if (state.Light != null)
                    {
                        if (lightChangeType < 2)
                        {
                            lightChangeType = 2;
                            state.Light.InvalidateAll();
                        }
                    }
                    Blueprint.RoofComp.ShapeDirty = 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 || recacheCutaway)
            {
                redrawWall = true;
            }
            if (recacheObjects)
            {
                redrawStaticObjects = true;
            }
            damage.Clear();

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

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

            pxOffset = newOff;

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

            if (recacheWalls)
            {
                Blueprint.WCRC?.Generate(gd, state, false);
            }
            else if (recacheCutaway)
            {
                Blueprint.WCRC?.Generate(gd, state, true);
            }

            state.Light?.ParseInvalidated((sbyte)(state.Level + ((state.DrawRoofs) ? 1 : 0)), state);

            if (recacheWalls || recacheCutaway)
            {
                _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);
                state.PrepareLighting();
                _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);
                Blueprint.FloorGeom.FullReset(gd, state.BuildMode > 1);
                ClearDrawBuffer(StaticFloorCache);
                _2d.End(StaticFloorCache, true);
            }

            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 (!drawImmediate)
            {
                state.PrepareLighting();

                if (redrawStaticObjects || redrawFloor || redrawWall)
                {
                    /** Draw static objects to a texture **/
                    Promise <Texture2D> bufferTexture = null;
                    Promise <Texture2D> depthTexture  = null;
                    using (var buffer = state._2D.WithBuffer(BUFFER_STATIC, ref bufferTexture, BUFFER_STATIC_DEPTH, ref depthTexture))
                    {
                        while (buffer.NextPass())
                        {
                            DrawFloorBuf(gd, state, pxOffset);
                            DrawWallBuf(gd, state, pxOffset);
                            DrawObjBuf(gd, state, pxOffset);
                        }
                    }
                    StaticObjects = new ScrollBuffer(bufferTexture.Get(), depthTexture.Get(), newOff, new Vector3(tileOffset, 0));
                }
            }
            //state._2D.PreciseZoom = state.PreciseZoom;
            state.CenterTile = oldCenter; //revert to our real scroll position

            state.ThisFrameImmediate = drawImmediate;
        }