mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-10-05 03:55:57 -04:00
175 lines
6.1 KiB
C#
175 lines
6.1 KiB
C#
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
|
using System;
|
|
using ClassicalSharp.Model;
|
|
using OpenTK;
|
|
|
|
namespace ClassicalSharp.Network {
|
|
|
|
public partial class NetworkProcessor : INetworkProcessor {
|
|
|
|
internal void HandleDefineBlock() {
|
|
if( !game.AllowCustomBlocks ) {
|
|
SkipPacketData( Opcode.CpeDefineBlock ); return;
|
|
}
|
|
byte id = HandleDefineBlockCommonStart( false );
|
|
BlockInfo info = game.BlockInfo;
|
|
byte shape = reader.ReadUInt8();
|
|
if( shape == 0 ) {
|
|
info.IsSprite[id] = true;
|
|
info.IsOpaque[id] = false;
|
|
info.IsTransparent[id] = true;
|
|
} else if( shape <= 16 ) {
|
|
info.MaxBB[id].Y = shape / 16f;
|
|
}
|
|
|
|
HandleDefineBlockCommonEnd( id );
|
|
// Update sprite BoundingBox if necessary
|
|
if( info.IsSprite[id] ) {
|
|
using( FastBitmap dst = new FastBitmap( game.TerrainAtlas.AtlasBitmap, true, true ) )
|
|
info.RecalculateBB( id, dst );
|
|
}
|
|
info.DefinedCustomBlocks[id >> 5] |= (1u << (id & 0x1F));
|
|
}
|
|
|
|
internal void HandleRemoveBlockDefinition() {
|
|
if( !game.AllowCustomBlocks ) {
|
|
SkipPacketData( Opcode.CpeRemoveBlockDefinition ); return;
|
|
}
|
|
game.BlockInfo.ResetBlockInfo( reader.ReadUInt8(), true );
|
|
game.BlockInfo.InitLightOffsets();
|
|
game.Events.RaiseBlockDefinitionChanged();
|
|
}
|
|
|
|
internal void HandleDefineBlockExt() {
|
|
if( !game.AllowCustomBlocks ) {
|
|
SkipPacketData( Opcode.CpeDefineBlockExt ); return;
|
|
}
|
|
byte id = HandleDefineBlockCommonStart( cpe.blockDefsExtVer >= 2 );
|
|
BlockInfo info = game.BlockInfo;
|
|
Vector3 min, max;
|
|
|
|
min.X = reader.ReadUInt8() / 16f; Utils.Clamp( ref min.X, 0, 15/16f );
|
|
min.Y = reader.ReadUInt8() / 16f; Utils.Clamp( ref min.Y, 0, 15/16f );
|
|
min.Z = reader.ReadUInt8() / 16f; Utils.Clamp( ref min.Z, 0, 15/16f );
|
|
max.X = reader.ReadUInt8() / 16f; Utils.Clamp( ref max.X, 1/16f, 1 );
|
|
max.Y = reader.ReadUInt8() / 16f; Utils.Clamp( ref max.Y, 1/16f, 1 );
|
|
max.Z = reader.ReadUInt8() / 16f; Utils.Clamp( ref max.Z, 1/16f, 1 );
|
|
|
|
info.MinBB[id] = min;
|
|
info.MaxBB[id] = max;
|
|
HandleDefineBlockCommonEnd( id );
|
|
info.DefinedCustomBlocks[id >> 5] |= (1u << (id & 0x1F));
|
|
}
|
|
|
|
byte HandleDefineBlockCommonStart( bool uniqueSideTexs ) {
|
|
byte block = reader.ReadUInt8();
|
|
BlockInfo info = game.BlockInfo;
|
|
info.ResetBlockInfo( block, false );
|
|
|
|
info.Name[block] = reader.ReadCp437String();
|
|
info.Collide[block] = (CollideType)reader.ReadUInt8();
|
|
if( info.Collide[block] != CollideType.Solid ) {
|
|
info.IsTransparent[block] = true;
|
|
info.IsOpaque[block] = false;
|
|
}
|
|
|
|
info.SpeedMultiplier[block] = (float)Math.Pow( 2, (reader.ReadUInt8() - 128) / 64f );
|
|
info.SetTex( reader.ReadUInt8(), Side.Top, (Block)block );
|
|
if( uniqueSideTexs ) {
|
|
info.SetTex( reader.ReadUInt8(), Side.Left, (Block)block );
|
|
info.SetTex( reader.ReadUInt8(), Side.Right, (Block)block );
|
|
info.SetTex( reader.ReadUInt8(), Side.Front, (Block)block );
|
|
info.SetTex( reader.ReadUInt8(), Side.Back, (Block)block );
|
|
} else {
|
|
info.SetSide( reader.ReadUInt8(), (Block)block );
|
|
}
|
|
info.SetTex( reader.ReadUInt8(), Side.Bottom, (Block)block );
|
|
|
|
info.BlocksLight[block] = reader.ReadUInt8() == 0;
|
|
byte sound = reader.ReadUInt8();
|
|
if( sound < breakSnds.Length ) {
|
|
info.StepSounds[block] = stepSnds[sound];
|
|
info.DigSounds[block] = breakSnds[sound];
|
|
}
|
|
info.FullBright[block] = reader.ReadUInt8() != 0;
|
|
return block;
|
|
}
|
|
|
|
internal void HandleDefineBlockCommonEnd( byte block ) {
|
|
BlockInfo info = game.BlockInfo;
|
|
byte blockDraw = reader.ReadUInt8();
|
|
SetBlockDraw( info, block, blockDraw );
|
|
|
|
byte fogDensity = reader.ReadUInt8();
|
|
info.FogDensity[block] = fogDensity == 0 ? 0 : (fogDensity + 1) / 128f;
|
|
info.FogColour[block] = new FastColour(
|
|
reader.ReadUInt8(), reader.ReadUInt8(), reader.ReadUInt8() );
|
|
info.SetupCullingCache( block );
|
|
info.InitLightOffsets();
|
|
game.Events.RaiseBlockDefinitionChanged();
|
|
}
|
|
|
|
#if FALSE
|
|
internal void HandleDefineModel() {
|
|
int start = reader.index - 1;
|
|
byte id = reader.ReadUInt8();
|
|
CustomModel model = null;
|
|
|
|
switch( reader.ReadUInt8() ) {
|
|
case 0:
|
|
model = new CustomModel( game );
|
|
model.ReadSetupPacket( reader );
|
|
game.ModelCache.CustomModels[id] = model;
|
|
break;
|
|
case 1:
|
|
model = game.ModelCache.CustomModels[id];
|
|
if( model != null ) model.ReadMetadataPacket( reader );
|
|
break;
|
|
case 2:
|
|
model = game.ModelCache.CustomModels[id];
|
|
if( model != null ) model.ReadDefinePartPacket( reader );
|
|
break;
|
|
case 3:
|
|
model = game.ModelCache.CustomModels[id];
|
|
if( model != null ) model.ReadRotationPacket( reader );
|
|
break;
|
|
}
|
|
int total = packetSizes[(byte)Opcode.CpeDefineModel];
|
|
reader.Skip( total - (reader.index - start) );
|
|
}
|
|
#endif
|
|
|
|
internal static SoundType[] stepSnds, breakSnds;
|
|
static NetworkProcessor() {
|
|
stepSnds = new SoundType[10];
|
|
breakSnds = new SoundType[10];
|
|
stepSnds[0] = SoundType.None; breakSnds[0] = SoundType.None;
|
|
stepSnds[1] = SoundType.Wood; breakSnds[1] = SoundType.Wood;
|
|
stepSnds[2] = SoundType.Gravel; breakSnds[2] = SoundType.Gravel;
|
|
stepSnds[3] = SoundType.Grass; breakSnds[3] = SoundType.Grass;
|
|
stepSnds[4] = SoundType.Stone; breakSnds[4] = SoundType.Stone;
|
|
// TODO: metal sound type, just use stone for now.
|
|
stepSnds[5] = SoundType.Stone; breakSnds[5] = SoundType.Stone;
|
|
stepSnds[6] = SoundType.Stone; breakSnds[6] = SoundType.Glass;
|
|
stepSnds[7] = SoundType.Cloth; breakSnds[7] = SoundType.Cloth;
|
|
stepSnds[8] = SoundType.Sand; breakSnds[8] = SoundType.Sand;
|
|
stepSnds[9] = SoundType.Snow; breakSnds[9] = SoundType.Snow;
|
|
}
|
|
|
|
internal static void SetBlockDraw( BlockInfo info, byte block, byte blockDraw ) {
|
|
if( blockDraw == 1 ) {
|
|
info.IsTransparent[block] = true;
|
|
} else if( blockDraw == 2 ) {
|
|
info.IsTransparent[block] = true;
|
|
info.CullWithNeighbours[block] = false;
|
|
} else if( blockDraw == 3 ) {
|
|
info.IsTranslucent[block] = true;
|
|
} else if( blockDraw == 4 ) {
|
|
info.IsTransparent[block] = true;
|
|
info.IsAir[block] = true;
|
|
}
|
|
if( info.IsOpaque[block] )
|
|
info.IsOpaque[block] = blockDraw == 0;
|
|
}
|
|
}
|
|
} |