Remove internal server cuz we have it in the networking branch.
Minor refactoring (changed all Chunk* world or Chunk world[] to World world)
This commit is contained in:
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
#/usr/bin/bash
|
#/usr/bin/bash
|
||||||
|
|
||||||
./makeheaders/makeheaders -h src/helpers/vars.hpp src/helpers/chunks.cpp src/helpers/debug.cpp src/helpers/entities.cpp src/helpers/input.cpp src/helpers/menu.cpp src/helpers/mesher.cpp src/helpers/networking.cpp src/helpers/utils.cpp src/helpers/inlines.hpp src/helpers/inventory.cpp src/helpers/locale.cpp src/helpers/recipes.cpp src/helpers/particles.cpp src/helpers/player.cpp src/helpers/multisound.cpp src/helpers/svlib.cpp -v > tmp.hpp
|
./makeheaders/makeheaders -h src/helpers/vars.hpp src/helpers/chunks.cpp src/helpers/debug.cpp src/helpers/entities.cpp src/helpers/input.cpp src/helpers/menu.cpp src/helpers/mesher.cpp src/helpers/networking.cpp src/helpers/utils.cpp src/helpers/inlines.hpp src/helpers/inventory.cpp src/helpers/locale.cpp src/helpers/recipes.cpp src/helpers/particles.cpp src/helpers/player.cpp src/helpers/multisound.cpp -v > tmp.hpp
|
||||||
cat additions.hpp tmp.hpp > src/helpers/common.hpp
|
cat additions.hpp tmp.hpp > src/helpers/common.hpp
|
||||||
rm tmp.hpp
|
rm tmp.hpp
|
||||||
|
|
||||||
echo Building x86-64 Linux...
|
echo Building x86-64 Linux...
|
||||||
rm -rf build
|
rm -rf build
|
||||||
cmake -B build -DUNIX=ON -DUNIX=true
|
cmake -B build -DUNIX=ON -DUNIX=true -DCMAKE_BUILD_TYPE=Debug
|
||||||
cd build
|
cd build
|
||||||
make -j12
|
make -j12
|
||||||
cd ..
|
cd ..
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ add_subdirectory(helpers)
|
|||||||
|
|
||||||
set(YAML_BUILD_SHARED_LIBS OFF)
|
set(YAML_BUILD_SHARED_LIBS OFF)
|
||||||
set(YAML_MSVC_SHARED_RT OFF)
|
set(YAML_MSVC_SHARED_RT OFF)
|
||||||
set(OPENGL_VERSION 1.1)
|
set(OPENGL_VERSION 2.1)
|
||||||
|
|
||||||
add_subdirectory(libraries/raylib)
|
add_subdirectory(libraries/raylib)
|
||||||
add_subdirectory(libraries/enet)
|
add_subdirectory(libraries/enet)
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ add_library(helpers STATIC
|
|||||||
particles.cpp
|
particles.cpp
|
||||||
player.cpp
|
player.cpp
|
||||||
multisound.cpp
|
multisound.cpp
|
||||||
svlib.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
@@ -24,6 +23,7 @@ if (WIN32)
|
|||||||
target_link_libraries(helpers INTERFACE winmm ws2_32)
|
target_link_libraries(helpers INTERFACE winmm ws2_32)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_compile_options(-Wno-narrowing)
|
||||||
execute_process(COMMAND date +v.%yw%W OUTPUT_VARIABLE BUILD_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
execute_process(COMMAND date +v.%yw%W OUTPUT_VARIABLE BUILD_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
add_compile_definitions(GAME_VERSION="${BUILD_DATE}")
|
add_compile_definitions(GAME_VERSION="${BUILD_DATE}")
|
||||||
|
|
||||||
|
|||||||
+32
-27
@@ -99,6 +99,14 @@ static int GetBlockRegularWorld(int x, int y, int z) {
|
|||||||
|
|
||||||
return BLOCK_AIR;
|
return BLOCK_AIR;
|
||||||
}
|
}
|
||||||
|
int GetBlock(World &world, int x, int y, int z) {
|
||||||
|
if(CheckOOBWorld(x, y, z)) return 0;
|
||||||
|
int locX = x % CHUNK_SIZE;
|
||||||
|
int locZ = z % CHUNK_SIZE;
|
||||||
|
int cx = x / CHUNK_SIZE;
|
||||||
|
int cz = z / CHUNK_SIZE;
|
||||||
|
return fetch_block(world.chunks[GetIndexWorld(cx, cz)], locX, y, locZ);
|
||||||
|
}
|
||||||
bool CanTick(int blockType) { // TODO: make smarter in case other blocks can tick too!
|
bool CanTick(int blockType) { // TODO: make smarter in case other blocks can tick too!
|
||||||
return blockType == BLOCK_SAND;
|
return blockType == BLOCK_SAND;
|
||||||
}
|
}
|
||||||
@@ -174,15 +182,15 @@ void SetBlockChunk(Chunk *c, int x, int y, int z, int t) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void RebuildHeightmap(Chunk *c) {
|
void RebuildHeightmap(Chunk &c) {
|
||||||
for (int x = 0; x < CHUNK_SIZE; x++)
|
for (int x = 0; x < CHUNK_SIZE; x++)
|
||||||
{
|
{
|
||||||
for (int z = 0; z < CHUNK_SIZE; z++)
|
for (int z = 0; z < CHUNK_SIZE; z++)
|
||||||
{
|
{
|
||||||
for (int y = WORLD_HEIGHT-1; y >= 0; y--)
|
for (int y = WORLD_HEIGHT-1; y >= 0; y--)
|
||||||
{
|
{
|
||||||
if(c->blocks[GetIndexChunk(x,y,z)] != 0) {
|
if(c.blocks[GetIndexChunk(x,y,z)] != 0) {
|
||||||
c->highestBlock[GetIndexChunk2D(x, z)] = y;
|
c.highestBlock[GetIndexChunk2D(x, z)] = y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,13 +203,13 @@ int GetBiome(int sx, int sy) {
|
|||||||
void SetBlockChunkFast(Chunk *c, int i, int t) {
|
void SetBlockChunkFast(Chunk *c, int i, int t) {
|
||||||
c->blocks[i] = t;
|
c->blocks[i] = t;
|
||||||
}
|
}
|
||||||
void SetBlock(Chunk world[], int x, int y, int z, int t) {
|
void SetBlock(World &world, int x, int y, int z, int t) {
|
||||||
if(CheckOOBWorld(x, y, z)) { return; }
|
if(CheckOOBWorld(x, y, z)) { return; }
|
||||||
int locX = x % CHUNK_SIZE;
|
int locX = x % CHUNK_SIZE;
|
||||||
int locZ = z % CHUNK_SIZE;
|
int locZ = z % CHUNK_SIZE;
|
||||||
int cx = x / CHUNK_SIZE;
|
int cx = x / CHUNK_SIZE;
|
||||||
int cz = z / CHUNK_SIZE;
|
int cz = z / CHUNK_SIZE;
|
||||||
SetBlockChunk(&world[GetIndexWorld(cx, cz)], locX, y, locZ, t);
|
SetBlockChunk(&world.chunks[GetIndexWorld(cx, cz)], locX, y, locZ, t);
|
||||||
}
|
}
|
||||||
void InitWorldgen(int worldType) {
|
void InitWorldgen(int worldType) {
|
||||||
const siv::PerlinNoise::seed_type seed = 123456u;
|
const siv::PerlinNoise::seed_type seed = 123456u;
|
||||||
@@ -238,7 +246,7 @@ Chunk GenerateChunk(int _x, int _y) {
|
|||||||
}
|
}
|
||||||
return new_chunk;
|
return new_chunk;
|
||||||
}
|
}
|
||||||
void GenerateWorldAdditional(Chunk world[]) {
|
void GenerateWorldAdditional(World &world) {
|
||||||
int biome = GetBiome(0, 0);
|
int biome = GetBiome(0, 0);
|
||||||
SetRandomSeed(0);
|
SetRandomSeed(0);
|
||||||
switch (world_type)
|
switch (world_type)
|
||||||
@@ -247,7 +255,7 @@ void GenerateWorldAdditional(Chunk world[]) {
|
|||||||
for (int x = 0; x < WORLD_SIZE_BLOCKS; x++)
|
for (int x = 0; x < WORLD_SIZE_BLOCKS; x++)
|
||||||
{
|
{
|
||||||
for (int z = 0; z < WORLD_SIZE_BLOCKS; z++) {
|
for (int z = 0; z < WORLD_SIZE_BLOCKS; z++) {
|
||||||
Chunk c = world[GetIndexWorld(x / CHUNK_SIZE, z / CHUNK_SIZE)];
|
Chunk c = world.chunks[GetIndexWorld(x / CHUNK_SIZE, z / CHUNK_SIZE)];
|
||||||
int highestY = c.highestBlock[GetIndexChunk2D(x % CHUNK_SIZE, z % CHUNK_SIZE)];
|
int highestY = c.highestBlock[GetIndexChunk2D(x % CHUNK_SIZE, z % CHUNK_SIZE)];
|
||||||
int b = fetch_block(c, x % CHUNK_SIZE, highestY, z % CHUNK_SIZE);
|
int b = fetch_block(c, x % CHUNK_SIZE, highestY, z % CHUNK_SIZE);
|
||||||
for (int _ = 0; _ < GetRandomValue(0, 6); _++)
|
for (int _ = 0; _ < GetRandomValue(0, 6); _++)
|
||||||
@@ -314,7 +322,7 @@ void GenerateWorldAdditional(Chunk world[]) {
|
|||||||
for (int x = 0; x < WORLD_SIZE_BLOCKS; x++)
|
for (int x = 0; x < WORLD_SIZE_BLOCKS; x++)
|
||||||
{
|
{
|
||||||
for (int z = 0; z < WORLD_SIZE_BLOCKS; z++) {
|
for (int z = 0; z < WORLD_SIZE_BLOCKS; z++) {
|
||||||
Chunk c = world[GetIndexWorld(x / CHUNK_SIZE, z / CHUNK_SIZE)];
|
Chunk c = world.chunks[GetIndexWorld(x / CHUNK_SIZE, z / CHUNK_SIZE)];
|
||||||
int highestY = c.highestBlock[GetIndexChunk2D(x % CHUNK_SIZE, z % CHUNK_SIZE)];
|
int highestY = c.highestBlock[GetIndexChunk2D(x % CHUNK_SIZE, z % CHUNK_SIZE)];
|
||||||
int b = fetch_block(c, x % CHUNK_SIZE, highestY, z % CHUNK_SIZE);
|
int b = fetch_block(c, x % CHUNK_SIZE, highestY, z % CHUNK_SIZE);
|
||||||
if(b == BLOCK_GRASS && GetRandomValue(0, 100) < 4 && biome == BIOME_FOREST) { // Regular trees
|
if(b == BLOCK_GRASS && GetRandomValue(0, 100) < 4 && biome == BIOME_FOREST) { // Regular trees
|
||||||
@@ -421,7 +429,7 @@ void GenerateWorldAdditional(Chunk world[]) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void TickBlock(Chunk world[], int wx, int wy, int wz) {
|
void TickBlock(World &world, int wx, int wy, int wz) {
|
||||||
if(CheckOOBWorld(wx, wy, wz)) return;
|
if(CheckOOBWorld(wx, wy, wz)) return;
|
||||||
int tile = GetBlock(world, wx, wy, wz);
|
int tile = GetBlock(world, wx, wy, wz);
|
||||||
if(tile == BLOCK_SAND) {
|
if(tile == BLOCK_SAND) {
|
||||||
@@ -436,7 +444,7 @@ void TickBlock(Chunk world[], int wx, int wy, int wz) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void TickChunk(Chunk *chunk, Chunk *world, int wx, int wz) {
|
void TickChunk(Chunk *chunk, World &world, int wx, int wz) {
|
||||||
for (int y = WORLD_HEIGHT-1; y > 1; y--) {
|
for (int y = WORLD_HEIGHT-1; y > 1; y--) {
|
||||||
for (int x = 0; x < CHUNK_SIZE; x++)
|
for (int x = 0; x < CHUNK_SIZE; x++)
|
||||||
{
|
{
|
||||||
@@ -472,36 +480,35 @@ void TickChunk(Chunk *chunk, Chunk *world, int wx, int wz) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void RebuildOpaqueMask(Chunk *chunk) {
|
void RebuildOpaqueMask(Chunk &chunk) {
|
||||||
const int GROUP = 16;
|
const int GROUP = 16;
|
||||||
const int GROUPS = CHUNK_DATA_SIZE / GROUP;
|
const int GROUPS = CHUNK_DATA_SIZE / GROUP;
|
||||||
|
|
||||||
uint16_t oMask[GROUPS] = { 0 };
|
uint16_t oMask[GROUPS] = { 0 };
|
||||||
uint16_t aMask[GROUPS] = { 0 };
|
uint16_t aMask[GROUPS] = { 0 };
|
||||||
uint8_t blocks[CHUNK_DATA_SIZE];
|
uint8_t blocks[CHUNK_DATA_SIZE];
|
||||||
memcpy(blocks, chunk->blocks, sizeof(blocks));
|
memcpy(blocks, chunk.blocks, sizeof(blocks));
|
||||||
|
|
||||||
for (int i = 0; i < CHUNK_DATA_SIZE; ++i) {
|
for (int i = 0; i < CHUNK_DATA_SIZE; ++i) {
|
||||||
int g = i / GROUP;
|
int g = i / GROUP;
|
||||||
int bit = i % GROUP;
|
int bit = i % GROUP;
|
||||||
if (chunk->blocks[i] == 0) {
|
if (chunk.blocks[i] == 0) {
|
||||||
aMask[g] |= 1 << bit;
|
aMask[g] |= 1 << bit;
|
||||||
}
|
}
|
||||||
if (!IsTranslucent(chunk->blocks[i])) {
|
if (!IsTranslucent(chunk.blocks[i])) {
|
||||||
oMask[g] |= 1 << bit;
|
oMask[g] |= 1 << bit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(chunk->opaqueMask, oMask, sizeof(oMask));
|
memcpy(chunk.opaqueMask, oMask, sizeof(oMask));
|
||||||
memcpy(chunk->airMask, aMask, sizeof(aMask));
|
memcpy(chunk.airMask, aMask, sizeof(aMask));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
//Generates an opaque CRD (ChunkRenderData). Outputs the CRD.
|
//Generates an opaque CRD (ChunkRenderData). Outputs the CRD.
|
||||||
ChunkRenderData GenerateCRDOpaque(const Chunk &chunk, Chunk world[]) {
|
ChunkRenderData GenerateCRDOpaque(Chunk &chunk, World &world) {
|
||||||
struct ChunkRenderData new_chunk = { 0 };
|
struct ChunkRenderData new_chunk = { 0 };
|
||||||
uint16_t mask[CHUNK_DATA_SIZE/16];
|
uint16_t *mask = chunk.opaqueMask;
|
||||||
memcpy(mask, chunk.opaqueMask, sizeof(chunk.opaqueMask));
|
|
||||||
|
|
||||||
const int cxw = chunk.x * CHUNK_SIZE;
|
const int cxw = chunk.x * CHUNK_SIZE;
|
||||||
const int cxz = chunk.z * CHUNK_SIZE;
|
const int cxz = chunk.z * CHUNK_SIZE;
|
||||||
@@ -517,8 +524,6 @@ ChunkRenderData GenerateCRDOpaque(const Chunk &chunk, Chunk world[]) {
|
|||||||
int _x = bit;
|
int _x = bit;
|
||||||
int y = step >> 4;
|
int y = step >> 4;
|
||||||
int _z = step & 0xF;
|
int _z = step & 0xF;
|
||||||
//int _x, y, _z;
|
|
||||||
//GetXYZFromIndex(i2, &_x, &y, &_z);
|
|
||||||
if (!TestMask(mask, i2)) continue; // Skip if this is translucent
|
if (!TestMask(mask, i2)) continue; // Skip if this is translucent
|
||||||
|
|
||||||
int x = _x + cxw;
|
int x = _x + cxw;
|
||||||
@@ -544,7 +549,7 @@ ChunkRenderData GenerateCRDOpaque(const Chunk &chunk, Chunk world[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Generates a translucent CRD (ChunkRenderData). Outputs the CRD.
|
//Generates a translucent CRD (ChunkRenderData). Outputs the CRD.
|
||||||
ChunkRenderData GenerateCRDTranslucent(Chunk chunk, Chunk world[]) {
|
ChunkRenderData GenerateCRDTranslucent(Chunk chunk, World &world) {
|
||||||
struct ChunkRenderData new_chunk = { 0 };
|
struct ChunkRenderData new_chunk = { 0 };
|
||||||
uint16_t *mask0= chunk.opaqueMask;
|
uint16_t *mask0= chunk.opaqueMask;
|
||||||
uint16_t *mask = chunk.airMask;
|
uint16_t *mask = chunk.airMask;
|
||||||
@@ -592,7 +597,7 @@ ChunkRenderData GenerateCRDTranslucent(Chunk chunk, Chunk world[]) {
|
|||||||
#endif
|
#endif
|
||||||
#define SAVE_FORMAT 0
|
#define SAVE_FORMAT 0
|
||||||
|
|
||||||
void SaveWorld(Chunk world[], const char* path) {
|
void SaveWorld(World &world, const char* path) {
|
||||||
std::ofstream data(path, std::ios::binary);
|
std::ofstream data(path, std::ios::binary);
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
|
||||||
@@ -601,7 +606,7 @@ void SaveWorld(Chunk world[], const char* path) {
|
|||||||
data.write(&fmt, 1);
|
data.write(&fmt, 1);
|
||||||
|
|
||||||
for (int i = 0; i < MAX_WORLD_AREA; ++i) {
|
for (int i = 0; i < MAX_WORLD_AREA; ++i) {
|
||||||
const Chunk &c = world[i];
|
const Chunk &c = world.chunks[i];
|
||||||
|
|
||||||
std::vector<uint8_t> temp;
|
std::vector<uint8_t> temp;
|
||||||
int last_type = -1;
|
int last_type = -1;
|
||||||
@@ -639,7 +644,7 @@ void SaveWorld(Chunk world[], const char* path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Debug_Write(const std::string &stuff);
|
void Debug_Write(const std::string &stuff);
|
||||||
bool LoadWorld(Chunk world[], const char* path) {
|
bool LoadWorld(World &world, const char* path) {
|
||||||
std::ifstream data(path, std::ios::binary);
|
std::ifstream data(path, std::ios::binary);
|
||||||
if (!data) return false;
|
if (!data) return false;
|
||||||
|
|
||||||
@@ -668,7 +673,7 @@ bool LoadWorld(Chunk world[], const char* path) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Chunk *c = &world[i];
|
Chunk *c = &world.chunks[i];
|
||||||
int outIndex = 0;
|
int outIndex = 0;
|
||||||
for (size_t p = 0; p + 1 < size; p += 2) {
|
for (size_t p = 0; p + 1 < size; p += 2) {
|
||||||
uint8_t count = temp[p];
|
uint8_t count = temp[p];
|
||||||
@@ -680,7 +685,7 @@ bool LoadWorld(Chunk world[], const char* path) {
|
|||||||
while (outIndex < CHUNK_DATA_SIZE) {
|
while (outIndex < CHUNK_DATA_SIZE) {
|
||||||
SetBlockChunkFast(c, outIndex++, 0);
|
SetBlockChunkFast(c, outIndex++, 0);
|
||||||
}
|
}
|
||||||
RebuildHeightmap(c);
|
RebuildHeightmap(*c);
|
||||||
}
|
}
|
||||||
free(temp);
|
free(temp);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
+35
-39
@@ -77,7 +77,7 @@
|
|||||||
#define DEFAULT_FONT_SIZE 16
|
#define DEFAULT_FONT_SIZE 16
|
||||||
#define TPS 30.0
|
#define TPS 30.0
|
||||||
#define TPS_DIV 1.0 / TPS
|
#define TPS_DIV 1.0 / TPS
|
||||||
#define RENDER_DISTANCE 16
|
#define RENDER_DISTANCE 128
|
||||||
#define RENDER_DISTANCE_SQUARED RENDER_DISTANCE*RENDER_DISTANCE
|
#define RENDER_DISTANCE_SQUARED RENDER_DISTANCE*RENDER_DISTANCE
|
||||||
#define MAX_HP 100
|
#define MAX_HP 100
|
||||||
#define PATH_APPEND "resources/"
|
#define PATH_APPEND "resources/"
|
||||||
@@ -152,7 +152,7 @@ struct Chunk {
|
|||||||
uint16_t opaqueMask[CHUNK_DATA_SIZE/16];
|
uint16_t opaqueMask[CHUNK_DATA_SIZE/16];
|
||||||
uint16_t airMask[CHUNK_DATA_SIZE/16];
|
uint16_t airMask[CHUNK_DATA_SIZE/16];
|
||||||
uint8_t highestBlock[CHUNK_SIZE*CHUNK_SIZE];
|
uint8_t highestBlock[CHUNK_SIZE*CHUNK_SIZE];
|
||||||
|
uint8_t lights[CHUNK_DATA_SIZE];
|
||||||
};
|
};
|
||||||
#if !defined(SERVER)
|
#if !defined(SERVER)
|
||||||
typedef struct ChunkRenderData ChunkRenderData;
|
typedef struct ChunkRenderData ChunkRenderData;
|
||||||
@@ -288,28 +288,33 @@ struct Particle {
|
|||||||
int lifetime;
|
int lifetime;
|
||||||
int data[8];
|
int data[8];
|
||||||
};
|
};
|
||||||
|
typedef struct World World;
|
||||||
|
struct World {
|
||||||
|
Chunk chunks[MAX_WORLD_AREA];
|
||||||
|
};
|
||||||
extern const BlockDef BLOCKS[];
|
extern const BlockDef BLOCKS[];
|
||||||
|
int GetBlock(World&world,int x,int y,int z);
|
||||||
bool CanTick(int blockType);
|
bool CanTick(int blockType);
|
||||||
bool GetCloud(int x,int z);
|
bool GetCloud(int x,int z);
|
||||||
bool IsTranslucent(int blockType);
|
bool IsTranslucent(int blockType);
|
||||||
void SetBlockChunk(Chunk *c,int x,int y,int z,int t);
|
void SetBlockChunk(Chunk *c,int x,int y,int z,int t);
|
||||||
void RebuildHeightmap(Chunk *c);
|
void RebuildHeightmap(Chunk&c);
|
||||||
int GetBiome(int sx,int sy);
|
int GetBiome(int sx,int sy);
|
||||||
void SetBlockChunkFast(Chunk *c,int i,int t);
|
void SetBlockChunkFast(Chunk *c,int i,int t);
|
||||||
void SetBlock(Chunk world[],int x,int y,int z,int t);
|
void SetBlock(World&world,int x,int y,int z,int t);
|
||||||
void InitWorldgen(int worldType);
|
void InitWorldgen(int worldType);
|
||||||
Vector3 WorldPosition(int cx,int cz,int localX,int y,int localZ);
|
Vector3 WorldPosition(int cx,int cz,int localX,int y,int localZ);
|
||||||
Chunk GenerateChunk(int _x,int _y);
|
Chunk GenerateChunk(int _x,int _y);
|
||||||
void GenerateWorldAdditional(Chunk world[]);
|
void GenerateWorldAdditional(World&world);
|
||||||
void TickBlock(Chunk world[],int wx,int wy,int wz);
|
void TickBlock(World&world,int wx,int wy,int wz);
|
||||||
void TickChunk(Chunk *chunk,Chunk *world,int wx,int wz);
|
void TickChunk(Chunk *chunk,World&world,int wx,int wz);
|
||||||
void RebuildOpaqueMask(Chunk *chunk);
|
void RebuildOpaqueMask(Chunk&chunk);
|
||||||
#if !defined(SERVER)
|
#if !defined(SERVER)
|
||||||
ChunkRenderData GenerateCRDOpaque(const Chunk&chunk,Chunk world[]);
|
ChunkRenderData GenerateCRDOpaque(Chunk&chunk,World&world);
|
||||||
ChunkRenderData GenerateCRDTranslucent(Chunk chunk,Chunk world[]);
|
ChunkRenderData GenerateCRDTranslucent(Chunk chunk,World&world);
|
||||||
#endif
|
#endif
|
||||||
void SaveWorld(Chunk world[],const char *path);
|
void SaveWorld(World&world,const char *path);
|
||||||
bool LoadWorld(Chunk world[],const char *path);
|
bool LoadWorld(World&world,const char *path);
|
||||||
extern long nsTotal;
|
extern long nsTotal;
|
||||||
void Debug_StartMeasure();
|
void Debug_StartMeasure();
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
@@ -356,11 +361,11 @@ extern Vector3 player_velocity;
|
|||||||
extern Vector3 player_velocity;
|
extern Vector3 player_velocity;
|
||||||
#if !defined(SERVER)
|
#if !defined(SERVER)
|
||||||
void TakeDamage(float amount);
|
void TakeDamage(float amount);
|
||||||
void SetBlockNetwork(Chunk world[],int bx,int by,int bz,int t);
|
void SetBlockNetwork(World&world,int bx,int by,int bz,int t);
|
||||||
#endif
|
#endif
|
||||||
Entity NewEntity();
|
Entity NewEntity();
|
||||||
void AddEntity(Entity ent);
|
void AddEntity(Entity ent);
|
||||||
void UpdateEntities(Chunk world[],float dt);
|
void UpdateEntities(World&world,float dt);
|
||||||
extern float globalCounter;
|
extern float globalCounter;
|
||||||
#if !defined(SERVER)
|
#if !defined(SERVER)
|
||||||
void DrawEntities(float dt);
|
void DrawEntities(float dt);
|
||||||
@@ -448,42 +453,43 @@ inline void GetXYZFromIndex(int index,int *x,int *y,int *z){
|
|||||||
};
|
};
|
||||||
inline int GetIndexChunk(int x,int y,int z){
|
inline int GetIndexChunk(int x,int y,int z){
|
||||||
if(x < 0 || y < 0 || z < 0 || x >= CHUNK_SIZE || y >= WORLD_HEIGHT || z >= CHUNK_SIZE) return 0;
|
if(x < 0 || y < 0 || z < 0 || x >= CHUNK_SIZE || y >= WORLD_HEIGHT || z >= CHUNK_SIZE) return 0;
|
||||||
return x + CHUNK_SIZE * (z + CHUNK_SIZE* y);
|
return x + CHUNK_SIZE * (z + CHUNK_SIZE * y);
|
||||||
};
|
};
|
||||||
inline int GetIndexChunk2D(int x,int z){
|
inline int GetIndexChunk2D(int x,int z){
|
||||||
if(x < 0 || z < 0 || x >= CHUNK_SIZE || z >= CHUNK_SIZE) return 0;
|
if(x < 0 || z < 0 || x >= CHUNK_SIZE || z >= CHUNK_SIZE) return 0;
|
||||||
return x + CHUNK_SIZE * z;
|
return x + CHUNK_SIZE * z;
|
||||||
};
|
};
|
||||||
|
inline bool CheckOOBWorld(int x,int y,int z){
|
||||||
|
return (x < 0 || y < 0 || z < 0 || x >= WORLD_SIZE_BLOCKS || y >= WORLD_HEIGHT || z >= WORLD_SIZE_BLOCKS);
|
||||||
|
};
|
||||||
inline int GetIndexWorld(int x,int z){
|
inline int GetIndexWorld(int x,int z){
|
||||||
|
if(CheckOOBWorld(x << 4, 0, z << 4)) return 0;
|
||||||
return x + MAX_WORLD_SIZE * z;
|
return x + MAX_WORLD_SIZE * z;
|
||||||
};
|
};
|
||||||
inline void GetXZFromIndex(int index,int *x,int *z){
|
inline void GetXZFromIndex(int index,int *x,int *z){
|
||||||
*z = index / MAX_WORLD_SIZE;
|
*z = index / MAX_WORLD_SIZE;
|
||||||
*x = index % MAX_WORLD_SIZE;
|
*x = index % MAX_WORLD_SIZE;
|
||||||
};
|
};
|
||||||
inline bool TestMask(uint16_t *maskArray,int position){
|
inline bool TestMask(const uint16_t *maskArray,int position){
|
||||||
|
if (position < 0 || position >= CHUNK_DATA_SIZE) return false;
|
||||||
int index = position >> 4;
|
int index = position >> 4;
|
||||||
int bit = position & 15;
|
int bit = position & 15;
|
||||||
int maskArrayLen = CHUNK_DATA_SIZE << 4;
|
|
||||||
return (maskArray[index] & (1u << bit)) != 0;
|
return (maskArray[index] & (1u << bit)) != 0;
|
||||||
};
|
};
|
||||||
inline bool CheckOOBWorld(int x,int y,int z){
|
|
||||||
return (x < 0 || y < 0 || z < 0 || x >= WORLD_SIZE_BLOCKS || y >= WORLD_HEIGHT || z >= WORLD_SIZE_BLOCKS);
|
|
||||||
};
|
|
||||||
inline bool CheckOOBChunk(int x,int y,int z){
|
inline bool CheckOOBChunk(int x,int y,int z){
|
||||||
return (x < 0 || y < 0 || z < 0 || x >= CHUNK_SIZE || y >= WORLD_HEIGHT || z >= CHUNK_SIZE);
|
return (x < 0 || y < 0 || z < 0 || x >= CHUNK_SIZE || y >= WORLD_HEIGHT || z >= CHUNK_SIZE);
|
||||||
};
|
};
|
||||||
inline bool TestOpaqueMaskWorld(Chunk world[],int x,int y,int z){
|
inline bool TestOpaqueMaskWorld(const World&world,int x,int y,int z){
|
||||||
if(CheckOOBWorld(x, y, z)) return true;
|
if(CheckOOBWorld(x, y, z)) return true;
|
||||||
Chunk* c = &world[GetIndexWorld(x >> 4, z >> 4)];
|
const Chunk c = world.chunks[GetIndexWorld(x >> 4, z >> 4)];
|
||||||
int localIndex = GetIndexChunk((uint8_t)x & 15, y, (uint8_t)z & 15);
|
const int localIndex = GetIndexChunk((uint8_t)x & 15, y, (uint8_t)z & 15);
|
||||||
return TestMask(c->opaqueMask, localIndex);
|
return TestMask(c.opaqueMask, localIndex);
|
||||||
};
|
};
|
||||||
inline bool TestAirMaskWorld(Chunk world[],int x,int y,int z){
|
inline bool TestAirMaskWorld(const World&world,int x,int y,int z){
|
||||||
if(CheckOOBWorld(x, y, z)) return true;
|
if(CheckOOBWorld(x, y, z)) return true;
|
||||||
Chunk* c = &world[GetIndexWorld(x >> 4, z >> 4)];
|
const Chunk c = world.chunks[GetIndexWorld(x >> 4, z >> 4)];
|
||||||
int localIndex = GetIndexChunk((uint8_t)x & 15, y, (uint8_t)z & 15);
|
const int localIndex = GetIndexChunk((uint8_t)x & 15, y, (uint8_t)z & 15);
|
||||||
return TestMask(c->airMask, localIndex);
|
return TestMask(c.airMask, localIndex);
|
||||||
};
|
};
|
||||||
inline int fetch_block(Chunk chunk,int x,int y,int z){
|
inline int fetch_block(Chunk chunk,int x,int y,int z){
|
||||||
if(x<0||x>=CHUNK_SIZE||y<0||y>=WORLD_HEIGHT||z<0||z>=CHUNK_SIZE) return 0;
|
if(x<0||x>=CHUNK_SIZE||y<0||y>=WORLD_HEIGHT||z<0||z>=CHUNK_SIZE) return 0;
|
||||||
@@ -493,14 +499,6 @@ inline int fetch_block_ptr(Chunk *chunk,int x,int y,int z){
|
|||||||
if(x<0||x>=CHUNK_SIZE||y<0||y>=WORLD_HEIGHT||z<0||z>=CHUNK_SIZE) return 0;
|
if(x<0||x>=CHUNK_SIZE||y<0||y>=WORLD_HEIGHT||z<0||z>=CHUNK_SIZE) return 0;
|
||||||
return chunk->blocks[GetIndexChunk(x, y, z)];
|
return chunk->blocks[GetIndexChunk(x, y, z)];
|
||||||
};
|
};
|
||||||
inline int GetBlock(Chunk world[],int x,int y,int z){
|
|
||||||
if(CheckOOBWorld(x, y, z)) return 0;
|
|
||||||
int locX = x % CHUNK_SIZE;
|
|
||||||
int locZ = z % CHUNK_SIZE;
|
|
||||||
int cx = x / CHUNK_SIZE;
|
|
||||||
int cz = z / CHUNK_SIZE;
|
|
||||||
return fetch_block(world[GetIndexWorld(cx, cz)], locX, y, locZ);
|
|
||||||
};
|
|
||||||
inline void *grow(void *ptr,size_t oldBytes,size_t newBytes){
|
inline void *grow(void *ptr,size_t oldBytes,size_t newBytes){
|
||||||
if (!ptr) return malloc(newBytes);
|
if (!ptr) return malloc(newBytes);
|
||||||
return realloc(ptr, newBytes);
|
return realloc(ptr, newBytes);
|
||||||
@@ -603,7 +601,7 @@ void UpdateHotbar();
|
|||||||
void LocaleUpdate();
|
void LocaleUpdate();
|
||||||
void LoadRecipes();
|
void LoadRecipes();
|
||||||
#endif
|
#endif
|
||||||
void ParticlesUpdate(float dt,Chunk world[]);
|
void ParticlesUpdate(float dt,World&world);
|
||||||
void ParticlesDraw();
|
void ParticlesDraw();
|
||||||
void AddParticle(Particle part);
|
void AddParticle(Particle part);
|
||||||
Particle NewParticle(Vector3 position);
|
Particle NewParticle(Vector3 position);
|
||||||
@@ -616,8 +614,6 @@ void SavePlayerData();
|
|||||||
bool LoadPlayerData();
|
bool LoadPlayerData();
|
||||||
void MS_PlaySound(Sound src,float pitch,float volume,Vector3 position);
|
void MS_PlaySound(Sound src,float pitch,float volume,Vector3 position);
|
||||||
void MS_Update(float dt,Camera camera);
|
void MS_Update(float dt,Camera camera);
|
||||||
void ServerNetworkUpdate();
|
|
||||||
void StopInternalServer();
|
|
||||||
#define INTERFACE 0
|
#define INTERFACE 0
|
||||||
#define EXPORT_INTERFACE 0
|
#define EXPORT_INTERFACE 0
|
||||||
#define LOCAL_INTERFACE 0
|
#define LOCAL_INTERFACE 0
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ extern bool online;
|
|||||||
extern Vector3 player_position;
|
extern Vector3 player_position;
|
||||||
extern Vector3 player_velocity;
|
extern Vector3 player_velocity;
|
||||||
void TakeDamage(float amount);
|
void TakeDamage(float amount);
|
||||||
void SetBlockNetwork(Chunk world[], int bx, int by, int bz, int t);
|
void SetBlockNetwork(World &world, int bx, int by, int bz, int t);
|
||||||
#else
|
#else
|
||||||
bool online = true;
|
bool online = true;
|
||||||
#endif
|
#endif
|
||||||
@@ -48,7 +48,7 @@ void AddEntity(Entity ent) {
|
|||||||
entities.push_back(ent);
|
entities.push_back(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateEntityPhysics(Chunk world[], Entity& ent, float dt) {
|
static void UpdateEntityPhysics(World &world, Entity& ent, float dt) {
|
||||||
Vector3 velocityTgt = Vector3Add(ent.velocity, {0, -dt * 20.0f, 0});
|
Vector3 velocityTgt = Vector3Add(ent.velocity, {0, -dt * 20.0f, 0});
|
||||||
Vector3 tgt = Vector3Add(ent.position, Vector3Scale(velocityTgt, dt));
|
Vector3 tgt = Vector3Add(ent.position, Vector3Scale(velocityTgt, dt));
|
||||||
Vector3 final = ent.position;
|
Vector3 final = ent.position;
|
||||||
@@ -67,7 +67,7 @@ static void UpdateEntityPhysics(Chunk world[], Entity& ent, float dt) {
|
|||||||
ent.velocity = velocityTgt;
|
ent.velocity = velocityTgt;
|
||||||
ent.position = final;
|
ent.position = final;
|
||||||
}
|
}
|
||||||
void UpdateEntities(Chunk world[], float dt) {
|
void UpdateEntities(World &world, float dt) {
|
||||||
if(entities.size() > 0) {
|
if(entities.size() > 0) {
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for(Entity& ent : entities) {
|
for(Entity& ent : entities) {
|
||||||
|
|||||||
+15
-23
@@ -30,13 +30,17 @@ inline void GetXYZFromIndex(int index, int *x, int *y, int *z) {
|
|||||||
|
|
||||||
inline int GetIndexChunk(int x, int y, int z) {
|
inline int GetIndexChunk(int x, int y, int z) {
|
||||||
if(x < 0 || y < 0 || z < 0 || x >= CHUNK_SIZE || y >= WORLD_HEIGHT || z >= CHUNK_SIZE) return 0;
|
if(x < 0 || y < 0 || z < 0 || x >= CHUNK_SIZE || y >= WORLD_HEIGHT || z >= CHUNK_SIZE) return 0;
|
||||||
return x + CHUNK_SIZE * (z + CHUNK_SIZE* y);
|
return x + CHUNK_SIZE * (z + CHUNK_SIZE * y);
|
||||||
}
|
}
|
||||||
inline int GetIndexChunk2D(int x, int z) {
|
inline int GetIndexChunk2D(int x, int z) {
|
||||||
if(x < 0 || z < 0 || x >= CHUNK_SIZE || z >= CHUNK_SIZE) return 0;
|
if(x < 0 || z < 0 || x >= CHUNK_SIZE || z >= CHUNK_SIZE) return 0;
|
||||||
return x + CHUNK_SIZE * z;
|
return x + CHUNK_SIZE * z;
|
||||||
}
|
}
|
||||||
|
inline bool CheckOOBWorld(int x, int y, int z) {
|
||||||
|
return (x < 0 || y < 0 || z < 0 || x >= WORLD_SIZE_BLOCKS || y >= WORLD_HEIGHT || z >= WORLD_SIZE_BLOCKS);
|
||||||
|
}
|
||||||
inline int GetIndexWorld(int x, int z) {
|
inline int GetIndexWorld(int x, int z) {
|
||||||
|
if(CheckOOBWorld(x << 4, 0, z << 4)) return 0;
|
||||||
return x + MAX_WORLD_SIZE * z;
|
return x + MAX_WORLD_SIZE * z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,32 +49,29 @@ inline void GetXZFromIndex(int index, int *x, int *z) {
|
|||||||
*x = index % MAX_WORLD_SIZE;
|
*x = index % MAX_WORLD_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool TestMask(uint16_t *maskArray, int position)
|
inline bool TestMask(const uint16_t *maskArray, int position)
|
||||||
{
|
{
|
||||||
|
if (position < 0 || position >= CHUNK_DATA_SIZE) return false;
|
||||||
int index = position >> 4;
|
int index = position >> 4;
|
||||||
int bit = position & 15;
|
int bit = position & 15;
|
||||||
int maskArrayLen = CHUNK_DATA_SIZE << 4;
|
|
||||||
return (maskArray[index] & (1u << bit)) != 0;
|
return (maskArray[index] & (1u << bit)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool CheckOOBWorld(int x, int y, int z) {
|
|
||||||
return (x < 0 || y < 0 || z < 0 || x >= WORLD_SIZE_BLOCKS || y >= WORLD_HEIGHT || z >= WORLD_SIZE_BLOCKS);
|
|
||||||
}
|
|
||||||
inline bool CheckOOBChunk(int x, int y, int z) {
|
inline bool CheckOOBChunk(int x, int y, int z) {
|
||||||
return (x < 0 || y < 0 || z < 0 || x >= CHUNK_SIZE || y >= WORLD_HEIGHT || z >= CHUNK_SIZE);
|
return (x < 0 || y < 0 || z < 0 || x >= CHUNK_SIZE || y >= WORLD_HEIGHT || z >= CHUNK_SIZE);
|
||||||
}
|
}
|
||||||
inline bool TestOpaqueMaskWorld(Chunk world[], int x, int y, int z) {
|
inline bool TestOpaqueMaskWorld(const World& world, int x, int y, int z) {
|
||||||
if(CheckOOBWorld(x, y, z)) return true;
|
if(CheckOOBWorld(x, y, z)) return true;
|
||||||
Chunk* c = &world[GetIndexWorld(x >> 4, z >> 4)];
|
const Chunk c = world.chunks[GetIndexWorld(x >> 4, z >> 4)];
|
||||||
int localIndex = GetIndexChunk((uint8_t)x & 15, y, (uint8_t)z & 15);
|
const int localIndex = GetIndexChunk((uint8_t)x & 15, y, (uint8_t)z & 15);
|
||||||
return TestMask(c->opaqueMask, localIndex);
|
return TestMask(c.opaqueMask, localIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool TestAirMaskWorld(Chunk world[], int x, int y, int z) {
|
inline bool TestAirMaskWorld(const World& world, int x, int y, int z) {
|
||||||
if(CheckOOBWorld(x, y, z)) return true;
|
if(CheckOOBWorld(x, y, z)) return true;
|
||||||
Chunk* c = &world[GetIndexWorld(x >> 4, z >> 4)];
|
const Chunk c = world.chunks[GetIndexWorld(x >> 4, z >> 4)];
|
||||||
int localIndex = GetIndexChunk((uint8_t)x & 15, y, (uint8_t)z & 15);
|
const int localIndex = GetIndexChunk((uint8_t)x & 15, y, (uint8_t)z & 15);
|
||||||
return TestMask(c->airMask, localIndex);
|
return TestMask(c.airMask, localIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int fetch_block(Chunk chunk, int x, int y, int z) {
|
inline int fetch_block(Chunk chunk, int x, int y, int z) {
|
||||||
@@ -83,15 +84,6 @@ inline int fetch_block_ptr(Chunk *chunk, int x, int y, int z) {
|
|||||||
return chunk->blocks[GetIndexChunk(x, y, z)];
|
return chunk->blocks[GetIndexChunk(x, y, z)];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int GetBlock(Chunk world[], int x, int y, int z) {
|
|
||||||
if(CheckOOBWorld(x, y, z)) return 0;
|
|
||||||
int locX = x % CHUNK_SIZE;
|
|
||||||
int locZ = z % CHUNK_SIZE;
|
|
||||||
int cx = x / CHUNK_SIZE;
|
|
||||||
int cz = z / CHUNK_SIZE;
|
|
||||||
return fetch_block(world[GetIndexWorld(cx, cz)], locX, y, locZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void *grow(void *ptr, size_t oldBytes, size_t newBytes) {
|
inline void *grow(void *ptr, size_t oldBytes, size_t newBytes) {
|
||||||
if (!ptr) return malloc(newBytes);
|
if (!ptr) return malloc(newBytes);
|
||||||
return realloc(ptr, newBytes);
|
return realloc(ptr, newBytes);
|
||||||
|
|||||||
@@ -503,7 +503,8 @@ void DrawWorldSelect() {
|
|||||||
}
|
}
|
||||||
if (Button(LocaleGet("create_world").c_str(), GetScreenWidth()/2+196-128, GetScreenHeight()-48, 128, 0)) {
|
if (Button(LocaleGet("create_world").c_str(), GetScreenWidth()/2+196-128, GetScreenHeight()-48, 128, 0)) {
|
||||||
UIResetMousePos();
|
UIResetMousePos();
|
||||||
//InitSingleplayer();
|
InitWorldgen(0);
|
||||||
|
state = GAME_STATE_LOADING;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Button(LocaleGet("create_world").c_str(), GetScreenWidth()/2+196-128, GetScreenHeight()-48-48, 128, 0)) {
|
if (Button(LocaleGet("create_world").c_str(), GetScreenWidth()/2+196-128, GetScreenHeight()-48-48, 128, 0)) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ ENetHost* StartServer() {
|
|||||||
/* Bind the server to port 1234. */
|
/* Bind the server to port 1234. */
|
||||||
address.port = PORT;
|
address.port = PORT;
|
||||||
|
|
||||||
server = enet_host_create(&address, 32, 1, 0, 0);
|
server = enet_host_create(&address, 32, 1, 0);
|
||||||
if (server == NULL)
|
if (server == NULL)
|
||||||
{
|
{
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
@@ -41,8 +41,7 @@ ENetHost* StartClient() {
|
|||||||
client = enet_host_create (NULL /* create a client host */,
|
client = enet_host_create (NULL /* create a client host */,
|
||||||
1 /* 1 channel*/,
|
1 /* 1 channel*/,
|
||||||
1 /* only allow 1 outgoing connection */,
|
1 /* only allow 1 outgoing connection */,
|
||||||
0 /* assume any amount of incoming bandwidth */,
|
0 /* assume any amount of incoming bandwidth */);
|
||||||
0);
|
|
||||||
|
|
||||||
if (client == NULL)
|
if (client == NULL)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ static void DrawParticle(Particle particle, Color color)
|
|||||||
|
|
||||||
rlSetTexture(0);
|
rlSetTexture(0);
|
||||||
}
|
}
|
||||||
void ParticlesUpdate(float dt, Chunk world[]) {
|
void ParticlesUpdate(float dt, World &world) {
|
||||||
particles.remove_if([](Particle x) { return x.lifetime > 200; });
|
particles.remove_if([](Particle x) { return x.lifetime > 200; });
|
||||||
for (Particle &part : particles)
|
for (Particle &part : particles)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,361 +0,0 @@
|
|||||||
#include "common.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstring>
|
|
||||||
#include <list>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <lua.hpp>
|
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
static std::list<NetPlayer> players;
|
|
||||||
static Chunk world[MAX_WORLD_AREA];
|
|
||||||
static ENetHost* server;
|
|
||||||
|
|
||||||
struct LuaPlugin {
|
|
||||||
std::string name;
|
|
||||||
lua_State* L;
|
|
||||||
bool has_on_connect = false;
|
|
||||||
bool has_on_disconnect = false;
|
|
||||||
bool has_on_packet = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
static std::vector<std::unique_ptr<LuaPlugin>> plugins;
|
|
||||||
|
|
||||||
static int l_server_send(lua_State* L) {
|
|
||||||
int peer_id = (int)luaL_checkinteger(L, 1);
|
|
||||||
size_t len;
|
|
||||||
const char* data = luaL_checklstring(L, 2, &len);
|
|
||||||
for (const NetPlayer &p : players) {
|
|
||||||
if (p.id == peer_id) {
|
|
||||||
SendPacketR(p.peer, (void*)data, (int)len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int l_server_broadcast(lua_State* L) {
|
|
||||||
size_t len;
|
|
||||||
const char* data = luaL_checklstring(L, 1, &len);
|
|
||||||
if (len > 0) {
|
|
||||||
BroadcastPacketR(server, (void*)data, (int)len);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int l_get_players(lua_State* L) {
|
|
||||||
lua_newtable(L);
|
|
||||||
int idx = 1;
|
|
||||||
for (const NetPlayer &p : players) {
|
|
||||||
lua_pushinteger(L, p.id);
|
|
||||||
lua_rawseti(L, -2, idx++);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void RegisterLuaAPI(lua_State* L) {
|
|
||||||
lua_newtable(L);
|
|
||||||
lua_pushcfunction(L, l_server_send);
|
|
||||||
lua_setfield(L, -2, "send");
|
|
||||||
lua_pushcfunction(L, l_server_broadcast);
|
|
||||||
lua_setfield(L, -2, "broadcast");
|
|
||||||
lua_pushcfunction(L, l_get_players);
|
|
||||||
lua_setfield(L, -2, "get_players");
|
|
||||||
lua_setglobal(L, "server");
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool LoadPluginFile(const std::filesystem::path& path) {
|
|
||||||
auto plugin = std::make_unique<LuaPlugin>();
|
|
||||||
plugin->name = path.filename().string();
|
|
||||||
plugin->L = luaL_newstate();
|
|
||||||
if (!plugin->L) return false;
|
|
||||||
luaL_openlibs(plugin->L);
|
|
||||||
|
|
||||||
RegisterLuaAPI(plugin->L);
|
|
||||||
|
|
||||||
int rc = luaL_dofile(plugin->L, path.string().c_str());
|
|
||||||
if (rc != LUA_OK) {
|
|
||||||
const char* err = lua_tostring(plugin->L, -1);
|
|
||||||
std::cerr << "Error loading plugin " << plugin->name << ": " << (err ? err : "unknown") << std::endl;
|
|
||||||
lua_close(plugin->L);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_getglobal(plugin->L, "on_connect");
|
|
||||||
if (lua_isfunction(plugin->L, -1)) plugin->has_on_connect = true;
|
|
||||||
lua_pop(plugin->L, 1);
|
|
||||||
|
|
||||||
lua_getglobal(plugin->L, "on_disconnect");
|
|
||||||
if (lua_isfunction(plugin->L, -1)) plugin->has_on_disconnect = true;
|
|
||||||
lua_pop(plugin->L, 1);
|
|
||||||
|
|
||||||
lua_getglobal(plugin->L, "on_packet");
|
|
||||||
if (lua_isfunction(plugin->L, -1)) plugin->has_on_packet = true;
|
|
||||||
lua_pop(plugin->L, 1);
|
|
||||||
|
|
||||||
plugins.push_back(std::move(plugin));
|
|
||||||
std::cout << "Loaded plugin: " << path.filename().string() << std::endl;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void LoadPluginsFromFolder(const std::string& folder) {
|
|
||||||
try {
|
|
||||||
if (!std::filesystem::exists(folder)) {
|
|
||||||
std::cout << "Plugins folder does not exist; skipping: " << folder << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (auto& p : std::filesystem::directory_iterator(folder)) {
|
|
||||||
if (!p.is_regular_file()) continue;
|
|
||||||
auto ext = p.path().extension().string();
|
|
||||||
if (ext == ".lua") LoadPluginFile(p.path());
|
|
||||||
}
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
std::cerr << "Error enumerating plugins: " << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void CallPluginOnConnect(int peer_id) {
|
|
||||||
for (auto &pl : plugins) {
|
|
||||||
if (!pl->has_on_connect) continue;
|
|
||||||
lua_State* L = pl->L;
|
|
||||||
lua_getglobal(L, "on_connect");
|
|
||||||
lua_pushinteger(L, peer_id);
|
|
||||||
if (lua_pcall(L, 1, 0, 0) != LUA_OK) {
|
|
||||||
std::cerr << "Plugin " << pl->name << " on_connect error: " << lua_tostring(L, -1) << std::endl;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void CallPluginOnDisconnect(int peer_id) {
|
|
||||||
for (auto &pl : plugins) {
|
|
||||||
if (!pl->has_on_disconnect) continue;
|
|
||||||
lua_State* L = pl->L;
|
|
||||||
lua_getglobal(L, "on_disconnect");
|
|
||||||
lua_pushinteger(L, peer_id);
|
|
||||||
if (lua_pcall(L, 1, 0, 0) != LUA_OK) {
|
|
||||||
std::cerr << "Plugin " << pl->name << " on_disconnect error: " << lua_tostring(L, -1) << std::endl;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void CallPluginOnPacket(int peer_id, const unsigned char* data, int len) {
|
|
||||||
for (auto &pl : plugins) {
|
|
||||||
if (!pl->has_on_packet) continue;
|
|
||||||
lua_State* L = pl->L;
|
|
||||||
lua_getglobal(L, "on_packet");
|
|
||||||
lua_pushinteger(L, peer_id);
|
|
||||||
lua_pushlstring(L, (const char*)data, len);
|
|
||||||
if (lua_pcall(L, 2, 0, 0) != LUA_OK) {
|
|
||||||
std::cerr << "Plugin " << pl->name << " on_packet error: " << lua_tostring(L, -1) << std::endl;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int PeerToPlayerID(ENetPeer* peer) {
|
|
||||||
for (const NetPlayer &p : players) {
|
|
||||||
if (p.addr == peer->address.host && p.port == peer->address.port) return p.id;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool CompareAddress(NetPlayer plr, ENetPeer* peer) {
|
|
||||||
return plr.addr == peer->address.host && plr.port == (int)(peer->address.port);
|
|
||||||
}
|
|
||||||
static void ParseData(ENetPacket* packet, ENetPeer* peer) {
|
|
||||||
int len = packet->dataLength;
|
|
||||||
unsigned char data[len];
|
|
||||||
memcpy(&data, packet->data, len);
|
|
||||||
|
|
||||||
int pid = PeerToPlayerID(peer);
|
|
||||||
if (pid >= 0) CallPluginOnPacket(pid, data, len);
|
|
||||||
|
|
||||||
unsigned char response[16];
|
|
||||||
switch (data[0])
|
|
||||||
{
|
|
||||||
case NET_ARG_REQWORLD:
|
|
||||||
puts("Client requested world; sending");
|
|
||||||
for (int i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
unsigned char responseChunk[2+CHUNK_DATA_SIZE+CHUNK_SIZE*CHUNK_SIZE];
|
|
||||||
responseChunk[0] = NET_ARG_CHUNKF;
|
|
||||||
responseChunk[1] = i;
|
|
||||||
|
|
||||||
memcpy(responseChunk+2, world[i].blocks, CHUNK_DATA_SIZE);
|
|
||||||
memcpy(responseChunk+2+CHUNK_DATA_SIZE, world[i].highestBlock, CHUNK_SIZE*CHUNK_SIZE);
|
|
||||||
SendPacket(peer, responseChunk, sizeof(responseChunk));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NET_ARG_PLAYERMOVE:
|
|
||||||
response[0] = NET_ARG_ECHOMOVE;
|
|
||||||
for (NetPlayer &plr : players)
|
|
||||||
{
|
|
||||||
if(CompareAddress(plr, peer)) {
|
|
||||||
float x = DeserializeFloat(data[1], data[2]);
|
|
||||||
float y = DeserializeFloat(data[3], data[4]);
|
|
||||||
float z = DeserializeFloat(data[5], data[6]);
|
|
||||||
plr.x = x;
|
|
||||||
plr.y = y;
|
|
||||||
plr.z = z;
|
|
||||||
response[1] = plr.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
response[2] = data[1]; response[3] = data[2];
|
|
||||||
response[4] = data[3]; response[5] = data[4];
|
|
||||||
response[6] = data[5]; response[7] = data[6];
|
|
||||||
response[8] = data[7];
|
|
||||||
BroadcastPacketR(server, response, 9);
|
|
||||||
break;
|
|
||||||
case NET_ARG_PLAYERYAW:
|
|
||||||
response[0] = NET_ARG_ECHOYAW;
|
|
||||||
for (NetPlayer &plr : players)
|
|
||||||
{
|
|
||||||
if(CompareAddress(plr, peer)) {
|
|
||||||
response[1] = plr.id;
|
|
||||||
plr.yaw = data[1];
|
|
||||||
response[2] = plr.yaw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BroadcastPacketR(server, response, 3);
|
|
||||||
break;
|
|
||||||
case NET_ARG_REQPLAYERS:
|
|
||||||
puts("Client requested players; sending");
|
|
||||||
|
|
||||||
for (NetPlayer &plr : players)
|
|
||||||
{
|
|
||||||
unsigned char responseP[9];
|
|
||||||
responseP[0] = NET_ARG_PLRREG;
|
|
||||||
if(!CompareAddress(plr, peer)) {
|
|
||||||
SerializeFloat2Data(plr.x, responseP, 2);
|
|
||||||
SerializeFloat2Data(plr.y, responseP, 4);
|
|
||||||
SerializeFloat2Data(plr.z, responseP, 6);
|
|
||||||
responseP[1] = plr.id;
|
|
||||||
responseP[8] = plr.yaw;
|
|
||||||
SendPacketR(peer, responseP, 9);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NET_ARG_BLOCKDELTA:
|
|
||||||
response[0] = NET_ARG_BLOCK;
|
|
||||||
for (NetPlayer &plr : players)
|
|
||||||
{
|
|
||||||
if(CompareAddress(plr, peer)) {
|
|
||||||
unsigned char responseB[6];
|
|
||||||
responseB[0] = NET_ARG_BLOCK;
|
|
||||||
responseB[1] = plr.id;
|
|
||||||
responseB[2] = data[1];
|
|
||||||
responseB[3] = data[2];
|
|
||||||
responseB[4] = data[3];
|
|
||||||
responseB[5] = data[4];
|
|
||||||
SetBlock(world, data[1], data[2], data[3], data[4]);
|
|
||||||
BroadcastPacketR(server, responseB, 6);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int FirstFreeID(const std::list<NetPlayer>& players) {
|
|
||||||
std::unordered_set<int> used;
|
|
||||||
used.reserve(players.size());
|
|
||||||
for (const auto &p : players) used.insert(p.id);
|
|
||||||
|
|
||||||
int id = 0;
|
|
||||||
while (used.find(id) != used.end()) ++id;
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
static bool serverStarted = false;
|
|
||||||
void StartInternalServer(std::atomic_bool& started) {
|
|
||||||
int worldType = 0;
|
|
||||||
InitWorldgen(worldType);
|
|
||||||
std::cout << "Building chunks..." << std::endl;
|
|
||||||
Chunk chunk = GenerateChunk(8, 8);
|
|
||||||
for (int x = 0; x < MAX_WORLD_SIZE; x++)
|
|
||||||
{
|
|
||||||
for (int y = 0; y < MAX_WORLD_SIZE; y++)
|
|
||||||
{
|
|
||||||
memcpy(&world[x + y * MAX_WORLD_SIZE], &chunk, sizeof(Chunk));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LoadPluginsFromFolder("plugins");
|
|
||||||
std::cout << "Starting server..." << std::endl;
|
|
||||||
server = StartServer();
|
|
||||||
std::cout << "Serving on port: " << PORT << std::endl;
|
|
||||||
serverStarted = true;
|
|
||||||
started = true;
|
|
||||||
}
|
|
||||||
void ServerNetworkUpdate() {
|
|
||||||
if(serverStarted) {
|
|
||||||
ENetEvent event;
|
|
||||||
while(enet_host_service (server, &event, 0) > 0)
|
|
||||||
{
|
|
||||||
switch (event.type)
|
|
||||||
{
|
|
||||||
int id;
|
|
||||||
char response[2];
|
|
||||||
case ENET_EVENT_TYPE_CONNECT:
|
|
||||||
printf ("A new client connected from %x:%u.\n",
|
|
||||||
event.peer -> address.host,
|
|
||||||
event.peer -> address.port);
|
|
||||||
response[0] = NET_ARG_PLRID;
|
|
||||||
id = FirstFreeID(players);
|
|
||||||
response[1] = id;
|
|
||||||
SendPacketR(event.peer, response, sizeof(response));
|
|
||||||
{
|
|
||||||
NetPlayer netPlayer;
|
|
||||||
netPlayer.id = id;
|
|
||||||
netPlayer.addr = event.peer->address.host;
|
|
||||||
netPlayer.port = (int)(event.peer->address.port);
|
|
||||||
netPlayer.peer = event.peer;
|
|
||||||
players.push_back(netPlayer);
|
|
||||||
|
|
||||||
response[0] = NET_ARG_PLRCON;
|
|
||||||
response[1] = netPlayer.id;
|
|
||||||
BroadcastPacketR(server, response, sizeof(response));
|
|
||||||
}
|
|
||||||
CallPluginOnConnect(id);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ENET_EVENT_TYPE_RECEIVE:
|
|
||||||
ParseData(event.packet, event.peer);
|
|
||||||
enet_packet_destroy (event.packet);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ENET_EVENT_TYPE_DISCONNECT:
|
|
||||||
printf ("%s disconnected.\n", event.peer -> data);
|
|
||||||
event.peer -> data = NULL;
|
|
||||||
for (auto it = players.begin(); it != players.end(); ++it) {
|
|
||||||
if (CompareAddress(*it, event.peer)) {
|
|
||||||
char responseD[2];
|
|
||||||
responseD[0] = NET_ARG_PLRDCN;
|
|
||||||
responseD[1] = it->id;
|
|
||||||
BroadcastPacketR(server, (unsigned char*)responseD, sizeof(responseD));
|
|
||||||
|
|
||||||
int disconnected_id = it->id;
|
|
||||||
it = players.erase(it);
|
|
||||||
|
|
||||||
// notify plugins
|
|
||||||
CallPluginOnDisconnect(disconnected_id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void StopInternalServer() {
|
|
||||||
for (auto &pl : plugins) {
|
|
||||||
lua_close(pl->L);
|
|
||||||
}
|
|
||||||
|
|
||||||
enet_host_destroy(server);
|
|
||||||
}
|
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
#define TPS 30.0
|
#define TPS 30.0
|
||||||
#define TPS_DIV 1.0 / TPS
|
#define TPS_DIV 1.0 / TPS
|
||||||
//Rendering
|
//Rendering
|
||||||
#define RENDER_DISTANCE 16
|
#define RENDER_DISTANCE 128
|
||||||
#define RENDER_DISTANCE_SQUARED RENDER_DISTANCE*RENDER_DISTANCE
|
#define RENDER_DISTANCE_SQUARED RENDER_DISTANCE*RENDER_DISTANCE
|
||||||
|
|
||||||
//Game stuff
|
//Game stuff
|
||||||
@@ -179,7 +179,7 @@ struct Chunk {
|
|||||||
uint16_t opaqueMask[CHUNK_DATA_SIZE/16];
|
uint16_t opaqueMask[CHUNK_DATA_SIZE/16];
|
||||||
uint16_t airMask[CHUNK_DATA_SIZE/16];
|
uint16_t airMask[CHUNK_DATA_SIZE/16];
|
||||||
uint8_t highestBlock[CHUNK_SIZE*CHUNK_SIZE];
|
uint8_t highestBlock[CHUNK_SIZE*CHUNK_SIZE];
|
||||||
|
uint8_t lights[CHUNK_DATA_SIZE];
|
||||||
};
|
};
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
struct ChunkRenderData {
|
struct ChunkRenderData {
|
||||||
@@ -306,4 +306,8 @@ struct Particle {
|
|||||||
Texture2D texture;
|
Texture2D texture;
|
||||||
int lifetime;
|
int lifetime;
|
||||||
int data[8];
|
int data[8];
|
||||||
};
|
};
|
||||||
|
struct World
|
||||||
|
{
|
||||||
|
Chunk chunks[MAX_WORLD_AREA];
|
||||||
|
};
|
||||||
|
|||||||
+36
-57
@@ -15,8 +15,6 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <thread>
|
|
||||||
#include <atomic>
|
|
||||||
#define MAX_RAY_DISTANCE 8.0f
|
#define MAX_RAY_DISTANCE 8.0f
|
||||||
struct MessageData {
|
struct MessageData {
|
||||||
std::string message;
|
std::string message;
|
||||||
@@ -91,7 +89,7 @@ static Vector3 CameraForwardFromYawPitch(float yaw, float pitch)
|
|||||||
f.z = cosf(pitch) * sinf(yaw);
|
f.z = cosf(pitch) * sinf(yaw);
|
||||||
return Vector3Normalize(f);
|
return Vector3Normalize(f);
|
||||||
}
|
}
|
||||||
Chunk world[MAX_WORLD_AREA];
|
World world;
|
||||||
static MeshUnit rendering[MAX_WORLD_AREA];
|
static MeshUnit rendering[MAX_WORLD_AREA];
|
||||||
static MeshUnit renderingT[MAX_WORLD_AREA];
|
static MeshUnit renderingT[MAX_WORLD_AREA];
|
||||||
|
|
||||||
@@ -269,13 +267,13 @@ bool dirtyChunks[MAX_WORLD_AREA] = { false };
|
|||||||
void Debug_EndMeasure(const std::string &stuff);
|
void Debug_EndMeasure(const std::string &stuff);
|
||||||
void Debug_EndMeasureLoops(const std::string &stuff, int loops);
|
void Debug_EndMeasureLoops(const std::string &stuff, int loops);
|
||||||
static void RemeshChunk(int x, int y) {
|
static void RemeshChunk(int x, int y) {
|
||||||
int idx = x + y * MAX_WORLD_SIZE;
|
int idx = GetIndexWorld(x, y);
|
||||||
if(loadedChunks[idx]) {
|
if(loadedChunks[idx]) {
|
||||||
UnloadModel(renderingT[idx].model);
|
UnloadModel(renderingT[idx].model);
|
||||||
UnloadModel(rendering[idx].model);
|
UnloadModel(rendering[idx].model);
|
||||||
}
|
}
|
||||||
Chunk chunk = world[idx];
|
Chunk &chunk = world.chunks[idx];
|
||||||
RebuildOpaqueMask(&chunk);
|
RebuildOpaqueMask(chunk);
|
||||||
|
|
||||||
MeshData renderDataOpq = GenerateChunkMesh(GenerateCRDOpaque(chunk, world), chunk, x, y, 0xFF);
|
MeshData renderDataOpq = GenerateChunkMesh(GenerateCRDOpaque(chunk, world), chunk, x, y, 0xFF);
|
||||||
MeshData renderDataTsl = GenerateChunkMesh(GenerateCRDTranslucent(chunk, world), chunk, x, y, 0xFF);
|
MeshData renderDataTsl = GenerateChunkMesh(GenerateCRDTranslucent(chunk, world), chunk, x, y, 0xFF);
|
||||||
@@ -387,7 +385,7 @@ void PlayRandomMusic() {
|
|||||||
PlayMusicStream(currentMusic);
|
PlayMusicStream(currentMusic);
|
||||||
}
|
}
|
||||||
static int _blockPlacedC = 0;
|
static int _blockPlacedC = 0;
|
||||||
void SetBlockNetwork(Chunk world[], int bx, int by, int bz, int t) {
|
void SetBlockNetwork(World &world, int bx, int by, int bz, int t) {
|
||||||
float pitch = GetRandomValue(-100, 100) / 100.0f * 0.25f + 1.0f;
|
float pitch = GetRandomValue(-100, 100) / 100.0f * 0.25f + 1.0f;
|
||||||
int sound = B_Stone;
|
int sound = B_Stone;
|
||||||
tickedBlocks.push({bx, by, bz});
|
tickedBlocks.push({bx, by, bz});
|
||||||
@@ -451,7 +449,7 @@ void SetBlockNetwork(Chunk world[], int bx, int by, int bz, int t) {
|
|||||||
data[2] = (uint8_t)by;
|
data[2] = (uint8_t)by;
|
||||||
data[3] = (uint8_t)bz;
|
data[3] = (uint8_t)bz;
|
||||||
data[4] = (uint8_t)t;
|
data[4] = (uint8_t)t;
|
||||||
SendPacketR(peer, data, sizeof(data));
|
SendPacketR(peer, data, 5);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SetBlock(world, bx, by, bz, t);
|
SetBlock(world, bx, by, bz, t);
|
||||||
@@ -482,9 +480,9 @@ static void TickAvailableBlocks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::atomic_bool serverStarted;
|
|
||||||
int TryConnect(const char* hostname) {
|
int TryConnect(const char* hostname) {
|
||||||
client = StartClient();
|
/*client = StartClient();
|
||||||
|
|
||||||
if(client == NULL)
|
if(client == NULL)
|
||||||
{
|
{
|
||||||
@@ -499,7 +497,7 @@ int TryConnect(const char* hostname) {
|
|||||||
int s = enet_address_set_host (& address, hostname);
|
int s = enet_address_set_host (& address, hostname);
|
||||||
address.port = PORT;
|
address.port = PORT;
|
||||||
|
|
||||||
peer = enet_host_connect(client, &address, 1, 0);
|
peer = enet_host_connect(client, &address, 1);
|
||||||
|
|
||||||
if (peer == NULL)
|
if (peer == NULL)
|
||||||
{
|
{
|
||||||
@@ -514,7 +512,7 @@ int TryConnect(const char* hostname) {
|
|||||||
puts ("Connection succeeded.");
|
puts ("Connection succeeded.");
|
||||||
char data[1];
|
char data[1];
|
||||||
data[0] = NET_ARG_REQWORLD;
|
data[0] = NET_ARG_REQWORLD;
|
||||||
SendPacketR(peer, data, 1);
|
SendPacketR(peer, data, 1); // Tell the server to send all chunks
|
||||||
online = true;
|
online = true;
|
||||||
state = GAME_STATE_LOADING;
|
state = GAME_STATE_LOADING;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -524,30 +522,9 @@ int TryConnect(const char* hostname) {
|
|||||||
enet_peer_reset (peer);
|
enet_peer_reset (peer);
|
||||||
|
|
||||||
return NET_ERROR_FAILED;
|
return NET_ERROR_FAILED;
|
||||||
}
|
}*/
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//std::thread serverThread;
|
|
||||||
std::atomic_bool stop_server = false;
|
|
||||||
void StartInternalServer(std::atomic_bool& started);
|
|
||||||
/*void ServerThread(std::atomic_bool& started) {
|
|
||||||
StartInternalServer(started);
|
|
||||||
stop_server = false;
|
|
||||||
while(true) {
|
|
||||||
if (stop_server)
|
|
||||||
return;
|
|
||||||
ServerNetworkUpdate();
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
/*void InitSingleplayer() {
|
|
||||||
online = true;
|
|
||||||
serverThread = std::thread(ServerThread, std::ref(serverStarted));
|
|
||||||
int result = TryConnect("localhost");
|
|
||||||
if(result == NET_ERROR_FAILED) {
|
|
||||||
state = GAME_STATE_MAINMENU;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
std::vector<MessageData> messages;
|
std::vector<MessageData> messages;
|
||||||
bool survival = false;
|
bool survival = false;
|
||||||
bool chatOpen = false;
|
bool chatOpen = false;
|
||||||
@@ -887,7 +864,7 @@ static void GameUpdate(Camera camera, float &time) {
|
|||||||
}
|
}
|
||||||
double PROFCOUNT = GetTime();
|
double PROFCOUNT = GetTime();
|
||||||
if (bestIdx != -1) {
|
if (bestIdx != -1) {
|
||||||
RebuildOpaqueMask(&world[bestIdx]);
|
RebuildOpaqueMask(world.chunks[bestIdx]);
|
||||||
int bx, by;
|
int bx, by;
|
||||||
GetXZFromIndex(bestIdx, &bx, &by);
|
GetXZFromIndex(bestIdx, &bx, &by);
|
||||||
RemeshChunk(bx, by);
|
RemeshChunk(bx, by);
|
||||||
@@ -946,7 +923,7 @@ static void GameUpdate(Camera camera, float &time) {
|
|||||||
_z *= CHUNK_SIZE;
|
_z *= CHUNK_SIZE;
|
||||||
|
|
||||||
if(!loadedChunks[x]) continue;
|
if(!loadedChunks[x]) continue;
|
||||||
if(!IsChunkInFrustum(frustum, world[x], _x, _z)) continue;
|
if(!IsChunkInFrustum(frustum, world.chunks[x], _x, _z)) continue;
|
||||||
DrawModel(rendering[x].model, {0, 0, 0}, 1, WHITE);
|
DrawModel(rendering[x].model, {0, 0, 0}, 1, WHITE);
|
||||||
debug_verts_opaque += rendering[x].vertices;
|
debug_verts_opaque += rendering[x].vertices;
|
||||||
}
|
}
|
||||||
@@ -1014,7 +991,7 @@ static void GameUpdate(Camera camera, float &time) {
|
|||||||
if (!loadedChunks[i]) continue;
|
if (!loadedChunks[i]) continue;
|
||||||
int cx, cz;
|
int cx, cz;
|
||||||
GetXZFromIndex(i, &cx, &cz);
|
GetXZFromIndex(i, &cx, &cz);
|
||||||
if (!IsChunkInFrustum(frustum, world[i], cx*CHUNK_SIZE, cz*CHUNK_SIZE)) continue;
|
if (!IsChunkInFrustum(frustum, world.chunks[i], cx*CHUNK_SIZE, cz*CHUNK_SIZE)) continue;
|
||||||
float wx = cx * CHUNK_SIZE + CHUNK_SIZE * 0.5f;
|
float wx = cx * CHUNK_SIZE + CHUNK_SIZE * 0.5f;
|
||||||
float wz = cz * CHUNK_SIZE + CHUNK_SIZE * 0.5f;
|
float wz = cz * CHUNK_SIZE + CHUNK_SIZE * 0.5f;
|
||||||
float dx = wx - camera.position.x;
|
float dx = wx - camera.position.x;
|
||||||
@@ -1157,10 +1134,12 @@ static void GameUpdate(Camera camera, float &time) {
|
|||||||
if(msg != nullptr) {
|
if(msg != nullptr) {
|
||||||
chatOpen = false;
|
chatOpen = false;
|
||||||
DisableCursor();
|
DisableCursor();
|
||||||
char data[1+MAX_MESSAGE_LENGTH];
|
if(online) {
|
||||||
data[0] = NET_ARG_MESSAGEC;
|
char data[1+MAX_MESSAGE_LENGTH];
|
||||||
memcpy(data+1, msg, MAX_MESSAGE_LENGTH);
|
data[0] = NET_ARG_MESSAGEC;
|
||||||
SendPacketR(peer, data, 1+MAX_MESSAGE_LENGTH);
|
memcpy(data+1, msg, MAX_MESSAGE_LENGTH);
|
||||||
|
SendPacketR(peer, data, 1+MAX_MESSAGE_LENGTH);
|
||||||
|
}
|
||||||
memset(msg, 0, MAX_MESSAGE_LENGTH);
|
memset(msg, 0, MAX_MESSAGE_LENGTH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1187,9 +1166,11 @@ static void GameStart() {
|
|||||||
}
|
}
|
||||||
LoadPlayerData();
|
LoadPlayerData();
|
||||||
//PlayRandomMusic();
|
//PlayRandomMusic();
|
||||||
char data[1];
|
if(online) {
|
||||||
data[0] = NET_ARG_REQPLAYERS;
|
char data[1];
|
||||||
SendPacketR(peer, data, 1);
|
data[0] = NET_ARG_REQPLAYERS;
|
||||||
|
SendPacketR(peer, data, 1); // Tell the server to fetch all players
|
||||||
|
}
|
||||||
|
|
||||||
camera = { 0 };
|
camera = { 0 };
|
||||||
camera.position = (Vector3){ MAX_WORLD_SIZE / 2 * CHUNK_SIZE, 12.0f, MAX_WORLD_SIZE / 2 * CHUNK_SIZE};
|
camera.position = (Vector3){ MAX_WORLD_SIZE / 2 * CHUNK_SIZE, 12.0f, MAX_WORLD_SIZE / 2 * CHUNK_SIZE};
|
||||||
@@ -1200,7 +1181,7 @@ static void GameStart() {
|
|||||||
|
|
||||||
int center = MAX_WORLD_SIZE / 2 * CHUNK_SIZE;
|
int center = MAX_WORLD_SIZE / 2 * CHUNK_SIZE;
|
||||||
player_position = (Vector3){ MAX_WORLD_SIZE / 2 * CHUNK_SIZE, 128.0f, MAX_WORLD_SIZE / 2 * CHUNK_SIZE};
|
player_position = (Vector3){ MAX_WORLD_SIZE / 2 * CHUNK_SIZE, 128.0f, MAX_WORLD_SIZE / 2 * CHUNK_SIZE};
|
||||||
player_position.y = world[GetIndexWorld(center / 16, center / 16)].highestBlock[0] + 2;
|
player_position.y = world.chunks[GetIndexWorld(center / 16, center / 16)].highestBlock[0] + 2;
|
||||||
player_velocity = (Vector3){ 0, 0, 0 };
|
player_velocity = (Vector3){ 0, 0, 0 };
|
||||||
|
|
||||||
DisableCursor();
|
DisableCursor();
|
||||||
@@ -1251,6 +1232,8 @@ static void ParseData(ENetPacket* packet) {
|
|||||||
{
|
{
|
||||||
a_data.push_back(packet->data[i]);
|
a_data.push_back(packet->data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (a_data[0])
|
switch (a_data[0])
|
||||||
{
|
{
|
||||||
case NET_ARG_CHUNKF:
|
case NET_ARG_CHUNKF:
|
||||||
@@ -1403,14 +1386,10 @@ void NetworkUpdate() {
|
|||||||
|
|
||||||
void GameModeCleanupFull() {
|
void GameModeCleanupFull() {
|
||||||
if(online) {
|
if(online) {
|
||||||
|
|
||||||
enet_host_destroy(client);
|
enet_host_destroy(client);
|
||||||
online = false;
|
online = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_server = true;
|
|
||||||
//serverThread.join();
|
|
||||||
|
|
||||||
for (int idx = 0; idx < MAX_WORLD_AREA; idx++)
|
for (int idx = 0; idx < MAX_WORLD_AREA; idx++)
|
||||||
{
|
{
|
||||||
if(loadedChunks[idx]) {
|
if(loadedChunks[idx]) {
|
||||||
@@ -1439,7 +1418,6 @@ extern void InitMenu();
|
|||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
SetTraceLogLevel(LOG_WARNING);
|
SetTraceLogLevel(LOG_WARNING);
|
||||||
NetworkingStart();
|
|
||||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
||||||
InitWindow(WIDTH, HEIGHT, GAME_NAME);
|
InitWindow(WIDTH, HEIGHT, GAME_NAME);
|
||||||
InitWorldgen(0);
|
InitWorldgen(0);
|
||||||
@@ -1496,7 +1474,6 @@ int main(void)
|
|||||||
GetXZFromIndex(idx, &x, &z);
|
GetXZFromIndex(idx, &x, &z);
|
||||||
c.x = (uint8_t)x;
|
c.x = (uint8_t)x;
|
||||||
c.z = (uint8_t)z;
|
c.z = (uint8_t)z;
|
||||||
std::cout << data.size() << std::endl;
|
|
||||||
for (int i = 2; i < CHUNK_DATA_SIZE+2; i++)
|
for (int i = 2; i < CHUNK_DATA_SIZE+2; i++)
|
||||||
{
|
{
|
||||||
c.blocks[i-2] = data[i];
|
c.blocks[i-2] = data[i];
|
||||||
@@ -1505,7 +1482,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
c.highestBlock[i-CHUNK_DATA_SIZE-2] = data[i];
|
c.highestBlock[i-CHUNK_DATA_SIZE-2] = data[i];
|
||||||
}
|
}
|
||||||
world[idx] = c;
|
world.chunks[idx] = c;
|
||||||
dirtyChunks[idx] = true;
|
dirtyChunks[idx] = true;
|
||||||
worldPacketStack.pop();
|
worldPacketStack.pop();
|
||||||
fetchedChunks++;
|
fetchedChunks++;
|
||||||
@@ -1552,7 +1529,7 @@ int main(void)
|
|||||||
int idx = x + y * MAX_WORLD_SIZE;
|
int idx = x + y * MAX_WORLD_SIZE;
|
||||||
if(worldCreationStep == 0 && !online) {
|
if(worldCreationStep == 0 && !online) {
|
||||||
Chunk chunk = GenerateChunk(x, y);
|
Chunk chunk = GenerateChunk(x, y);
|
||||||
world[idx] = chunk;
|
world.chunks[idx] = chunk;
|
||||||
}
|
}
|
||||||
if(worldCreationStep == 1 && !online) {
|
if(worldCreationStep == 1 && !online) {
|
||||||
if(worldCreationProgress > 0) {
|
if(worldCreationProgress > 0) {
|
||||||
@@ -1564,12 +1541,14 @@ int main(void)
|
|||||||
}
|
}
|
||||||
if (worldCreationStep == 2)
|
if (worldCreationStep == 2)
|
||||||
{
|
{
|
||||||
//RebuildOpaqueMask(&world[idx]);
|
RebuildOpaqueMask(world.chunks[idx]);
|
||||||
}
|
}
|
||||||
if (worldCreationStep == 3) {
|
if (worldCreationStep == 3) {
|
||||||
dirtyChunks[idx] = true;
|
dirtyChunks[idx] = true;
|
||||||
}
|
}
|
||||||
if(online)
|
if(!(worldCreationStep == 0 && online))
|
||||||
|
worldCreationProgress++;
|
||||||
|
else
|
||||||
worldCreationProgress = fetchedChunks+1;
|
worldCreationProgress = fetchedChunks+1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1603,7 +1582,7 @@ int main(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enet_deinitialize();
|
|
||||||
GameModeCleanupFull();
|
GameModeCleanupFull();
|
||||||
|
|
||||||
UnloadTexture(terrain);
|
UnloadTexture(terrain);
|
||||||
|
|||||||
Reference in New Issue
Block a user