public override void Update(UpdateState state) { base.Update(state); if (TempVM == null && GUID != 0) { var world = new ExternalWorld(GameFacade.GraphicsDevice); world.Initialize(GameFacade.Scenes); var context = new VMContext(world); TempVM = new VM(context, new VMServerDriver(new VMTSOGlobalLinkStub()), new VMNullHeadlineProvider()); TempVM.Init(); var blueprint = new Blueprint(32, 32); blueprint.Light = new RoomLighting[] { new RoomLighting() { OutsideLight = 100 }, new RoomLighting() { OutsideLight = 100 }, new RoomLighting() { OutsideLight = 100 }, }; blueprint.OutsideColor = Color.White; blueprint.GenerateRoomLights(); blueprint.RoomColors[2].A /= 2; world.State.AmbientLight.SetData(blueprint.RoomColors); world.InitBlueprint(blueprint); context.Blueprint = blueprint; context.Architecture = new VMArchitecture(1, 1, blueprint, TempVM.Context); } if (GUID != oldGUID) { SetGUIDLocal(GUID, TempVM); state.SharedData["ExternalDraw"] = true; } if (ForceRedraw) { state.SharedData["ExternalDraw"] = true; ForceRedraw = false; } if (TempVM != null) { TempVM.Update(); } }
/// <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 }
/// <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; }
public override 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 recacheWalls = false; var recacheCutaway = false; var recacheFloors = false; var recacheTerrain = false; var recacheObjects = false; var drawImmediate = false; var lightChangeType = 0; if (Math.Abs(Blueprint.OutsideTime - LastTimeOfDay) > 0.001f) { damage.Add(new BlueprintDamage(BlueprintDamageType.OUTDOORS_LIGHTING_CHANGED)); LastTimeOfDay = Blueprint.OutsideTime; } 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; state.Light?.InvalidateOutdoors(); //recacheTerrain = true; break; case BlueprintDamageType.SCROLL: break; case BlueprintDamageType.PRECISE_ZOOM: drawImmediate = true; break; case BlueprintDamageType.LIGHTING_CHANGED: if (lightChangeType >= 2) { break; } var room = (ushort)item.TileX; 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; 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.Indoors = null; Blueprint.RoofComp.ShapeDirty = true; break; case BlueprintDamageType.FLOOR_CHANGED: case BlueprintDamageType.WALL_CHANGED: recacheFloors = true; recacheWalls = true; Blueprint.RoofComp.ShapeDirty = true; break; } } damage.Clear(); if (recacheTerrain) { Blueprint.Terrain.RegenTerrain(gd, Blueprint); } if (recacheWalls) { Blueprint.WCRC?.Generate(gd, state, false); } else if (recacheCutaway) { Blueprint.WCRC?.Generate(gd, state, true); } if (recacheFloors) { Blueprint.FloorGeom.FullReset(gd, state.BuildMode > 1); } if (Drawn) { state.Light?.ParseInvalidated((sbyte)(state.Level + ((state.DrawRoofs) ? 1 : 0)), state); } if (recacheObjects) { /* objects no longer statically cached? * _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); */ } state.ThisFrameImmediate = drawImmediate; }
public override void Update(UpdateState state) { base.Update(state); if (TempVM == null && GUID != 0) { var world = new ExternalWorld(GameFacade.GraphicsDevice); world.Initialize(GameFacade.Scenes); var context = new VMContext(world); TempVM = new VM(context, new VMServerDriver(new VMTSOGlobalLinkStub()), new VMNullHeadlineProvider()); TempVM.Init(); var blueprint = new Blueprint(1, 1); blueprint.Light = new RoomLighting[] { new RoomLighting() { OutsideLight = 100 }, new RoomLighting() { OutsideLight = 100 }, new RoomLighting() { OutsideLight = 100 }, }; blueprint.OutsideColor = Color.White; blueprint.GenerateRoomLights(); blueprint.RoomColors[2].A /= 2; world.State.AmbientLight.SetData(blueprint.RoomColors); world.State.OutsidePx.SetData(new Color[] { Color.White }); world.InitBlueprint(blueprint); context.Blueprint = blueprint; context.Architecture = new VMArchitecture(1, 1, blueprint, TempVM.Context); } if (GUID != oldGUID) { SetGUIDLocal(GUID, TempVM); state.SharedData["ExternalDraw"] = true; } if (ForceRedraw) { state.SharedData["ExternalDraw"] = true; ForceRedraw = false; } if (TempVM != null) { var lcount = TempVM.Scheduler.CurrentTickID; TempVM.Update(); var count = TempVM.Scheduler.CurrentTickID; foreach (var ent in TempVM.Entities) { if (ent is VMAvatar) { for (uint i = lcount; i < count; i++) { ent.Tick(); } } } TempVM.PreDraw(); } }
/// <summary> /// Prep work before screen is painted /// </summary> /// <param name="gd"></param> /// <param name="state"></param> public void PreDraw(GraphicsDevice gd, WorldState state) { if (Blueprint == null) { return; } var pxOffset = -state.WorldSpace.GetScreenOffset(); var damage = Blueprint.Damage; var _2d = state._2D; var oldLevel = state.Level; var oldBuild = state.BuildMode; state.SilentLevel = State.Level; state.SilentBuildMode = 0; /** * This is a little bit different from a normal 2d world. All objects are part of the static * buffer, and they are redrawn into the parent world's scroll buffers. */ var recacheWalls = false; var recacheObjects = false; if (TicksSinceLight++ > 60 * 4) { damage.Add(new BlueprintDamage(BlueprintDamageType.OUTDOORS_LIGHTING_CHANGED)); } foreach (var item in damage) { switch (item.Type) { case BlueprintDamageType.ROTATE: case BlueprintDamageType.ZOOM: case BlueprintDamageType.LEVEL_CHANGED: recacheObjects = true; recacheWalls = true; break; case BlueprintDamageType.SCROLL: break; case BlueprintDamageType.LIGHTING_CHANGED: Blueprint.OutsideColor = state.OutsideColor; Blueprint.GenerateRoomLights(); State.OutsideColor = Blueprint.RoomColors[1]; State.AmbientLight.SetData(Blueprint.RoomColors); TicksSinceLight = 0; break; case BlueprintDamageType.OBJECT_MOVE: case BlueprintDamageType.OBJECT_GRAPHIC_CHANGE: case BlueprintDamageType.OBJECT_RETURN_TO_STATIC: recacheObjects = true; break; case BlueprintDamageType.WALL_CUT_CHANGED: case BlueprintDamageType.FLOOR_CHANGED: case BlueprintDamageType.WALL_CHANGED: recacheWalls = true; break; } } damage.Clear(); state._2D.End(); state._2D.Begin(state.Camera); if (recacheWalls) { //clear the sprite buffer before we begin drawing what we're going to cache Blueprint.Terrain.RegenTerrain(gd, state, Blueprint); Blueprint.FloorComp.Draw(gd, state); Blueprint.WallComp.Draw(gd, state); StaticArchCache.Clear(); state._2D.End(StaticArchCache, true); } if (recacheObjects) { state._2D.Pause(); state._2D.Resume(); foreach (var obj in Blueprint.Objects) { if (obj.Level > state.Level) { continue; } var tilePosition = obj.Position; state._2D.OffsetPixel(state.WorldSpace.GetScreenFromTile(tilePosition)); state._2D.OffsetTile(tilePosition); state._2D.SetObjID(obj.ObjectID); obj.Draw(gd, state); } StaticObjectsCache.Clear(); state._2D.End(StaticObjectsCache, true); } state.SilentBuildMode = oldBuild; state.SilentLevel = oldLevel; }
public void PreDraw(GraphicsDevice gd, WorldState state) { DrawImmediate = state.ForceImmediate; UpdateColor = false; if (state.CameraMode < CameraRenderMode._3D) { state.CameraMode = (state.Cameras.Safe2D) ? CameraRenderMode._2D : CameraRenderMode._2DRotate; } if (state.CameraMode > CameraRenderMode._2D) { DrawImmediate = true; } if (Math.Abs(Blueprint.OutsideTime - LastTimeOfDay) > 0.001f) { Dirty |= BlueprintGlobalChanges.OUTDOORS_LIGHTING_CHANGED; LastTimeOfDay = Blueprint.OutsideTime; } if ((Dirty & BlueprintGlobalChanges.ALL) > 0) { if ((Dirty & BlueprintGlobalChanges.VIEW_CHANGE_2D) > 0) { StaticSurfaceDirty = true; Dirty |= BlueprintGlobalChanges.WALL_CHANGED; Dirty |= BlueprintGlobalChanges.FLOOR_CHANGED; if ((Dirty & BlueprintGlobalChanges.ROTATE) > 0) { foreach (var obj in Blueprint.Objects) { obj.UpdateDrawOrder(state); } } //invalidate walls //invalidate floors //invalidate outdoors? } if ((Dirty & BlueprintGlobalChanges.SCROLL) > 0) { //invalidate scroll buffers if our new scroll view is outside their ranges var pxOffset = -state.WorldSpace.GetScreenOffset(); if (StaticSurface == null || StaticSurface.PxOffset != StaticSurface.GetScrollIncrement(pxOffset, state)) { StaticSurfaceDirty = true; } } if ((Dirty & BlueprintGlobalChanges.PRECISE_ZOOM) > 0) { DrawImmediate = true; } if ((Dirty & BlueprintGlobalChanges.LIGHTING_ANY) > 0) { UpdateColor = true; Blueprint.GenerateRoomLights(); state.OutsideColor = Blueprint.RoomColors[1]; 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); } if ((Dirty & BlueprintGlobalChanges.ROOM_CHANGED) == 0) { if ((Dirty & BlueprintGlobalChanges.LIGHTING_CHANGED) > 0 && state.Light != null) { //pass invalidated rooms foreach (var room in RoomLightInvalid) { state.Light?.InvalidateRoom((ushort)room); } RoomLightInvalid.Clear(); } if ((Dirty & BlueprintGlobalChanges.OUTDOORS_LIGHTING_CHANGED) > 0) { state.Light?.InvalidateOutdoors(); if (Blueprint.SubWorlds.Count > 0) { Blueprint.SubWorlds[LastSubLightUpdate].RefreshLighting(); LastSubLightUpdate = (LastSubLightUpdate + 1) % Blueprint.SubWorlds.Count; } } } if (LastSubLightUpdate == -1) { foreach (var sub in Blueprint.SubWorlds) { sub.RefreshLighting(); } LastSubLightUpdate = 0; } TicksSinceLight = 0; StaticSurfaceDirty = true; } var wallFlags = (Dirty & (BlueprintGlobalChanges.WALL_CHANGED | BlueprintGlobalChanges.WALL_CUT_CHANGED)); if (wallFlags > 0) { //process wall changes state.Platform.RecacheWalls(gd, state, wallFlags == BlueprintGlobalChanges.WALL_CUT_CHANGED); StaticSurfaceDirty = true; } if ((Dirty & BlueprintGlobalChanges.ROOF_STYLE_CHANGED) > 0) { Blueprint.RoofComp.StyleDirty = true; } if ((Dirty & BlueprintGlobalChanges.ARCH_CHANGED) > 0) { if ((Dirty & BlueprintGlobalChanges.FLOOR_CHANGED) > 0) { //process floor changes Blueprint.FloorGeom.FullReset(gd, state.BuildMode > 1); } if ((Dirty & BlueprintGlobalChanges.ROOM_CHANGED) > 0) { for (sbyte i = 0; i < Blueprint.RoomMap.Length; i++) { state.Rooms.SetRoomMap(i, Blueprint.RoomMap[i]); } if (state.Light != null) { UpdateColor = true; state.Light.InvalidateAll(); } Blueprint.Indoors = null; Blueprint.RoofComp.ShapeDirty = true; } StaticSurfaceDirty = true; } if ((Dirty & (BlueprintGlobalChanges.OPENGL_SECOND_DRAW)) > 0) { //must redraw to avoid issues with floors StaticSurfaceDirty = true; } } Dirty = 0; state.Light?.ParseInvalidated((sbyte)(state.Level + ((state.DrawRoofs) ? 1 : 0)), state); //for moved objects, regenerate depth and move them to dynamic if they aren't already there. foreach (var obj in ObjectMoved) { if (obj.Dead) { continue; } obj.UpdateDrawOrder(state); Layers.EnsureDynamic(obj); } StaticObjectDirty = ObjectSetDirty; ObjectSetDirty = false; if (StaticObjectDirty) { StaticSurfaceDirty = true; } ObjectMoved.Clear(); if (Layers.Update()) { //static buffer is dirty. StaticSurfaceDirty = true; } }