mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-13 17:47:12 -04:00
Fix game being stuffed after getting disconnected
This commit is contained in:
parent
0ace7afa1e
commit
04c3683ba1
@ -144,16 +144,16 @@ static bool Physics_IsEdgeWater(int x, int y, int z) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void Physics_BlockChanged(void* obj, Vector3I p, BlockID old, BlockID now) {
|
void Physics_OnBlockChanged(int x, int y, int z, BlockID old, BlockID now) {
|
||||||
PhysicsHandler handler;
|
PhysicsHandler handler;
|
||||||
int index;
|
int index;
|
||||||
if (!Physics_Enabled) return;
|
if (!Physics_Enabled) return;
|
||||||
|
|
||||||
if (now == BLOCK_AIR && Physics_IsEdgeWater(p.X, p.Y, p.Z)) {
|
if (now == BLOCK_AIR && Physics_IsEdgeWater(x, y, z)) {
|
||||||
now = BLOCK_STILL_WATER;
|
now = BLOCK_STILL_WATER;
|
||||||
Game_UpdateBlock(p.X, p.Y, p.Z, BLOCK_STILL_WATER);
|
Game_UpdateBlock(x, y, z, BLOCK_STILL_WATER);
|
||||||
}
|
}
|
||||||
index = World_Pack(p.X, p.Y, p.Z);
|
index = World_Pack(x, y, z);
|
||||||
|
|
||||||
if (now == BLOCK_AIR) {
|
if (now == BLOCK_AIR) {
|
||||||
handler = Physics_OnDelete[old];
|
handler = Physics_OnDelete[old];
|
||||||
@ -162,7 +162,7 @@ static void Physics_BlockChanged(void* obj, Vector3I p, BlockID old, BlockID now
|
|||||||
handler = Physics_OnPlace[now];
|
handler = Physics_OnPlace[now];
|
||||||
if (handler) handler(index, now);
|
if (handler) handler(index, now);
|
||||||
}
|
}
|
||||||
Physics_ActivateNeighbours(p.X, p.Y, p.Z, index);
|
Physics_ActivateNeighbours(x, y, z, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Physics_TickRandomBlocks(void) {
|
static void Physics_TickRandomBlocks(void) {
|
||||||
@ -515,7 +515,6 @@ static void Physics_HandleTnt(int index, BlockID block) {
|
|||||||
|
|
||||||
void Physics_Init(void) {
|
void Physics_Init(void) {
|
||||||
Event_RegisterVoid(&WorldEvents_MapLoaded, NULL, Physics_OnNewMapLoaded);
|
Event_RegisterVoid(&WorldEvents_MapLoaded, NULL, Physics_OnNewMapLoaded);
|
||||||
Event_RegisterBlock(&UserEvents_BlockChanged, NULL, Physics_BlockChanged);
|
|
||||||
Physics_Enabled = Options_GetBool(OPT_BLOCK_PHYSICS, true);
|
Physics_Enabled = Options_GetBool(OPT_BLOCK_PHYSICS, true);
|
||||||
TickQueue_Init(&physics_lavaQ);
|
TickQueue_Init(&physics_lavaQ);
|
||||||
TickQueue_Init(&physics_waterQ);
|
TickQueue_Init(&physics_waterQ);
|
||||||
@ -559,7 +558,6 @@ void Physics_Init(void) {
|
|||||||
|
|
||||||
void Physics_Free(void) {
|
void Physics_Free(void) {
|
||||||
Event_UnregisterVoid(&WorldEvents_MapLoaded, NULL, Physics_OnNewMapLoaded);
|
Event_UnregisterVoid(&WorldEvents_MapLoaded, NULL, Physics_OnNewMapLoaded);
|
||||||
Event_UnregisterBlock(&UserEvents_BlockChanged, NULL, Physics_BlockChanged);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Physics_Tick(void) {
|
void Physics_Tick(void) {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
extern bool Physics_Enabled;
|
extern bool Physics_Enabled;
|
||||||
void Physics_SetEnabled(bool enabled);
|
void Physics_SetEnabled(bool enabled);
|
||||||
|
void Physics_OnBlockChanged(int x, int y, int z, BlockID old, BlockID now);
|
||||||
void Physics_Init(void);
|
void Physics_Init(void);
|
||||||
void Physics_Free(void);
|
void Physics_Free(void);
|
||||||
void Physics_Tick(void);
|
void Physics_Tick(void);
|
||||||
|
@ -461,7 +461,7 @@ static void CuboidCommand_DoCuboid(void) {
|
|||||||
for (y = min.Y; y <= max.Y; y++) {
|
for (y = min.Y; y <= max.Y; y++) {
|
||||||
for (z = min.Z; z <= max.Z; z++) {
|
for (z = min.Z; z <= max.Z; z++) {
|
||||||
for (x = min.X; x <= max.X; x++) {
|
for (x = min.X; x <= max.X; x++) {
|
||||||
Game_UpdateBlock(x, y, z, toPlace);
|
Game_ChangeBlock(x, y, z, toPlace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -566,7 +566,7 @@ void Chat_Send(const String* text, bool logUsage) {
|
|||||||
if (Commands_IsCommandPrefix(text)) {
|
if (Commands_IsCommandPrefix(text)) {
|
||||||
Commands_Execute(text);
|
Commands_Execute(text);
|
||||||
} else {
|
} else {
|
||||||
ServerConnection_SendChat(text);
|
ServerConnection.SendChat(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ typedef signed __int64 int64_t;
|
|||||||
|
|
||||||
#define CC_INLINE inline
|
#define CC_INLINE inline
|
||||||
#define CC_NOINLINE __declspec(noinline)
|
#define CC_NOINLINE __declspec(noinline)
|
||||||
#define CC_ALIGN_HINT(x) /* TODO: Why does this cause LNK2005 errors */
|
#define CC_ALIGN_HINT(x) __declspec(align(x))
|
||||||
#ifndef CC_EXPORT
|
#ifndef CC_EXPORT
|
||||||
#define CC_EXPORT __declspec(dllexport, noinline)
|
#define CC_EXPORT __declspec(dllexport, noinline)
|
||||||
#endif
|
#endif
|
||||||
|
@ -940,7 +940,7 @@ static void LocalPlayer_DoRespawn(void) {
|
|||||||
if (World_IsValidPos_3I(pos)) {
|
if (World_IsValidPos_3I(pos)) {
|
||||||
AABB_Make(&bb, &spawn, &p->Base.Size);
|
AABB_Make(&bb, &spawn, &p->Base.Size);
|
||||||
for (y = pos.Y; y <= World_Height; y++) {
|
for (y = pos.Y; y <= World_Height; y++) {
|
||||||
spawnY = Respawn_HighestFreeY(&bb);
|
spawnY = Respawn_HighestSolidY(&bb);
|
||||||
|
|
||||||
if (spawnY == RESPAWN_NOT_FOUND) {
|
if (spawnY == RESPAWN_NOT_FOUND) {
|
||||||
block = World_GetPhysicsBlock(pos.X, y, pos.Z);
|
block = World_GetPhysicsBlock(pos.X, y, pos.Z);
|
||||||
|
15
src/Game.c
15
src/Game.c
@ -194,6 +194,7 @@ void Game_Disconnect(const String* title, const String* reason) {
|
|||||||
Event_RaiseVoid(&WorldEvents_NewMap);
|
Event_RaiseVoid(&WorldEvents_NewMap);
|
||||||
Gui_FreeActive();
|
Gui_FreeActive();
|
||||||
Gui_SetActive(DisconnectScreen_MakeInstance(title, reason));
|
Gui_SetActive(DisconnectScreen_MakeInstance(title, reason));
|
||||||
|
Game_Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game_Reset(void) {
|
void Game_Reset(void) {
|
||||||
@ -211,13 +212,13 @@ void Game_Reset(void) {
|
|||||||
void Game_UpdateBlock(int x, int y, int z, BlockID block) {
|
void Game_UpdateBlock(int x, int y, int z, BlockID block) {
|
||||||
struct ChunkInfo* chunk;
|
struct ChunkInfo* chunk;
|
||||||
int cx = x >> 4, cy = y >> 4, cz = z >> 4;
|
int cx = x >> 4, cy = y >> 4, cz = z >> 4;
|
||||||
BlockID oldBlock = World_GetBlock(x, y, z);
|
BlockID old = World_GetBlock(x, y, z);
|
||||||
World_SetBlock(x, y, z, block);
|
World_SetBlock(x, y, z, block);
|
||||||
|
|
||||||
if (Weather_Heightmap) {
|
if (Weather_Heightmap) {
|
||||||
EnvRenderer_OnBlockChanged(x, y, z, oldBlock, block);
|
EnvRenderer_OnBlockChanged(x, y, z, old, block);
|
||||||
}
|
}
|
||||||
Lighting_OnBlockChanged(x, y, z, oldBlock, block);
|
Lighting_OnBlockChanged(x, y, z, old, block);
|
||||||
|
|
||||||
/* Refresh the chunk the block was located in. */
|
/* Refresh the chunk the block was located in. */
|
||||||
chunk = MapRenderer_GetChunk(cx, cy, cz);
|
chunk = MapRenderer_GetChunk(cx, cy, cz);
|
||||||
@ -225,6 +226,12 @@ void Game_UpdateBlock(int x, int y, int z, BlockID block) {
|
|||||||
MapRenderer_RefreshChunk(cx, cy, cz);
|
MapRenderer_RefreshChunk(cx, cy, cz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Game_ChangeBlock(int x, int y, int z, BlockID block) {
|
||||||
|
BlockID old = World_GetBlock(x, y, z);
|
||||||
|
Game_UpdateBlock(x, y, z, block);
|
||||||
|
ServerConnection.SendBlock(x, y, z, old, block);
|
||||||
|
}
|
||||||
|
|
||||||
bool Game_CanPick(BlockID block) {
|
bool Game_CanPick(BlockID block) {
|
||||||
if (Block_Draw[block] == DRAW_GAS) return false;
|
if (Block_Draw[block] == DRAW_GAS) return false;
|
||||||
if (Block_Draw[block] == DRAW_SPRITE) return true;
|
if (Block_Draw[block] == DRAW_SPRITE) return true;
|
||||||
@ -526,7 +533,7 @@ void Game_Load(void) {
|
|||||||
|
|
||||||
Gui_FreeActive();
|
Gui_FreeActive();
|
||||||
Gui_SetActive(LoadingScreen_MakeInstance(&title, &String_Empty));
|
Gui_SetActive(LoadingScreen_MakeInstance(&title, &String_Empty));
|
||||||
ServerConnection_BeginConnect();
|
ServerConnection.BeginConnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game_SetFpsLimit(enum FpsLimit method) {
|
void Game_SetFpsLimit(enum FpsLimit method) {
|
||||||
|
@ -82,7 +82,12 @@ void Game_UserSetViewDistance(int distance);
|
|||||||
void Game_UpdateProjection(void);
|
void Game_UpdateProjection(void);
|
||||||
void Game_Disconnect(const String* title, const String* reason);
|
void Game_Disconnect(const String* title, const String* reason);
|
||||||
void Game_Reset(void);
|
void Game_Reset(void);
|
||||||
void Game_UpdateBlock(int x, int y, int z, BlockID block);
|
/* Sets the block in the map at the given coordinates, then updates state associated with the block. */
|
||||||
|
/* (updating state means recalculating light, redrawing chunk block is in, etc) */
|
||||||
|
/* NOTE: This does NOT notify the server, use Game_ChangeBlock for that. */
|
||||||
|
CC_EXPORT void Game_UpdateBlock(int x, int y, int z, BlockID block);
|
||||||
|
/* Calls Game_UpdateBlock, then sends the block change to the server. */
|
||||||
|
CC_EXPORT void Game_ChangeBlock(int x, int y, int z, BlockID block);
|
||||||
bool Game_CanPick(BlockID block);
|
bool Game_CanPick(BlockID block);
|
||||||
bool Game_UpdateTexture(GfxResourceID* texId, struct Stream* src, const String* file, uint8_t* skinType);
|
bool Game_UpdateTexture(GfxResourceID* texId, struct Stream* src, const String* file, uint8_t* skinType);
|
||||||
bool Game_ValidateBitmap(const String* file, Bitmap* bmp);
|
bool Game_ValidateBitmap(const String* file, Bitmap* bmp);
|
||||||
|
@ -44,7 +44,7 @@ static void InputHandler_ButtonStateUpdate(MouseButton button, bool pressed) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input_buttonsDown[button] = pressed;
|
input_buttonsDown[button] = pressed;
|
||||||
ServerConnection_SendPlayerClick(button, pressed,
|
ServerConnection.SendPlayerClick(button, pressed,
|
||||||
(EntityID)input_pickingId, &Game_SelectedPos);
|
(EntityID)input_pickingId, &Game_SelectedPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,7 +347,7 @@ void InputHandler_PickBlocks(bool cooldown, bool left, bool middle, bool right)
|
|||||||
old = World_GetBlock(p.X, p.Y, p.Z);
|
old = World_GetBlock(p.X, p.Y, p.Z);
|
||||||
if (Block_Draw[old] == DRAW_GAS || !Block_CanDelete[old]) return;
|
if (Block_Draw[old] == DRAW_GAS || !Block_CanDelete[old]) return;
|
||||||
|
|
||||||
Game_UpdateBlock(p.X, p.Y, p.Z, BLOCK_AIR);
|
Game_ChangeBlock(p.X, p.Y, p.Z, BLOCK_AIR);
|
||||||
Event_RaiseBlock(&UserEvents_BlockChanged, p, old, BLOCK_AIR);
|
Event_RaiseBlock(&UserEvents_BlockChanged, p, old, BLOCK_AIR);
|
||||||
} else if (right) {
|
} else if (right) {
|
||||||
p = Game_SelectedPos.TranslatedPos;
|
p = Game_SelectedPos.TranslatedPos;
|
||||||
@ -362,7 +362,7 @@ void InputHandler_PickBlocks(bool cooldown, bool left, bool middle, bool right)
|
|||||||
if (Block_Draw[block] == DRAW_GAS && Block_Draw[old] != DRAW_GAS) return;
|
if (Block_Draw[block] == DRAW_GAS && Block_Draw[old] != DRAW_GAS) return;
|
||||||
if (!InputHandler_CheckIsFree(block)) return;
|
if (!InputHandler_CheckIsFree(block)) return;
|
||||||
|
|
||||||
Game_UpdateBlock(p.X, p.Y, p.Z, block);
|
Game_ChangeBlock(p.X, p.Y, p.Z, block);
|
||||||
Event_RaiseBlock(&UserEvents_BlockChanged, p, old, block);
|
Event_RaiseBlock(&UserEvents_BlockChanged, p, old, block);
|
||||||
} else if (middle) {
|
} else if (middle) {
|
||||||
p = Game_SelectedPos.BlockPos;
|
p = Game_SelectedPos.BlockPos;
|
||||||
|
@ -106,8 +106,6 @@ extern GfxResourceID Model_Vb;
|
|||||||
extern VertexP3fT2fC4b Model_Vertices[MODEL_MAX_VERTICES];
|
extern VertexP3fT2fC4b Model_Vertices[MODEL_MAX_VERTICES];
|
||||||
extern struct Model* Human_ModelPtr;
|
extern struct Model* Human_ModelPtr;
|
||||||
|
|
||||||
void Models_Init(void);
|
|
||||||
void Models_Free(void);
|
|
||||||
/* Returns pointer to model whose name caselessly matches given name. */
|
/* Returns pointer to model whose name caselessly matches given name. */
|
||||||
CC_EXPORT struct Model* Model_Get(const String* name);
|
CC_EXPORT struct Model* Model_Get(const String* name);
|
||||||
/* Returns index of cached texture whose name caselessly matches given name. */
|
/* Returns index of cached texture whose name caselessly matches given name. */
|
||||||
|
@ -1521,7 +1521,7 @@ static bool DisconnectScreen_MouseDown(void* screen, int x, int y, MouseButton b
|
|||||||
|
|
||||||
Gui_FreeActive();
|
Gui_FreeActive();
|
||||||
Gui_SetActive(LoadingScreen_MakeInstance(&title, &String_Empty));
|
Gui_SetActive(LoadingScreen_MakeInstance(&title, &String_Empty));
|
||||||
ServerConnection_BeginConnect();
|
ServerConnection.BeginConnect();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -28,17 +28,12 @@ static char server_motdBuffer[STRING_SIZE];
|
|||||||
static char server_appBuffer[STRING_SIZE];
|
static char server_appBuffer[STRING_SIZE];
|
||||||
static int server_ticks;
|
static int server_ticks;
|
||||||
|
|
||||||
|
struct ServerConnectionFuncs ServerConnection;
|
||||||
bool ServerConnection_IsSinglePlayer, ServerConnection_Disconnected;
|
bool ServerConnection_IsSinglePlayer, ServerConnection_Disconnected;
|
||||||
String ServerConnection_ServerName = String_FromArray(server_nameBuffer);
|
String ServerConnection_ServerName = String_FromArray(server_nameBuffer);
|
||||||
String ServerConnection_ServerMOTD = String_FromArray(server_motdBuffer);
|
String ServerConnection_ServerMOTD = String_FromArray(server_motdBuffer);
|
||||||
String ServerConnection_AppName = String_FromArray(server_appBuffer);
|
String ServerConnection_AppName = String_FromArray(server_appBuffer);
|
||||||
|
|
||||||
void (*ServerConnection_BeginConnect)(void);
|
|
||||||
void (*ServerConnection_SendChat)(const String* text);
|
|
||||||
void (*ServerConnection_SendPosition)(Vector3 pos, float rotY, float headX);
|
|
||||||
void (*ServerConnection_SendPlayerClick)(MouseButton button, bool isDown, EntityID targetId, struct PickedPos* pos);
|
|
||||||
void (*ServerConnection_Tick)(struct ScheduledTask* task);
|
|
||||||
|
|
||||||
uint8_t* ServerConnection_WriteBuffer;
|
uint8_t* ServerConnection_WriteBuffer;
|
||||||
bool ServerConnection_SupportsExtPlayerList, ServerConnection_SupportsPlayerClick;
|
bool ServerConnection_SupportsExtPlayerList, ServerConnection_SupportsPlayerClick;
|
||||||
bool ServerConnection_SupportsPartialMessages, ServerConnection_SupportsFullCP437;
|
bool ServerConnection_SupportsPartialMessages, ServerConnection_SupportsFullCP437;
|
||||||
@ -205,6 +200,10 @@ static void SPConnection_AddPart(const String* text) {
|
|||||||
Chat_Add(&tmp);
|
Chat_Add(&tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SPConnection_SendBlock(int x, int y, int z, BlockID old, BlockID now) {
|
||||||
|
Physics_OnBlockChanged(x, y, z, old, now);
|
||||||
|
}
|
||||||
|
|
||||||
static void SPConnection_SendChat(const String* text) {
|
static void SPConnection_SendChat(const String* text) {
|
||||||
String left, part;
|
String left, part;
|
||||||
if (!text->length) return;
|
if (!text->length) return;
|
||||||
@ -232,19 +231,21 @@ static void SPConnection_Tick(struct ScheduledTask* task) {
|
|||||||
server_ticks++;
|
server_ticks++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct ServerConnectionFuncs SPConnection = {
|
||||||
|
SPConnection_BeginConnect, SPConnection_Tick,
|
||||||
|
SPConnection_SendBlock, SPConnection_SendChat,
|
||||||
|
SPConnection_SendPosition, SPConnection_SendPlayerClick
|
||||||
|
};
|
||||||
|
|
||||||
static void SPConnection_Init(void) {
|
static void SPConnection_Init(void) {
|
||||||
ServerConnection_ResetState();
|
ServerConnection_ResetState();
|
||||||
Physics_Init();
|
Physics_Init();
|
||||||
|
|
||||||
ServerConnection_SupportsFullCP437 = !Game_ClassicMode;
|
ServerConnection_SupportsFullCP437 = !Game_ClassicMode;
|
||||||
ServerConnection_SupportsPartialMessages = true;
|
ServerConnection_SupportsPartialMessages = true;
|
||||||
ServerConnection_IsSinglePlayer = true;
|
ServerConnection_IsSinglePlayer = true;
|
||||||
|
|
||||||
ServerConnection_BeginConnect = SPConnection_BeginConnect;
|
ServerConnection = SPConnection;
|
||||||
ServerConnection_SendChat = SPConnection_SendChat;
|
|
||||||
ServerConnection_SendPosition = SPConnection_SendPosition;
|
|
||||||
ServerConnection_SendPlayerClick = SPConnection_SendPlayerClick;
|
|
||||||
ServerConnection_Tick = SPConnection_Tick;
|
|
||||||
|
|
||||||
ServerConnection_WriteBuffer = NULL;
|
ServerConnection_WriteBuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,16 +270,6 @@ static bool net_connecting;
|
|||||||
static TimeMS net_connectTimeout;
|
static TimeMS net_connectTimeout;
|
||||||
#define NET_TIMEOUT_MS (15 * 1000)
|
#define NET_TIMEOUT_MS (15 * 1000)
|
||||||
|
|
||||||
static void MPConnection_BlockChanged(void* obj, Vector3I p, BlockID old, BlockID now) {
|
|
||||||
if (now == BLOCK_AIR) {
|
|
||||||
now = Inventory_SelectedBlock;
|
|
||||||
Classic_WriteSetBlock(p.X, p.Y, p.Z, false, now);
|
|
||||||
} else {
|
|
||||||
Classic_WriteSetBlock(p.X, p.Y, p.Z, true, now);
|
|
||||||
}
|
|
||||||
Net_SendPacket();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ServerConnection_Free(void);
|
static void ServerConnection_Free(void);
|
||||||
static void MPConnection_FinishConnect(void) {
|
static void MPConnection_FinishConnect(void) {
|
||||||
net_connecting = false;
|
net_connecting = false;
|
||||||
@ -334,7 +325,6 @@ static void MPConnection_TickConnect(void) {
|
|||||||
|
|
||||||
static void MPConnection_BeginConnect(void) {
|
static void MPConnection_BeginConnect(void) {
|
||||||
ReturnCode res;
|
ReturnCode res;
|
||||||
Event_RegisterBlock(&UserEvents_BlockChanged, NULL, MPConnection_BlockChanged);
|
|
||||||
Socket_Create(&net_socket);
|
Socket_Create(&net_socket);
|
||||||
ServerConnection_Disconnected = false;
|
ServerConnection_Disconnected = false;
|
||||||
|
|
||||||
@ -348,6 +338,16 @@ static void MPConnection_BeginConnect(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void MPConnection_SendBlock(int x, int y, int z, BlockID old, BlockID now) {
|
||||||
|
if (now == BLOCK_AIR) {
|
||||||
|
now = Inventory_SelectedBlock;
|
||||||
|
Classic_WriteSetBlock(x, y, z, false, now);
|
||||||
|
} else {
|
||||||
|
Classic_WriteSetBlock(x, y, z, true, now);
|
||||||
|
}
|
||||||
|
Net_SendPacket();
|
||||||
|
}
|
||||||
|
|
||||||
static void MPConnection_SendChat(const String* text) {
|
static void MPConnection_SendChat(const String* text) {
|
||||||
String left, part;
|
String left, part;
|
||||||
if (!text->length || net_connecting) return;
|
if (!text->length || net_connecting) return;
|
||||||
@ -514,17 +514,18 @@ void Net_SendPacket(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct ServerConnectionFuncs MPConnection = {
|
||||||
|
MPConnection_BeginConnect, MPConnection_Tick,
|
||||||
|
MPConnection_SendBlock, MPConnection_SendChat,
|
||||||
|
MPConnection_SendPosition, MPConnection_SendPlayerClick
|
||||||
|
};
|
||||||
|
|
||||||
static void MPConnection_Init(void) {
|
static void MPConnection_Init(void) {
|
||||||
ServerConnection_ResetState();
|
ServerConnection_ResetState();
|
||||||
ServerConnection_IsSinglePlayer = false;
|
ServerConnection_IsSinglePlayer = false;
|
||||||
|
|
||||||
ServerConnection_BeginConnect = MPConnection_BeginConnect;
|
ServerConnection = MPConnection;
|
||||||
ServerConnection_SendChat = MPConnection_SendChat;
|
net_readCurrent = net_readBuffer;
|
||||||
ServerConnection_SendPosition = MPConnection_SendPosition;
|
|
||||||
ServerConnection_SendPlayerClick = MPConnection_SendPlayerClick;
|
|
||||||
ServerConnection_Tick = MPConnection_Tick;
|
|
||||||
|
|
||||||
net_readCurrent = net_readBuffer;
|
|
||||||
ServerConnection_WriteBuffer = net_writeBuffer;
|
ServerConnection_WriteBuffer = net_writeBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,8 +562,8 @@ static void ServerConnection_Init(void) {
|
|||||||
MPConnection_Init();
|
MPConnection_Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx_LostContextFunction = ServerConnection_Tick;
|
Gfx_LostContextFunction = ServerConnection.Tick;
|
||||||
ScheduledTask_Add(GAME_NET_TICKS, ServerConnection_Tick);
|
ScheduledTask_Add(GAME_NET_TICKS, ServerConnection.Tick);
|
||||||
String_AppendConst(&ServerConnection_AppName, PROGRAM_APP_NAME);
|
String_AppendConst(&ServerConnection_AppName, PROGRAM_APP_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,7 +572,6 @@ static void ServerConnection_Free(void) {
|
|||||||
Physics_Free();
|
Physics_Free();
|
||||||
} else {
|
} else {
|
||||||
if (ServerConnection_Disconnected) return;
|
if (ServerConnection_Disconnected) return;
|
||||||
Event_UnregisterBlock(&UserEvents_BlockChanged, NULL, MPConnection_BlockChanged);
|
|
||||||
Socket_Close(net_socket);
|
Socket_Close(net_socket);
|
||||||
ServerConnection_Disconnected = true;
|
ServerConnection_Disconnected = true;
|
||||||
}
|
}
|
||||||
|
@ -46,22 +46,45 @@ int PingList_NextPingData(void);
|
|||||||
void PingList_Update(int data);
|
void PingList_Update(int data);
|
||||||
int PingList_AveragePingMs(void);
|
int PingList_AveragePingMs(void);
|
||||||
|
|
||||||
|
/* Whether the player is connected to singleplayer/loopback server. */
|
||||||
extern bool ServerConnection_IsSinglePlayer;
|
extern bool ServerConnection_IsSinglePlayer;
|
||||||
|
/* Whether the player has been disconnected from the server. */
|
||||||
extern bool ServerConnection_Disconnected;
|
extern bool ServerConnection_Disconnected;
|
||||||
|
/* The current name of the server. (Shows as first line when loading) */
|
||||||
extern String ServerConnection_ServerName;
|
extern String ServerConnection_ServerName;
|
||||||
|
/* The current MOTD of the server. (Shows as second line when loading) */
|
||||||
extern String ServerConnection_ServerMOTD;
|
extern String ServerConnection_ServerMOTD;
|
||||||
|
/* The software name the client identifies itself as being to the server. */
|
||||||
|
/* By default this is the same as PROGRAM_APP_NAME */
|
||||||
extern String ServerConnection_AppName;
|
extern String ServerConnection_AppName;
|
||||||
|
|
||||||
extern void (*ServerConnection_BeginConnect)(void);
|
struct ServerConnectionFuncs {
|
||||||
extern void (*ServerConnection_SendChat)(const String* text);
|
/* Begins connecting to the server. */
|
||||||
extern void (*ServerConnection_SendPosition)(Vector3 pos, float rotY, float headX);
|
/* NOTE: Usually asynchronous, but not always. */
|
||||||
extern void (*ServerConnection_SendPlayerClick)(MouseButton button, bool isDown, EntityID targetId, struct PickedPos* pos);
|
void (*BeginConnect)(void);
|
||||||
extern void (*ServerConnection_Tick)(struct ScheduledTask* task);
|
/* Ticks state of the server. */
|
||||||
|
void (*Tick)(struct ScheduledTask* task);
|
||||||
|
/* Sends a block update to the server. */
|
||||||
|
void (*SendBlock)(int x, int y, int z, BlockID old, BlockID now);
|
||||||
|
/* Sends a chat message to the server. */
|
||||||
|
void (*SendChat)(const String* text);
|
||||||
|
/* Sends a position update to the server. */
|
||||||
|
void (*SendPosition)(Vector3 pos, float rotY, float headX);
|
||||||
|
/* Sends a PlayerClick packet to the server. */
|
||||||
|
void (*SendPlayerClick)(MouseButton button, bool isDown, EntityID targetId, struct PickedPos* pos);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Currently active connection to a server. */
|
||||||
|
extern struct ServerConnectionFuncs ServerConnection;
|
||||||
extern uint8_t* ServerConnection_WriteBuffer;
|
extern uint8_t* ServerConnection_WriteBuffer;
|
||||||
|
|
||||||
|
/* Whether the server supports separate tab list from entities in world. */
|
||||||
extern bool ServerConnection_SupportsExtPlayerList;
|
extern bool ServerConnection_SupportsExtPlayerList;
|
||||||
|
/* Whether the server supports packet with detailed info on mouse clicks. */
|
||||||
extern bool ServerConnection_SupportsPlayerClick;
|
extern bool ServerConnection_SupportsPlayerClick;
|
||||||
|
/* Whether the server supports combining multiple chat packets into one. */
|
||||||
extern bool ServerConnection_SupportsPartialMessages;
|
extern bool ServerConnection_SupportsPartialMessages;
|
||||||
|
/* Whether the server supports all of code page 437, not just ASCII. */
|
||||||
extern bool ServerConnection_SupportsFullCP437;
|
extern bool ServerConnection_SupportsFullCP437;
|
||||||
|
|
||||||
void ServerConnection_RetrieveTexturePack(const String* url);
|
void ServerConnection_RetrieveTexturePack(const String* url);
|
||||||
|
10
src/World.c
10
src/World.c
@ -253,11 +253,11 @@ void Env_SetShadowCol(PackedCol col) {
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*-------------------------------------------------------Respawning--------------------------------------------------------*
|
*-------------------------------------------------------Respawning--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
float Respawn_HighestFreeY(struct AABB* bb) {
|
float Respawn_HighestSolidY(struct AABB* bb) {
|
||||||
int minX = Math_Floor(bb->Min.X), maxX = Math_Floor(bb->Max.X);
|
int minX = Math_Floor(bb->Min.X), maxX = Math_Floor(bb->Max.X);
|
||||||
int minY = Math_Floor(bb->Min.Y), maxY = Math_Floor(bb->Max.Y);
|
int minY = Math_Floor(bb->Min.Y), maxY = Math_Floor(bb->Max.Y);
|
||||||
int minZ = Math_Floor(bb->Min.Z), maxZ = Math_Floor(bb->Max.Z);
|
int minZ = Math_Floor(bb->Min.Z), maxZ = Math_Floor(bb->Max.Z);
|
||||||
float spawnY = RESPAWN_NOT_FOUND;
|
float highestY = RESPAWN_NOT_FOUND;
|
||||||
|
|
||||||
BlockID block;
|
BlockID block;
|
||||||
struct AABB blockBB;
|
struct AABB blockBB;
|
||||||
@ -274,11 +274,11 @@ float Respawn_HighestFreeY(struct AABB* bb) {
|
|||||||
|
|
||||||
if (Block_Collide[block] != COLLIDE_SOLID) continue;
|
if (Block_Collide[block] != COLLIDE_SOLID) continue;
|
||||||
if (!AABB_Intersects(bb, &blockBB)) continue;
|
if (!AABB_Intersects(bb, &blockBB)) continue;
|
||||||
if (blockBB.Max.Y > spawnY) spawnY = blockBB.Max.Y;
|
if (blockBB.Max.Y > highestY) highestY = blockBB.Max.Y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return spawnY;
|
return highestY;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Respawn_FindSpawnPosition(float x, float z, Vector3 modelSize) {
|
Vector3 Respawn_FindSpawnPosition(float x, float z, Vector3 modelSize) {
|
||||||
@ -292,7 +292,7 @@ Vector3 Respawn_FindSpawnPosition(float x, float z, Vector3 modelSize) {
|
|||||||
spawn.Y = 0.0f;
|
spawn.Y = 0.0f;
|
||||||
|
|
||||||
for (y = World_Height; y >= 0; y--) {
|
for (y = World_Height; y >= 0; y--) {
|
||||||
highestY = Respawn_HighestFreeY(&bb);
|
highestY = Respawn_HighestSolidY(&bb);
|
||||||
if (highestY != RESPAWN_NOT_FOUND) {
|
if (highestY != RESPAWN_NOT_FOUND) {
|
||||||
spawn.Y = highestY; break;
|
spawn.Y = highestY; break;
|
||||||
}
|
}
|
||||||
|
10
src/World.h
10
src/World.h
@ -129,9 +129,11 @@ CC_EXPORT void Env_SetSunCol(PackedCol col);
|
|||||||
CC_EXPORT void Env_SetShadowCol(PackedCol col);
|
CC_EXPORT void Env_SetShadowCol(PackedCol col);
|
||||||
|
|
||||||
#define RESPAWN_NOT_FOUND -100000.0f
|
#define RESPAWN_NOT_FOUND -100000.0f
|
||||||
/* Finds the highest free Y coordinate in the given bounding box */
|
/* Finds the highest Y coordinate of any solid block that intersects the given bounding box */
|
||||||
float Respawn_HighestFreeY(struct AABB* bb);
|
/* So essentially, means max(Y + Block_MaxBB[block].Y) over all solid blocks the AABB touches */
|
||||||
/* Finds a suitable spawn position for the entity. */
|
/* Returns RESPAWN_NOT_FOUND when no intersecting solid blocks are found. */
|
||||||
/* Works by iterating downwards from top of world until ground is found. */
|
float Respawn_HighestSolidY(struct AABB* bb);
|
||||||
|
/* Finds a suitable initial spawn position for the entity. */
|
||||||
|
/* Works by iterating downwards from top of world until solid ground is found. */
|
||||||
Vector3 Respawn_FindSpawnPosition(float x, float z, Vector3 modelSize);
|
Vector3 Respawn_FindSpawnPosition(float x, float z, Vector3 modelSize);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user