Add basic singleplayer support. Generates a flatgrass map, but has no support for saving. Partially addresses #40.

This commit is contained in:
UnknownShadow200 2015-09-01 06:48:46 +10:00
parent 385c46e21d
commit 6ebed77929
12 changed files with 233 additions and 111 deletions

View File

@ -1,6 +1,6 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
# SharpDevelop 4.4
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassicalSharp", "ClassicalSharp\ClassicalSharp.csproj", "{BEB1C785-5CAD-48FF-A886-876BF0A318D4}"
EndProject
@ -21,14 +21,14 @@ Global
{23B9BDA8-4330-46AB-9012-08D87430391A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23B9BDA8-4330-46AB-9012-08D87430391A}.Release|Any CPU.Build.0 = Release|Any CPU
{23B9BDA8-4330-46AB-9012-08D87430391A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23B9BDA8-4330-46AB-9012-08D87430391A}.Debug_DX|Any CPU.Build.0 = Debug|Any CPU
{23B9BDA8-4330-46AB-9012-08D87430391A}.Debug_DX|Any CPU.ActiveCfg = Debug|Any CPU
{23B9BDA8-4330-46AB-9012-08D87430391A}.Debug_DX|Any CPU.Build.0 = Debug|Any CPU
{23B9BDA8-4330-46AB-9012-08D87430391A}.Debug_DX|Any CPU.ActiveCfg = Debug|Any CPU
{BEB1C785-5CAD-48FF-A886-876BF0A318D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BEB1C785-5CAD-48FF-A886-876BF0A318D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BEB1C785-5CAD-48FF-A886-876BF0A318D4}.Release|Any CPU.Build.0 = Release|Any CPU
{BEB1C785-5CAD-48FF-A886-876BF0A318D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BEB1C785-5CAD-48FF-A886-876BF0A318D4}.Debug_DX|Any CPU.Build.0 = Debug_DX|Any CPU
{BEB1C785-5CAD-48FF-A886-876BF0A318D4}.Debug_DX|Any CPU.ActiveCfg = Debug_DX|Any CPU
{BEB1C785-5CAD-48FF-A886-876BF0A318D4}.Debug_DX|Any CPU.ActiveCfg = Debug_DX|Any CPU
{35FEE071-2DE6-48A1-9343-B5C1F202A12B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{35FEE071-2DE6-48A1-9343-B5C1F202A12B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{35FEE071-2DE6-48A1-9343-B5C1F202A12B}.Release|Any CPU.Build.0 = Release|Any CPU

View File

@ -128,11 +128,13 @@
<Compile Include="Model\SpiderModel.cs" />
<Compile Include="Model\ZombieModel.cs" />
<Compile Include="Network\Enums.cs" />
<Compile Include="Network\FastNetReader.cs" />
<Compile Include="Network\FixedBufferStream.cs" />
<Compile Include="Network\GZipHeaderReader.cs" />
<Compile Include="Network\INetworkProcessor.cs" />
<Compile Include="Network\SinglePlayerServer.cs" />
<Compile Include="Network\NetworkProcessor.cs" />
<Compile Include="Network\AsyncDownloader.cs" />
<Compile Include="Network\Utils\AsyncDownloader.cs" />
<Compile Include="Network\Utils\FastNetReader.cs" />
<Compile Include="Network\Utils\FixedBufferStream.cs" />
<Compile Include="Network\Utils\GZipHeaderReader.cs" />
<Compile Include="Network\WomConfigHandler.cs" />
<Compile Include="Commands\CommandManager.cs" />
<Compile Include="Commands\CommandReader.cs" />
@ -184,6 +186,7 @@
<Folder Include="Map" />
<Folder Include="Game" />
<Folder Include="Model" />
<Folder Include="Network\Utils" />
<Folder Include="Utils" />
<Folder Include="Physics" />
</ItemGroup>

View File

@ -19,7 +19,7 @@ namespace ClassicalSharp {
public IGraphicsApi Graphics;
public Map Map;
public NetworkProcessor Network;
public INetworkProcessor Network;
public EntityList Players = new EntityList();
public CpeListInfo[] CpePlayersList = new CpeListInfo[256];

View File

@ -278,7 +278,7 @@ namespace ClassicalSharp.GraphicsAPI {
}
public override void DrawIndexedVb( DrawMode mode, int indicesCount, int startIndex ) {
device.DrawIndexedPrimitives( modeMappings[(int)mode], 0, 0,
device.DrawIndexedPrimitives( modeMappings[(int)mode], 0, startIndex / 6 * 4,
indicesCount / 6 * 4, startIndex, NumPrimitives( indicesCount, mode ) );
}

View File

@ -0,0 +1,31 @@
using System;
using System.Net;
using OpenTK;
using OpenTK.Input;
namespace ClassicalSharp {
/// <summary> Represents a connection to either a multiplayer server, or an internal single player server. </summary>
public abstract class INetworkProcessor {
public abstract bool IsSinglePlayer { get; }
public abstract void Connect( IPAddress address, int port );
public abstract void SendChat( string text );
public abstract void SendPosition( Vector3 pos, float yaw, float pitch );
public abstract void SendSetBlock( int x, int y, int z, bool place, byte block );
public abstract void SendPlayerClick( MouseButton button, bool buttonDown, byte targetId, PickedPos pos );
public abstract void Tick( double delta );
public abstract void Dispose();
public string ServerName, ServerMotd;
public bool Disconnected;
public bool UsingExtPlayerList, UsingPlayerClick;
}
}

View File

@ -14,31 +14,31 @@ using OpenTK.Input;
namespace ClassicalSharp {
public partial class NetworkProcessor {
public partial class NetworkProcessor : INetworkProcessor {
public NetworkProcessor( Game window ) {
Window = window;
game = window;
}
public override bool IsSinglePlayer {
get { return false; }
}
Socket socket;
NetworkStream stream;
public Game Window;
public string ServerName, ServerMotd;
public bool Disconnected;
Game game;
bool sendHeldBlock;
bool useMessageTypes;
bool useBlockPermissions;
bool receivedFirstPosition;
public bool UsingExtPlayerList;
public bool UsingPlayerClick;
public void Connect( IPAddress address, int port ) {
public override void Connect( IPAddress address, int port ) {
socket = new Socket( address.AddressFamily, SocketType.Stream, ProtocolType.Tcp );
try {
socket.Connect( address, port );
} catch( SocketException ex ) {
Utils.LogError( "Error while trying to connect: {0}{1}", Environment.NewLine, ex );
Window.Disconnect( "&eUnable to reach " + address + ":" + port,
game.Disconnect( "&eUnable to reach " + address + ":" + port,
"Unable to establish an underlying connection" );
Dispose();
return;
@ -46,55 +46,55 @@ namespace ClassicalSharp {
stream = new NetworkStream( socket, true );
reader = new FastNetReader( stream );
gzippedMap = new FixedBufferStream( reader.buffer );
MakeLoginPacket( Window.Username, Window.Mppass );
MakeLoginPacket( game.Username, game.Mppass );
SendPacket();
}
public void SendChat( string text ) {
public override void SendChat( string text ) {
if( !String.IsNullOrEmpty( text ) ) {
MakeMessagePacket( text );
SendPacket();
}
}
public void SendPosition( Vector3 pos, float yaw, float pitch ) {
byte payload = sendHeldBlock ? (byte)Window.HeldBlock : (byte)0xFF;
public override void SendPosition( Vector3 pos, float yaw, float pitch ) {
byte payload = sendHeldBlock ? (byte)game.HeldBlock : (byte)0xFF;
MakePositionPacket( pos, yaw, pitch, payload );
SendPacket();
}
public void SendSetBlock( int x, int y, int z, bool place, byte block ) {
public override void SendSetBlock( int x, int y, int z, bool place, byte block ) {
MakeSetBlockPacket( (short)x, (short)y, (short)z, place, block );
SendPacket();
}
public void SendPlayerClick( MouseButton button, bool buttonDown, byte targetId, PickedPos pos ) {
Player p = Window.LocalPlayer;
public override void SendPlayerClick( MouseButton button, bool buttonDown, byte targetId, PickedPos pos ) {
Player p = game.LocalPlayer;
MakePlayerClick( (byte)button, buttonDown, p.YawDegrees, p.PitchDegrees, targetId,
pos.BlockPos, pos.BlockFace );
}
public void Dispose() {
public override void Dispose() {
socket.Close();
Disconnected = true;
}
void CheckForNewTerrainAtlas() {
DownloadedItem item;
Window.AsyncDownloader.TryGetItem( "terrain", out item );
game.AsyncDownloader.TryGetItem( "terrain", out item );
if( item != null && item.Bmp != null ) {
Window.ChangeTerrainAtlas( item.Bmp );
game.ChangeTerrainAtlas( item.Bmp );
}
}
public void Tick( double delta ) {
public override void Tick( double delta ) {
if( Disconnected ) return;
try {
reader.ReadPendingData();
} catch( IOException ex ) {
Utils.LogError( "Error while reading packets: {0}{1}", Environment.NewLine, ex );
Window.Disconnect( "&eLost connection to the server", "Underlying connection was closed" );
game.Disconnect( "&eLost connection to the server", "Underlying connection was closed" );
Dispose();
return;
}
@ -105,7 +105,7 @@ namespace ClassicalSharp {
ReadPacket( opcode );
}
Player player = Window.LocalPlayer;
Player player = game.LocalPlayer;
if( receivedFirstPosition ) {
SendPosition( player.Position, player.YawDegrees, player.PitchDegrees );
}
@ -232,7 +232,7 @@ namespace ClassicalSharp {
stream.Write( outBuffer, 0, packetLength );
} catch( IOException ex ) {
Utils.LogError( "Error while writing packets: {0}{1}", Environment.NewLine, ex );
Window.Disconnect( "&eLost connection to the server", "Underlying connection was closed" );
game.Disconnect( "&eLost connection to the server", "Underlying connection was closed" );
Dispose();
}
}
@ -262,11 +262,11 @@ namespace ClassicalSharp {
ServerMotd = reader.ReadAsciiString();
byte userType = reader.ReadUInt8();
if( !useBlockPermissions ) {
Window.CanDelete[(int)Block.Bedrock] = userType == 0x64;
game.CanDelete[(int)Block.Bedrock] = userType == 0x64;
}
Window.LocalPlayer.UserType = userType;
game.LocalPlayer.UserType = userType;
receivedFirstPosition = false;
Window.LocalPlayer.ParseHackFlags( ServerName, ServerMotd );
game.LocalPlayer.ParseHackFlags( ServerName, ServerMotd );
} break;
case PacketId.Ping:
@ -274,10 +274,10 @@ namespace ClassicalSharp {
case PacketId.LevelInitialise:
{
Window.Map.Reset();
Window.RaiseOnNewMap();
Window.SelectionManager.Dispose();
Window.SetNewScreen( new LoadingMapScreen( Window, ServerName, ServerMotd ) );
game.Map.Reset();
game.RaiseOnNewMap();
game.SelectionManager.Dispose();
game.SetNewScreen( new LoadingMapScreen( game, ServerName, ServerMotd ) );
if( ServerMotd.Contains( "cfg=" ) ) {
ReadWomConfigurationAsync();
}
@ -322,20 +322,20 @@ namespace ClassicalSharp {
}
reader.Remove( 1024 );
byte progress = reader.ReadUInt8();
Window.RaiseMapLoading( progress );
game.RaiseMapLoading( progress );
} break;
case PacketId.LevelFinalise:
{
Window.SetNewScreen( new NormalScreen( Window ) );
game.SetNewScreen( new NormalScreen( game ) );
int mapWidth = reader.ReadInt16();
int mapHeight = reader.ReadInt16();
int mapLength = reader.ReadInt16();
double loadingMs = ( DateTime.UtcNow - receiveStart ).TotalMilliseconds;
Utils.LogDebug( "map loading took:" + loadingMs );
Window.Map.UseRawMap( map, mapWidth, mapHeight, mapLength );
Window.RaiseOnNewMapLoaded();
game.Map.UseRawMap( map, mapWidth, mapHeight, mapLength );
game.RaiseOnNewMapLoaded();
map = null;
gzipStream.Close();
if( sendWomId && !sentWomId ) {
@ -352,7 +352,7 @@ namespace ClassicalSharp {
int y = reader.ReadInt16();
int z = reader.ReadInt16();
byte type = reader.ReadUInt8();
Window.UpdateBlock( x, y, z, type );
game.UpdateBlock( x, y, z, type );
} break;
case PacketId.AddEntity:
@ -383,11 +383,11 @@ namespace ClassicalSharp {
case PacketId.RemoveEntity:
{
byte entityId = reader.ReadUInt8();
Player player = Window.Players[entityId];
Player player = game.Players[entityId];
if( entityId != 0xFF && player != null ) {
Window.RaiseEntityRemoved( entityId );
game.RaiseEntityRemoved( entityId );
player.Despawn();
Window.Players[entityId] = null;
game.Players[entityId] = null;
}
} break;
@ -395,13 +395,13 @@ namespace ClassicalSharp {
{
byte messageType = reader.ReadUInt8();
string text = reader.ReadChatString( ref messageType, useMessageTypes );
Window.AddChat( text, (CpeMessage)messageType );
game.AddChat( text, (CpeMessage)messageType );
} break;
case PacketId.Kick:
{
string reason = reader.ReadAsciiString();
Window.Disconnect( "&eLost connection to the server", reason );
game.Disconnect( "&eLost connection to the server", reason );
Dispose();
} break;
@ -409,9 +409,9 @@ namespace ClassicalSharp {
{
byte userType = reader.ReadUInt8();
if( !useBlockPermissions ) {
Window.CanDelete[(int)Block.Bedrock] = userType == 0x64;
game.CanDelete[(int)Block.Bedrock] = userType == 0x64;
}
Window.LocalPlayer.UserType = userType;
game.LocalPlayer.UserType = userType;
} break;
case PacketId.CpeExtInfo:
@ -451,7 +451,7 @@ namespace ClassicalSharp {
case PacketId.CpeSetClickDistance:
{
Window.LocalPlayer.ReachDistance = reader.ReadInt16() / 32f;
game.LocalPlayer.ReachDistance = reader.ReadInt16() / 32f;
} break;
case PacketId.CpeCustomBlockSupportLevel:
@ -462,10 +462,10 @@ namespace ClassicalSharp {
if( supportLevel == 1 ) {
for( int i = (int)Block.CobblestoneSlab; i <= (int)Block.StoneBrick; i++ ) {
Window.CanPlace[i] = true;
Window.CanDelete[i] = true;
game.CanPlace[i] = true;
game.CanDelete[i] = true;
}
Window.RaiseBlockPermissionsChanged();
game.RaiseBlockPermissionsChanged();
} else {
Utils.LogWarning( "Server's block support level is {0}, this client only supports level 1.", supportLevel );
Utils.LogWarning( "You won't be able to see or use blocks from levels above level 1" );
@ -476,9 +476,9 @@ namespace ClassicalSharp {
{
byte blockType = reader.ReadUInt8();
bool canChange = reader.ReadUInt8() == 0;
Window.CanChangeHeldBlock = true;
Window.HeldBlock = (Block)blockType;
Window.CanChangeHeldBlock = canChange;
game.CanChangeHeldBlock = true;
game.HeldBlock = (Block)blockType;
game.CanChangeHeldBlock = canChange;
} break;
case PacketId.CpeExtAddPlayerName:
@ -489,14 +489,14 @@ namespace ClassicalSharp {
string groupName = reader.ReadAsciiString();
byte groupRank = reader.ReadUInt8();
if( nameId >= 0 && nameId <= 255 ) {
CpeListInfo oldInfo = Window.CpePlayersList[nameId];
CpeListInfo oldInfo = game.CpePlayersList[nameId];
CpeListInfo info = new CpeListInfo( (byte)nameId, playerName, listName, groupName, groupRank );
Window.CpePlayersList[nameId] = info;
game.CpePlayersList[nameId] = info;
if( oldInfo != null ) {
Window.RaiseCpeListInfoChanged( (byte)nameId );
game.RaiseCpeListInfoChanged( (byte)nameId );
} else {
Window.RaiseCpeListInfoAdded( (byte)nameId );
game.RaiseCpeListInfoAdded( (byte)nameId );
}
}
} break;
@ -513,7 +513,7 @@ namespace ClassicalSharp {
{
short nameId = reader.ReadInt16();
if( nameId >= 0 && nameId <= 255 ) {
Window.RaiseCpeListInfoRemoved( (byte)nameId );
game.RaiseCpeListInfoRemoved( (byte)nameId );
}
} break;
@ -536,13 +536,13 @@ namespace ClassicalSharp {
Vector3I p1 = Vector3I.Min( startX, startY, startZ, endX, endY, endZ );
Vector3I p2 = Vector3I.Max( startX, startY, startZ, endX, endY, endZ );
FastColour col = new FastColour( r, g, b, a );
Window.SelectionManager.AddSelection( selectionId, p1, p2, col );
game.SelectionManager.AddSelection( selectionId, p1, p2, col );
} break;
case PacketId.CpeRemoveSelection:
{
byte selectionId = reader.ReadUInt8();
Window.SelectionManager.RemoveSelection( selectionId );
game.SelectionManager.RemoveSelection( selectionId );
} break;
case PacketId.CpeEnvColours:
@ -555,15 +555,15 @@ namespace ClassicalSharp {
FastColour col = new FastColour( red, green, blue );
if( variable == 0 ) { // sky colour
Window.Map.SetSkyColour( invalid ? Map.DefaultSkyColour : col );
game.Map.SetSkyColour( invalid ? Map.DefaultSkyColour : col );
} else if( variable == 1 ) { // clouds colour
Window.Map.SetCloudsColour( invalid ? Map.DefaultCloudsColour : col );
game.Map.SetCloudsColour( invalid ? Map.DefaultCloudsColour : col );
} else if( variable == 2 ) { // fog colour
Window.Map.SetFogColour( invalid ? Map.DefaultFogColour : col );
game.Map.SetFogColour( invalid ? Map.DefaultFogColour : col );
} else if( variable == 3 ) { // ambient light (shadow light)
Window.Map.SetShadowlight( invalid ? Map.DefaultShadowlight : col );
game.Map.SetShadowlight( invalid ? Map.DefaultShadowlight : col );
} else if( variable == 4 ) { // diffuse light (sun light)
Window.Map.SetSunlight( invalid ? Map.DefaultSunlight : col );
game.Map.SetSunlight( invalid ? Map.DefaultSunlight : col );
}
} break;
@ -573,22 +573,22 @@ namespace ClassicalSharp {
bool canPlace = reader.ReadUInt8() != 0;
bool canDelete = reader.ReadUInt8() != 0;
if( blockId == 0 ) {
for( int i = 1; i < Window.CanPlace.Length; i++ ) {
Window.CanPlace[i] = canPlace;
Window.CanDelete[i] = canDelete;
for( int i = 1; i < game.CanPlace.Length; i++ ) {
game.CanPlace[i] = canPlace;
game.CanDelete[i] = canDelete;
}
} else {
Window.CanPlace[blockId] = canPlace;
Window.CanDelete[blockId] = canDelete;
game.CanPlace[blockId] = canPlace;
game.CanDelete[blockId] = canDelete;
}
Window.RaiseBlockPermissionsChanged();
game.RaiseBlockPermissionsChanged();
} break;
case PacketId.CpeChangeModel:
{
byte playerId = reader.ReadUInt8();
string modelName = reader.ReadAsciiString().ToLowerInvariant();
Player player = Window.Players[playerId];
Player player = game.Players[playerId];
if( player != null ) {
player.SetModel( modelName );
}
@ -600,36 +600,36 @@ namespace ClassicalSharp {
byte sideBlock = reader.ReadUInt8();
byte edgeBlock = reader.ReadUInt8();
short waterLevel = reader.ReadInt16();
Window.Map.SetWaterLevel( waterLevel );
Window.Map.SetEdgeBlock( (Block)edgeBlock );
Window.Map.SetSidesBlock( (Block)sideBlock );
game.Map.SetWaterLevel( waterLevel );
game.Map.SetEdgeBlock( (Block)edgeBlock );
game.Map.SetSidesBlock( (Block)sideBlock );
if( url == String.Empty ) {
Bitmap bmp = new Bitmap( "terrain.png" );
Window.ChangeTerrainAtlas( bmp );
game.ChangeTerrainAtlas( bmp );
} else {
Window.AsyncDownloader.DownloadImage( url, true, "terrain" );
game.AsyncDownloader.DownloadImage( url, true, "terrain" );
}
Utils.LogDebug( "Image url: " + url );
} break;
case PacketId.CpeEnvWeatherType:
{
Window.Map.SetWeather( (Weather)reader.ReadUInt8() );
game.Map.SetWeather( (Weather)reader.ReadUInt8() );
} break;
case PacketId.CpeHackControl:
{
Window.LocalPlayer.CanFly = reader.ReadUInt8() != 0;
Window.LocalPlayer.CanNoclip = reader.ReadUInt8() != 0;
Window.LocalPlayer.CanSpeed = reader.ReadUInt8() != 0;
Window.LocalPlayer.CanRespawn = reader.ReadUInt8() != 0;
Window.CanUseThirdPersonCamera = reader.ReadUInt8() != 0;
if( !Window.CanUseThirdPersonCamera ) {
Window.SetCamera( false );
game.LocalPlayer.CanFly = reader.ReadUInt8() != 0;
game.LocalPlayer.CanNoclip = reader.ReadUInt8() != 0;
game.LocalPlayer.CanSpeed = reader.ReadUInt8() != 0;
game.LocalPlayer.CanRespawn = reader.ReadUInt8() != 0;
game.CanUseThirdPersonCamera = reader.ReadUInt8() != 0;
if( !game.CanUseThirdPersonCamera ) {
game.SetCamera( false );
}
float jumpHeight = reader.ReadInt16() / 32f;
if( jumpHeight < 0 ) jumpHeight = 1.4f;
Window.LocalPlayer.CalculateJumpVelocity( jumpHeight );
game.LocalPlayer.CalculateJumpVelocity( jumpHeight );
} break;
case PacketId.CpeExtAddEntity2:
@ -647,19 +647,19 @@ namespace ClassicalSharp {
void AddEntity( byte entityId, string displayName, string skinName, bool readPosition ) {
if( entityId != 0xFF ) {
Player oldPlayer = Window.Players[entityId];
Player oldPlayer = game.Players[entityId];
if( oldPlayer != null ) {
Window.RaiseEntityRemoved( entityId );
game.RaiseEntityRemoved( entityId );
oldPlayer.Despawn();
}
Window.Players[entityId] = new NetPlayer( displayName, skinName, Window );
Window.RaiseEntityAdded( entityId );
Window.AsyncDownloader.DownloadSkin( skinName );
game.Players[entityId] = new NetPlayer( displayName, skinName, game );
game.RaiseEntityAdded( entityId );
game.AsyncDownloader.DownloadSkin( skinName );
}
if( readPosition ) {
ReadAbsoluteLocation( entityId, false );
if( entityId == 0xFF ) {
Window.LocalPlayer.SpawnPoint = Window.LocalPlayer.Position;
game.LocalPlayer.SpawnPoint = game.LocalPlayer.Position;
}
}
}
@ -706,7 +706,7 @@ namespace ClassicalSharp {
}
void UpdateLocation( byte playerId, LocationUpdate update, bool interpolate ) {
Player player = Window.Players[playerId];
Player player = game.Players[playerId];
if( player != null ) {
player.SetLocation( update, interpolate );
}

View File

@ -0,0 +1,88 @@
using System;
using System.Net;
using OpenTK;
using OpenTK.Input;
namespace ClassicalSharp {
public sealed class SinglePlayerServer : INetworkProcessor {
Game game;
public SinglePlayerServer( Game window ) {
game = window;
}
public override bool IsSinglePlayer {
get { return true; }
}
public override void Connect( IPAddress address, int port ) {
for( int i = (int)Block.Stone; i <= (int)Block.StoneBrick; i++ ) {
game.CanPlace[i] = true;
game.CanDelete[i] = true;
}
game.RaiseBlockPermissionsChanged();
NewMap();
MapLoaded();
}
public override void SendChat( string text ) {
if( !String.IsNullOrEmpty( text ) ) {
game.AddChat( text, CpeMessage.Normal );
}
}
public override void SendPosition( Vector3 pos, float yaw, float pitch ) {
}
public override void SendSetBlock( int x, int y, int z, bool place, byte block ) {
}
public override void SendPlayerClick( MouseButton button, bool buttonDown, byte targetId, PickedPos pos ) {
}
public override void Dispose() {
}
public override void Tick( double delta ) {
if( Disconnected ) return;
}
void NewMap() {
ServerName = "Single player";
ServerMotd = "Generating a map..";
game.LocalPlayer.UserType = 0x64;
game.Map.Reset();
game.RaiseOnNewMap();
game.SetNewScreen( new LoadingMapScreen( game, ServerName, ServerMotd ) );
}
void MapLoaded() {
game.SetNewScreen( new NormalScreen( game ) );
int width = 16, height = 16, length = 16;
byte[] map = new byte[width * height * length];
MapSet( width, length, map, 0, height / 2 - 2, (byte)Block.Dirt );
MapSet( width, length, map, height / 2 - 1, height / 2 - 1, (byte)Block.Grass );
game.Map.UseRawMap( map, width, height, length );
game.RaiseOnNewMapLoaded();
ResetPlayerPosition();
game.AddChat( "&ePlaying single player", CpeMessage.Status1 );
GC.Collect();
}
void MapSet( int width, int length, byte[] map, int yStart, int yEnd, byte block ) {
int startIndex = yStart * length * width;
int endIndex = ( yEnd * length + (length - 1) ) * width + (width - 1);
for( int i = startIndex; i <= endIndex; i++ ) {
map[i] = block;
}
}
void ResetPlayerPosition() {
float x = game.Map.Width / 2, y = game.Map.Height / 2, z = game.Map.Length / 2;
LocationUpdate update = LocationUpdate.MakePosAndOri( x, y, z, 0, 0, false );
game.LocalPlayer.SetLocation( update, false );
}
}
}

View File

@ -12,14 +12,14 @@ namespace ClassicalSharp {
void CheckForWomEnvironment() {
DownloadedItem item;
Window.AsyncDownloader.TryGetItem( womEnvIdentifier, out item );
game.AsyncDownloader.TryGetItem( womEnvIdentifier, out item );
if( item != null && item.Page != null ) {
ParseWomConfig( item.Page );
}
Window.AsyncDownloader.TryGetItem( womTerrainIdentifier, out item );
game.AsyncDownloader.TryGetItem( womTerrainIdentifier, out item );
if( item != null && item.Bmp != null ) {
Window.ChangeTerrainAtlas( item.Bmp );
game.ChangeTerrainAtlas( item.Bmp );
}
}
@ -35,17 +35,17 @@ namespace ClassicalSharp {
if( key == "environment.cloud" ) {
FastColour col = ParseWomColour( value, Map.DefaultCloudsColour );
Window.Map.SetCloudsColour( col );
game.Map.SetCloudsColour( col );
} else if( key == "environment.sky" ) {
FastColour col = ParseWomColour( value, Map.DefaultSkyColour );
Window.Map.SetSkyColour( col );
game.Map.SetSkyColour( col );
} else if( key == "environment.fog" ) {
FastColour col = ParseWomColour( value, Map.DefaultFogColour );
Window.Map.SetFogColour( col );
game.Map.SetFogColour( col );
} else if( key == "environment.level" ) {
int waterLevel = 0;
if( Int32.TryParse( value, out waterLevel ) )
Window.Map.SetWaterLevel( waterLevel );
game.Map.SetWaterLevel( waterLevel );
} else if( key == "environment.terrain" ) {
GetWomImageAsync( "terrain", value );
} else if( key == "environment.edge" ) { // TODO: custom edges and sides
@ -53,7 +53,7 @@ namespace ClassicalSharp {
} else if( key == "environment.side" ) {
//GetWomImageAsync( "side", value );
} else if( key == "user.detail" && !useMessageTypes ) {
Window.AddChat( value, CpeMessage.Status2 );
game.AddChat( value, CpeMessage.Status2 );
}
}
}
@ -63,20 +63,20 @@ namespace ClassicalSharp {
const string hostFormat = "http://files.worldofminecraft.com/skin.php?type={0}&id={1}";
string url = String.Format( hostFormat, type, Uri.EscapeDataString( id ) );
string identifier = "wom" + type + "_" + womCounter;
Window.AsyncDownloader.DownloadImage( url, true, identifier );
game.AsyncDownloader.DownloadImage( url, true, identifier );
}
void ReadWomConfigurationAsync() {
string host = ServerMotd.Substring( ServerMotd.IndexOf( "cfg=" ) + 4 );
string url = "http://" + host;
url = url.Replace( "$U", Window.Username );
url = url.Replace( "$U", game.Username );
// NOTE: this (should, I did test this) ensure that if the user quickly changes to a
// different world, the environment settings from the last world are not loaded in the
// new world if the async 'get request' didn't complete before the new world was loaded.
womCounter++;
womEnvIdentifier = "womenv_" + womCounter;
womTerrainIdentifier = "womterrain_" + womCounter;
Window.AsyncDownloader.DownloadPage( url, true, womEnvIdentifier );
game.AsyncDownloader.DownloadPage( url, true, womEnvIdentifier );
sendWomId = true;
}