2015-05-12 16:48:58 -06:00
|
|
|
|
using System;
|
2015-09-24 21:20:36 -04:00
|
|
|
|
using System.Collections.Concurrent;
|
2015-05-13 11:30:29 -06:00
|
|
|
|
using System.Collections.Generic;
|
2015-09-24 21:20:36 -04:00
|
|
|
|
using System.ComponentModel;
|
2015-05-13 11:30:29 -06:00
|
|
|
|
using System.IO;
|
2015-05-13 14:20:35 -06:00
|
|
|
|
using System.Net;
|
2015-09-24 21:20:36 -04:00
|
|
|
|
using Microsoft.Xna.Framework;
|
|
|
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
|
|
using Microsoft.Xna.Framework.Input;
|
|
|
|
|
using MonoGame.Utilities.Png;
|
2015-05-13 16:26:23 -06:00
|
|
|
|
using TrueCraft.API;
|
2015-09-24 21:20:36 -04:00
|
|
|
|
using TrueCraft.API.Logic;
|
2015-05-17 16:18:09 -06:00
|
|
|
|
using TrueCraft.API.World;
|
2015-06-16 21:58:55 -04:00
|
|
|
|
using TrueCraft.Core;
|
2015-09-24 21:20:36 -04:00
|
|
|
|
using TrueCraft.Core.Networking.Packets;
|
|
|
|
|
using TrueCraft.Client.Input;
|
|
|
|
|
using TrueCraft.Client.Modules;
|
|
|
|
|
using TrueCraft.Client.Rendering;
|
2015-05-12 16:48:58 -06:00
|
|
|
|
|
2015-05-16 21:50:10 -06:00
|
|
|
|
namespace TrueCraft.Client
|
2015-05-12 16:48:58 -06:00
|
|
|
|
{
|
|
|
|
|
public class TrueCraftGame : Game
|
|
|
|
|
{
|
2015-09-24 21:20:36 -04:00
|
|
|
|
public MultiplayerClient Client { get; private set; }
|
|
|
|
|
public GraphicsDeviceManager Graphics { get; private set; }
|
|
|
|
|
public TextureMapper TextureMapper { get; private set; }
|
|
|
|
|
public Camera Camera { get; private set; }
|
|
|
|
|
public ConcurrentBag<Action> PendingMainThreadActions { get; set; }
|
|
|
|
|
public double Bobbing { get; set; }
|
2015-09-24 22:28:44 -04:00
|
|
|
|
public ChunkModule ChunkModule { get; set; }
|
2015-09-27 17:14:04 -04:00
|
|
|
|
public float ScaleFactor { get; set; }
|
2015-09-24 21:20:36 -04:00
|
|
|
|
|
|
|
|
|
private List<IGameplayModule> Modules { get; set; }
|
2015-05-13 11:30:29 -06:00
|
|
|
|
private SpriteBatch SpriteBatch { get; set; }
|
2015-09-24 21:20:36 -04:00
|
|
|
|
private KeyboardHandler KeyboardComponent { get; set; }
|
|
|
|
|
private MouseHandler MouseComponent { get; set; }
|
|
|
|
|
private RenderTarget2D RenderTarget { get; set; }
|
|
|
|
|
|
|
|
|
|
private FontRenderer Pixel { get; set; }
|
2015-05-13 14:20:35 -06:00
|
|
|
|
private IPEndPoint EndPoint { get; set; }
|
2015-09-20 17:45:15 -04:00
|
|
|
|
private DateTime LastPhysicsUpdate { get; set; }
|
2015-05-13 16:26:23 -06:00
|
|
|
|
private DateTime NextPhysicsUpdate { get; set; }
|
2015-09-24 21:20:36 -04:00
|
|
|
|
private bool MouseCaptured { get; set; }
|
2015-06-13 19:17:06 -04:00
|
|
|
|
private GameTime GameTime { get; set; }
|
2015-09-24 22:28:44 -04:00
|
|
|
|
private DebugInfoModule DebugInfoModule { get; set; }
|
2015-05-12 17:39:34 -06:00
|
|
|
|
|
2015-09-27 17:14:04 -04:00
|
|
|
|
public static readonly double Reach = 3;
|
2015-09-24 08:28:16 -04:00
|
|
|
|
|
2015-09-24 21:20:36 -04:00
|
|
|
|
public IBlockRepository BlockRepository
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return Client.World.World.BlockRepository;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-13 14:20:35 -06:00
|
|
|
|
public TrueCraftGame(MultiplayerClient client, IPEndPoint endPoint)
|
2015-05-12 16:48:58 -06:00
|
|
|
|
{
|
|
|
|
|
Window.Title = "TrueCraft";
|
2015-05-13 11:30:29 -06:00
|
|
|
|
Content.RootDirectory = "Content";
|
2015-05-12 16:48:58 -06:00
|
|
|
|
Graphics = new GraphicsDeviceManager(this);
|
2015-06-17 19:23:24 -04:00
|
|
|
|
Graphics.SynchronizeWithVerticalRetrace = false;
|
2015-06-17 15:03:06 -04:00
|
|
|
|
Graphics.IsFullScreen = UserSettings.Local.IsFullscreen;
|
2015-06-17 14:23:46 -04:00
|
|
|
|
Graphics.PreferredBackBufferWidth = UserSettings.Local.WindowResolution.Width;
|
|
|
|
|
Graphics.PreferredBackBufferHeight = UserSettings.Local.WindowResolution.Height;
|
2015-09-24 22:28:44 -04:00
|
|
|
|
Graphics.ApplyChanges();
|
2015-09-27 17:14:04 -04:00
|
|
|
|
Window.ClientSizeChanged += Window_ClientSizeChanged;
|
2015-05-12 17:30:56 -06:00
|
|
|
|
Client = client;
|
2015-05-13 14:20:35 -06:00
|
|
|
|
EndPoint = endPoint;
|
2015-09-20 17:45:15 -04:00
|
|
|
|
LastPhysicsUpdate = DateTime.MinValue;
|
2015-05-13 16:26:23 -06:00
|
|
|
|
NextPhysicsUpdate = DateTime.MinValue;
|
2015-05-24 11:07:13 -06:00
|
|
|
|
PendingMainThreadActions = new ConcurrentBag<Action>();
|
2015-05-17 16:18:09 -06:00
|
|
|
|
MouseCaptured = true;
|
2015-09-20 18:11:02 -04:00
|
|
|
|
Bobbing = 0;
|
2015-06-13 19:17:06 -04:00
|
|
|
|
|
2015-09-24 21:20:36 -04:00
|
|
|
|
var keyboardComponent = new KeyboardHandler(this);
|
2015-06-14 11:24:37 -04:00
|
|
|
|
KeyboardComponent = keyboardComponent;
|
|
|
|
|
Components.Add(keyboardComponent);
|
|
|
|
|
|
2015-09-24 21:20:36 -04:00
|
|
|
|
var mouseComponent = new MouseHandler(this);
|
2015-06-13 19:17:06 -04:00
|
|
|
|
MouseComponent = mouseComponent;
|
|
|
|
|
Components.Add(mouseComponent);
|
2015-05-12 16:48:58 -06:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-27 17:14:04 -04:00
|
|
|
|
void Window_ClientSizeChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (GraphicsDevice.Viewport.Width < 640 || GraphicsDevice.Viewport.Height < 480)
|
|
|
|
|
ScaleFactor = 0.5f;
|
|
|
|
|
else if (GraphicsDevice.Viewport.Width < 978 || GraphicsDevice.Viewport.Height < 720)
|
|
|
|
|
ScaleFactor = 1.0f;
|
|
|
|
|
else
|
|
|
|
|
ScaleFactor = 1.5f;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-13 11:30:29 -06:00
|
|
|
|
protected override void Initialize()
|
|
|
|
|
{
|
2015-09-24 21:20:36 -04:00
|
|
|
|
Modules = new List<IGameplayModule>();
|
|
|
|
|
|
2015-05-13 14:20:35 -06:00
|
|
|
|
base.Initialize(); // (calls LoadContent)
|
2015-09-24 21:20:36 -04:00
|
|
|
|
|
2015-09-24 22:28:44 -04:00
|
|
|
|
ChunkModule = new ChunkModule(this);
|
|
|
|
|
DebugInfoModule = new DebugInfoModule(this, Pixel);
|
|
|
|
|
|
|
|
|
|
Modules.Add(ChunkModule);
|
2015-09-24 21:20:36 -04:00
|
|
|
|
Modules.Add(new HighlightModule(this));
|
|
|
|
|
Modules.Add(new PlayerControlModule(this));
|
2015-09-27 17:14:04 -04:00
|
|
|
|
Modules.Add(new HUDModule(this));
|
2015-09-24 22:28:44 -04:00
|
|
|
|
Modules.Add(DebugInfoModule);
|
2015-09-24 21:20:36 -04:00
|
|
|
|
|
2015-05-14 18:47:16 -06:00
|
|
|
|
Client.PropertyChanged += HandleClientPropertyChanged;
|
2015-05-13 14:20:35 -06:00
|
|
|
|
Client.Connect(EndPoint);
|
2015-09-24 21:20:36 -04:00
|
|
|
|
|
2015-05-13 23:09:49 -06:00
|
|
|
|
var centerX = GraphicsDevice.Viewport.Width / 2;
|
|
|
|
|
var centerY = GraphicsDevice.Viewport.Height / 2;
|
|
|
|
|
Mouse.SetPosition(centerX, centerY);
|
2015-09-24 21:20:36 -04:00
|
|
|
|
|
2015-09-21 17:51:19 -04:00
|
|
|
|
Camera = new Camera(GraphicsDevice.Viewport.AspectRatio, 70.0f, 0.1f, 1000.0f);
|
2015-06-12 17:10:28 -04:00
|
|
|
|
UpdateCamera();
|
2015-09-24 21:20:36 -04:00
|
|
|
|
|
2015-06-13 19:17:06 -04:00
|
|
|
|
MouseComponent.Move += OnMouseComponentMove;
|
2015-06-14 11:24:37 -04:00
|
|
|
|
KeyboardComponent.KeyDown += OnKeyboardKeyDown;
|
|
|
|
|
KeyboardComponent.KeyUp += OnKeyboardKeyUp;
|
2015-06-03 15:22:49 -06:00
|
|
|
|
|
2015-09-24 21:20:36 -04:00
|
|
|
|
Window.ClientSizeChanged += (sender, e) => CreateRenderTarget();
|
|
|
|
|
CreateRenderTarget();
|
|
|
|
|
SpriteBatch = new SpriteBatch(GraphicsDevice);
|
2015-09-27 17:14:04 -04:00
|
|
|
|
|
|
|
|
|
Window_ClientSizeChanged(null, null);
|
2015-09-24 08:28:16 -04:00
|
|
|
|
}
|
|
|
|
|
|
2015-06-03 15:22:49 -06:00
|
|
|
|
private void CreateRenderTarget()
|
|
|
|
|
{
|
|
|
|
|
RenderTarget = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height,
|
|
|
|
|
false, GraphicsDevice.PresentationParameters.BackBufferFormat, DepthFormat.Depth24);
|
2015-05-14 18:47:16 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HandleClientPropertyChanged(object sender, PropertyChangedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
switch (e.PropertyName)
|
|
|
|
|
{
|
|
|
|
|
case "Position":
|
2015-06-12 17:10:28 -04:00
|
|
|
|
UpdateCamera();
|
2015-05-14 18:47:16 -06:00
|
|
|
|
break;
|
|
|
|
|
}
|
2015-05-13 11:30:29 -06:00
|
|
|
|
}
|
|
|
|
|
|
2015-05-12 17:39:34 -06:00
|
|
|
|
protected override void LoadContent()
|
|
|
|
|
{
|
2015-06-16 23:31:56 -04:00
|
|
|
|
// Ensure we have default textures loaded.
|
|
|
|
|
TextureMapper.LoadDefaults(GraphicsDevice);
|
|
|
|
|
|
|
|
|
|
// Load any custom textures if needed.
|
2015-06-17 09:10:42 -04:00
|
|
|
|
TextureMapper = new TextureMapper(GraphicsDevice);
|
|
|
|
|
if (UserSettings.Local.SelectedTexturePack != TexturePack.Default.Name)
|
|
|
|
|
TextureMapper.AddTexturePack(TexturePack.FromArchive(Path.Combine(TexturePack.TexturePackPath, UserSettings.Local.SelectedTexturePack)));
|
2015-06-16 23:31:56 -04:00
|
|
|
|
|
2015-06-23 15:49:21 -04:00
|
|
|
|
Pixel = new FontRenderer(
|
2015-09-24 21:20:36 -04:00
|
|
|
|
new Font(Content, "Fonts/Pixel"),
|
2015-09-24 22:28:44 -04:00
|
|
|
|
new Font(Content, "Fonts/Pixel", FontStyle.Bold), null, null,
|
2015-06-23 15:49:21 -04:00
|
|
|
|
new Font(Content, "Fonts/Pixel", FontStyle.Italic));
|
2015-09-24 08:28:16 -04:00
|
|
|
|
|
2015-05-12 17:39:34 -06:00
|
|
|
|
base.LoadContent();
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-14 11:24:37 -04:00
|
|
|
|
private void OnKeyboardKeyDown(object sender, KeyboardKeyEventArgs e)
|
2015-05-13 16:26:23 -06:00
|
|
|
|
{
|
2015-09-24 21:20:36 -04:00
|
|
|
|
foreach (var module in Modules)
|
2015-06-03 15:30:03 -06:00
|
|
|
|
{
|
2015-09-24 21:20:36 -04:00
|
|
|
|
var input = module as IInputModule;
|
|
|
|
|
if (input != null)
|
|
|
|
|
{
|
|
|
|
|
if (input.KeyDown(GameTime, e))
|
2015-09-20 17:45:15 -04:00
|
|
|
|
break;
|
2015-09-24 21:20:36 -04:00
|
|
|
|
}
|
2015-06-03 15:30:03 -06:00
|
|
|
|
}
|
2015-06-14 11:24:37 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnKeyboardKeyUp(object sender, KeyboardKeyEventArgs e)
|
|
|
|
|
{
|
2015-09-24 21:20:36 -04:00
|
|
|
|
foreach (var module in Modules)
|
2015-05-17 16:52:16 -06:00
|
|
|
|
{
|
2015-09-24 21:20:36 -04:00
|
|
|
|
var input = module as IInputModule;
|
|
|
|
|
if (input != null)
|
|
|
|
|
{
|
|
|
|
|
if (input.KeyUp(GameTime, e))
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-06-14 11:24:37 -04:00
|
|
|
|
}
|
2015-06-13 19:17:06 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnMouseComponentMove(object sender, MouseMoveEventArgs e)
|
|
|
|
|
{
|
2015-09-24 21:20:36 -04:00
|
|
|
|
foreach (var module in Modules)
|
2015-05-17 16:18:09 -06:00
|
|
|
|
{
|
2015-09-24 21:20:36 -04:00
|
|
|
|
var input = module as IInputModule;
|
|
|
|
|
if (input != null)
|
|
|
|
|
input.MouseMove(GameTime, e);
|
2015-05-17 16:18:09 -06:00
|
|
|
|
}
|
2015-05-13 16:26:23 -06:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-24 21:20:36 -04:00
|
|
|
|
public void TakeScreenshot()
|
2015-06-14 11:24:37 -04:00
|
|
|
|
{
|
|
|
|
|
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
|
2015-06-23 15:56:35 -06:00
|
|
|
|
".truecraft", "screenshots", DateTime.Now.ToString("yyyy-MM-dd_H.mm.ss") + ".png");
|
2015-06-14 11:24:37 -04:00
|
|
|
|
if (!Directory.Exists(Path.GetDirectoryName(path)))
|
|
|
|
|
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
|
|
|
|
using (var stream = File.OpenWrite(path))
|
2015-06-23 15:56:35 -06:00
|
|
|
|
new PngWriter().Write(RenderTarget, stream);
|
2015-06-14 11:24:37 -04:00
|
|
|
|
}
|
|
|
|
|
|
2015-05-13 16:26:23 -06:00
|
|
|
|
protected override void Update(GameTime gameTime)
|
|
|
|
|
{
|
2015-06-13 19:17:06 -04:00
|
|
|
|
GameTime = gameTime;
|
|
|
|
|
|
2015-05-17 16:52:16 -06:00
|
|
|
|
Action action;
|
2015-05-24 11:07:13 -06:00
|
|
|
|
if (PendingMainThreadActions.TryTake(out action))
|
2015-05-17 16:52:16 -06:00
|
|
|
|
action();
|
|
|
|
|
|
2015-09-20 17:45:15 -04:00
|
|
|
|
IChunk chunk;
|
2015-09-24 21:20:36 -04:00
|
|
|
|
var adjusted = Client.World.World.FindBlockPosition(
|
|
|
|
|
new Coordinates3D((int)Client.Position.X, 0, (int)Client.Position.Z), out chunk);
|
2015-09-20 17:55:57 -04:00
|
|
|
|
if (chunk != null && Client.LoggedIn)
|
2015-09-20 17:45:15 -04:00
|
|
|
|
{
|
|
|
|
|
if (chunk.GetHeight((byte)adjusted.X, (byte)adjusted.Z) != 0)
|
|
|
|
|
Client.Physics.Update(gameTime.ElapsedGameTime);
|
|
|
|
|
}
|
2015-07-02 12:14:55 -06:00
|
|
|
|
if (NextPhysicsUpdate < DateTime.UtcNow && Client.LoggedIn)
|
2015-05-13 16:26:23 -06:00
|
|
|
|
{
|
2015-05-17 16:52:16 -06:00
|
|
|
|
// NOTE: This is to make the vanilla server send us chunk packets
|
|
|
|
|
// We should eventually make some means of detecing that we're on a vanilla server to enable this
|
|
|
|
|
// It's a waste of bandwidth to do it on a TrueCraft server
|
|
|
|
|
Client.QueuePacket(new PlayerGroundedPacket { OnGround = true });
|
|
|
|
|
Client.QueuePacket(new PlayerPositionAndLookPacket(Client.Position.X, Client.Position.Y,
|
|
|
|
|
Client.Position.Y + MultiplayerClient.Height, Client.Position.Z, Client.Yaw, Client.Pitch, false));
|
2015-07-02 12:14:55 -06:00
|
|
|
|
NextPhysicsUpdate = DateTime.UtcNow.AddMilliseconds(1000 / 20);
|
2015-05-13 16:26:23 -06:00
|
|
|
|
}
|
2015-06-14 11:24:37 -04:00
|
|
|
|
|
2015-09-24 21:20:36 -04:00
|
|
|
|
foreach (var module in Modules)
|
|
|
|
|
module.Update(gameTime);
|
2015-06-14 11:24:37 -04:00
|
|
|
|
|
2015-09-20 17:45:15 -04:00
|
|
|
|
UpdateCamera();
|
2015-09-24 21:20:36 -04:00
|
|
|
|
|
2015-05-12 16:48:58 -06:00
|
|
|
|
base.Update(gameTime);
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-12 17:10:28 -04:00
|
|
|
|
private void UpdateCamera()
|
2015-05-12 16:48:58 -06:00
|
|
|
|
{
|
2015-09-22 08:44:52 -04:00
|
|
|
|
const double bobbingMultiplier = 0.015;
|
2015-09-24 21:20:36 -04:00
|
|
|
|
|
2015-09-22 08:44:52 -04:00
|
|
|
|
var bobbing = Bobbing * 1.5;
|
2015-09-24 21:20:36 -04:00
|
|
|
|
var xbob = Math.Cos(bobbing + Math.PI / 2) * bobbingMultiplier;
|
|
|
|
|
var ybob = Math.Sin(Math.PI / 2 - (2 * bobbing)) * bobbingMultiplier;
|
2015-09-27 17:14:04 -04:00
|
|
|
|
|
2015-06-12 17:10:28 -04:00
|
|
|
|
Camera.Position = new TrueCraft.API.Vector3(
|
2015-09-24 21:20:36 -04:00
|
|
|
|
Client.Position.X + xbob - (Client.Size.Width / 2),
|
2015-09-27 17:14:04 -04:00
|
|
|
|
Client.Position.Y + Client.Size.Height + ybob,
|
2015-09-21 17:51:19 -04:00
|
|
|
|
Client.Position.Z - (Client.Size.Depth / 2));
|
2015-05-13 23:09:49 -06:00
|
|
|
|
|
2015-06-12 17:10:28 -04:00
|
|
|
|
Camera.Pitch = Client.Pitch;
|
|
|
|
|
Camera.Yaw = Client.Yaw;
|
2015-05-14 18:47:16 -06:00
|
|
|
|
}
|
2015-05-13 23:09:49 -06:00
|
|
|
|
|
2015-05-14 18:47:16 -06:00
|
|
|
|
protected override void Draw(GameTime gameTime)
|
|
|
|
|
{
|
2015-06-03 15:22:49 -06:00
|
|
|
|
GraphicsDevice.SetRenderTarget(RenderTarget);
|
2015-06-17 21:47:34 -04:00
|
|
|
|
GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
|
2015-06-03 15:22:49 -06:00
|
|
|
|
|
2015-05-12 16:48:58 -06:00
|
|
|
|
Graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
|
2015-05-13 23:45:13 -06:00
|
|
|
|
GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
|
|
|
|
|
GraphicsDevice.SamplerStates[1] = SamplerState.PointClamp;
|
2015-05-13 23:09:49 -06:00
|
|
|
|
|
2015-09-24 22:28:44 -04:00
|
|
|
|
Mesh.ResetStats();
|
2015-09-24 21:20:36 -04:00
|
|
|
|
foreach (var module in Modules)
|
2015-05-13 23:09:49 -06:00
|
|
|
|
{
|
2015-09-24 21:20:36 -04:00
|
|
|
|
var drawable = module as IGraphicalModule;
|
|
|
|
|
if (drawable != null)
|
|
|
|
|
drawable.Draw(gameTime);
|
2015-05-17 16:52:16 -06:00
|
|
|
|
}
|
|
|
|
|
|
2015-06-03 15:22:49 -06:00
|
|
|
|
GraphicsDevice.SetRenderTarget(null);
|
|
|
|
|
|
|
|
|
|
SpriteBatch.Begin();
|
|
|
|
|
SpriteBatch.Draw(RenderTarget, new Vector2(0));
|
|
|
|
|
SpriteBatch.End();
|
|
|
|
|
|
2015-05-12 16:48:58 -06:00
|
|
|
|
base.Draw(gameTime);
|
|
|
|
|
}
|
2015-06-14 12:36:38 -04:00
|
|
|
|
|
|
|
|
|
protected override void Dispose(bool disposing)
|
|
|
|
|
{
|
|
|
|
|
if (disposing)
|
|
|
|
|
{
|
|
|
|
|
KeyboardComponent.Dispose();
|
|
|
|
|
MouseComponent.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
base.Dispose(disposing);
|
|
|
|
|
}
|
2015-05-12 16:48:58 -06:00
|
|
|
|
}
|
2015-05-29 17:43:23 -06:00
|
|
|
|
}
|