From 1e3fad593008ff3fee1f2781c5a81027679d573a Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 1 May 2016 11:23:38 +1000 Subject: [PATCH] Make all game components handle new map / new map loaded. --- ClassicalSharp/2D/Screens/HudScreen.cs | 5 +- ClassicalSharp/Audio/AudioPlayer.cs | 2 + ClassicalSharp/Commands/CommandManager.cs | 2 + ClassicalSharp/Commands/DefaultCommands.cs | 10 ++-- ClassicalSharp/Game/ChatLog.cs | 2 + ClassicalSharp/Game/Game.Properties.cs | 8 +++- ClassicalSharp/Game/Game.cs | 46 +++++++++++++++---- ClassicalSharp/Game/Inventory.cs | 2 + .../Network/Utils/AsyncDownloader.cs | 2 + ClassicalSharp/Rendering/BlockHandRenderer.cs | 2 + ClassicalSharp/Rendering/EnvRenderer.cs | 20 ++++---- .../Rendering/MapBordersRenderer.cs | 24 ++++------ .../Rendering/MinimalEnvRenderer.cs | 18 +++----- .../Rendering/StandardEnvRenderer.cs | 23 ++++------ ClassicalSharp/Rendering/WeatherRenderer.cs | 14 ++---- .../Selections/AxisLinesRenderer.cs | 2 + .../Selections/PickedPosRenderer.cs | 2 + ClassicalSharp/Selections/SelectionManager.cs | 16 ++----- 18 files changed, 109 insertions(+), 91 deletions(-) diff --git a/ClassicalSharp/2D/Screens/HudScreen.cs b/ClassicalSharp/2D/Screens/HudScreen.cs index 594ca774e..23d45b613 100644 --- a/ClassicalSharp/2D/Screens/HudScreen.cs +++ b/ClassicalSharp/2D/Screens/HudScreen.cs @@ -15,9 +15,10 @@ namespace ClassicalSharp.Gui { PlayerListWidget playerList; Font playerFont; - public void Init( Game game ) { Init(); } - + public void Init( Game game ) { Init(); } public void Reset( Game game ) { } + public void OnNewMap( Game game ) { } + public void OnNewMapLoaded( Game game ) { } public override void Render( double delta ) { if( game.HideGui ) return; diff --git a/ClassicalSharp/Audio/AudioPlayer.cs b/ClassicalSharp/Audio/AudioPlayer.cs index 77e1bcae1..a89b9ffd4 100644 --- a/ClassicalSharp/Audio/AudioPlayer.cs +++ b/ClassicalSharp/Audio/AudioPlayer.cs @@ -27,6 +27,8 @@ namespace ClassicalSharp.Audio { } public void Reset( Game game ) { } + public void OnNewMap( Game game ) { } + public void OnNewMapLoaded( Game game ) { } public void SetMusic( bool enabled ) { if( enabled ) diff --git a/ClassicalSharp/Commands/CommandManager.cs b/ClassicalSharp/Commands/CommandManager.cs index 3c7a56ef3..3d138fe6c 100644 --- a/ClassicalSharp/Commands/CommandManager.cs +++ b/ClassicalSharp/Commands/CommandManager.cs @@ -26,6 +26,8 @@ namespace ClassicalSharp.Commands { } public void Reset( Game game ) { } + public void OnNewMap( Game game ) { } + public void OnNewMapLoaded( Game game ) { } public void Register( Command command ) { command.game = game; diff --git a/ClassicalSharp/Commands/DefaultCommands.cs b/ClassicalSharp/Commands/DefaultCommands.cs index 8bfaa33bc..8bbf7598e 100644 --- a/ClassicalSharp/Commands/DefaultCommands.cs +++ b/ClassicalSharp/Commands/DefaultCommands.cs @@ -141,14 +141,10 @@ namespace ClassicalSharp.Commands { void SetNewRenderType( bool legacy, bool minimal ) { game.MapBordersRenderer.UseLegacyMode( legacy ); if( minimal ) { - game.EnvRenderer.Dispose(); - game.EnvRenderer = new MinimalEnvRenderer( game ); - game.EnvRenderer.Init(); + game.ReplaceComponent( ref game.EnvRenderer, new MinimalEnvRenderer() ); } else { - if( !( game.EnvRenderer is StandardEnvRenderer ) ) { - game.EnvRenderer.Dispose(); - game.EnvRenderer = new StandardEnvRenderer( game ); - game.EnvRenderer.Init(); + if( !(game.EnvRenderer is StandardEnvRenderer) ) { + game.ReplaceComponent( ref game.EnvRenderer, new StandardEnvRenderer() ); } ((StandardEnvRenderer)game.EnvRenderer).UseLegacyMode( legacy ); } diff --git a/ClassicalSharp/Game/ChatLog.cs b/ClassicalSharp/Game/ChatLog.cs index eb17cf33e..a703b7e99 100644 --- a/ClassicalSharp/Game/ChatLog.cs +++ b/ClassicalSharp/Game/ChatLog.cs @@ -19,6 +19,8 @@ namespace ClassicalSharp { } public void Reset( Game game ) { } + public void OnNewMap( Game game ) { } + public void OnNewMapLoaded( Game game ) { } /// List of chat messages received from the server and added by client commands. /// index 0 is the oldest chat message, last index is newest. diff --git a/ClassicalSharp/Game/Game.Properties.cs b/ClassicalSharp/Game/Game.Properties.cs index cd974e79c..674cc2a68 100644 --- a/ClassicalSharp/Game/Game.Properties.cs +++ b/ClassicalSharp/Game/Game.Properties.cs @@ -28,8 +28,14 @@ namespace ClassicalSharp { /// Called when the game has loaded. void Init( Game game ); - /// Called to reset the state when the user is reconnecting to a server. + /// Called to reset the component's state when the user is reconnecting to a server. void Reset( Game game ); + + /// Called to update the component's state when the user begins loading a new map. + void OnNewMap( Game game ); + + /// Called to update the component's state when the user has finished loading a new map. + void OnNewMapLoaded( Game game ); } public partial class Game { diff --git a/ClassicalSharp/Game/Game.cs b/ClassicalSharp/Game/Game.cs index 027af7bf3..8174f06f7 100644 --- a/ClassicalSharp/Game/Game.cs +++ b/ClassicalSharp/Game/Game.cs @@ -62,6 +62,8 @@ namespace ClassicalSharp { LoadOptions(); LoadGuiOptions(); Chat = AddComponent( new Chat() ); + WorldEvents.OnNewMap += OnNewMapCore; + WorldEvents.OnNewMapLoaded += OnNewMapLoadedCore; BlockInfo = new BlockInfo(); BlockInfo.Init(); @@ -89,8 +91,8 @@ namespace ClassicalSharp { width = Width; height = Height; MapRenderer = new MapRenderer( this ); - MapBordersRenderer = new MapBordersRenderer( this ); - EnvRenderer = new StandardEnvRenderer( this ); + MapBordersRenderer = AddComponent( new MapBordersRenderer() ); + EnvRenderer = AddComponent( new StandardEnvRenderer() ); if( IPAddress == null ) { Network = new Singleplayer.SinglePlayerServer( this ); } else { @@ -117,8 +119,6 @@ namespace ClassicalSharp { fpsScreen.Init(); hudScreen = AddComponent( new HudScreen( this ) ); Culling = new FrustumCulling(); - EnvRenderer.Init(); - MapBordersRenderer.Init(); Picking = AddComponent( new PickedPosRenderer() ); AudioPlayer = AddComponent( new AudioPlayer() ); AxisLinesRenderer = AddComponent( new AxisLinesRenderer() ); @@ -136,11 +136,6 @@ namespace ClassicalSharp { Network.Connect( IPAddress, Port ); } - public T AddComponent( T obj ) { - Components.Add( (IGameComponent)obj ); - return obj; - } - void LoadOptions() { ClassicMode = Options.GetBool( "mode-classic", false ); ClassicHacks = Options.GetBool( OptionsKey.AllowClassicHacks, false ); @@ -200,6 +195,37 @@ namespace ClassicalSharp { } } + void OnNewMapCore( object sender, EventArgs e ) { + foreach( IGameComponent comp in Components ) + comp.OnNewMap( this ); + } + + void OnNewMapLoadedCore( object sender, EventArgs e ) { + foreach( IGameComponent comp in Components ) + comp.OnNewMapLoaded( this ); + } + + public T AddComponent( T obj ) where T : IGameComponent { + Components.Add( obj ); + return obj; + } + + public bool ReplaceComponent( ref T old, T obj ) where T : IGameComponent { + for( int i = 0; i < Components.Count; i++ ) { + if( !object.ReferenceEquals( Components[i], old ) ) continue; + old.Dispose(); + + Components[i] = obj; + old = obj; + obj.Init( this ); + return true; + } + + Components.Add( obj ); + obj.Init( this ); + return false; + } + public void SetViewDistance( int distance, bool save ) { ViewDistance = distance; if( ViewDistance > MaxViewDistance ) @@ -485,6 +511,8 @@ namespace ClassicalSharp { ModelCache.Dispose(); ParticleManager.Dispose(); Players.Dispose(); + WorldEvents.OnNewMap -= OnNewMapCore; + WorldEvents.OnNewMapLoaded -= OnNewMapLoadedCore; foreach( IGameComponent comp in Components ) comp.Dispose(); diff --git a/ClassicalSharp/Game/Inventory.cs b/ClassicalSharp/Game/Inventory.cs index 7e0fc061a..f868c7673 100644 --- a/ClassicalSharp/Game/Inventory.cs +++ b/ClassicalSharp/Game/Inventory.cs @@ -23,6 +23,8 @@ namespace ClassicalSharp { } public void Reset( Game game ) { } + public void OnNewMap( Game game ) { } + public void OnNewMapLoaded( Game game ) { } public void Dispose() { } diff --git a/ClassicalSharp/Network/Utils/AsyncDownloader.cs b/ClassicalSharp/Network/Utils/AsyncDownloader.cs index c51e609c4..2f33e7a90 100644 --- a/ClassicalSharp/Network/Utils/AsyncDownloader.cs +++ b/ClassicalSharp/Network/Utils/AsyncDownloader.cs @@ -42,6 +42,8 @@ namespace ClassicalSharp.Network { requests.Clear(); handle.Set(); } + public void OnNewMap( Game game ) { } + public void OnNewMapLoaded( Game game ) { } /// Asynchronously downloads a skin. If 'skinName' points to the url then the skin is /// downloaded from that url, otherwise it is downloaded from the url 'defaultSkinServer'/'skinName'.png diff --git a/ClassicalSharp/Rendering/BlockHandRenderer.cs b/ClassicalSharp/Rendering/BlockHandRenderer.cs index f1f86d3c5..12a011cf2 100644 --- a/ClassicalSharp/Rendering/BlockHandRenderer.cs +++ b/ClassicalSharp/Rendering/BlockHandRenderer.cs @@ -31,6 +31,8 @@ namespace ClassicalSharp.Renderers { } public void Reset( Game game ) { } + public void OnNewMap( Game game ) { } + public void OnNewMapLoaded( Game game ) { } public void Render( double delta, float t ) { if( game.Camera.IsThirdPerson || !game.ShowBlockInHand ) return; diff --git a/ClassicalSharp/Rendering/EnvRenderer.cs b/ClassicalSharp/Rendering/EnvRenderer.cs index 3501805b9..2f414ea7f 100644 --- a/ClassicalSharp/Rendering/EnvRenderer.cs +++ b/ClassicalSharp/Rendering/EnvRenderer.cs @@ -6,28 +6,26 @@ using ClassicalSharp.Map; namespace ClassicalSharp.Renderers { - public abstract class EnvRenderer : IDisposable { + public abstract class EnvRenderer : IGameComponent { protected World map; protected Game game; protected IGraphicsApi graphics; - public virtual void Init() { + public virtual void Init( Game game ) { + this.game = game; + map = game.World; graphics = game.Graphics; - game.WorldEvents.OnNewMap += OnNewMap; - game.WorldEvents.OnNewMapLoaded += OnNewMapLoaded; game.WorldEvents.EnvVariableChanged += EnvVariableChanged; - } - - public virtual void OnNewMap( object sender, EventArgs e ) { } - public virtual void OnNewMapLoaded( object sender, EventArgs e ) { - } + public virtual void Reset( Game game ) { OnNewMap( game ); } + + public abstract void OnNewMap( Game game ); + + public abstract void OnNewMapLoaded( Game game ); public virtual void Dispose() { - game.WorldEvents.OnNewMap -= OnNewMap; - game.WorldEvents.OnNewMapLoaded -= OnNewMapLoaded; game.WorldEvents.EnvVariableChanged -= EnvVariableChanged; } diff --git a/ClassicalSharp/Rendering/MapBordersRenderer.cs b/ClassicalSharp/Rendering/MapBordersRenderer.cs index d292f9c8d..a071c17f2 100644 --- a/ClassicalSharp/Rendering/MapBordersRenderer.cs +++ b/ClassicalSharp/Rendering/MapBordersRenderer.cs @@ -9,18 +9,12 @@ using OpenTK; namespace ClassicalSharp.Renderers { - public unsafe sealed class MapBordersRenderer : IDisposable { + public unsafe sealed class MapBordersRenderer : IGameComponent { World map; Game game; IGraphicsApi graphics; - public MapBordersRenderer( Game game ) { - this.game = game; - map = game.World; - graphics = game.Graphics; - } - int sidesVb = -1, edgesVb = -1; int edgeTexId, sideTexId; int sidesVertices, edgesVertices; @@ -31,9 +25,11 @@ namespace ClassicalSharp.Renderers { ResetSidesAndEdges( null, null ); } - public void Init() { - game.WorldEvents.OnNewMap += OnNewMap; - game.WorldEvents.OnNewMapLoaded += OnNewMapLoaded; + public void Init( Game game ) { + this.game = game; + map = game.World; + graphics = game.Graphics; + game.WorldEvents.EnvVariableChanged += EnvVariableChanged; game.Events.ViewDistanceChanged += ResetSidesAndEdges; game.Events.TerrainAtlasChanged += ResetTextures; @@ -74,8 +70,6 @@ namespace ClassicalSharp.Renderers { } public void Dispose() { - game.WorldEvents.OnNewMap -= OnNewMap; - game.WorldEvents.OnNewMapLoaded -= OnNewMapLoaded; game.WorldEvents.EnvVariableChanged -= EnvVariableChanged; game.Events.ViewDistanceChanged -= ResetSidesAndEdges; game.Events.TerrainAtlasChanged -= ResetTextures; @@ -87,7 +81,9 @@ namespace ClassicalSharp.Renderers { sidesVb = edgesVb = -1; } - void OnNewMap( object sender, EventArgs e ) { + public void Reset( Game game ) { OnNewMap( game ); } + + public void OnNewMap( Game game ) { graphics.DeleteVb( sidesVb ); graphics.DeleteVb( edgesVb ); sidesVb = edgesVb = -1; @@ -96,7 +92,7 @@ namespace ClassicalSharp.Renderers { MakeTexture( ref sideTexId, ref lastSideTexLoc, map.SidesBlock ); } - void OnNewMapLoaded( object sender, EventArgs e ) { + public void OnNewMapLoaded( Game game ) { CalculateRects( game.ViewDistance ); RebuildSides( map.SidesHeight, legacy ? 128 : 65536 ); RebuildEdges( map.EdgeHeight, legacy ? 128 : 65536 ); diff --git a/ClassicalSharp/Rendering/MinimalEnvRenderer.cs b/ClassicalSharp/Rendering/MinimalEnvRenderer.cs index 2f8addb7b..a61325ce0 100644 --- a/ClassicalSharp/Rendering/MinimalEnvRenderer.cs +++ b/ClassicalSharp/Rendering/MinimalEnvRenderer.cs @@ -8,25 +8,19 @@ namespace ClassicalSharp.Renderers { /// (no fog, clouds, or proper overhead sky) public class MinimalEnvRenderer : EnvRenderer { - public MinimalEnvRenderer( Game game ) { - this.game = game; - map = game.World; + public override void Init( Game game ) { + base.Init( game ); + graphics.Fog = false; + graphics.ClearColour( map.SkyCol ); } public override void Render( double deltaTime ) { graphics.ClearColour( map.SkyCol ); } - public override void Init() { - base.Init(); - graphics.Fog = false; - graphics.ClearColour( map.SkyCol ); - } + public override void OnNewMap( Game game ) { } - public override void OnNewMap( object sender, EventArgs e ) { - } - - public override void OnNewMapLoaded( object sender, EventArgs e ) { + public override void OnNewMapLoaded( Game game ) { graphics.ClearColour( map.SkyCol ); } diff --git a/ClassicalSharp/Rendering/StandardEnvRenderer.cs b/ClassicalSharp/Rendering/StandardEnvRenderer.cs index b6c326c86..37a3a49fb 100644 --- a/ClassicalSharp/Rendering/StandardEnvRenderer.cs +++ b/ClassicalSharp/Rendering/StandardEnvRenderer.cs @@ -8,11 +8,6 @@ namespace ClassicalSharp.Renderers { public unsafe class StandardEnvRenderer : EnvRenderer { - public StandardEnvRenderer( Game game ) { - this.game = game; - map = game.World; - } - int cloudsVb = -1, cloudVertices, skyVb = -1, skyVertices; bool legacy; @@ -58,25 +53,25 @@ namespace ClassicalSharp.Renderers { } } - public override void OnNewMap( object sender, EventArgs e ) { + public override void Init( Game game ) { + base.Init( game ); + graphics.Fog = true; + ResetAllEnv( null, null ); + game.Events.ViewDistanceChanged += ResetAllEnv; + } + + public override void OnNewMap( Game game ) { graphics.Fog = false; graphics.DeleteVb( skyVb ); graphics.DeleteVb( cloudsVb ); skyVb = cloudsVb = -1; } - public override void OnNewMapLoaded( object sender, EventArgs e ) { + public override void OnNewMapLoaded( Game game ) { graphics.Fog = true; ResetAllEnv( null, null ); } - public override void Init() { - base.Init(); - graphics.Fog = true; - ResetAllEnv( null, null ); - game.Events.ViewDistanceChanged += ResetAllEnv; - } - void ResetAllEnv( object sender, EventArgs e ) { ResetFog(); ResetSky(); diff --git a/ClassicalSharp/Rendering/WeatherRenderer.cs b/ClassicalSharp/Rendering/WeatherRenderer.cs index 44e422f1f..53d7cd754 100644 --- a/ClassicalSharp/Rendering/WeatherRenderer.cs +++ b/ClassicalSharp/Rendering/WeatherRenderer.cs @@ -19,11 +19,7 @@ namespace ClassicalSharp.Renderers { graphics = game.Graphics; info = game.BlockInfo; weatherVb = graphics.CreateDynamicVb( VertexFormat.P3fT2fC4b, vertices.Length ); - game.WorldEvents.OnNewMap += OnNewMap; - game.WorldEvents.OnNewMapLoaded += OnNewMapLoaded; - } - - public void Reset( Game game ) { } + } int weatherVb; short[] heightmap; @@ -98,12 +94,14 @@ namespace ClassicalSharp.Renderers { } int length, width, maxY, oneY; - void OnNewMap( object sender, EventArgs e ) { + public void Reset( Game game ) { OnNewMap( game ); } + + public void OnNewMap( Game game ) { heightmap = null; lastPos = new Vector3I( Int32.MaxValue ); } - void OnNewMapLoaded( object sender, EventArgs e ) { + public void OnNewMapLoaded( Game game ) { length = map.Length; width = map.Width; maxY = map.Height - 1; @@ -118,8 +116,6 @@ namespace ClassicalSharp.Renderers { } public void Dispose() { - game.WorldEvents.OnNewMap -= OnNewMap; - game.WorldEvents.OnNewMapLoaded -= OnNewMapLoaded; graphics.DeleteDynamicVb( weatherVb ); } diff --git a/ClassicalSharp/Selections/AxisLinesRenderer.cs b/ClassicalSharp/Selections/AxisLinesRenderer.cs index 875399065..c79be5a5c 100644 --- a/ClassicalSharp/Selections/AxisLinesRenderer.cs +++ b/ClassicalSharp/Selections/AxisLinesRenderer.cs @@ -16,6 +16,8 @@ namespace ClassicalSharp.Selections { } public void Reset( Game game ) { } + public void OnNewMap( Game game ) { } + public void OnNewMapLoaded( Game game ) { } public void Dispose() { game.Graphics.DeleteDynamicVb( vb ); diff --git a/ClassicalSharp/Selections/PickedPosRenderer.cs b/ClassicalSharp/Selections/PickedPosRenderer.cs index 7df614036..0e08030c0 100644 --- a/ClassicalSharp/Selections/PickedPosRenderer.cs +++ b/ClassicalSharp/Selections/PickedPosRenderer.cs @@ -18,6 +18,8 @@ namespace ClassicalSharp.Renderers { } public void Reset( Game game ) { } + public void OnNewMap( Game game ) { } + public void OnNewMapLoaded( Game game ) { } FastColour col = FastColour.Black; int index; diff --git a/ClassicalSharp/Selections/SelectionManager.cs b/ClassicalSharp/Selections/SelectionManager.cs index fa02e57ec..c08249cc6 100644 --- a/ClassicalSharp/Selections/SelectionManager.cs +++ b/ClassicalSharp/Selections/SelectionManager.cs @@ -16,12 +16,11 @@ namespace ClassicalSharp.Selections { public void Init( Game game ) { this.game = game; Graphics = game.Graphics; - game.WorldEvents.OnNewMap += OnNewMap; } - public void Reset( Game game ) { - selections.Clear(); - } + public void Reset( Game game ) { selections.Clear(); } + public void OnNewMap( Game game ) { selections.Clear(); } + public void OnNewMapLoaded( Game game ) { } List selections = new List( 256 ); public void AddSelection( byte id, Vector3I p1, Vector3I p2, FastColour col ) { @@ -71,10 +70,7 @@ namespace ClassicalSharp.Selections { Graphics.AlphaBlending = false; } - public void Dispose() { - OnNewMap( null, null ); - game.WorldEvents.OnNewMap -= OnNewMap; - + public void Dispose() { if( lineVb <= 0 ) return; Graphics.DeleteDynamicVb( vb ); Graphics.DeleteDynamicVb( lineVb ); @@ -87,9 +83,5 @@ namespace ClassicalSharp.Selections { vb = Graphics.CreateDynamicVb( VertexFormat.P3fC4b, vertices.Length ); lineVb = Graphics.CreateDynamicVb( VertexFormat.P3fC4b, lineVertices.Length ); } - - void OnNewMap( object sender, EventArgs e ) { - selections.Clear(); - } } } \ No newline at end of file