mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-14 10:05:44 -04:00
C client: start work on inf id
This commit is contained in:
parent
a57d261703
commit
834c387a04
@ -42,7 +42,7 @@ namespace ClassicalSharp {
|
||||
Vector3I pos = game.SelectedPos.BlockPos;
|
||||
if (!game.SelectedPos.Valid || !game.World.IsValidPos(pos)) return;
|
||||
|
||||
BlockID old = game.World.GetBlock(pos);
|
||||
BlockID old = game.World.GetBlock(pos.X, pos.Y, pos.Z);
|
||||
if (BlockInfo.Draw[old] == DrawType.Gas || !BlockInfo.CanDelete[old]) return;
|
||||
|
||||
game.UpdateBlock(pos.X, pos.Y, pos.Z, Block.Air);
|
||||
@ -51,7 +51,7 @@ namespace ClassicalSharp {
|
||||
Vector3I pos = game.SelectedPos.TranslatedPos;
|
||||
if (!game.SelectedPos.Valid || !game.World.IsValidPos(pos)) return;
|
||||
|
||||
BlockID old = game.World.GetBlock(pos);
|
||||
BlockID old = game.World.GetBlock(pos.X, pos.Y, pos.Z);
|
||||
BlockID block = inv.Selected;
|
||||
if (game.AutoRotate)
|
||||
block = AutoRotate.RotateBlock(game, block);
|
||||
@ -66,7 +66,7 @@ namespace ClassicalSharp {
|
||||
} else if (middle) {
|
||||
Vector3I pos = game.SelectedPos.BlockPos;
|
||||
if (!game.SelectedPos.Valid || !game.World.IsValidPos(pos)) return;
|
||||
BlockID cur = game.World.GetBlock(pos);
|
||||
BlockID cur = game.World.GetBlock(pos.X, pos.Y, pos.Z);
|
||||
|
||||
if (BlockInfo.Draw[cur] == DrawType.Gas) return;
|
||||
if (!(BlockInfo.CanPlace[cur] || BlockInfo.CanDelete[cur])) return;
|
||||
|
@ -56,7 +56,7 @@ namespace ClassicalSharp.Map {
|
||||
blocks[i] = (BlockRaw)blockId;
|
||||
|
||||
// defer allocation of second map array if possible
|
||||
if (blocks == blocks2) {
|
||||
if (blocks == blocks2) {
|
||||
if (blockId < 256) return;
|
||||
blocks2 = new BlockRaw[blocks.Length];
|
||||
BlockInfo.SetMaxUsed(767);
|
||||
@ -83,7 +83,7 @@ namespace ClassicalSharp.Map {
|
||||
}
|
||||
|
||||
public BlockID SafeGetBlock(Vector3I p) {
|
||||
return IsValidPos(p.X, p.Y, p.Z) ? GetBlock(p) : Block.Air;
|
||||
return IsValidPos(p) ? GetBlock(p.X, p.Y, p.Z) : Block.Air;
|
||||
}
|
||||
|
||||
public bool IsValidPos(int x, int y, int z) {
|
||||
|
@ -78,7 +78,7 @@ bool ManageCookies;
|
||||
bool KeepAlive;
|
||||
/* TODO: Connection pooling */
|
||||
|
||||
static void AsyncDownloader_Add(const String* url, bool priority, const String* id, UInt8 type, UInt64* lastModified, const String* etag, const String* data) {
|
||||
static void AsyncDownloader_Add(const String* url, bool priority, const String* id, UInt8 type, TimeMS* lastModified, const String* etag, const String* data) {
|
||||
Mutex_Lock(async_pendingMutex);
|
||||
{
|
||||
struct AsyncRequest req = { 0 };
|
||||
@ -134,14 +134,14 @@ void AsyncDownloader_PostString(const String* url, bool priority, const String*
|
||||
AsyncDownloader_Add(url, priority, id, REQUEST_TYPE_DATA, NULL, NULL, contents);
|
||||
}
|
||||
|
||||
void AsyncDownloader_GetDataEx(const String* url, bool priority, const String* id, UInt64* lastModified, const String* etag) {
|
||||
void AsyncDownloader_GetDataEx(const String* url, bool priority, const String* id, TimeMS* lastModified, const String* etag) {
|
||||
AsyncDownloader_Add(url, priority, id, REQUEST_TYPE_DATA, lastModified, etag, NULL);
|
||||
}
|
||||
|
||||
void AsyncDownloader_PurgeOldEntriesTask(struct ScheduledTask* task) {
|
||||
Mutex_Lock(async_processedMutex);
|
||||
{
|
||||
UInt64 now = DateTime_CurrentUTC_MS();
|
||||
TimeMS now = DateTime_CurrentUTC_MS();
|
||||
Int32 i;
|
||||
|
||||
for (i = async_processed.Count - 1; i >= 0; i--) {
|
||||
|
@ -19,14 +19,14 @@ struct AsyncRequest {
|
||||
char URL[STRING_SIZE];
|
||||
char ID[STRING_SIZE];
|
||||
|
||||
UInt64 TimeAdded, TimeDownloaded;
|
||||
TimeMS TimeAdded, TimeDownloaded;
|
||||
Int32 StatusCode;
|
||||
ReturnCode Result;
|
||||
|
||||
void* ResultData;
|
||||
UInt32 ResultSize;
|
||||
|
||||
UInt64 LastModified; /* Time item cached at (if at all) */
|
||||
TimeMS LastModified; /* Time item cached at (if at all) */
|
||||
char Etag[STRING_SIZE]; /* ETag of cached item (if any) */
|
||||
UInt8 RequestType;
|
||||
};
|
||||
@ -39,7 +39,7 @@ void AsyncDownloader_GetData(const String* url, bool priority, const String* id)
|
||||
void AsyncDownloader_GetContentLength(const String* url, bool priority, const String* id);
|
||||
/* TODO: Implement post */
|
||||
/* void AsyncDownloader_PostString(const String* url, bool priority, const String* id, const String* contents); */
|
||||
void AsyncDownloader_GetDataEx(const String* url, bool priority, const String* id, UInt64* lastModified, const String* etag);
|
||||
void AsyncDownloader_GetDataEx(const String* url, bool priority, const String* id, TimeMS* lastModified, const String* etag);
|
||||
|
||||
bool AsyncDownloader_Get(const String* id, struct AsyncRequest* item);
|
||||
bool AsyncDownloader_GetCurrent(struct AsyncRequest* request, Int32* progress);
|
||||
|
@ -37,6 +37,13 @@ UInt8 Block_BottomTex[BLOCK_CPE_COUNT] = { 0, 1, 2, 2, 16, 4, 15, 17, 14,
|
||||
72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 56, 55, 6, 6, 7, 10, 4,
|
||||
36, 37, 16, 11, 57, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 58, 53, 52 };
|
||||
|
||||
#ifdef EXTENDED_BLOCKS
|
||||
void Block_SetUsedCount(Int32 count) {
|
||||
Block_UsedCount = count;
|
||||
Block_IDMask = Math_NextPowOf2(count) - 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Block_Reset(void) {
|
||||
Block_Init();
|
||||
Block_RecalculateSpriteBB();
|
||||
|
@ -78,6 +78,11 @@ UInt8 Block_Hidden[BLOCK_COUNT * BLOCK_COUNT];
|
||||
/* Gets a bit flags of which faces of a block can stretch with greedy meshing. */
|
||||
UInt8 Block_CanStretch[BLOCK_COUNT];
|
||||
|
||||
#ifdef EXTENDED_BLOCKS
|
||||
Int32 Block_UsedCount, Block_IDMask;
|
||||
void Block_SetUsedCount(Int32 count);
|
||||
#endif
|
||||
|
||||
void Block_Reset(void);
|
||||
void Block_Init(void);
|
||||
void Block_SetDefaultPerms(void);
|
||||
|
@ -241,8 +241,8 @@ static void Physics_HandleSapling(Int32 index, BlockID block) {
|
||||
Game_UpdateBlock(x, y, z, BLOCK_AIR);
|
||||
|
||||
if (TreeGen_CanGrow(x, y, z, treeHeight)) {
|
||||
Vector3I coords[Tree_BufferCount];
|
||||
BlockID blocks[Tree_BufferCount];
|
||||
Vector3I coords[TREE_MAX_COUNT];
|
||||
BlockRaw blocks[TREE_MAX_COUNT];
|
||||
Int32 count = TreeGen_Grow(x, y, z, treeHeight, coords, blocks);
|
||||
|
||||
Int32 m;
|
||||
|
10
src/Chat.c
10
src/Chat.c
@ -17,11 +17,11 @@
|
||||
#include "GameStructs.h"
|
||||
|
||||
#define CHAT_LOGTIMES_DEF_ELEMS 256
|
||||
UInt64 Chat_DefaultLogTimes[CHAT_LOGTIMES_DEF_ELEMS];
|
||||
UInt64* Chat_LogTimes = Chat_DefaultLogTimes;
|
||||
TimeMS Chat_DefaultLogTimes[CHAT_LOGTIMES_DEF_ELEMS];
|
||||
TimeMS* Chat_LogTimes = Chat_DefaultLogTimes;
|
||||
Int32 Chat_LogTimesMax = CHAT_LOGTIMES_DEF_ELEMS, Chat_LogTimesCount;
|
||||
|
||||
UInt64 Chat_GetLogTime(Int32 i) {
|
||||
TimeMS Chat_GetLogTime(Int32 i) {
|
||||
if (i < 0 || i >= Chat_LogTimesCount) ErrorHandler_Fail("Tried to get time past LogTime end");
|
||||
return Chat_LogTimes[i];
|
||||
}
|
||||
@ -29,10 +29,10 @@ UInt64 Chat_GetLogTime(Int32 i) {
|
||||
static void Chat_AppendLogTime(void) {
|
||||
if (Chat_LogTimesCount == Chat_LogTimesMax) {
|
||||
Chat_LogTimes = Utils_Resize(Chat_LogTimes, &Chat_LogTimesMax,
|
||||
sizeof(UInt64), CHAT_LOGTIMES_DEF_ELEMS, 512);
|
||||
sizeof(TimeMS), CHAT_LOGTIMES_DEF_ELEMS, 512);
|
||||
}
|
||||
|
||||
UInt64 now = DateTime_CurrentUTC_MS();
|
||||
TimeMS now = DateTime_CurrentUTC_MS();
|
||||
Chat_LogTimes[Chat_LogTimesCount++] = now;
|
||||
}
|
||||
|
||||
|
@ -22,10 +22,10 @@ enum MSG_TYPE {
|
||||
MSG_TYPE_CLIENTSTATUS_3 = 258, /* Tab list matching names*/
|
||||
};
|
||||
|
||||
struct ChatLine { char Buffer[STRING_SIZE]; UInt64 Received; };
|
||||
struct ChatLine { char Buffer[STRING_SIZE]; TimeMS Received; };
|
||||
struct ChatLine Chat_Status[3], Chat_BottomRight[3], Chat_ClientStatus[3], Chat_Announcement;
|
||||
StringsBuffer Chat_Log, Chat_InputLog;
|
||||
UInt64 Chat_GetLogTime(Int32 i);
|
||||
TimeMS Chat_GetLogTime(Int32 i);
|
||||
|
||||
void Chat_MakeComponent(struct IGameComponent* comp);
|
||||
void Chat_SetLogName(const String* name);
|
||||
|
13
src/Core.h
13
src/Core.h
@ -42,16 +42,25 @@ typedef UInt8 bool;
|
||||
#define false 0
|
||||
#define NULL ((void*)0)
|
||||
|
||||
#ifdef INF_ID
|
||||
//#define EXTENDED_BLOCKS
|
||||
#ifdef EXTENDED_BLOCKS
|
||||
typedef UInt16 BlockID;
|
||||
#else
|
||||
typedef UInt8 BlockID;
|
||||
#endif
|
||||
|
||||
#define EXTENDED_TEXTURES
|
||||
#ifdef EXTENDED_TEXTURES
|
||||
typedef UInt16 TextureLoc;
|
||||
#else
|
||||
typedef UInt8 TextureLoc;
|
||||
#endif
|
||||
|
||||
typedef UInt8 BlockRaw;
|
||||
typedef UInt8 EntityID;
|
||||
typedef UInt16 TextureLoc;
|
||||
typedef UInt8 Face;
|
||||
typedef UInt32 ReturnCode;
|
||||
typedef UInt64 TimeMS;
|
||||
|
||||
typedef struct Rect2D_ { Int32 X, Y, Width, Height; } Rect2D;
|
||||
typedef struct Point2D_ { Int32 X, Y; } Point2D;
|
||||
|
@ -348,16 +348,28 @@ static void EnvRenderer_InitWeatherHeightmap(void) {
|
||||
}
|
||||
}
|
||||
|
||||
#define EnvRenderer_RainCalcBody(get_block)\
|
||||
for (y = maxY; y >= 0; y--, i -= World_OneY) {\
|
||||
UInt8 draw = Block_Draw[get_block];\
|
||||
if (!(draw == DRAW_GAS || draw == DRAW_SPRITE)) {\
|
||||
Weather_Heightmap[index] = y;\
|
||||
return y;\
|
||||
}\
|
||||
}
|
||||
|
||||
static Int32 EnvRenderer_CalcRainHeightAt(Int32 x, Int32 maxY, Int32 z, Int32 index) {
|
||||
Int32 i = World_Pack(x, maxY, z), y;
|
||||
|
||||
for (y = maxY; y >= 0; y--, i -= World_OneY) {
|
||||
UInt8 draw = Block_Draw[World_Blocks[i]];
|
||||
if (!(draw == DRAW_GAS || draw == DRAW_SPRITE)) {
|
||||
Weather_Heightmap[index] = y;
|
||||
return y;
|
||||
}
|
||||
#ifndef EXTENDED_BLOCKS
|
||||
EnvRenderer_RainCalcBody(World_Blocks[i]);
|
||||
#else
|
||||
if (Block_UsedCount <= 256) {
|
||||
EnvRenderer_RainCalcBody(World_Blocks[i]);
|
||||
} else {
|
||||
EnvRenderer_RainCalcBody(World_Blocks[i] | (World_Blocks2[i] << 8));
|
||||
}
|
||||
#endif
|
||||
|
||||
Weather_Heightmap[index] = -1;
|
||||
return -1;
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ double Math_FastExp(double x) {
|
||||
|
||||
void Random_Init(Random* seed, Int32 seedInit) { Random_SetSeed(seed, seedInit); }
|
||||
void Random_InitFromCurrentTime(Random* rnd) {
|
||||
UInt64 now = DateTime_CurrentUTC_MS();
|
||||
TimeMS now = DateTime_CurrentUTC_MS();
|
||||
Random_Init(rnd, (Int32)now);
|
||||
}
|
||||
|
||||
|
@ -371,7 +371,7 @@ static bool Cw_Callback_1(struct NbtTag* tag) {
|
||||
if (IsTag(tag, "BlockArray")) {
|
||||
World_BlocksSize = tag->DataSize;
|
||||
if (tag->DataSize < NBT_SMALL_SIZE) {
|
||||
World_Blocks = Mem_Alloc(World_BlocksSize, sizeof(UInt8), ".cw map blocks");
|
||||
World_Blocks = Mem_Alloc(World_BlocksSize, 1, ".cw map blocks");
|
||||
Mem_Copy(World_Blocks, tag->DataSmall, tag->DataSize);
|
||||
} else {
|
||||
World_Blocks = tag->DataBig;
|
||||
@ -954,8 +954,8 @@ ReturnCode Cw_Save(struct Stream* stream) {
|
||||
col = Env_ShadowCol; tmp[253] = col.R; tmp[259] = col.G; tmp[265] = col.B;
|
||||
col = Env_SunCol; tmp[283] = col.R; tmp[289] = col.G; tmp[295] = col.B;
|
||||
|
||||
tmp[352] = Env_SidesBlock;
|
||||
tmp[365] = Env_EdgeBlock;
|
||||
tmp[352] = (BlockRaw)Env_SidesBlock;
|
||||
tmp[365] = (BlockRaw)Env_EdgeBlock;
|
||||
Stream_SetU16_BE(&tmp[378], Env_EdgeHeight);
|
||||
}
|
||||
Int32 b, len = Cw_WriteEndString(&tmp[393], &World_TextureUrl);
|
||||
|
@ -445,6 +445,9 @@ void Game_Load(void) {
|
||||
Event_RegisterVoid(&WindowEvents_Resized, NULL, Game_OnResize);
|
||||
Event_RegisterVoid(&WindowEvents_Closed, NULL, Game_Free);
|
||||
|
||||
#ifdef EXTENDED_BLOCKS
|
||||
Block_SetUsedCount(256);
|
||||
#endif
|
||||
Block_Init();
|
||||
ModelCache_Init();
|
||||
|
||||
|
@ -22,7 +22,7 @@ bool input_buttonsDown[3];
|
||||
Int32 input_pickingId = -1;
|
||||
Int32 input_normViewDists[10] = { 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 };
|
||||
Int32 input_classicViewDists[4] = { 8, 32, 128, 512 };
|
||||
UInt64 input_lastClick;
|
||||
TimeMS input_lastClick;
|
||||
float input_fovIndex = -1.0f;
|
||||
|
||||
bool InputHandler_IsMousePressed(MouseButton button) {
|
||||
@ -300,7 +300,7 @@ static bool InputHandler_CheckIsFree(BlockID block) {
|
||||
}
|
||||
|
||||
void InputHandler_PickBlocks(bool cooldown, bool left, bool middle, bool right) {
|
||||
UInt64 now = DateTime_CurrentUTC_MS();
|
||||
TimeMS now = DateTime_CurrentUTC_MS();
|
||||
Int32 delta = (Int32)(now - input_lastClick);
|
||||
if (cooldown && delta < 250) return; /* 4 times per second */
|
||||
|
||||
@ -318,19 +318,19 @@ void InputHandler_PickBlocks(bool cooldown, bool left, bool middle, bool right)
|
||||
/* always play delete animations, even if we aren't picking a block */
|
||||
HeldBlockRenderer_ClickAnim(true);
|
||||
|
||||
Vector3I pos = Game_SelectedPos.BlockPos;
|
||||
if (!Game_SelectedPos.Valid || !World_IsValidPos_3I(pos)) return;
|
||||
Vector3I p = Game_SelectedPos.BlockPos;
|
||||
if (!Game_SelectedPos.Valid || !World_IsValidPos_3I(p)) return;
|
||||
|
||||
BlockID old = World_GetBlock_3I(pos);
|
||||
BlockID old = World_GetBlock(p.X, p.Y, p.Z);
|
||||
if (Block_Draw[old] == DRAW_GAS || !Block_CanDelete[old]) return;
|
||||
|
||||
Game_UpdateBlock(pos.X, pos.Y, pos.Z, BLOCK_AIR);
|
||||
Event_RaiseBlock(&UserEvents_BlockChanged, pos, old, BLOCK_AIR);
|
||||
Game_UpdateBlock(p.X, p.Y, p.Z, BLOCK_AIR);
|
||||
Event_RaiseBlock(&UserEvents_BlockChanged, p, old, BLOCK_AIR);
|
||||
} else if (right) {
|
||||
Vector3I pos = Game_SelectedPos.TranslatedPos;
|
||||
if (!Game_SelectedPos.Valid || !World_IsValidPos_3I(pos)) return;
|
||||
Vector3I p = Game_SelectedPos.TranslatedPos;
|
||||
if (!Game_SelectedPos.Valid || !World_IsValidPos_3I(p)) return;
|
||||
|
||||
BlockID old = World_GetBlock_3I(pos);
|
||||
BlockID old = World_GetBlock(p.X, p.Y, p.Z);
|
||||
BlockID block = Inventory_SelectedBlock;
|
||||
if (Game_AutoRotate) { block = AutoRotate_RotateBlock(block); }
|
||||
|
||||
@ -339,13 +339,13 @@ void InputHandler_PickBlocks(bool cooldown, bool left, bool middle, bool right)
|
||||
if (Block_Draw[block] == DRAW_GAS && Block_Draw[old] != DRAW_GAS) return;
|
||||
if (!InputHandler_CheckIsFree(block)) return;
|
||||
|
||||
Game_UpdateBlock(pos.X, pos.Y, pos.Z, block);
|
||||
Event_RaiseBlock(&UserEvents_BlockChanged, pos, old, block);
|
||||
Game_UpdateBlock(p.X, p.Y, p.Z, block);
|
||||
Event_RaiseBlock(&UserEvents_BlockChanged, p, old, block);
|
||||
} else if (middle) {
|
||||
Vector3I pos = Game_SelectedPos.BlockPos;
|
||||
if (!Game_SelectedPos.Valid || !World_IsValidPos_3I(pos)) return;
|
||||
Vector3I p = Game_SelectedPos.BlockPos;
|
||||
if (!Game_SelectedPos.Valid || !World_IsValidPos_3I(p)) return;
|
||||
|
||||
BlockID cur = World_GetBlock_3I(pos);
|
||||
BlockID cur = World_GetBlock(p.X, p.Y, p.Z);
|
||||
if (Block_Draw[cur] == DRAW_GAS) return;
|
||||
if (!(Block_CanPlace[cur] || Block_CanDelete[cur])) return;
|
||||
if (!Inventory_CanChangeSelected() || Inventory_SelectedBlock == cur) return;
|
||||
|
@ -8,17 +8,31 @@
|
||||
#include "Event.h"
|
||||
#include "GameStructs.h"
|
||||
|
||||
#define HEIGHT_UNCALCULATED Int16_MaxValue
|
||||
|
||||
#define Lighting_CalcBody(get_block)\
|
||||
for (y = maxY; y >= 0; y--, i -= World_OneY) {\
|
||||
BlockID block = get_block;\
|
||||
if (Block_BlocksLight[block]) {\
|
||||
Int32 offset = (Block_LightOffset[block] >> FACE_YMAX) & 1;\
|
||||
Lighting_Heightmap[index] = y - offset;\
|
||||
return y - offset;\
|
||||
}\
|
||||
}
|
||||
|
||||
static Int32 Lighting_CalcHeightAt(Int32 x, Int32 maxY, Int32 z, Int32 index) {
|
||||
Int32 y, i = World_Pack(x, maxY, z);
|
||||
|
||||
for (y = maxY; y >= 0; y--, i -= World_OneY) {
|
||||
BlockID block = World_Blocks[i];
|
||||
if (Block_BlocksLight[block]) {
|
||||
Int32 offset = (Block_LightOffset[block] >> FACE_YMAX) & 1;
|
||||
Lighting_Heightmap[index] = y - offset;
|
||||
return y - offset;
|
||||
}
|
||||
#ifndef EXTENDED_BLOCKS
|
||||
Lighting_CalcBody(World_Blocks[i]);
|
||||
#else
|
||||
if (Block_UsedCount <= 256) {
|
||||
Lighting_CalcBody(World_Blocks[i]);
|
||||
} else {
|
||||
Lighting_CalcBody(World_Blocks[i] | (World_Blocks2[i] << 8));
|
||||
}
|
||||
#endif
|
||||
|
||||
Lighting_Heightmap[index] = -10;
|
||||
return -10;
|
||||
}
|
||||
@ -26,7 +40,7 @@ static Int32 Lighting_CalcHeightAt(Int32 x, Int32 maxY, Int32 z, Int32 index) {
|
||||
static Int32 Lighting_GetLightHeight(Int32 x, Int32 z) {
|
||||
Int32 index = (z * World_Width) + x;
|
||||
Int32 lightH = Lighting_Heightmap[index];
|
||||
return lightH == Int16_MaxValue ? Lighting_CalcHeightAt(x, World_Height - 1, z, index) : lightH;
|
||||
return lightH == HEIGHT_UNCALCULATED ? Lighting_CalcHeightAt(x, World_Height - 1, z, index) : lightH;
|
||||
}
|
||||
|
||||
/* Outside colour is same as sunlight colour, so we reuse when possible */
|
||||
@ -65,7 +79,7 @@ PackedCol Lighting_Col_ZSide_Fast(Int32 x, Int32 y, Int32 z) {
|
||||
void Lighting_Refresh(void) {
|
||||
Int32 i;
|
||||
for (i = 0; i < World_Width * World_Length; i++) {
|
||||
Lighting_Heightmap[i] = Int16_MaxValue;
|
||||
Lighting_Heightmap[i] = HEIGHT_UNCALCULATED;
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +88,7 @@ void Lighting_Refresh(void) {
|
||||
*----------------------------------------------------Lighting update------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static void Lighting_UpdateLighting(Int32 x, Int32 y, Int32 z, BlockID oldBlock, BlockID newBlock, Int32 index, Int32 lightH) {
|
||||
bool didBlock = Block_BlocksLight[oldBlock];
|
||||
bool didBlock = Block_BlocksLight[oldBlock];
|
||||
bool nowBlocks = Block_BlocksLight[newBlock];
|
||||
Int32 oldOffset = (Block_LightOffset[oldBlock] >> FACE_YMAX) & 1;
|
||||
Int32 newOffset = (Block_LightOffset[newBlock] >> FACE_YMAX) & 1;
|
||||
@ -111,13 +125,24 @@ static bool Lighting_Needs(BlockID block, BlockID other) {
|
||||
return Block_Draw[block] != DRAW_OPAQUE || Block_Draw[other] != DRAW_GAS;
|
||||
}
|
||||
|
||||
#define Lighting_NeedsNeighourBody(get_block)\
|
||||
/* Update if any blocks in the chunk are affected by light change. */ \
|
||||
for (; y >= minY; y--, index -= World_OneY) {\
|
||||
BlockID other = World_Blocks[index];\
|
||||
bool affected = y == nY ? Lighting_Needs(block, other) : Block_Draw[other] != DRAW_GAS;\
|
||||
if (affected) return true;\
|
||||
}
|
||||
|
||||
static bool Lighting_NeedsNeighour(BlockID block, Int32 index, Int32 minY, Int32 y, Int32 nY) {
|
||||
/* Update if any blocks in the chunk are affected by light change. */
|
||||
for (; y >= minY; y--, index -= World_OneY) {
|
||||
BlockID other = World_Blocks[index];
|
||||
bool affected = y == nY ? Lighting_Needs(block, other) : Block_Draw[other] != DRAW_GAS;
|
||||
if (affected) return true;
|
||||
#ifndef EXTENDED_BLOCKS
|
||||
Lighting_NeedsNeighourBody(World_Blocks[i]);
|
||||
#else
|
||||
if (Block_UsedCount <= 256) {
|
||||
Lighting_NeedsNeighourBody(World_Blocks[i]);
|
||||
} else {
|
||||
Lighting_NeedsNeighourBody(World_Blocks[i] | (World_Blocks2[i] << 8));
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -187,7 +212,7 @@ void Lighting_OnBlockChanged(Int32 x, Int32 y, Int32 z, BlockID oldBlock, BlockI
|
||||
Int32 lightH = Lighting_Heightmap[index];
|
||||
/* Since light wasn't checked to begin with, means column never had meshes for any of its chunks built. */
|
||||
/* So we don't need to do anything. */
|
||||
if (lightH == Int16_MaxValue) return;
|
||||
if (lightH == HEIGHT_UNCALCULATED) return;
|
||||
|
||||
Lighting_UpdateLighting(x, y, z, oldBlock, newBlock, index, lightH);
|
||||
Int32 newHeight = Lighting_Heightmap[index] + 1;
|
||||
@ -207,7 +232,7 @@ static Int32 Lighting_InitialHeightmapCoverage(Int32 x1, Int32 z1, Int32 xCount,
|
||||
for (x = 0; x < xCount; x++) {
|
||||
Int32 lightH = Lighting_Heightmap[heightmapIndex++];
|
||||
skip[index] = 0;
|
||||
if (lightH == Int16_MaxValue) {
|
||||
if (lightH == HEIGHT_UNCALCULATED) {
|
||||
elemsLeft++;
|
||||
curRunCount = 0;
|
||||
} else {
|
||||
@ -275,7 +300,7 @@ static void Lighting_FinishHeightmapCoverage(Int32 x1, Int32 z1, Int32 xCount, I
|
||||
Int32 heightmapIndex = Lighting_Pack(x1, z1 + z);
|
||||
for (x = 0; x < xCount; x++) {
|
||||
Int32 lightH = Lighting_Heightmap[heightmapIndex];
|
||||
if (lightH == Int16_MaxValue)
|
||||
if (lightH == HEIGHT_UNCALCULATED)
|
||||
Lighting_Heightmap[heightmapIndex] = -10;
|
||||
heightmapIndex++;
|
||||
}
|
||||
@ -283,10 +308,10 @@ static void Lighting_FinishHeightmapCoverage(Int32 x1, Int32 z1, Int32 xCount, I
|
||||
}
|
||||
|
||||
void Lighting_LightHint(Int32 startX, Int32 startZ) {
|
||||
Int32 x1 = max(startX, 0), x2 = min(World_Width, startX + 18);
|
||||
Int32 z1 = max(startZ, 0), z2 = min(World_Length, startZ + 18);
|
||||
Int32 x1 = max(startX, 0), x2 = min(World_Width, startX + EXTCHUNK_SIZE);
|
||||
Int32 z1 = max(startZ, 0), z2 = min(World_Length, startZ + EXTCHUNK_SIZE);
|
||||
Int32 xCount = x2 - x1, zCount = z2 - z1;
|
||||
Int32 skip[18 * 18];
|
||||
Int32 skip[EXTCHUNK_SIZE * EXTCHUNK_SIZE];
|
||||
|
||||
Int32 elemsLeft = Lighting_InitialHeightmapCoverage(x1, z1, xCount, zCount, skip);
|
||||
if (!Lighting_CalculateHeightmapCoverage(x1, z1, xCount, zCount, elemsLeft, skip)) {
|
||||
|
@ -453,8 +453,8 @@ static void NotchyGen_PlantTrees(void) {
|
||||
BlockRaw blockUnder = treeY > 0 ? Gen_Blocks[index - oneY] : BLOCK_AIR;
|
||||
|
||||
if (blockUnder == BLOCK_GRASS && TreeGen_CanGrow(treeX, treeY, treeZ, treeHeight)) {
|
||||
Vector3I coords[Tree_BufferCount];
|
||||
BlockRaw blocks[Tree_BufferCount];
|
||||
Vector3I coords[TREE_MAX_COUNT];
|
||||
BlockRaw blocks[TREE_MAX_COUNT];
|
||||
Int32 count = TreeGen_Grow(treeX, treeY, treeZ, treeHeight, coords, blocks);
|
||||
|
||||
for (m = 0; m < count; m++) {
|
||||
|
@ -37,7 +37,7 @@ Int32 Tree_Width, Tree_Height, Tree_Length;
|
||||
BlockRaw* Tree_Blocks;
|
||||
Random* Tree_Rnd;
|
||||
/* Appropriate buffer size to hold positions and blocks generated by the tree generator. */
|
||||
#define Tree_BufferCount 96
|
||||
#define TREE_MAX_COUNT 96
|
||||
|
||||
bool TreeGen_CanGrow(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 treeHeight);
|
||||
Int32 TreeGen_Grow(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 height, Vector3I* coords, BlockRaw* blocks);
|
||||
|
@ -25,11 +25,36 @@
|
||||
#include "Errors.h"
|
||||
#include "TerrainAtlas.h"
|
||||
|
||||
/* Classic state */
|
||||
UInt8 classic_tabList[256 >> 3];
|
||||
|
||||
/* CPE state */
|
||||
Int32 cpe_serverExtensionsCount, cpe_pingTicks;
|
||||
Int32 cpe_envMapVer = 2, cpe_blockDefsExtVer = 2;
|
||||
bool cpe_twoWayPing, cpe_extTextures, cpe_extBlocks;
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-----------------------------------------------------Common handlers-----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
UInt8 classicTabList[256 >> 3];
|
||||
#define Handlers_ReadBlock(data) *data++;
|
||||
|
||||
|
||||
#ifndef EXTENDED_BLOCKS
|
||||
#define Handlers_ReadBlock(data, value) value = *data++;
|
||||
#else
|
||||
#define Handlers_ReadBlock(data, value)\
|
||||
if (cpe_extBlocks) {\
|
||||
value = Stream_GetU16_BE(data, value); data += 2;\
|
||||
} else { value = *data++; }
|
||||
#endif
|
||||
|
||||
#ifndef EXTENDED_BLOCKS
|
||||
#define Handlers_WriteBlock(data, value) *data++ = value;
|
||||
#else
|
||||
#define Handlers_WriteBlock(data, value)\
|
||||
if (cpe_extBlocks) {\
|
||||
Stream_SetU16_BE(data, value); data += 2;\
|
||||
} else { *data++ = value; }
|
||||
#endif
|
||||
|
||||
static void Handlers_ReadString(UInt8** ptr, String* str) {
|
||||
Int32 i, length = 0;
|
||||
@ -140,10 +165,10 @@ void Handlers_RemoveEntity(EntityID id) {
|
||||
|
||||
/* See comment about some servers in Classic_AddEntity */
|
||||
Int32 mask = id >> 3, bit = 1 << (id & 0x7);
|
||||
if (!(classicTabList[mask] & bit)) return;
|
||||
if (!(classic_tabList[mask] & bit)) return;
|
||||
|
||||
Handlers_RemoveTablistEntry(id);
|
||||
classicTabList[mask] &= (UInt8)~bit;
|
||||
classic_tabList[mask] &= (UInt8)~bit;
|
||||
}
|
||||
|
||||
static void Handlers_UpdateLocation(EntityID playerId, struct LocationUpdate* update, bool interpolate) {
|
||||
@ -284,7 +309,7 @@ static void WoM_Tick(void) {
|
||||
/*########################################################################################################################*
|
||||
*----------------------------------------------------Classic protocol-----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
UInt64 mapReceiveStart;
|
||||
TimeMS mapReceiveStart;
|
||||
struct InflateState mapInflateState;
|
||||
struct Stream mapInflateStream;
|
||||
bool mapInflateInited;
|
||||
@ -298,65 +323,62 @@ bool receivedFirstPosition;
|
||||
|
||||
void Classic_WriteChat(const String* text, bool partial) {
|
||||
UInt8* data = ServerConnection_WriteBuffer;
|
||||
data[0] = OPCODE_MESSAGE;
|
||||
*data++ = OPCODE_MESSAGE;
|
||||
{
|
||||
data[1] = ServerConnection_SupportsPartialMessages ? partial : ENTITIES_SELF_ID;
|
||||
Handlers_WriteString(&data[2], text);
|
||||
*data++ = ServerConnection_SupportsPartialMessages ? partial : ENTITIES_SELF_ID;
|
||||
Handlers_WriteString(data, text); data += STRING_SIZE;
|
||||
}
|
||||
ServerConnection_WriteBuffer += 66;
|
||||
ServerConnection_WriteBuffer = data;
|
||||
}
|
||||
|
||||
void Classic_WritePosition(Vector3 pos, float rotY, float headX) {
|
||||
UInt8* data = ServerConnection_WriteBuffer;
|
||||
data[0] = OPCODE_ENTITY_TELEPORT;
|
||||
Int32 len;
|
||||
*data++ = OPCODE_ENTITY_TELEPORT;
|
||||
{
|
||||
data[1] = cpe_sendHeldBlock ? Inventory_SelectedBlock : ENTITIES_SELF_ID; /* TODO: extended blocks */
|
||||
*data++ = cpe_sendHeldBlock ? Inventory_SelectedBlock : ENTITIES_SELF_ID; /* TODO: extended blocks */
|
||||
Int32 x = (Int32)(pos.X * 32);
|
||||
Int32 y = (Int32)(pos.Y * 32) + 51;
|
||||
Int32 z = (Int32)(pos.Z * 32);
|
||||
|
||||
if (cpe_extEntityPos) {
|
||||
Stream_SetU32_BE(&data[2], x);
|
||||
Stream_SetU32_BE(&data[6], y);
|
||||
Stream_SetU32_BE(&data[10], z);
|
||||
len = 14;
|
||||
Stream_SetU32_BE(data, x); data += 4;
|
||||
Stream_SetU32_BE(data, y); data += 4;
|
||||
Stream_SetU32_BE(data, z); data += 4;
|
||||
} else {
|
||||
Stream_SetU16_BE(&data[2], x);
|
||||
Stream_SetU16_BE(&data[4], y);
|
||||
Stream_SetU16_BE(&data[6], z);
|
||||
len = 8;
|
||||
Stream_SetU16_BE(data, x); data += 2;
|
||||
Stream_SetU16_BE(data, y); data += 2;
|
||||
Stream_SetU16_BE(data, z); data += 2;
|
||||
}
|
||||
|
||||
data[len++] = Math_Deg2Packed(rotY);
|
||||
data[len++] = Math_Deg2Packed(headX);
|
||||
*data++ = Math_Deg2Packed(rotY);
|
||||
*data++ = Math_Deg2Packed(headX);
|
||||
}
|
||||
ServerConnection_WriteBuffer += len;
|
||||
ServerConnection_WriteBuffer = data;
|
||||
}
|
||||
|
||||
void Classic_WriteSetBlock(Int32 x, Int32 y, Int32 z, bool place, BlockID block) {
|
||||
UInt8* data = ServerConnection_WriteBuffer;
|
||||
data[0] = OPCODE_SET_BLOCK_CLIENT;
|
||||
*data++ = OPCODE_SET_BLOCK_CLIENT;
|
||||
{
|
||||
Stream_SetU16_BE(&data[1], x);
|
||||
Stream_SetU16_BE(&data[3], y);
|
||||
Stream_SetU16_BE(&data[5], z);
|
||||
data[7] = place;
|
||||
data[8] = block; /* TODO: extended blocks */
|
||||
Stream_SetU16_BE(data, x); data += 2;
|
||||
Stream_SetU16_BE(data, y); data += 2;
|
||||
Stream_SetU16_BE(data, z); data += 2;
|
||||
*data++ = place;
|
||||
*data++ = block; /* TODO: extended blocks */
|
||||
}
|
||||
ServerConnection_WriteBuffer += 9;
|
||||
ServerConnection_WriteBuffer = data;
|
||||
}
|
||||
|
||||
void Classic_WriteLogin(const String* username, const String* verKey) {
|
||||
UInt8* data = ServerConnection_WriteBuffer;
|
||||
data[0] = OPCODE_HANDSHAKE;
|
||||
*data++ = OPCODE_HANDSHAKE;
|
||||
{
|
||||
data[1] = 7; /* protocol version */
|
||||
Handlers_WriteString(&data[2], username);
|
||||
Handlers_WriteString(&data[66], verKey);
|
||||
data[130] = Game_UseCPE ? 0x42 : 0x00;
|
||||
*data++ = 7; /* protocol version */
|
||||
Handlers_WriteString(data, username); data += STRING_SIZE;
|
||||
Handlers_WriteString(data, verKey); data += STRING_SIZE;
|
||||
*data++ = Game_UseCPE ? 0x42 : 0x00;
|
||||
}
|
||||
ServerConnection_WriteBuffer += 131;
|
||||
ServerConnection_WriteBuffer = data;
|
||||
}
|
||||
|
||||
static void Classic_Handshake(UInt8* data) {
|
||||
@ -485,7 +507,7 @@ static void Classic_SetBlock(UInt8* data) {
|
||||
Int32 z = Stream_GetU16_BE(&data[4]);
|
||||
|
||||
data += 6;
|
||||
BlockID block = Handlers_ReadBlock(data);
|
||||
BlockID block; Handlers_ReadBlock(data, block);
|
||||
if (World_IsValidPos(x, y, z)) {
|
||||
Game_UpdateBlock(x, y, z, block);
|
||||
}
|
||||
@ -505,7 +527,7 @@ static void Classic_AddEntity(UInt8* data) {
|
||||
/* Workaround for some servers that declare support for ExtPlayerList but don't send ExtAddPlayerName */
|
||||
String group = String_FromConst("Players");
|
||||
Handlers_AddTablistEntry(id, &name, &name, &group, 0);
|
||||
classicTabList[id >> 3] |= (UInt8)(1 << (id & 0x7));
|
||||
classic_tabList[id >> 3] |= (UInt8)(1 << (id & 0x7));
|
||||
}
|
||||
|
||||
static void Classic_EntityTeleport(UInt8* data) {
|
||||
@ -648,11 +670,6 @@ static void Classic_Tick(void) {
|
||||
/*########################################################################################################################*
|
||||
*------------------------------------------------------CPE protocol-------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
|
||||
Int32 cpe_serverExtensionsCount, cpe_pingTicks;
|
||||
Int32 cpe_envMapVer = 2, cpe_blockDefsExtVer = 2;
|
||||
bool cpe_twoWayPing, cpe_extTextures;
|
||||
|
||||
const char* cpe_clientExtensions[29] = {
|
||||
"ClickDistance", "CustomBlocks", "HeldBlock", "EmoteFix", "TextHotKey", "ExtPlayerList",
|
||||
"EnvColors", "SelectionCuboid", "BlockPermissions", "ChangeModel", "EnvMapAppearance",
|
||||
@ -667,76 +684,80 @@ static void CPE_SetMapEnvUrl(UInt8* data);
|
||||
void CPE_WritePlayerClick(MouseButton button, bool buttonDown, UInt8 targetId, struct PickedPos* pos) {
|
||||
struct Entity* p = &LocalPlayer_Instance.Base;
|
||||
UInt8* data = ServerConnection_WriteBuffer;
|
||||
data[0] = OPCODE_PLAYER_CLICK;
|
||||
*data++ = OPCODE_PLAYER_CLICK;
|
||||
{
|
||||
data[1] = button;
|
||||
data[2] = buttonDown;
|
||||
Stream_SetU16_BE(&data[3], Ext_Deg2Packed(p->HeadY));
|
||||
Stream_SetU16_BE(&data[5], Ext_Deg2Packed(p->HeadX));
|
||||
*data++ = button;
|
||||
*data++ = buttonDown;
|
||||
Stream_SetU16_BE(data, Ext_Deg2Packed(p->HeadY)); data += 2;
|
||||
Stream_SetU16_BE(data, Ext_Deg2Packed(p->HeadX)); data += 2;
|
||||
|
||||
data[7] = targetId;
|
||||
Stream_SetU16_BE(&data[8], pos->BlockPos.X);
|
||||
Stream_SetU16_BE(&data[10], pos->BlockPos.Y);
|
||||
Stream_SetU16_BE(&data[12], pos->BlockPos.Z);
|
||||
*data++ = targetId;
|
||||
Stream_SetU16_BE(data, pos->BlockPos.X); data += 2;
|
||||
Stream_SetU16_BE(data, pos->BlockPos.Y); data += 2;
|
||||
Stream_SetU16_BE(data, pos->BlockPos.Z); data += 2;
|
||||
|
||||
data[14] = 255;
|
||||
*data = 255;
|
||||
/* Our own face values differ from CPE block face */
|
||||
switch (pos->ClosestFace) {
|
||||
case FACE_XMAX: data[14] = 0; break;
|
||||
case FACE_XMIN: data[14] = 1; break;
|
||||
case FACE_YMAX: data[14] = 2; break;
|
||||
case FACE_YMIN: data[14] = 3; break;
|
||||
case FACE_ZMAX: data[14] = 4; break;
|
||||
case FACE_ZMIN: data[14] = 5; break;
|
||||
case FACE_XMAX: *data = 0; break;
|
||||
case FACE_XMIN: *data = 1; break;
|
||||
case FACE_YMAX: *data = 2; break;
|
||||
case FACE_YMIN: *data = 3; break;
|
||||
case FACE_ZMAX: *data = 4; break;
|
||||
case FACE_ZMIN: *data = 5; break;
|
||||
}
|
||||
data++;
|
||||
}
|
||||
ServerConnection_WriteBuffer += 15;
|
||||
}
|
||||
|
||||
static void CPE_WriteExtInfo(const String* appName, Int32 extensionsCount) {
|
||||
UInt8* data = ServerConnection_WriteBuffer;
|
||||
data[0] = OPCODE_EXT_INFO;
|
||||
*data++ = OPCODE_EXT_INFO;
|
||||
{
|
||||
Handlers_WriteString(&data[1], appName);
|
||||
Stream_SetU16_BE(&data[65], extensionsCount);
|
||||
Handlers_WriteString(data, appName); data += STRING_SIZE;
|
||||
Stream_SetU16_BE(data, extensionsCount); data += 2;
|
||||
}
|
||||
ServerConnection_WriteBuffer += 67;
|
||||
ServerConnection_WriteBuffer = data;
|
||||
}
|
||||
|
||||
static void CPE_WriteExtEntry(const String* extensionName, Int32 extensionVersion) {
|
||||
UInt8* data = ServerConnection_WriteBuffer;
|
||||
data[0] = OPCODE_EXT_ENTRY;
|
||||
*data++ = OPCODE_EXT_ENTRY;
|
||||
{
|
||||
Handlers_WriteString(&data[1], extensionName);
|
||||
Stream_SetU32_BE(&data[65], extensionVersion);
|
||||
Handlers_WriteString(data, extensionName); data += STRING_SIZE;
|
||||
Stream_SetU32_BE(data, extensionVersion); data += 4;
|
||||
}
|
||||
ServerConnection_WriteBuffer += 69;
|
||||
ServerConnection_WriteBuffer = data;
|
||||
}
|
||||
|
||||
static void CPE_WriteCustomBlockLevel(UInt8 version) {
|
||||
UInt8* data = ServerConnection_WriteBuffer;
|
||||
data[0] = OPCODE_CUSTOM_BLOCK_LEVEL;
|
||||
*data++ = OPCODE_CUSTOM_BLOCK_LEVEL;
|
||||
{
|
||||
data[1] = version;
|
||||
*data++ = version;
|
||||
}
|
||||
ServerConnection_WriteBuffer += 2;
|
||||
ServerConnection_WriteBuffer = data;
|
||||
}
|
||||
|
||||
static void CPE_WriteTwoWayPing(bool serverToClient, UInt16 payload) {
|
||||
UInt8* data = ServerConnection_WriteBuffer;
|
||||
data[0] = OPCODE_TWO_WAY_PING;
|
||||
*data++ = OPCODE_TWO_WAY_PING;
|
||||
{
|
||||
data[1] = serverToClient;
|
||||
Stream_SetU16_BE(&data[2], payload);
|
||||
*data++ = serverToClient;
|
||||
Stream_SetU16_BE(data, payload); data += 2;
|
||||
}
|
||||
ServerConnection_WriteBuffer += 4;
|
||||
ServerConnection_WriteBuffer = data;
|
||||
}
|
||||
|
||||
static void CPE_SendCpeExtInfoReply(void) {
|
||||
if (cpe_serverExtensionsCount) return;
|
||||
Int32 count = Array_Elems(cpe_clientExtensions);
|
||||
if (!Game_AllowCustomBlocks) count -= 2;
|
||||
#ifndef EXTENDED_TEXTURES
|
||||
count--;
|
||||
#endif
|
||||
|
||||
if (!Game_AllowCustomBlocks) count -= 2;
|
||||
CPE_WriteExtInfo(&ServerConnection_AppName, count);
|
||||
Net_SendPacket();
|
||||
Int32 i, ver;
|
||||
@ -753,6 +774,10 @@ static void CPE_SendCpeExtInfoReply(void) {
|
||||
if (String_CaselessEqualsConst(&name, "BlockDefinitions")) continue;
|
||||
}
|
||||
|
||||
#ifndef EXTENDED_TEXTURES
|
||||
if (String_CaselessEqualsConst(&name, "ExtendedTextures")) continue;
|
||||
#endif
|
||||
|
||||
CPE_WriteExtEntry(&name, ver);
|
||||
Net_SendPacket();
|
||||
}
|
||||
@ -818,11 +843,14 @@ static void CPE_ExtEntry(UInt8* data) {
|
||||
} else if (String_CaselessEqualsConst(&ext, "FastMap")) {
|
||||
Net_PacketSizes[OPCODE_LEVEL_BEGIN] += 4;
|
||||
cpe_fastMap = true;
|
||||
} else if (String_CaselessEqualsConst(&ext, "ExtendedTextures")) {
|
||||
}
|
||||
#ifdef EXTENDED_TEXTURES
|
||||
else if (String_CaselessEqualsConst(&ext, "ExtendedTextures")) {
|
||||
Net_PacketSizes[OPCODE_DEFINE_BLOCK] += 3;
|
||||
Net_PacketSizes[OPCODE_DEFINE_BLOCK_EXT] += 6;
|
||||
cpe_extTextures = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void CPE_SetClickDistance(UInt8* data) {
|
||||
@ -837,7 +865,7 @@ static void CPE_CustomBlockLevel(UInt8* data) {
|
||||
}
|
||||
|
||||
static void CPE_HoldThis(UInt8* data) {
|
||||
BlockID block = Handlers_ReadBlock(data);
|
||||
BlockID block; Handlers_ReadBlock(data, block);
|
||||
bool canChange = *data == 0;
|
||||
|
||||
Inventory_CanChangeHeldBlock = true;
|
||||
@ -891,7 +919,7 @@ static void CPE_ExtAddPlayerName(UInt8* data) {
|
||||
|
||||
/* Workarond for server software that declares support for ExtPlayerList, but sends AddEntity then AddPlayerName */
|
||||
Int32 mask = id >> 3, bit = 1 << (id & 0x7);
|
||||
classicTabList[mask] &= (UInt8)~bit;
|
||||
classic_tabList[mask] &= (UInt8)~bit;
|
||||
Handlers_AddTablistEntry(id, &playerName, &listName, &groupName, groupRank);
|
||||
}
|
||||
|
||||
@ -901,7 +929,7 @@ static void CPE_ExtAddEntity(UInt8* data) {
|
||||
String displayName = String_FromArray(displayNameBuffer);
|
||||
String skinName = String_FromArray(skinNameBuffer);
|
||||
|
||||
UInt8 id = *data++;
|
||||
EntityID id = *data++;
|
||||
Handlers_ReadString(&data, &displayName);
|
||||
Handlers_ReadString(&data, &skinName);
|
||||
|
||||
@ -960,7 +988,7 @@ static void CPE_SetEnvCol(UInt8* data) {
|
||||
}
|
||||
|
||||
static void CPE_SetBlockPermission(UInt8* data) {
|
||||
BlockID block = Handlers_ReadBlock(data);
|
||||
BlockID block; Handlers_ReadBlock(data, block);
|
||||
Block_CanPlace[block] = *data++ != 0;
|
||||
Block_CanDelete[block] = *data++ != 0;
|
||||
Event_RaiseVoid(&BlockEvents_PermissionsChanged);
|
||||
@ -1021,7 +1049,7 @@ static void CPE_ExtAddEntity2(UInt8* data) {
|
||||
String displayName = String_FromArray(displayNameBuffer);
|
||||
String skinName = String_FromArray(skinNameBuffer);
|
||||
|
||||
UInt8 id = *data++;
|
||||
EntityID id = *data++;
|
||||
Handlers_ReadString(&data, &displayName);
|
||||
Handlers_ReadString(&data, &skinName);
|
||||
|
||||
@ -1031,7 +1059,7 @@ static void CPE_ExtAddEntity2(UInt8* data) {
|
||||
|
||||
#define BULK_MAX_BLOCKS 256
|
||||
static void CPE_BulkBlockUpdate(UInt8* data) {
|
||||
Int32 i, count = *data++ + 1;
|
||||
Int32 i, count = 1 + *data++;
|
||||
|
||||
UInt32 indices[BULK_MAX_BLOCKS];
|
||||
for (i = 0; i < count; i++) {
|
||||
@ -1119,7 +1147,7 @@ static void CPE_SetMapEnvProperty(UInt8* data) {
|
||||
}
|
||||
|
||||
static void CPE_SetEntityProperty(UInt8* data) {
|
||||
UInt8 id = *data++;
|
||||
EntityID id = *data++;
|
||||
UInt8 type = *data++;
|
||||
Int32 value = (Int32)Stream_GetU32_BE(data);
|
||||
|
||||
@ -1167,8 +1195,8 @@ static void CPE_TwoWayPing(UInt8* data) {
|
||||
}
|
||||
|
||||
static void CPE_SetInventoryOrder(UInt8* data) {
|
||||
BlockID block = Handlers_ReadBlock(data);
|
||||
BlockID order = Handlers_ReadBlock(data);
|
||||
BlockID block; Handlers_ReadBlock(data, block);
|
||||
BlockID order; Handlers_ReadBlock(data, order);
|
||||
|
||||
Inventory_Remove(block);
|
||||
if (order) { Inventory_Map[order - 1] = block; }
|
||||
@ -1248,7 +1276,7 @@ static BlockID BlockDefs_DefineBlockCommonStart(UInt8** ptr, bool uniqueSideTexs
|
||||
char nameBuffer[STRING_SIZE];
|
||||
String name = String_FromArray(nameBuffer);
|
||||
|
||||
BlockID block = Handlers_ReadBlock(data);
|
||||
BlockID block; Handlers_ReadBlock(data, block);
|
||||
bool didBlockLight = Block_BlocksLight[block];
|
||||
Block_ResetProps(block);
|
||||
|
||||
@ -1317,7 +1345,7 @@ static void BlockDefs_DefineBlock(UInt8* data) {
|
||||
}
|
||||
|
||||
static void BlockDefs_UndefineBlock(UInt8* data) {
|
||||
BlockID block = Handlers_ReadBlock(data);
|
||||
BlockID block; Handlers_ReadBlock(data, block);
|
||||
bool didBlockLight = Block_BlocksLight[block];
|
||||
|
||||
Block_ResetProps(block);
|
||||
|
@ -189,7 +189,7 @@ void Platform_Log(const String* message) {
|
||||
|
||||
#define FILETIME_EPOCH 50491123200000ULL
|
||||
#define FileTime_TotalMS(time) ((time / 10000) + FILETIME_EPOCH)
|
||||
UInt64 DateTime_CurrentUTC_MS(void) {
|
||||
TimeMS DateTime_CurrentUTC_MS(void) {
|
||||
FILETIME ft; GetSystemTimeAsFileTime(&ft);
|
||||
/* in 100 nanosecond units, since Jan 1 1601 */
|
||||
UInt64 raw = ft.dwLowDateTime | ((UInt64)ft.dwHighDateTime << 32);
|
||||
@ -238,7 +238,7 @@ void Platform_Log(const String* message) {
|
||||
|
||||
#define UNIX_EPOCH 62135596800000ULL
|
||||
#define UnixTime_TotalMS(time) ((UInt64)time.tv_sec * 1000 + UNIX_EPOCH + (time.tv_usec / 1000))
|
||||
UInt64 DateTime_CurrentUTC_MS(void) {
|
||||
TimeMS DateTime_CurrentUTC_MS(void) {
|
||||
struct timeval cur;
|
||||
gettimeofday(&cur, NULL);
|
||||
return UnixTime_TotalMS(cur);
|
||||
@ -332,7 +332,7 @@ ReturnCode Directory_Enum(const String* path, void* obj, Directory_EnumCallback
|
||||
return Win_Return(result == ERROR_NO_MORE_FILES);
|
||||
}
|
||||
|
||||
ReturnCode File_GetModifiedTime_MS(const String* path, UInt64* time) {
|
||||
ReturnCode File_GetModifiedTime_MS(const String* path, TimeMS* time) {
|
||||
void* file; ReturnCode result = File_Open(&file, path);
|
||||
if (result) return result;
|
||||
|
||||
@ -443,7 +443,7 @@ ReturnCode Directory_Enum(const String* path, void* obj, Directory_EnumCallback
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnCode File_GetModifiedTime_MS(const String* path, UInt64* time) {
|
||||
ReturnCode File_GetModifiedTime_MS(const String* path, TimeMS* time) {
|
||||
char str[600]; Platform_ConvertString(str, path);
|
||||
struct stat sb;
|
||||
if (stat(str, &sb) == -1) return errno;
|
||||
|
@ -46,7 +46,7 @@ void Platform_Log2(const char* format, const void* a1, const void* a2);
|
||||
void Platform_Log3(const char* format, const void* a1, const void* a2, const void* a3);
|
||||
void Platform_Log4(const char* format, const void* a1, const void* a2, const void* a3, const void* a4);
|
||||
|
||||
UInt64 DateTime_CurrentUTC_MS(void);
|
||||
TimeMS DateTime_CurrentUTC_MS(void);
|
||||
void DateTime_CurrentUTC(DateTime* time);
|
||||
void DateTime_CurrentLocal(DateTime* time);
|
||||
void Stopwatch_Measure(UInt64* timer);
|
||||
@ -57,7 +57,7 @@ ReturnCode Directory_Create(const String* path);
|
||||
typedef void Directory_EnumCallback(const String* filename, void* obj);
|
||||
ReturnCode Directory_Enum(const String* path, void* obj, Directory_EnumCallback callback);
|
||||
bool File_Exists(const String* path);
|
||||
ReturnCode File_GetModifiedTime_MS(const String* path, UInt64* ms);
|
||||
ReturnCode File_GetModifiedTime_MS(const String* path, TimeMS* ms);
|
||||
|
||||
ReturnCode File_Create(void** file, const String* path);
|
||||
ReturnCode File_Open(void** file, const String* path);
|
||||
|
@ -93,7 +93,7 @@ struct ChatScreen {
|
||||
|
||||
struct DisconnectScreen {
|
||||
Screen_Layout
|
||||
UInt64 InitTime;
|
||||
TimeMS InitTime;
|
||||
bool CanReconnect, LastActive;
|
||||
Int32 LastSecsLeft;
|
||||
struct ButtonWidget Reconnect;
|
||||
@ -1111,7 +1111,7 @@ static void ChatScreen_Render(void* screen, double delta) {
|
||||
Texture_Render(&tex);
|
||||
}
|
||||
|
||||
UInt64 now = DateTime_CurrentUTC_MS();
|
||||
TimeMS now = DateTime_CurrentUTC_MS();
|
||||
if (s->HandlesAllInput) {
|
||||
Elem_Render(&s->Chat, delta);
|
||||
} else {
|
||||
|
@ -53,7 +53,7 @@ void ServerConnection_DownloadTexturePack(const String* url) {
|
||||
if (TextureCache_HasDenied(url)) return;
|
||||
char etagBuffer[STRING_SIZE];
|
||||
String etag = String_FromArray(etagBuffer);
|
||||
UInt64 lastModified = 0;
|
||||
TimeMS lastModified = 0;
|
||||
|
||||
if (TextureCache_HasUrl(url)) {
|
||||
TextureCache_GetLastModified(url, &lastModified);
|
||||
@ -247,12 +247,12 @@ UInt8* net_readCurrent;
|
||||
|
||||
bool net_writeFailed;
|
||||
Int32 net_ticks;
|
||||
UInt64 net_lastPacket;
|
||||
TimeMS net_lastPacket;
|
||||
UInt8 net_lastOpcode;
|
||||
double net_discAccumulator;
|
||||
|
||||
bool net_connecting;
|
||||
UInt64 net_connectTimeout;
|
||||
TimeMS net_connectTimeout;
|
||||
#define NET_TIMEOUT_MS (15 * 1000)
|
||||
|
||||
static void MPConnection_BlockChanged(void* obj, Vector3I p, BlockID old, BlockID now) {
|
||||
@ -302,7 +302,7 @@ static void MPConnection_TickConnect(void) {
|
||||
MPConnection_FailConnect(err); return;
|
||||
}
|
||||
|
||||
UInt64 now = DateTime_CurrentUTC_MS();
|
||||
TimeMS now = DateTime_CurrentUTC_MS();
|
||||
bool poll_write = false;
|
||||
Socket_Select(net_socket, SOCKET_SELECT_WRITE, &poll_write);
|
||||
|
||||
@ -378,7 +378,7 @@ static void MPConnection_Tick(struct ScheduledTask* task) {
|
||||
if (net_connecting) { MPConnection_TickConnect(); return; }
|
||||
|
||||
/* over 30 seconds since last packet */
|
||||
UInt64 now = DateTime_CurrentUTC_MS();
|
||||
TimeMS now = DateTime_CurrentUTC_MS();
|
||||
if (net_lastPacket + (30 * 1000) < now) {
|
||||
MPConnection_CheckDisconnection(task->Interval);
|
||||
}
|
||||
|
@ -8,7 +8,11 @@
|
||||
#define ATLAS2D_TILES_PER_ROW 16
|
||||
#define ATLAS2D_MASK 15
|
||||
#define ATLAS2D_SHIFT 4
|
||||
#ifdef EXTENDED_TEXTURES
|
||||
#define ATLAS2D_MAX_ROWS_COUNT 32
|
||||
#else
|
||||
#define ATLAS2D_MAX_ROWS_COUNT 16
|
||||
#endif
|
||||
#define ATLAS1D_MAX_ATLASES (ATLAS2D_TILES_PER_ROW * ATLAS2D_MAX_ROWS_COUNT)
|
||||
|
||||
Bitmap Atlas2D_Bitmap;
|
||||
|
@ -334,11 +334,11 @@ void TexturePack_GetFromTags(const String* url, String* result, struct EntryList
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCache_GetLastModified(const String* url, UInt64* time) {
|
||||
void TextureCache_GetLastModified(const String* url, TimeMS* time) {
|
||||
char entryBuffer[STRING_SIZE];
|
||||
String entry = String_FromArray(entryBuffer);
|
||||
TexturePack_GetFromTags(url, &entry, &cache_lastModified);
|
||||
UInt64 temp;
|
||||
TimeMS temp;
|
||||
|
||||
if (entry.length && Convert_TryParseUInt64(&entry, &temp)) {
|
||||
*time = temp / TEXCACHE_TICKS_PER_MS;
|
||||
@ -393,7 +393,7 @@ void TextureCache_AddETag(const String* url, const String* etag) {
|
||||
TextureCache_AddToTags(url, etag, &cache_eTags);
|
||||
}
|
||||
|
||||
void TextureCache_AddLastModified(const String* url, UInt64* lastModified) {
|
||||
void TextureCache_AddLastModified(const String* url, TimeMS* lastModified) {
|
||||
if (!lastModified) return;
|
||||
UInt64 ticks = (*lastModified) * TEXCACHE_TICKS_PER_MS;
|
||||
|
||||
|
@ -30,11 +30,11 @@ void TextureCache_Deny(const String* url);
|
||||
|
||||
bool TextureCache_HasUrl(const String* url);
|
||||
bool TextureCache_GetStream(const String* url, struct Stream* stream);
|
||||
void TextureCache_GetLastModified(const String* url, UInt64* time);
|
||||
void TextureCache_GetLastModified(const String* url, TimeMS* time);
|
||||
void TextureCache_GetETag(const String* url, String* etag);
|
||||
void TextureCache_AddData(const String* url, UInt8* data, UInt32 length);
|
||||
void TextureCache_AddETag(const String* url, const String* etag);
|
||||
void TextureCache_AddLastModified(const String* url, UInt64* lastModified);
|
||||
void TextureCache_AddLastModified(const String* url, TimeMS* lastModified);
|
||||
|
||||
void TexturePack_ExtractZip_File(const String* filename);
|
||||
void TexturePack_ExtractDefault(void);
|
||||
|
@ -38,7 +38,7 @@ Int32 DateTime_TotalDays(DateTime* time) {
|
||||
return days;
|
||||
}
|
||||
|
||||
UInt64 DateTime_TotalMs(DateTime* time) {
|
||||
TimeMS DateTime_TotalMs(DateTime* time) {
|
||||
Int32 days = DateTime_TotalDays(time);
|
||||
UInt64 seconds =
|
||||
(UInt64)days * DATETIME_SECONDS_PER_DAY +
|
||||
@ -48,7 +48,7 @@ UInt64 DateTime_TotalMs(DateTime* time) {
|
||||
return seconds * DATETIME_MILLIS_PER_SEC + time->Milli;
|
||||
}
|
||||
|
||||
void DateTime_FromTotalMs(DateTime* time, UInt64 ms) {
|
||||
void DateTime_FromTotalMs(DateTime* time, TimeMS ms) {
|
||||
/* Work out time component for just this day */
|
||||
Int32 dayMS = (Int32)(ms % DATETIME_MILLISECS_PER_DAY);
|
||||
time->Milli = dayMS % DATETIME_MILLIS_PER_SEC; dayMS /= DATETIME_MILLIS_PER_SEC;
|
||||
@ -81,7 +81,7 @@ void DateTime_FromTotalMs(DateTime* time, UInt64 ms) {
|
||||
}
|
||||
}
|
||||
|
||||
void DateTime_HttpDate(UInt64 ms, String* str) {
|
||||
void DateTime_HttpDate(TimeMS ms, String* str) {
|
||||
static char* days_of_weeks[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
|
||||
static char* month_names[13] = { NULL, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
|
||||
|
@ -17,9 +17,9 @@ typedef struct DateTime_ {
|
||||
} DateTime;
|
||||
|
||||
#define DATETIME_MILLIS_PER_SEC 1000
|
||||
UInt64 DateTime_TotalMs(DateTime* time);
|
||||
void DateTime_FromTotalMs(DateTime* time, UInt64 ms);
|
||||
void DateTime_HttpDate(UInt64 ms, String* str);
|
||||
TimeMS DateTime_TotalMs(DateTime* time);
|
||||
void DateTime_FromTotalMs(DateTime* time, TimeMS ms);
|
||||
void DateTime_HttpDate(TimeMS ms, String* str);
|
||||
|
||||
UInt32 Utils_ParseEnum(const String* text, UInt32 defValue, const char** names, UInt32 namesCount);
|
||||
bool Utils_IsValidInputChar(char c, bool supportsCP437);
|
||||
|
22
src/World.c
22
src/World.c
@ -44,6 +44,9 @@ void World_SetNewMap(BlockRaw* blocks, Int32 blocksSize, Int32 width, Int32 heig
|
||||
if (blocksSize != (width * height * length)) {
|
||||
ErrorHandler_Fail("Blocks array size does not match volume of map");
|
||||
}
|
||||
#ifdef EXTENDED_BLOCKS
|
||||
World_Blocks2 = World_Blocks;
|
||||
#endif
|
||||
|
||||
World_OneY = width * length;
|
||||
World_MaxX = width - 1;
|
||||
@ -59,6 +62,25 @@ void World_SetNewMap(BlockRaw* blocks, Int32 blocksSize, Int32 width, Int32 heig
|
||||
}
|
||||
|
||||
|
||||
#ifdef EXTENDED_BLOCKS
|
||||
void World_SetBlock(Int32 x, Int32 y, Int32 z, BlockID block) {
|
||||
Int32 i = World_Pack(x, y, z);
|
||||
World_Blocks[i] = (BlockRaw)block;
|
||||
|
||||
/* defer allocation of second map array if possible */
|
||||
if (World_Blocks == World_Blocks2) {
|
||||
if (block < 256) return;
|
||||
World_Blocks2 = Mem_Alloc(World_BlocksSize, 1, "blocks array upper");
|
||||
Block_SetUsedCount(768);
|
||||
}
|
||||
World_Blocks2[i] = (BlockRaw)(block >> 8);
|
||||
}
|
||||
#else
|
||||
void World_SetBlock(Int32 x, Int32 y, Int32 z, BlockID block) {
|
||||
World_Blocks[World_Pack(x, y, z)] = block;
|
||||
}
|
||||
#endif
|
||||
|
||||
BlockID World_GetPhysicsBlock(Int32 x, Int32 y, Int32 z) {
|
||||
if (x < 0 || x >= World_Width || z < 0 || z >= World_Length || y < 0) return BLOCK_BEDROCK;
|
||||
if (y >= World_Height) return BLOCK_AIR;
|
||||
|
47
src/World.h
47
src/World.h
@ -12,7 +12,11 @@ struct AABB;
|
||||
#define World_Pack(x, y, z) (((y) * World_Length + (z)) * World_Width + (x))
|
||||
|
||||
BlockRaw* World_Blocks;
|
||||
#ifdef EXTENDED_BLOCKS
|
||||
BlockRaw* World_Blocks2;
|
||||
#endif
|
||||
Int32 World_BlocksSize;
|
||||
|
||||
Int32 World_Width, World_Height, World_Length;
|
||||
Int32 World_MaxX, World_MaxY, World_MaxZ;
|
||||
Int32 World_OneY;
|
||||
@ -21,12 +25,19 @@ extern String World_TextureUrl;
|
||||
|
||||
void World_Reset(void);
|
||||
void World_SetNewMap(BlockRaw* blocks, Int32 blocksSize, Int32 width, Int32 height, Int32 length);
|
||||
BlockID World_GetPhysicsBlock(Int32 x, Int32 y, Int32 z);
|
||||
|
||||
#define World_SetBlock(x, y, z, blockId) World_Blocks[World_Pack(x, y, z)] = blockId
|
||||
#define World_SetBlock_3I(p, blockId) World_Blocks[World_Pack(p.X, p.Y, p.Z)] = blockId
|
||||
#ifdef EXTENDED_BLOCKS
|
||||
extern Int32 Block_IDMask;
|
||||
static inline BlockID World_GetBlock(Int32 x, Int32 y, Int32 z) {
|
||||
Int32 i = World_Pack(x, y, z);
|
||||
return (BlockID)((World_Blocks[i] | (World_Blocks2[i] << 8)) & Block_IDMask);
|
||||
}
|
||||
#else
|
||||
#define World_GetBlock(x, y, z) World_Blocks[World_Pack(x, y, z)]
|
||||
#define World_GetBlock_3I(p) World_Blocks[World_Pack(p.X, p.Y, p.Z)]
|
||||
#endif
|
||||
|
||||
BlockID World_GetPhysicsBlock(Int32 x, Int32 y, Int32 z);
|
||||
void World_SetBlock(Int32 x, Int32 y, Int32 z, BlockID block);
|
||||
BlockID World_SafeGetBlock_3I(Vector3I p);
|
||||
bool World_IsValidPos(Int32 x, Int32 y, Int32 z);
|
||||
bool World_IsValidPos_3I(Vector3I p);
|
||||
@ -39,8 +50,7 @@ enum ENV_VAR {
|
||||
ENV_VAR_SHADOW_COL,
|
||||
};
|
||||
|
||||
BlockID Env_EdgeBlock;
|
||||
BlockID Env_SidesBlock;
|
||||
BlockID Env_EdgeBlock, Env_SidesBlock;
|
||||
Int32 Env_EdgeHeight;
|
||||
Int32 Env_SidesOffset;
|
||||
#define Env_SidesHeight (Env_EdgeHeight + Env_SidesOffset)
|
||||
@ -53,23 +63,18 @@ float Env_WeatherSpeed;
|
||||
float Env_WeatherFade;
|
||||
Int32 Env_Weather;
|
||||
bool Env_ExpFog;
|
||||
float Env_SkyboxHorSpeed;
|
||||
float Env_SkyboxVerSpeed;
|
||||
float Env_SkyboxHorSpeed, Env_SkyboxVerSpeed;
|
||||
|
||||
PackedCol Env_SkyCol;
|
||||
extern PackedCol Env_DefaultSkyCol;
|
||||
#define ENV_DEFAULT_SKYCOL_HEX "99CCFF"
|
||||
PackedCol Env_FogCol;
|
||||
extern PackedCol Env_DefaultFogCol;
|
||||
#define ENV_DEFAULT_FOGCOL_HEX "FFFFFF"
|
||||
PackedCol Env_CloudsCol;
|
||||
extern PackedCol Env_DefaultCloudsCol;
|
||||
#define ENV_DEFAULT_CLOUDSCOL_HEX "FFFFFF"
|
||||
PackedCol Env_SunCol, Env_SunXSide, Env_SunZSide, Env_SunYMin;
|
||||
extern PackedCol Env_DefaultSunCol;
|
||||
#define ENV_DEFAULT_SUNCOL_HEX "FFFFFF"
|
||||
PackedCol Env_SkyCol, Env_FogCol, Env_CloudsCol;
|
||||
extern PackedCol Env_DefaultSkyCol, Env_DefaultFogCol, Env_DefaultCloudsCol;
|
||||
PackedCol Env_SunCol, Env_SunXSide, Env_SunZSide, Env_SunYMin;
|
||||
PackedCol Env_ShadowCol, Env_ShadowXSide, Env_ShadowZSide, Env_ShadowYMin;
|
||||
extern PackedCol Env_DefaultShadowCol;
|
||||
extern PackedCol Env_DefaultSunCol, Env_DefaultShadowCol;
|
||||
|
||||
#define ENV_DEFAULT_SKYCOL_HEX "99CCFF"
|
||||
#define ENV_DEFAULT_FOGCOL_HEX "FFFFFF"
|
||||
#define ENV_DEFAULT_CLOUDSCOL_HEX "FFFFFF"
|
||||
#define ENV_DEFAULT_SUNCOL_HEX "FFFFFF"
|
||||
#define ENV_DEFAULT_SHADOWCOL_HEX "9B9B9B"
|
||||
|
||||
void Env_Reset(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user