C client: Inf id

This commit is contained in:
UnknownShadow200 2018-09-28 01:26:34 +10:00
parent 834c387a04
commit 51417b950d
13 changed files with 374 additions and 281 deletions

View File

@ -49,13 +49,8 @@ namespace ClassicalSharp.Entities {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
// Unpack the block and coordinate data // Unpack the block and coordinate data
State state = Searcher.stateCache[i]; State state = Searcher.stateCache[i];
#if !ONLY_8BIT
bPos.X = state.X >> 3; bPos.Y = state.Y >> 4; bPos.Z = state.Z >> 3; bPos.X = state.X >> 3; bPos.Y = state.Y >> 4; bPos.Z = state.Z >> 3;
int block = (state.X & 0x7) | (state.Y & 0xF) << 3 | (state.Z & 0x7) << 7; int block = (state.X & 0x7) | (state.Y & 0xF) << 3 | (state.Z & 0x7) << 7;
#else
bPos.X = state.X >> 3; bPos.Y = state.Y >> 3; bPos.Z = state.Z >> 3;
int block = (state.X & 0x7) | (state.Y & 0x7) << 3 | (state.Z & 0x7) << 6;
#endif
blockBB.Min = BlockInfo.MinBB[block]; blockBB.Min = BlockInfo.MinBB[block];
blockBB.Min.X += bPos.X; blockBB.Min.Y += bPos.Y; blockBB.Min.Z += bPos.Z; blockBB.Min.X += bPos.X; blockBB.Min.Y += bPos.Y; blockBB.Min.Z += bPos.Z;

View File

@ -59,15 +59,9 @@ namespace ClassicalSharp.Physics {
CalcTime(ref vel, ref entityBB, ref blockBB, out tx, out ty, out tz); CalcTime(ref vel, ref entityBB, ref blockBB, out tx, out ty, out tz);
if (tx > 1 || ty > 1 || tz > 1) continue; if (tx > 1 || ty > 1 || tz > 1) continue;
#if !ONLY_8BIT
state.X = (x << 3) | (block & 0x007); state.X = (x << 3) | (block & 0x007);
state.Y = (y << 4) | ((block & 0x078) >> 3); state.Y = (y << 4) | ((block & 0x078) >> 3);
state.Z = (z << 3) | ((block & 0x380) >> 7); state.Z = (z << 3) | ((block & 0x380) >> 7);
#else
state.X = (x << 3) | (block & 0x007);
state.Y = (y << 3) | ((block & 0x038) >> 3);
state.Z = (z << 3) | ((block & 0x1C0) >> 6);
#endif
state.tSquared = tx * tx + ty * ty + tz * tz; state.tSquared = tx * tx + ty * ty + tz * tz;
stateCache[count++] = state; stateCache[count++] = state;

View File

@ -1,9 +1,9 @@
#ifndef CC_BLOCK_H #ifndef CC_BLOCK_H
#define CC_BLOCK_H #define CC_BLOCK_H
#include "BlockID.h"
#include "PackedCol.h" #include "PackedCol.h"
#include "Vectors.h" #include "Vectors.h"
#include "Constants.h" #include "Constants.h"
#include "BlockID.h"
/* Stores properties and data for blocks. /* Stores properties and data for blocks.
Also performs automatic rotation of directional blocks. Also performs automatic rotation of directional blocks.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3

View File

@ -1,5 +1,6 @@
#ifndef CC_BLOCKID_H #ifndef CC_BLOCKID_H
#define CC_BLOCKID_H #define CC_BLOCKID_H
#include "Core.h" /* TODO: Remove this include when we move to external defines */
/* List of all core/standard block IDs /* List of all core/standard block IDs
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/ */
@ -84,8 +85,8 @@ enum BLOCKID {
/* Number of blocks in original classic plus CPE blocks. */ /* Number of blocks in original classic plus CPE blocks. */
BLOCK_CPE_COUNT = (BLOCK_MAX_CPE + 1), BLOCK_CPE_COUNT = (BLOCK_MAX_CPE + 1),
#if USE16_BIT #ifdef EXTENDED_BLOCKS
BLOCK_MAX_DEFINED = 0x3FF, BLOCK_MAX_DEFINED = 0x2FF,
#else #else
BLOCK_MAX_DEFINED = 0xFF, BLOCK_MAX_DEFINED = 0xFF,
#endif #endif

View File

@ -1,7 +1,6 @@
#ifndef CC_BLOCKPHYSICS_H #ifndef CC_BLOCKPHYSICS_H
#define CC_BLOCKPHYSICS_H #define CC_BLOCKPHYSICS_H
#include "Core.h" #include "Core.h"
#include "BlockID.h"
/* Implements simple block physics. /* Implements simple block physics.
Copyright 2014 - 2017 ClassicalSharp | Licensed under BSD-3 Copyright 2014 - 2017 ClassicalSharp | Licensed under BSD-3
*/ */

View File

@ -231,39 +231,50 @@ static void Builder_Stretch(Int32 x1, Int32 y1, Int32 z1) {
} }
} }
#define Builder_ReadChunkBody(get_block)\
for (yy = -1; yy < 17; ++yy) {\
Int32 y = yy + y1;\
if (y < 0) continue;\
if (y >= World_Height) break;\
\
for (zz = -1; zz < 17; ++zz) {\
Int32 z = zz + z1;\
if (z < 0) continue;\
if (z >= World_Length) break;\
\
/* need to subtract 1 as index is pre incremented in for loop. */ \
Int32 index = World_Pack(x1 - 1, y, z) - 1;\
Int32 chunkIndex = (yy + 1) * EXTCHUNK_SIZE_2 + (zz + 1) * EXTCHUNK_SIZE + (-1 + 1) - 1;\
\
for (xx = -1; xx < 17; ++xx) {\
Int32 x = xx + x1;\
++index;\
++chunkIndex;\
\
if (x < 0) continue;\
if (x >= World_Width) break;\
BlockID block = get_block;\
\
allAir = allAir && Block_Draw[block] == DRAW_GAS;\
allSolid = allSolid && Block_FullOpaque[block];\
Builder_Chunk[chunkIndex] = block;\
}\
}\
}
static void Builder_ReadChunkData(Int32 x1, Int32 y1, Int32 z1, bool* outAllAir, bool* outAllSolid) { static void Builder_ReadChunkData(Int32 x1, Int32 y1, Int32 z1, bool* outAllAir, bool* outAllSolid) {
bool allAir = true, allSolid = true; bool allAir = true, allSolid = true;
Int32 xx, yy, zz; Int32 xx, yy, zz;
for (yy = -1; yy < 17; ++yy) { #ifndef EXTENDED_BLOCKS
Int32 y = yy + y1; Builder_ReadChunkBody(World_Blocks[index]);
if (y < 0) continue; #else
if (y >= World_Height) break; if (Block_UsedCount <= 256) {
Builder_ReadChunkBody(World_Blocks[index]);
for (zz = -1; zz < 17; ++zz) { } else {
Int32 z = zz + z1; Builder_ReadChunkBody(World_Blocks[index] | (World_Blocks2[index] << 8));
if (z < 0) continue;
if (z >= World_Length) break;
/* need to subtract 1 as index is pre incremented in for loop. */
Int32 index = World_Pack(x1 - 1, y, z) - 1;
Int32 chunkIndex = (yy + 1) * EXTCHUNK_SIZE_2 + (zz + 1) * EXTCHUNK_SIZE + (-1 + 1) - 1;
for (xx = -1; xx < 17; ++xx) {
Int32 x = xx + x1;
++index;
++chunkIndex;
if (x < 0) continue;
if (x >= World_Width) break;
BlockID rawBlock = World_Blocks[index];
allAir = allAir && Block_Draw[rawBlock] == DRAW_GAS;
allSolid = allSolid && Block_FullOpaque[rawBlock];
Builder_Chunk[chunkIndex] = rawBlock;
}
}
} }
#endif
*outAllAir = allAir; *outAllAir = allAir;
*outAllSolid = allSolid; *outAllSolid = allSolid;

View File

@ -42,7 +42,7 @@ typedef UInt8 bool;
#define false 0 #define false 0
#define NULL ((void*)0) #define NULL ((void*)0)
//#define EXTENDED_BLOCKS #define EXTENDED_BLOCKS
#ifdef EXTENDED_BLOCKS #ifdef EXTENDED_BLOCKS
typedef UInt16 BlockID; typedef UInt16 BlockID;
#else #else

View File

@ -804,8 +804,8 @@ static void Collisions_CollideWithReachableBlocks(struct CollisionsComp* comp, I
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
/* Unpack the block and coordinate data */ /* Unpack the block and coordinate data */
struct SearcherState state = Searcher_States[i]; struct SearcherState state = Searcher_States[i];
bPos.X = state.X >> 3; bPos.Y = state.Y >> 3; bPos.Z = state.Z >> 3; bPos.X = state.X >> 3; bPos.Y = state.Y >> 4; bPos.Z = state.Z >> 3;
Int32 block = (state.X & 0x7) | (state.Y & 0x7) << 3 | (state.Z & 0x7) << 6; Int32 block = (state.X & 0x7) | (state.Y & 0xF) << 3 | (state.Z & 0x7) << 7;
Vector3_Add(&blockBB.Min, &Block_MinBB[block], &bPos); Vector3_Add(&blockBB.Min, &Block_MinBB[block], &bPos);
Vector3_Add(&blockBB.Max, &Block_MaxBB[block], &bPos); Vector3_Add(&blockBB.Max, &Block_MaxBB[block], &bPos);

View File

@ -246,50 +246,61 @@ static Int32 Lighting_InitialHeightmapCoverage(Int32 x1, Int32 z1, Int32 xCount,
return elemsLeft; return elemsLeft;
} }
#define Lighting_CalculateBody(get_block)\
for (y = World_Height - 1; y >= 0; y--) {\
if (elemsLeft <= 0) { return true; } \
Int32 mapIndex = World_Pack(x1, y, z1);\
Int32 heightmapIndex = Lighting_Pack(x1, z1);\
\
for (z = 0; z < zCount; z++) {\
Int32 baseIndex = mapIndex;\
Int32 index = z * xCount;\
for (x = 0; x < xCount;) {\
Int32 curRunCount = skip[index];\
x += curRunCount; mapIndex += curRunCount; index += curRunCount;\
\
if (x < xCount && Block_BlocksLight[get_block]) {\
Int32 lightOffset = (Block_LightOffset[get_block] >> FACE_YMAX) & 1;\
Lighting_Heightmap[heightmapIndex + x] = (Int16)(y - lightOffset);\
elemsLeft--;\
skip[index] = 0;\
Int32 offset = prevRunCount + curRunCount;\
Int32 newRunCount = skip[index - offset] + 1;\
\
/* consider case 1 0 1 0, where we are at 0 */ \
/* we need to make this 3 0 0 0 and advance by 1 */ \
Int32 oldRunCount = (x - offset + newRunCount) < xCount ? skip[index - offset + newRunCount] : 0; \
if (oldRunCount != 0) {\
skip[index - offset + newRunCount] = 0; \
newRunCount += oldRunCount; \
} \
skip[index - offset] = newRunCount; \
x += oldRunCount; index += oldRunCount; mapIndex += oldRunCount; \
prevRunCount = newRunCount; \
} else { \
prevRunCount = 0; \
}\
x++; mapIndex++; index++; \
}\
prevRunCount = 0;\
heightmapIndex += World_Width;\
mapIndex = baseIndex + World_Width; /* advance one Z */ \
}\
}
static bool Lighting_CalculateHeightmapCoverage(Int32 x1, Int32 z1, Int32 xCount, Int32 zCount, Int32 elemsLeft, Int32* skip) { static bool Lighting_CalculateHeightmapCoverage(Int32 x1, Int32 z1, Int32 xCount, Int32 zCount, Int32 elemsLeft, Int32* skip) {
Int32 prevRunCount = 0; Int32 prevRunCount = 0;
Int32 x, y, z; Int32 x, y, z;
for (y = World_Height - 1; y >= 0; y--) { #ifndef EXTENDED_BLOCKS
if (elemsLeft <= 0) return true; Lighting_CalculateBody(World_Blocks[mapIndex]);
Int32 mapIndex = World_Pack(x1, y, z1); #else
Int32 heightmapIndex = Lighting_Pack(x1, z1); if (Block_UsedCount <= 256) {
Lighting_CalculateBody(World_Blocks[mapIndex]);
for (z = 0; z < zCount; z++) { } else {
Int32 baseIndex = mapIndex; Lighting_CalculateBody(World_Blocks[mapIndex] | (World_Blocks2[mapIndex] << 8));
Int32 index = z * xCount;
for (x = 0; x < xCount;) {
Int32 curRunCount = skip[index];
x += curRunCount; mapIndex += curRunCount; index += curRunCount;
if (x < xCount && Block_BlocksLight[World_Blocks[mapIndex]]) {
Int32 lightOffset = (Block_LightOffset[World_Blocks[mapIndex]] >> FACE_YMAX) & 1;
Lighting_Heightmap[heightmapIndex + x] = (short)(y - lightOffset);
elemsLeft--;
skip[index] = 0;
Int32 offset = prevRunCount + curRunCount;
Int32 newRunCount = skip[index - offset] + 1;
/* consider case 1 0 1 0, where we are at 0 */
/* we need to make this 3 0 0 0 and advance by 1 */
Int32 oldRunCount = (x - offset + newRunCount) < xCount ? skip[index - offset + newRunCount] : 0;
if (oldRunCount != 0) {
skip[index - offset + newRunCount] = 0;
newRunCount += oldRunCount;
}
skip[index - offset] = newRunCount;
x += oldRunCount; index += oldRunCount; mapIndex += oldRunCount;
prevRunCount = newRunCount;
} else {
prevRunCount = 0;
}
x++; mapIndex++; index++;
}
prevRunCount = 0;
heightmapIndex += World_Width;
mapIndex = baseIndex + World_Width; /* advance one Z */
}
} }
#endif
return false; return false;
} }

View File

@ -26,11 +26,31 @@
#include "TerrainAtlas.h" #include "TerrainAtlas.h"
/* Classic state */ /* Classic state */
UInt8 classic_tabList[256 >> 3]; UInt8 classic_tabList[ENTITIES_MAX_COUNT >> 3];
struct Screen* classic_prevScreen;
bool classic_receivedFirstPos;
/* Map state */
bool map_begunLoading;
TimeMS map_receiveStart;
struct InflateState map_inflateState;
struct Stream map_stream, map_part;
struct GZipHeader map_gzHeader;
Int32 map_sizeIndex, map_index, map_volume;
UInt8 map_size[4];
BlockRaw* map_blocks;
#ifdef EXTENDED_BLOCKS
struct InflateState map2_inflateState;
struct Stream map2_stream;
Int32 map2_index;
BlockRaw* map2_blocks;
#endif
/* CPE state */ /* CPE state */
Int32 cpe_serverExtensionsCount, cpe_pingTicks; Int32 cpe_serverExtensionsCount, cpe_pingTicks;
Int32 cpe_envMapVer = 2, cpe_blockDefsExtVer = 2; Int32 cpe_envMapVer = 2, cpe_blockDefsExtVer = 2;
bool cpe_sendHeldBlock, cpe_useMessageTypes, cpe_extEntityPos, cpe_blockPerms, cpe_fastMap;
bool cpe_twoWayPing, cpe_extTextures, cpe_extBlocks; bool cpe_twoWayPing, cpe_extTextures, cpe_extBlocks;
/*########################################################################################################################* /*########################################################################################################################*
@ -43,7 +63,7 @@ bool cpe_twoWayPing, cpe_extTextures, cpe_extBlocks;
#else #else
#define Handlers_ReadBlock(data, value)\ #define Handlers_ReadBlock(data, value)\
if (cpe_extBlocks) {\ if (cpe_extBlocks) {\
value = Stream_GetU16_BE(data, value); data += 2;\ value = Stream_GetU16_BE(data); data += 2;\
} else { value = *data++; } } else { value = *data++; }
#endif #endif
@ -53,7 +73,7 @@ if (cpe_extBlocks) {\
#define Handlers_WriteBlock(data, value)\ #define Handlers_WriteBlock(data, value)\
if (cpe_extBlocks) {\ if (cpe_extBlocks) {\
Stream_SetU16_BE(data, value); data += 2;\ Stream_SetU16_BE(data, value); data += 2;\
} else { *data++ = value; } } else { *data++ = (BlockRaw)value; }
#endif #endif
static void Handlers_ReadString(UInt8** ptr, String* str) { static void Handlers_ReadString(UInt8** ptr, String* str) {
@ -309,17 +329,6 @@ static void WoM_Tick(void) {
/*########################################################################################################################* /*########################################################################################################################*
*----------------------------------------------------Classic protocol-----------------------------------------------------* *----------------------------------------------------Classic protocol-----------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
TimeMS mapReceiveStart;
struct InflateState mapInflateState;
struct Stream mapInflateStream;
bool mapInflateInited;
struct GZipHeader gzHeader;
Int32 mapSizeIndex, mapIndex, mapVolume;
UInt8 mapSize[4];
BlockRaw* map;
struct Stream mapPartStream;
struct Screen* prevScreen;
bool receivedFirstPosition;
void Classic_WriteChat(const String* text, bool partial) { void Classic_WriteChat(const String* text, bool partial) {
UInt8* data = ServerConnection_WriteBuffer; UInt8* data = ServerConnection_WriteBuffer;
@ -335,7 +344,8 @@ void Classic_WritePosition(Vector3 pos, float rotY, float headX) {
UInt8* data = ServerConnection_WriteBuffer; UInt8* data = ServerConnection_WriteBuffer;
*data++ = OPCODE_ENTITY_TELEPORT; *data++ = OPCODE_ENTITY_TELEPORT;
{ {
*data++ = cpe_sendHeldBlock ? Inventory_SelectedBlock : ENTITIES_SELF_ID; /* TODO: extended blocks */ BlockID payload = cpe_sendHeldBlock ? Inventory_SelectedBlock : ENTITIES_SELF_ID;
Handlers_WriteBlock(data, payload);
Int32 x = (Int32)(pos.X * 32); Int32 x = (Int32)(pos.X * 32);
Int32 y = (Int32)(pos.Y * 32) + 51; Int32 y = (Int32)(pos.Y * 32) + 51;
Int32 z = (Int32)(pos.Z * 32); Int32 z = (Int32)(pos.Z * 32);
@ -364,7 +374,7 @@ void Classic_WriteSetBlock(Int32 x, Int32 y, Int32 z, bool place, BlockID block)
Stream_SetU16_BE(data, y); data += 2; Stream_SetU16_BE(data, y); data += 2;
Stream_SetU16_BE(data, z); data += 2; Stream_SetU16_BE(data, z); data += 2;
*data++ = place; *data++ = place;
*data++ = block; /* TODO: extended blocks */ Handlers_WriteBlock(data, block);
} }
ServerConnection_WriteBuffer = data; ServerConnection_WriteBuffer = data;
} }
@ -403,102 +413,127 @@ static void Classic_Ping(UInt8* data) { }
static void Classic_StartLoading(void) { static void Classic_StartLoading(void) {
World_Reset(); World_Reset();
Event_RaiseVoid(&WorldEvents_NewMap); Event_RaiseVoid(&WorldEvents_NewMap);
Stream_ReadonlyMemory(&mapPartStream, NULL, 0); Stream_ReadonlyMemory(&map_part, NULL, 0);
prevScreen = Gui_Active; classic_prevScreen = Gui_Active;
if (prevScreen == LoadingScreen_UNSAFE_RawPointer) { if (classic_prevScreen == LoadingScreen_UNSAFE_RawPointer) {
/* otherwise replacing LoadingScreen with LoadingScreen will cause issues */ /* otherwise replacing LoadingScreen with LoadingScreen will cause issues */
Gui_FreeActive(); Gui_FreeActive();
prevScreen = NULL; classic_prevScreen = NULL;
} }
Gui_SetActive(LoadingScreen_MakeInstance(&ServerConnection_ServerName, &ServerConnection_ServerMOTD)); Gui_SetActive(LoadingScreen_MakeInstance(&ServerConnection_ServerName, &ServerConnection_ServerMOTD));
WoM_CheckMotd(); WoM_CheckMotd();
receivedFirstPosition = false; classic_receivedFirstPos = false;
GZipHeader_Init(&gzHeader);
Inflate_MakeStream(&mapInflateStream, &mapInflateState, &mapPartStream); GZipHeader_Init(&map_gzHeader);
mapInflateInited = true; Inflate_MakeStream(&map_stream, &map_inflateState, &map_part);
map_begunLoading = true;
mapSizeIndex = 0; map_sizeIndex = 0;
mapIndex = 0; map_index = 0;
mapReceiveStart = DateTime_CurrentUTC_MS(); map_receiveStart = DateTime_CurrentUTC_MS();
#ifdef EXTENDED_BLOCKS
Inflate_MakeStream(&map2_stream, &map2_inflateState, &map_part);
map2_index = 0;
#endif
} }
static void Classic_LevelInit(UInt8* data) { static void Classic_LevelInit(UInt8* data) {
if (!mapInflateInited) Classic_StartLoading(); if (!map_begunLoading) Classic_StartLoading();
/* Fast map puts volume in header, doesn't bother with gzip */ /* Fast map puts volume in header, doesn't bother with gzip */
if (cpe_fastMap) { if (cpe_fastMap) {
mapVolume = Stream_GetU32_BE(data); map_volume = Stream_GetU32_BE(data);
gzHeader.Done = true; map_gzHeader.Done = true;
mapSizeIndex = sizeof(UInt32); map_sizeIndex = sizeof(UInt32);
map = Mem_Alloc(mapVolume, sizeof(BlockID), "map blocks"); map_blocks = Mem_Alloc(map_volume, 1, "map blocks");
} }
} }
static void Classic_LevelDataChunk(UInt8* data) { static void Classic_LevelDataChunk(UInt8* data) {
/* Workaround for some servers that send LevelDataChunk before LevelInit due to their async sending behaviour */ /* Workaround for some servers that send LevelDataChunk before LevelInit due to their async sending behaviour */
if (!mapInflateInited) Classic_StartLoading(); if (!map_begunLoading) Classic_StartLoading();
Int32 usedLength = Stream_GetU16_BE(data); data += 2; Int32 usedLength = Stream_GetU16_BE(data); data += 2;
mapPartStream.Meta.Mem.Cur = data; map_part.Meta.Mem.Cur = data;
mapPartStream.Meta.Mem.Base = data; map_part.Meta.Mem.Base = data;
mapPartStream.Meta.Mem.Left = usedLength; map_part.Meta.Mem.Left = usedLength;
mapPartStream.Meta.Mem.Length = usedLength; map_part.Meta.Mem.Length = usedLength;
data += 1024; data += 1024;
UInt8 value = *data; /* progress in original classic, but we ignore it */ UInt8 value = *data; /* progress in original classic, but we ignore it */
if (!gzHeader.Done) { if (!map_gzHeader.Done) {
ReturnCode res = GZipHeader_Read(&mapPartStream, &gzHeader); ReturnCode res = GZipHeader_Read(&map_part, &map_gzHeader);
if (res && res != ERR_END_OF_STREAM) ErrorHandler_Fail2(res, "reading map data"); if (res && res != ERR_END_OF_STREAM) ErrorHandler_Fail2(res, "reading map data");
} }
if (gzHeader.Done) { if (map_gzHeader.Done) {
if (mapSizeIndex < sizeof(UInt32)) { if (map_sizeIndex < 4) {
UInt8* src = mapSize + mapSizeIndex; UInt32 left = 4 - map_sizeIndex, read = 0;
UInt32 count = sizeof(UInt32) - mapSizeIndex, modified = 0; map_stream.Read(&map_stream, &map_size[map_sizeIndex], left, &read); map_sizeIndex += read;
mapInflateStream.Read(&mapInflateStream, src, count, &modified);
mapSizeIndex += modified;
} }
if (mapSizeIndex == sizeof(UInt32)) { if (map_sizeIndex == 4) {
if (!map) { if (!map_blocks) {
mapVolume = Stream_GetU32_BE(mapSize); map_volume = Stream_GetU32_BE(map_size);
map = Mem_Alloc(mapVolume, sizeof(BlockID), "map blocks"); map_blocks = Mem_Alloc(map_volume, 1, "map blocks");
} }
UInt8* src = map + mapIndex; #ifndef EXTENDED_BLOCKS
UInt32 count = mapVolume - mapIndex, modified = 0; UInt32 left = map_volume - map_index, read = 0;
mapInflateStream.Read(&mapInflateStream, src, count, &modified); map_stream.Read(&map_stream, &map_blocks[map_index], left, &read);
mapIndex += modified; map_index += read;
#else
if (cpe_extBlocks && value) {
/* Only allocate map2 when needed */
if (!map2_blocks) map2_blocks = Mem_Alloc(map_volume, 1, "map blocks upper");
UInt32 left = map_volume - map2_index, read = 0;
map2_stream.Read(&map2_stream, &map2_blocks[map2_index], left, &read); map2_index += read;
} else {
UInt32 left = map_volume - map_index, read = 0;
map_stream.Read(&map_stream, &map_blocks[map_index], left, &read); map_index += read;
}
#endif
} }
} }
float progress = !map ? 0.0f : (float)mapIndex / mapVolume; float progress = !map_blocks ? 0.0f : (float)map_index / map_volume;
Event_RaiseFloat(&WorldEvents_Loading, progress); Event_RaiseFloat(&WorldEvents_Loading, progress);
} }
static void Classic_LevelFinalise(UInt8* data) { static void Classic_LevelFinalise(UInt8* data) {
Gui_CloseActive(); Gui_CloseActive();
Gui_Active = prevScreen; Gui_Active = classic_prevScreen;
prevScreen = NULL; classic_prevScreen = NULL;
Gui_CalcCursorVisible(); Gui_CalcCursorVisible();
Int32 mapWidth = Stream_GetU16_BE(&data[0]); Int32 width = Stream_GetU16_BE(&data[0]);
Int32 mapHeight = Stream_GetU16_BE(&data[2]); Int32 height = Stream_GetU16_BE(&data[2]);
Int32 mapLength = Stream_GetU16_BE(&data[4]); Int32 length = Stream_GetU16_BE(&data[4]);
Int32 loadingMs = (Int32)(DateTime_CurrentUTC_MS() - mapReceiveStart); Int32 loadingMs = (Int32)(DateTime_CurrentUTC_MS() - map_receiveStart);
Platform_Log1("map loading took: %i", &loadingMs); Platform_Log1("map loading took: %i", &loadingMs);
World_SetNewMap(map, mapVolume, mapWidth, mapHeight, mapLength); World_SetNewMap(map_blocks, map_volume, width, height, length);
#ifdef EXTENDED_BLOCKS
if (cpe_extBlocks) {
/* defer allocation of scond map array if possible */
World_Blocks2 = map2_blocks ? map2_blocks : map_blocks;
Block_SetUsedCount(map2_blocks ? 768 : 256);
}
#endif
Event_RaiseVoid(&WorldEvents_MapLoaded); Event_RaiseVoid(&WorldEvents_MapLoaded);
WoM_CheckSendWomID(); WoM_CheckSendWomID();
map = NULL; map_blocks = NULL;
mapInflateInited = false; map_begunLoading = false;
#ifdef EXTENDED_BLOCKS
map2_blocks = NULL;
#endif
} }
static void Classic_SetBlock(UInt8* data) { static void Classic_SetBlock(UInt8* data) {
@ -632,14 +667,14 @@ static void Classic_ReadAbsoluteLocation(UInt8* data, EntityID id, bool interpol
float rotY = Math_Packed2Deg(*data++); float rotY = Math_Packed2Deg(*data++);
float headX = Math_Packed2Deg(*data++); float headX = Math_Packed2Deg(*data++);
if (id == ENTITIES_SELF_ID) receivedFirstPosition = true; if (id == ENTITIES_SELF_ID) classic_receivedFirstPos = true;
struct LocationUpdate update; LocationUpdate_MakePosAndOri(&update, pos, rotY, headX, false); struct LocationUpdate update; LocationUpdate_MakePosAndOri(&update, pos, rotY, headX, false);
Handlers_UpdateLocation(id, &update, interpolate); Handlers_UpdateLocation(id, &update, interpolate);
} }
static void Classic_Reset(void) { static void Classic_Reset(void) {
mapInflateInited = false; map_begunLoading = false;
receivedFirstPosition = false; classic_receivedFirstPos = false;
Net_Set(OPCODE_HANDSHAKE, Classic_Handshake, 131); Net_Set(OPCODE_HANDSHAKE, Classic_Handshake, 131);
Net_Set(OPCODE_PING, Classic_Ping, 1); Net_Set(OPCODE_PING, Classic_Ping, 1);
@ -661,22 +696,22 @@ static void Classic_Reset(void) {
} }
static void Classic_Tick(void) { static void Classic_Tick(void) {
if (!receivedFirstPosition) return; if (!classic_receivedFirstPos) return;
struct Entity* entity = &LocalPlayer_Instance.Base; struct Entity* e = &LocalPlayer_Instance.Base;
Classic_WritePosition(entity->Position, entity->HeadY, entity->HeadX); Classic_WritePosition(e->Position, e->HeadY, e->HeadX);
} }
/*########################################################################################################################* /*########################################################################################################################*
*------------------------------------------------------CPE protocol-------------------------------------------------------* *------------------------------------------------------CPE protocol-------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
const char* cpe_clientExtensions[29] = { const char* cpe_clientExtensions[30] = {
"ClickDistance", "CustomBlocks", "HeldBlock", "EmoteFix", "TextHotKey", "ExtPlayerList", "ClickDistance", "CustomBlocks", "HeldBlock", "EmoteFix", "TextHotKey", "ExtPlayerList",
"EnvColors", "SelectionCuboid", "BlockPermissions", "ChangeModel", "EnvMapAppearance", "EnvColors", "SelectionCuboid", "BlockPermissions", "ChangeModel", "EnvMapAppearance",
"EnvWeatherType", "MessageTypes", "HackControl", "PlayerClick", "FullCP437", "LongerMessages", "EnvWeatherType", "MessageTypes", "HackControl", "PlayerClick", "FullCP437", "LongerMessages",
"BlockDefinitions", "BlockDefinitionsExt", "BulkBlockUpdate", "TextColors", "EnvMapAspect", "BlockDefinitions", "BlockDefinitionsExt", "BulkBlockUpdate", "TextColors", "EnvMapAspect",
"EntityProperty", "ExtEntityPositions", "TwoWayPing", "InventoryOrder", "InstantMOTD", "FastMap", "EntityProperty", "ExtEntityPositions", "TwoWayPing", "InventoryOrder", "InstantMOTD", "FastMap",
"ExtendedTextures", "ExtendedTextures", "ExtendedBlocks",
}; };
static void CPE_SetMapEnvUrl(UInt8* data); static void CPE_SetMapEnvUrl(UInt8* data);
@ -756,8 +791,16 @@ static void CPE_SendCpeExtInfoReply(void) {
#ifndef EXTENDED_TEXTURES #ifndef EXTENDED_TEXTURES
count--; count--;
#endif #endif
#ifndef EXTENDED_BLOCKS
count--;
#endif
#ifdef EXTENDED_BLOCKS
if (!Game_AllowCustomBlocks) count -= 3;
#else
if (!Game_AllowCustomBlocks) count -= 2; if (!Game_AllowCustomBlocks) count -= 2;
#endif
CPE_WriteExtInfo(&ServerConnection_AppName, count); CPE_WriteExtInfo(&ServerConnection_AppName, count);
Net_SendPacket(); Net_SendPacket();
Int32 i, ver; Int32 i, ver;
@ -772,11 +815,17 @@ static void CPE_SendCpeExtInfoReply(void) {
if (!Game_AllowCustomBlocks) { if (!Game_AllowCustomBlocks) {
if (String_CaselessEqualsConst(&name, "BlockDefinitionsExt")) continue; if (String_CaselessEqualsConst(&name, "BlockDefinitionsExt")) continue;
if (String_CaselessEqualsConst(&name, "BlockDefinitions")) continue; if (String_CaselessEqualsConst(&name, "BlockDefinitions")) continue;
#ifdef EXTENDED_BLOCKS
if (String_CaselessEqualsConst(&name, "ExtendedBlocks")) continue;
#endif
} }
#ifndef EXTENDED_TEXTURES #ifndef EXTENDED_TEXTURES
if (String_CaselessEqualsConst(&name, "ExtendedTextures")) continue; if (String_CaselessEqualsConst(&name, "ExtendedTextures")) continue;
#endif #endif
#ifndef EXTENDED_BLOCKS
if (String_CaselessEqualsConst(&name, "ExtendedBlocks")) continue;
#endif
CPE_WriteExtEntry(&name, ver); CPE_WriteExtEntry(&name, ver);
Net_SendPacket(); Net_SendPacket();
@ -851,6 +900,21 @@ static void CPE_ExtEntry(UInt8* data) {
cpe_extTextures = true; cpe_extTextures = true;
} }
#endif #endif
#ifdef EXTENDED_BLOCKS
else if (String_CaselessEqualsConst(&ext, "ExtendedBlocks")) {
if (!Game_AllowCustomBlocks) return;
cpe_extBlocks = true;
Net_PacketSizes[OPCODE_SET_BLOCK] += 1;
Net_PacketSizes[OPCODE_HOLD_THIS] += 1;
Net_PacketSizes[OPCODE_SET_BLOCK_PERMISSION] += 1;
Net_PacketSizes[OPCODE_DEFINE_BLOCK] += 1;
Net_PacketSizes[OPCODE_UNDEFINE_BLOCK] += 1;
Net_PacketSizes[OPCODE_DEFINE_BLOCK_EXT] += 1;
Net_PacketSizes[OPCODE_SET_INVENTORY_ORDER] += 2;
Net_PacketSizes[OPCODE_BULK_BLOCK_UPDATE] += 256 / 4;
}
#endif
} }
static void CPE_SetClickDistance(UInt8* data) { static void CPE_SetClickDistance(UInt8* data) {
@ -1067,6 +1131,23 @@ static void CPE_BulkBlockUpdate(UInt8* data) {
} }
data += (BULK_MAX_BLOCKS - count) * sizeof(Int32); data += (BULK_MAX_BLOCKS - count) * sizeof(Int32);
BlockID blocks[BULK_MAX_BLOCKS];
for (i = 0; i < count; i++) {
blocks[i] = data[i];
}
data += BULK_MAX_BLOCKS;
if (cpe_extBlocks) {
for (i = 0; i < count; i += 4) {
UInt8 flags = data[i >> 2];
blocks[i + 0] |= (BlockID)((flags & 0x03) << 8);
blocks[i + 1] |= (BlockID)((flags & 0x0C) << 6);
blocks[i + 2] |= (BlockID)((flags & 0x30) << 4);
blocks[i + 3] |= (BlockID)((flags & 0xC0) << 2);
}
data += BULK_MAX_BLOCKS / 4;
}
Int32 x, y, z; Int32 x, y, z;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
Int32 index = indices[i]; Int32 index = indices[i];
@ -1074,7 +1155,7 @@ static void CPE_BulkBlockUpdate(UInt8* data) {
World_Unpack(index, x, y, z); World_Unpack(index, x, y, z);
if (World_IsValidPos(x, y, z)) { if (World_IsValidPos(x, y, z)) {
Game_UpdateBlock(x, y, z, data[i]); Game_UpdateBlock(x, y, z, blocks[i]);
} }
} }
} }
@ -1207,7 +1288,7 @@ static void CPE_Reset(void) {
cpe_sendHeldBlock = false; cpe_useMessageTypes = false; cpe_sendHeldBlock = false; cpe_useMessageTypes = false;
cpe_envMapVer = 2; cpe_blockDefsExtVer = 2; cpe_envMapVer = 2; cpe_blockDefsExtVer = 2;
cpe_needD3Fix = false; cpe_extEntityPos = false; cpe_twoWayPing = false; cpe_needD3Fix = false; cpe_extEntityPos = false; cpe_twoWayPing = false;
cpe_extTextures = false; cpe_fastMap = false; cpe_extTextures = false; cpe_fastMap = false; cpe_extBlocks = false;
Game_UseCPEBlocks = false; Game_UseCPEBlocks = false;
if (!Game_UseCPE) return; if (!Game_UseCPE) return;

View File

@ -13,7 +13,7 @@ void Handlers_RemoveEntity(EntityID id);
void Handlers_Reset(void); void Handlers_Reset(void);
void Handlers_Tick(void); void Handlers_Tick(void);
bool cpe_sendHeldBlock, cpe_useMessageTypes, cpe_needD3Fix, cpe_extEntityPos, cpe_blockPerms, cpe_fastMap; bool cpe_needD3Fix;
void Classic_WriteChat(const String* text, bool partial); void Classic_WriteChat(const String* text, bool partial);
void Classic_WritePosition(Vector3 pos, float rotY, float headX); void Classic_WritePosition(Vector3 pos, float rotY, float headX);
void Classic_WriteSetBlock(Int32 x, Int32 y, Int32 z, bool place, BlockID block); void Classic_WriteSetBlock(Int32 x, Int32 y, Int32 z, bool place, BlockID block);

View File

@ -185,9 +185,9 @@ Int32 Searcher_FindReachableBlocks(struct Entity* entity, struct AABB* entityBB,
Searcher_CalcTime(&vel, entityBB, &blockBB, &tx, &ty, &tz); Searcher_CalcTime(&vel, entityBB, &blockBB, &tx, &ty, &tz);
if (tx > 1.0f || ty > 1.0f || tz > 1.0f) continue; if (tx > 1.0f || ty > 1.0f || tz > 1.0f) continue;
curState->X = (x << 3) | (block & 0x07); curState->X = (x << 3) | (block & 0x007);
curState->Y = (y << 3) | ((block & 0x38) >> 3); curState->Y = (y << 4) | ((block & 0x078) >> 3);
curState->Z = (z << 3) | ((block & 0xC0) >> 6); curState->Z = (z << 3) | ((block & 0x380) >> 7);
curState->tSquared = tx * tx + ty * ty + tz * tz; curState->tSquared = tx * tx + ty * ty + tz * tz;
curState++; curState++;
} }

View File

@ -529,7 +529,8 @@ static void TableWidget_MakeBlockDesc(String* desc, BlockID block) {
String_AppendString(desc, &name); String_AppendString(desc, &name);
if (Game_ClassicMode) return; if (Game_ClassicMode) return;
String_Format1(desc, " (ID %b&f", &block); Int32 block_ = block;
String_Format1(desc, " (ID %i&f", &block_);
if (!Block_CanPlace[block]) { String_AppendConst(desc, ", place &cNo&f"); } if (!Block_CanPlace[block]) { String_AppendConst(desc, ", place &cNo&f"); }
if (!Block_CanDelete[block]) { String_AppendConst(desc, ", delete &cNo&f"); } if (!Block_CanDelete[block]) { String_AppendConst(desc, ", delete &cNo&f"); }
String_Append(desc, ')'); String_Append(desc, ')');