mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-27 23:41:14 -04:00
128 lines
3.7 KiB
C#
128 lines
3.7 KiB
C#
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
|
//#define TEST_VANILLA
|
|
using System;
|
|
using System.Net;
|
|
using ClassicalSharp.Entities;
|
|
using ClassicalSharp.Generator;
|
|
using ClassicalSharp.Gui.Screens;
|
|
using ClassicalSharp.Physics;
|
|
using OpenTK;
|
|
using OpenTK.Input;
|
|
|
|
namespace ClassicalSharp.Singleplayer {
|
|
|
|
public sealed class SinglePlayerServer : IServerConnection {
|
|
|
|
internal PhysicsBase physics;
|
|
internal byte[] generatedMap;
|
|
IMapGenerator generator;
|
|
string lastState;
|
|
|
|
public SinglePlayerServer(Game window) {
|
|
game = window;
|
|
physics = new PhysicsBase(game);
|
|
SupportsFullCP437 = !game.ClassicMode;
|
|
SupportsPartialMessages = true;
|
|
}
|
|
|
|
public override bool IsSinglePlayer { get { return true; } }
|
|
|
|
public override void Connect(IPAddress address, int port) {
|
|
game.Chat.SetLogName("Singleplayer");
|
|
game.UseCPEBlocks = game.UseCPE;
|
|
int max = game.UseCPEBlocks ? Block.MaxCpeBlock : Block.MaxOriginalBlock;
|
|
for (int i = 1; i <= max; i++) {
|
|
game.Inventory.CanPlace[i] = true;
|
|
game.Inventory.CanDelete[i] = true;
|
|
}
|
|
game.AsyncDownloader.DownloadSkin(game.LocalPlayer.SkinIdentifier,
|
|
game.LocalPlayer.SkinName);
|
|
|
|
game.Events.RaiseBlockPermissionsChanged();
|
|
int seed = new Random().Next();
|
|
GenMap(128, 64, 128, seed, new NotchyGenerator());
|
|
}
|
|
|
|
char lastCol = '\0';
|
|
public override void SendChat(string text, bool partial) {
|
|
if (!String.IsNullOrEmpty(text))
|
|
AddChat(text);
|
|
if (!partial) lastCol = '\0';
|
|
}
|
|
|
|
void AddChat(string text) {
|
|
text = text.TrimEnd().Replace('%', '&');
|
|
if (!IDrawer2D.IsWhiteColour(lastCol))
|
|
text = "&" + lastCol + text;
|
|
|
|
char col = game.Drawer2D.LastColour(text, text.Length);
|
|
if (col != '\0') lastCol = col;
|
|
game.Chat.Add(text, MessageType.Normal);
|
|
}
|
|
|
|
public override void SendPosition(Vector3 pos, float rotY, float headX) {
|
|
}
|
|
|
|
public override void SendPlayerClick(MouseButton button, bool buttonDown, byte targetId, PickedPos pos) {
|
|
}
|
|
|
|
public override void Dispose() {
|
|
physics.Dispose();
|
|
}
|
|
|
|
public override void Tick(ScheduledTask task) {
|
|
if (Disconnected) return;
|
|
physics.Tick();
|
|
CheckAsyncResources();
|
|
|
|
if (generator == null) return;
|
|
if (generator.Done) { EndGeneration(); return; }
|
|
|
|
string state = generator.CurrentState;
|
|
float progress = generator.CurrentProgress;
|
|
LoadingMapScreen screen = ((LoadingMapScreen)game.Gui.UnderlyingScreen);
|
|
|
|
screen.SetProgress(progress);
|
|
if (state == lastState) return;
|
|
lastState = state;
|
|
screen.SetMessage(state);
|
|
}
|
|
|
|
void EndGeneration() {
|
|
game.Gui.SetNewScreen(null);
|
|
if (generatedMap == null) {
|
|
game.Chat.Add("&cFailed to generate the map.");
|
|
} else {
|
|
IMapGenerator gen = generator;
|
|
game.World.SetNewMap(generatedMap, gen.Width, gen.Height, gen.Length);
|
|
generatedMap = null;
|
|
ResetPlayerPosition();
|
|
|
|
game.WorldEvents.RaiseOnNewMapLoaded();
|
|
gen.ApplyEnv(game.World);
|
|
}
|
|
|
|
generator = null;
|
|
GC.Collect();
|
|
}
|
|
|
|
internal void GenMap(int width, int height, int length, int seed, IMapGenerator generator) {
|
|
game.World.Reset();
|
|
GC.Collect();
|
|
this.generator = generator;
|
|
game.Gui.SetNewScreen(new LoadingMapScreen(game, "Generating level", "Generating.."));
|
|
generator.GenerateAsync(game, width, height, length, seed);
|
|
}
|
|
|
|
void ResetPlayerPosition() {
|
|
float x = (game.World.Width / 2) + 0.5f;
|
|
float z = (game.World.Length / 2) + 0.5f;
|
|
Vector3 spawn = Respawn.FindSpawnPosition(game, x, z, game.LocalPlayer.Size);
|
|
|
|
LocationUpdate update = LocationUpdate.MakePosAndOri(spawn, 0, 0, false);
|
|
game.LocalPlayer.SetLocation(update, false);
|
|
game.LocalPlayer.Spawn = spawn;
|
|
game.CurrentCameraPos = game.Camera.GetCameraPos(0);
|
|
}
|
|
}
|
|
} |