Make ticking tasks code more extensible.

This commit is contained in:
UnknownShadow200 2016-08-06 15:06:20 +10:00
parent ae5f379438
commit 38be2f192e
15 changed files with 271 additions and 236 deletions

View File

@ -170,6 +170,7 @@
<Compile Include="Events\Events.cs" />
<Compile Include="Events\UserEvents.cs" />
<Compile Include="Events\WorldEvents.cs" />
<Compile Include="Game\Game.Init.cs" />
<Compile Include="Game\Game.Properties.cs" />
<Compile Include="Game\GuiInterface.cs" />
<Compile Include="Game\PickingHandler.cs" />

View File

@ -33,10 +33,10 @@ namespace ClassicalSharp.Entities {
}
/// <summary> Performs a tick call for all player entities contained in this list. </summary>
public void Tick( double delta ) {
public void Tick( ScheduledTask task ) {
for( int i = 0; i < Players.Length; i++ ) {
if( Players[i] == null ) continue;
Players[i].Tick( delta );
Players[i].Tick( task.Interval );
}
}
@ -55,9 +55,8 @@ namespace ClassicalSharp.Entities {
/// <summary> Renders the names of all player entities contained in this list.<br/>
/// If ShowHoveredNames is false, this method only renders names of entities that are
/// not currently being looked at by the user. </summary>
public void RenderNames( IGraphicsApi api, double delta, float t ) {
if( NamesMode == NameMode.NoNames )
return;
public void RenderNames( IGraphicsApi api, double delta ) {
if( NamesMode == NameMode.NoNames ) return;
api.Texturing = true;
api.AlphaTest = true;
LocalPlayer localP = game.LocalPlayer;
@ -81,7 +80,7 @@ namespace ClassicalSharp.Entities {
api.AlphaTest = false;
}
public void RenderHoveredNames( IGraphicsApi api, double delta, float t ) {
public void RenderHoveredNames( IGraphicsApi api, double delta ) {
if( NamesMode == NameMode.NoNames || NamesMode == NameMode.All )
return;
api.Texturing = true;

View File

@ -0,0 +1,203 @@
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
using System;
using System.Drawing;
using System.Net;
using ClassicalSharp.Audio;
using ClassicalSharp.Commands;
using ClassicalSharp.Entities;
using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Gui;
using ClassicalSharp.Map;
using ClassicalSharp.Model;
using ClassicalSharp.Network;
using ClassicalSharp.Particles;
using ClassicalSharp.Renderers;
using ClassicalSharp.Selections;
using ClassicalSharp.TexturePack;
#if ANDROID
using Android.Graphics;
#endif
using PathIO = System.IO.Path; // Android.Graphics.Path clash otherwise
namespace ClassicalSharp {
public partial class Game : IDisposable {
internal void OnLoad() {
Mouse = window.Mouse;
Keyboard = window.Keyboard;
#if !USE_DX
Graphics = new OpenGLApi();
#else
Graphics = new Direct3D9Api( this );
#endif
Graphics.MakeGraphicsInfo();
Options.Load();
Entities = new EntityList( this );
AcceptedUrls.Load();
DeniedUrls.Load();
ETags.Load();
InputHandler = new InputHandler( this );
defaultIb = Graphics.MakeDefaultIb();
ParticleManager = AddComponent( new ParticleManager() );
TabList = AddComponent( new TabList() );
LoadOptions();
LoadGuiOptions();
Chat = AddComponent( new Chat() );
WorldEvents.OnNewMap += OnNewMapCore;
WorldEvents.OnNewMapLoaded += OnNewMapLoadedCore;
BlockInfo = new BlockInfo();
BlockInfo.Init();
ModelCache = new ModelCache( this );
ModelCache.InitCache();
AsyncDownloader = AddComponent( new AsyncDownloader() );
Drawer2D = new GdiPlusDrawer2D( Graphics );
Drawer2D.UseBitmappedChat = ClassicMode || !Options.GetBool( OptionsKey.ArialChatFont, false );
Drawer2D.BlackTextShadows = Options.GetBool( OptionsKey.BlackTextShadows, false );
TerrainAtlas1D = new TerrainAtlas1D( Graphics );
TerrainAtlas = new TerrainAtlas2D( Graphics, Drawer2D );
Animations = AddComponent( new Animations() );
Inventory = AddComponent( new Inventory() );
BlockInfo.SetDefaultBlockPermissions( Inventory.CanPlace, Inventory.CanDelete );
World = new World( this );
LocalPlayer = AddComponent( new LocalPlayer( this ) );
Entities[255] = LocalPlayer;
Width = window.Width; Height = window.Height;
MapRenderer = new MapRenderer( this );
string renType = Options.Get( OptionsKey.RenderType ) ?? "normal";
if( !SetRenderType( renType ) )
SetRenderType( "normal" );
if( IPAddress == null ) {
Network = new Singleplayer.SinglePlayerServer( this );
} else {
Network = new Network.NetworkProcessor( this );
}
Graphics.LostContextFunction = Network.Tick;
firstPersonCam = new FirstPersonCamera( this );
thirdPersonCam = new ThirdPersonCamera( this );
forwardThirdPersonCam = new ForwardThirdPersonCamera( this );
Camera = firstPersonCam;
UpdateProjection();
Gui = AddComponent( new GuiInterface( this ) );
CommandManager = AddComponent( new CommandManager() );
SelectionManager = AddComponent( new SelectionManager() );
WeatherRenderer = AddComponent( new WeatherRenderer() );
HeldBlockRenderer = AddComponent( new HeldBlockRenderer() );
Graphics.DepthTest = true;
Graphics.DepthTestFunc( CompareFunc.LessEqual );
//Graphics.DepthWrite = true;
Graphics.AlphaBlendFunc( BlendFunc.SourceAlpha, BlendFunc.InvSourceAlpha );
Graphics.AlphaTestFunc( CompareFunc.Greater, 0.5f );
Culling = new FrustumCulling();
Picking = AddComponent( new PickedPosRenderer() );
AudioPlayer = AddComponent( new AudioPlayer() );
AxisLinesRenderer = AddComponent( new AxisLinesRenderer() );
SkyboxRenderer = AddComponent( new SkyboxRenderer() );
foreach( IGameComponent comp in Components )
comp.Init( this );
ExtractInitialTexturePack();
foreach( IGameComponent comp in Components )
comp.Ready( this );
InitScheduledTasks();
window.LoadIcon();
string connectString = "Connecting to " + IPAddress + ":" + Port + "..";
if( Graphics.WarnIfNecessary( Chat ) ) {
MapBordersRenderer.UseLegacyMode( true );
EnvRenderer.UseLegacyMode( true );
}
Gui.SetNewScreen( new LoadingMapScreen( this, connectString, "Waiting for handshake" ) );
Network.Connect( IPAddress, Port );
}
void ExtractInitialTexturePack() {
defTexturePack = Options.Get( OptionsKey.DefaultTexturePack ) ?? "default.zip";
TexturePackExtractor extractor = new TexturePackExtractor();
extractor.Extract( "default.zip", this );
// in case the user's default texture pack doesn't have all required textures
if( DefaultTexturePack != "default.zip" )
extractor.Extract( DefaultTexturePack, this );
}
void LoadOptions() {
ClassicMode = Options.GetBool( "mode-classic", false );
ClassicHacks = Options.GetBool( OptionsKey.AllowClassicHacks, false );
UseClassicGui = Options.GetBool( OptionsKey.UseClassicGui, true );
UseClassicTabList = Options.GetBool( OptionsKey.UseClassicTabList, false );
UseClassicOptions = Options.GetBool( OptionsKey.UseClassicOptions, false );
AllowCustomBlocks = Options.GetBool( OptionsKey.AllowCustomBlocks, true );
UseCPE = Options.GetBool( OptionsKey.UseCPE, true );
SimpleArmsAnim = Options.GetBool( OptionsKey.SimpleArmsAnim, false );
ViewBobbing = Options.GetBool( OptionsKey.ViewBobbing, false );
FpsLimitMethod method = Options.GetEnum( OptionsKey.FpsLimit, FpsLimitMethod.LimitVSync );
SetFpsLimitMethod( method );
ViewDistance = Options.GetInt( OptionsKey.ViewDist, 16, 4096, 512 );
UserViewDistance = ViewDistance;
SmoothLighting = Options.GetBool( OptionsKey.SmoothLighting, false );
DefaultFov = Options.GetInt( OptionsKey.FieldOfView, 1, 150, 70 );
Fov = DefaultFov;
ZoomFov = DefaultFov;
ModifiableLiquids = !ClassicMode && Options.GetBool( OptionsKey.ModifiableLiquids, false );
CameraClipping = Options.GetBool( OptionsKey.CameraClipping, true );
AllowServerTextures = Options.GetBool( OptionsKey.AllowServerTextures, true );
MouseSensitivity = Options.GetInt( OptionsKey.Sensitivity, 1, 100, 30 );
ShowBlockInHand = Options.GetBool( OptionsKey.ShowBlockInHand, true );
InvertMouse = Options.GetBool( OptionsKey.InvertMouse, false );
bool skipSsl = Options.GetBool( "skip-ssl-check", false );
if( skipSsl ) {
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
Options.Set( "skip-ssl-check", false );
}
}
void LoadGuiOptions() {
ChatLines = Options.GetInt( OptionsKey.ChatLines, 1, 30, 12 );
ClickableChat = Options.GetBool( OptionsKey.ClickableChat, false );
InventoryScale = Options.GetFloat( OptionsKey.InventoryScale, 0.25f, 5f, 1f );
HotbarScale = Options.GetFloat( OptionsKey.HotbarScale, 0.25f, 5f, 1f );
ChatScale = Options.GetFloat( OptionsKey.ChatScale, 0.35f, 5f, 1f );
ShowFPS = Options.GetBool( OptionsKey.ShowFPS, true );
TabAutocomplete = Options.GetBool( OptionsKey.TabAutocomplete, false );
FontName = Options.Get( OptionsKey.FontName ) ?? "Arial";
if( ClassicMode ) FontName = "Arial";
try {
using( Font f = new Font( FontName, 16 ) ) { }
} catch( Exception ) {
FontName = "Arial";
Options.Set( OptionsKey.FontName, "Arial" );
}
}
ScheduledTask entTask;
void InitScheduledTasks() {
const double defTicks = 1.0 / 20, camTicks = 1.0 / 60;
AddScheduledTask( 30, AsyncDownloader.PurgeOldEntriesTask );
AddScheduledTask( defTicks, Network.Tick );
entTask = AddScheduledTask( defTicks, Entities.Tick );
AddScheduledTask( defTicks, ParticleManager.Tick );
AddScheduledTask( defTicks, Animations.Tick );
AddScheduledTask( camTicks, CameraTick );
}
void CameraTick( ScheduledTask task ) {
Camera.Tick( task.Interval );
}
}
}

View File

@ -41,6 +41,12 @@ namespace ClassicalSharp {
void OnNewMapLoaded( Game game );
}
/// <summary> Represents a task that runs on the main thread every certain interval. </summary>
public class ScheduledTask {
public double Accumulator, Interval;
public Action<ScheduledTask> Callback;
}
public partial class Game {
/// <summary> Abstracts the underlying 3D graphics rendering API. </summary>
@ -115,6 +121,7 @@ namespace ClassicalSharp {
public SkyboxRenderer SkyboxRenderer;
public List<IGameComponent> Components = new List<IGameComponent>();
public List<ScheduledTask> Tasks = new List<ScheduledTask>();
/// <summary> Whether x to stone brick tiles should be used. </summary>
public bool UseCPEBlocks = false;

View File

@ -51,166 +51,6 @@ namespace ClassicalSharp {
public void Exit() { window.Exit(); }
internal void OnLoad() {
Mouse = window.Mouse;
Keyboard = window.Keyboard;
#if !USE_DX
Graphics = new OpenGLApi();
#else
Graphics = new Direct3D9Api( this );
#endif
Graphics.MakeGraphicsInfo();
Options.Load();
Entities = new EntityList( this );
AcceptedUrls.Load();
DeniedUrls.Load();
ETags.Load();
InputHandler = new InputHandler( this );
defaultIb = Graphics.MakeDefaultIb();
ParticleManager = AddComponent( new ParticleManager() );
TabList = AddComponent( new TabList() );
LoadOptions();
LoadGuiOptions();
Chat = AddComponent( new Chat() );
WorldEvents.OnNewMap += OnNewMapCore;
WorldEvents.OnNewMapLoaded += OnNewMapLoadedCore;
BlockInfo = new BlockInfo();
BlockInfo.Init();
ModelCache = new ModelCache( this );
ModelCache.InitCache();
AsyncDownloader = AddComponent( new AsyncDownloader() );
Drawer2D = new GdiPlusDrawer2D( Graphics );
Drawer2D.UseBitmappedChat = ClassicMode || !Options.GetBool( OptionsKey.ArialChatFont, false );
Drawer2D.BlackTextShadows = Options.GetBool( OptionsKey.BlackTextShadows, false );
TerrainAtlas1D = new TerrainAtlas1D( Graphics );
TerrainAtlas = new TerrainAtlas2D( Graphics, Drawer2D );
Animations = AddComponent( new Animations() );
Inventory = AddComponent( new Inventory() );
BlockInfo.SetDefaultBlockPermissions( Inventory.CanPlace, Inventory.CanDelete );
World = new World( this );
LocalPlayer = AddComponent( new LocalPlayer( this ) );
Entities[255] = LocalPlayer;
Width = window.Width; Height = window.Height;
MapRenderer = new MapRenderer( this );
string renType = Options.Get( OptionsKey.RenderType ) ?? "normal";
if( !SetRenderType( renType ) )
SetRenderType( "normal" );
if( IPAddress == null ) {
Network = new Singleplayer.SinglePlayerServer( this );
} else {
Network = new Network.NetworkProcessor( this );
}
Graphics.LostContextFunction = Network.Tick;
firstPersonCam = new FirstPersonCamera( this );
thirdPersonCam = new ThirdPersonCamera( this );
forwardThirdPersonCam = new ForwardThirdPersonCamera( this );
Camera = firstPersonCam;
UpdateProjection();
Gui = AddComponent( new GuiInterface( this ) );
CommandManager = AddComponent( new CommandManager() );
SelectionManager = AddComponent( new SelectionManager() );
WeatherRenderer = AddComponent( new WeatherRenderer() );
HeldBlockRenderer = AddComponent( new HeldBlockRenderer() );
Graphics.DepthTest = true;
Graphics.DepthTestFunc( CompareFunc.LessEqual );
//Graphics.DepthWrite = true;
Graphics.AlphaBlendFunc( BlendFunc.SourceAlpha, BlendFunc.InvSourceAlpha );
Graphics.AlphaTestFunc( CompareFunc.Greater, 0.5f );
Culling = new FrustumCulling();
Picking = AddComponent( new PickedPosRenderer() );
AudioPlayer = AddComponent( new AudioPlayer() );
AxisLinesRenderer = AddComponent( new AxisLinesRenderer() );
SkyboxRenderer = AddComponent( new SkyboxRenderer() );
foreach( IGameComponent comp in Components )
comp.Init( this );
ExtractInitialTexturePack();
foreach( IGameComponent comp in Components )
comp.Ready( this );
window.LoadIcon();
string connectString = "Connecting to " + IPAddress + ":" + Port + "..";
if( Graphics.WarnIfNecessary( Chat ) ) {
MapBordersRenderer.UseLegacyMode( true );
EnvRenderer.UseLegacyMode( true );
}
Gui.SetNewScreen( new LoadingMapScreen( this, connectString, "Waiting for handshake" ) );
Network.Connect( IPAddress, Port );
}
void ExtractInitialTexturePack() {
defTexturePack = Options.Get( OptionsKey.DefaultTexturePack ) ?? "default.zip";
TexturePackExtractor extractor = new TexturePackExtractor();
extractor.Extract( "default.zip", this );
// in case the user's default texture pack doesn't have all required textures
if( DefaultTexturePack != "default.zip" )
extractor.Extract( DefaultTexturePack, this );
}
void LoadOptions() {
ClassicMode = Options.GetBool( "mode-classic", false );
ClassicHacks = Options.GetBool( OptionsKey.AllowClassicHacks, false );
UseClassicGui = Options.GetBool( OptionsKey.UseClassicGui, true );
UseClassicTabList = Options.GetBool( OptionsKey.UseClassicTabList, false );
UseClassicOptions = Options.GetBool( OptionsKey.UseClassicOptions, false );
AllowCustomBlocks = Options.GetBool( OptionsKey.AllowCustomBlocks, true );
UseCPE = Options.GetBool( OptionsKey.UseCPE, true );
SimpleArmsAnim = Options.GetBool( OptionsKey.SimpleArmsAnim, false );
ViewBobbing = Options.GetBool( OptionsKey.ViewBobbing, false );
FpsLimitMethod method = Options.GetEnum( OptionsKey.FpsLimit, FpsLimitMethod.LimitVSync );
SetFpsLimitMethod( method );
ViewDistance = Options.GetInt( OptionsKey.ViewDist, 16, 4096, 512 );
UserViewDistance = ViewDistance;
SmoothLighting = Options.GetBool( OptionsKey.SmoothLighting, false );
DefaultFov = Options.GetInt( OptionsKey.FieldOfView, 1, 150, 70 );
Fov = DefaultFov;
ZoomFov = DefaultFov;
ModifiableLiquids = !ClassicMode && Options.GetBool( OptionsKey.ModifiableLiquids, false );
CameraClipping = Options.GetBool( OptionsKey.CameraClipping, true );
AllowServerTextures = Options.GetBool( OptionsKey.AllowServerTextures, true );
MouseSensitivity = Options.GetInt( OptionsKey.Sensitivity, 1, 100, 30 );
ShowBlockInHand = Options.GetBool( OptionsKey.ShowBlockInHand, true );
InvertMouse = Options.GetBool( OptionsKey.InvertMouse, false );
bool skipSsl = Options.GetBool( "skip-ssl-check", false );
if( skipSsl ) {
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
Options.Set( "skip-ssl-check", false );
}
}
void LoadGuiOptions() {
ChatLines = Options.GetInt( OptionsKey.ChatLines, 1, 30, 12 );
ClickableChat = Options.GetBool( OptionsKey.ClickableChat, false );
InventoryScale = Options.GetFloat( OptionsKey.InventoryScale, 0.25f, 5f, 1f );
HotbarScale = Options.GetFloat( OptionsKey.HotbarScale, 0.25f, 5f, 1f );
ChatScale = Options.GetFloat( OptionsKey.ChatScale, 0.35f, 5f, 1f );
ShowFPS = Options.GetBool( OptionsKey.ShowFPS, true );
TabAutocomplete = Options.GetBool( OptionsKey.TabAutocomplete, false );
FontName = Options.Get( OptionsKey.FontName ) ?? "Arial";
if( ClassicMode ) FontName = "Arial";
try {
using( Font f = new Font( FontName, 16 ) ) { }
} catch( Exception ) {
FontName = "Arial";
Options.Set( OptionsKey.FontName, "Arial" );
}
}
void OnNewMapCore( object sender, EventArgs e ) {
foreach( IGameComponent comp in Components )
comp.OnNewMap( this );
@ -269,9 +109,10 @@ namespace ClassicalSharp {
Gui.SetNewScreen( new PauseScreen( this ) );
CheckZoomFov();
CheckScheduledTasks( delta );
float t = (float)( ticksAccumulator / ticksPeriod );
DoScheduledTasks( delta );
float t = (float)(entTask.Accumulator / entTask.Interval);
LocalPlayer.SetInterpPosition( t );
if( !SkipClear || SkyboxRenderer.ShouldRender )
Graphics.Clear();
UpdateViewMatrix( delta, t );
@ -310,7 +151,7 @@ namespace ClassicalSharp {
SkyboxRenderer.Render( delta );
AxisLinesRenderer.Render( delta );
Entities.RenderModels( Graphics, delta, t );
Entities.RenderNames( Graphics, delta, t );
Entities.RenderNames( Graphics, delta );
ParticleManager.Render( delta, t );
Camera.GetPickedBlock( SelectedPos ); // TODO: only pick when necessary
@ -341,50 +182,34 @@ namespace ClassicalSharp {
Entities.DrawShadows();
SelectionManager.Render( delta );
Entities.RenderHoveredNames( Graphics, delta, t );
Entities.RenderHoveredNames( Graphics, delta );
bool left = IsMousePressed( MouseButton.Left );
bool middle = IsMousePressed( MouseButton.Middle );
bool right = IsMousePressed( MouseButton.Right );
InputHandler.PickBlocks( true, left, middle, right );
if( !HideGui )
HeldBlockRenderer.Render( delta, t );
HeldBlockRenderer.Render( delta );
}
const int ticksFrequency = 20;
const double ticksPeriod = 1.0 / ticksFrequency;
const double imageCheckPeriod = 30.0;
const double cameraPeriod = 1.0 / 60;
double ticksAccumulator, imageCheckAccumulator,
cameraAccumulator;
void DoScheduledTasks( double time ) {
for( int i = 0; i < Tasks.Count; i++ ) {
ScheduledTask task = Tasks[i];
task.Accumulator += time;
while( task.Accumulator >= task.Interval ) {
task.Callback( task );
task.Accumulator -= task.Interval;
}
}
}
void CheckScheduledTasks( double time ) {
imageCheckAccumulator += time;
ticksAccumulator += time;
cameraAccumulator += time;
if( imageCheckAccumulator > imageCheckPeriod ) {
imageCheckAccumulator -= imageCheckPeriod;
AsyncDownloader.PurgeOldEntries( 10 );
}
int ticksThisFrame = 0;
while( ticksAccumulator >= ticksPeriod ) {
Network.Tick( ticksPeriod );
Entities.Tick( ticksPeriod );
ParticleManager.Tick( ticksPeriod );
Animations.Tick( ticksPeriod );
ticksThisFrame++;
ticksAccumulator -= ticksPeriod;
}
while( cameraAccumulator >= cameraPeriod ) {
Camera.Tick( cameraPeriod );
cameraAccumulator -= cameraPeriod;
}
if( ticksThisFrame > ticksFrequency / 3 )
Utils.LogDebug( "Falling behind (did {0} ticks this frame)", ticksThisFrame );
public ScheduledTask AddScheduledTask( double interval,
Action<ScheduledTask> callback ) {
ScheduledTask task = new ScheduledTask();
task.Interval = interval; task.Callback = callback;
Tasks.Add( task );
return task;
}
void TakeScreenshot() {

View File

@ -427,14 +427,17 @@ namespace ClassicalSharp.GraphicsAPI {
}
void LoopUntilRetrieved() {
ScheduledTask task = new ScheduledTask();
task.Interval = 1.0 / 20;
task.Callback = LostContextFunction;
while( true ) {
Thread.Sleep( 50 );
uint code = (uint)device.TestCooperativeLevel();
if( (uint)code == (uint)Direct3DError.DeviceNotReset ) {
Utils.LogDebug( "Retrieved Direct3D device again." );
return;
Utils.LogDebug( "Retrieved Direct3D device again." ); return;
}
LostContextFunction( 1 / 20.0 );
task.Callback( task );
}
}

View File

@ -31,7 +31,7 @@ namespace ClassicalSharp.GraphicsAPI {
/// <summary> Delegate that is invoked when the current context is lost,
/// and is repeatedly invoked until the context can be retrieved. </summary>
public Action<double> LostContextFunction;
public Action<ScheduledTask> LostContextFunction;
/// <summary> Creates a new native texture with the specified dimensions and using the

View File

@ -30,7 +30,7 @@ namespace ClassicalSharp {
/// the client clicked on a particular block or entity. </summary>
public abstract void SendPlayerClick( MouseButton button, bool buttonDown, byte targetId, PickedPos pos );
public abstract void Tick( double delta );
public abstract void Tick( ScheduledTask task );
public abstract void Dispose();

View File

@ -161,7 +161,7 @@ namespace ClassicalSharp.Network {
int mapLength = reader.ReadInt16();
double loadingMs = ( DateTime.UtcNow - receiveStart ).TotalMilliseconds;
Utils.LogDebug( "map loading took:" + loadingMs );
game.Chat.Add( "&cmap loading took:&f " + loadingMs + " ms" );
game.World.SetNewMap( map, mapWidth, mapHeight, mapLength );
game.WorldEvents.RaiseOnNewMapLoaded();

View File

@ -65,10 +65,10 @@ namespace ClassicalSharp.Network {
Disconnected = true;
}
public override void Tick( double delta ) {
public override void Tick( ScheduledTask task ) {
if( Disconnected ) return;
if( (DateTime.UtcNow - lastPacket).TotalSeconds >= 20 )
CheckDisconnection( delta );
CheckDisconnection( task.Interval );
if( Disconnected ) return;
LocalPlayer player = game.LocalPlayer;

View File

@ -127,7 +127,8 @@ namespace ClassicalSharp.Network {
/// <summary> Removes older entries that were downloaded a certain time ago
/// but were never removed from the downloaded queue. </summary>
public void PurgeOldEntries( int seconds ) {
public void PurgeOldEntriesTask( ScheduledTask task ) {
const int seconds = 10;
lock( downloadedLocker ) {
DateTime now = DateTime.UtcNow;
List<string> itemsToRemove = new List<string>( downloaded.Count );

View File

@ -109,9 +109,9 @@ namespace ClassicalSharp.Particles {
graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, vb, vertices, drawCount, drawCount * 6 / 4 );
}
public void Tick( double delta ) {
TickParticles( terrainParticles, ref terrainCount, delta );
TickParticles( rainParticles, ref rainCount, delta );
public void Tick( ScheduledTask task ) {
TickParticles( terrainParticles, ref terrainCount, task.Interval );
TickParticles( rainParticles, ref rainCount, task.Interval );
}
void TickParticles( Particle[] particles, ref int count, double delta ) {

View File

@ -34,7 +34,7 @@ namespace ClassicalSharp.Renderers {
public void OnNewMap( Game game ) { }
public void OnNewMapLoaded( Game game ) { }
public void Render( double delta, float t ) {
public void Render( double delta ) {
if( game.Camera.IsThirdPerson || !game.ShowBlockInHand ) return;
Vector3 last = anim.pos;

View File

@ -45,8 +45,8 @@ namespace ClassicalSharp.Singleplayer {
char lastCol = '\0';
public override void SendChat( string text, bool partial ) {
if( !String.IsNullOrEmpty( text ) )
AddChat( text );
if( !partial ) lastCol = '\0';
AddChat( text );
if( !partial ) lastCol = '\0';
}
void AddChat( string text ) {
@ -69,26 +69,22 @@ namespace ClassicalSharp.Singleplayer {
physics.Dispose();
}
public override void Tick( double delta ) {
public override void Tick( ScheduledTask task ) {
if( Disconnected ) return;
physics.Tick();
CheckAsyncResources();
if( generator == null )
return;
if( generator.Done ) {
EndGeneration();
} else {
string state = generator.CurrentState;
float progress = generator.CurrentProgress;
LoadingMapScreen screen = ((LoadingMapScreen)game.Gui.ActiveScreen);
screen.SetProgress( progress );
if( state != lastState ) {
lastState = state;
screen.SetMessage( state );
}
}
if( generator == null ) return;
if( generator.Done ) { EndGeneration(); return; }
string state = generator.CurrentState;
float progress = generator.CurrentProgress;
LoadingMapScreen screen = ((LoadingMapScreen)game.Gui.ActiveScreen);
screen.SetProgress( progress );
if( state == lastState ) return;
lastState = state;
screen.SetMessage( state );
}
void EndGeneration() {

View File

@ -61,7 +61,7 @@ namespace ClassicalSharp.TexturePack {
}
/// <summary> Runs through all animations and if necessary updates the terrain atlas. </summary>
public unsafe void Tick( double delta ) {
public unsafe void Tick( ScheduledTask task ) {
if( useLavaAnim ) DrawAnimation( null, 30, LavaAnimation.Size );
if( animations.Count == 0 ) return;