diff --git a/include/Cubed/gameplay/biome.hpp b/include/Cubed/gameplay/biome.hpp index 3cab7ab..da0a499 100644 --- a/include/Cubed/gameplay/biome.hpp +++ b/include/Cubed/gameplay/biome.hpp @@ -80,7 +80,7 @@ DesertParams& desert_params(); MountainParams& mountain_params(); RiverParams& river_params(); -inline BiomeType get_biome(int id) { +inline BiomeType get_biome_from_id(int id) { using enum BiomeType; auto to = std::to_underlying; if (id == to(PLAIN)) { diff --git a/include/Cubed/gameplay/client_player.hpp b/include/Cubed/gameplay/client_player.hpp index 8afb594..b7ae386 100644 --- a/include/Cubed/gameplay/client_player.hpp +++ b/include/Cubed/gameplay/client_player.hpp @@ -16,7 +16,7 @@ class ClientPlayer { public: ClientPlayer(ClientWorld& world); ~ClientPlayer(); - AABB get_aabb() const; + AABB get_aabb(const glm::vec3& pos) const; const glm::vec3& get_front() const; const Gait& get_gait() const; const std::optional& get_look_block_pos() const; diff --git a/src/gameplay/client_chunk.cpp b/src/gameplay/client_chunk.cpp index 44465cb..58ff06b 100644 --- a/src/gameplay/client_chunk.cpp +++ b/src/gameplay/client_chunk.cpp @@ -96,7 +96,11 @@ inline int choose_buf(BlockType id) { } } // namespace -ClientChunk::ClientChunk(ClientWorld& world) : m_world(world) {} +ClientChunk::ClientChunk(ClientWorld& world) : m_world(world) { + for (int i = 0; i < VERTEX_DATA_SUM; i++) { + m_vertex_data.emplace_back(m_world); + } +} ClientChunk::~ClientChunk() {} ClientChunk::ClientChunk(ClientChunk&& other) noexcept @@ -110,7 +114,9 @@ ClientChunk& ClientChunk::operator=(ClientChunk&& other) noexcept { // Logger::info("other Chunk pos {} {} in Chunk& Chunk::operator=(Chunk&& // other) this {}", other.m_chunk_pos.x, other.m_chunk_pos.z, // static_cast(&other)); - + if (this == &other) { + return *this; + } m_chunk_pos = std::move(other.m_chunk_pos); m_blocks = std::move(other.m_blocks); m_dirty = other.is_dirty(); @@ -498,6 +504,11 @@ void ClientChunk::gen_cross_plane_vertices(int world_x, int world_y, void ClientChunk::receive_chunk(const ChunkDataRsp& data) { OptionalBlockVectorArray neighbor; + m_chunk_pos.x = data.pos().x(); + m_chunk_pos.z = data.pos().z(); + m_seed = data.chunk_seed(); + m_biome = get_biome_from_id(data.biome_type()); + for (int i = 0; i < 4; i++) { neighbor[i] = std::nullopt; } @@ -506,41 +517,28 @@ void ClientChunk::receive_chunk(const ChunkDataRsp& data) { Logger::error("Bad Chunk, size {}", data.chunk_blocks_size()); return; } - m_blocks.reserve(BLOCK_SIZE); for (const auto& b : data.chunk_blocks()) { m_blocks.push_back(static_cast(b)); } // temp neighbor block data - if (data.neighbor_blocks_1_size() == BLOCK_SIZE) { - neighbor[0] = std::vector(); - neighbor[0]->reserve(BLOCK_SIZE); - for (const auto& b : data.chunk_blocks()) { - neighbor[0]->push_back(static_cast(b)); + auto load_neighbor = [&](int idx, const auto& blocks) { + if (blocks.size() != BLOCK_SIZE) + return; + + neighbor[idx].emplace(); + neighbor[idx]->reserve(BLOCK_SIZE); + + for (auto b : blocks) { + neighbor[idx]->push_back(static_cast(b)); } - } - if (data.neighbor_blocks_2_size() == BLOCK_SIZE) { - neighbor[1] = std::vector(); - neighbor[1]->reserve(BLOCK_SIZE); - for (const auto& b : data.chunk_blocks()) { - neighbor[1]->push_back(static_cast(b)); - } - } - if (data.neighbor_blocks_3_size() == BLOCK_SIZE) { - neighbor[2] = std::vector(); - neighbor[2]->reserve(BLOCK_SIZE); - for (const auto& b : data.chunk_blocks()) { - neighbor[2]->push_back(static_cast(b)); - } - } - if (data.neighbor_blocks_3_size() == BLOCK_SIZE) { - neighbor[3] = std::vector(); - neighbor[3]->reserve(BLOCK_SIZE); - for (const auto& b : data.chunk_blocks()) { - neighbor[3]->push_back(static_cast(b)); - } - } + }; + + load_neighbor(0, data.neighbor_blocks_1()); + load_neighbor(1, data.neighbor_blocks_2()); + load_neighbor(2, data.neighbor_blocks_3()); + load_neighbor(3, data.neighbor_blocks_4()); gen_vertex_data(neighbor); mark_dirty(); diff --git a/src/gameplay/client_player.cpp b/src/gameplay/client_player.cpp index a66bc63..2aa0ebf 100644 --- a/src/gameplay/client_player.cpp +++ b/src/gameplay/client_player.cpp @@ -8,15 +8,13 @@ namespace Cubed { ClientPlayer::ClientPlayer(ClientWorld& world) : m_world(world) {} ClientPlayer::~ClientPlayer() {} -AABB ClientPlayer::get_aabb() const { +AABB ClientPlayer::get_aabb(const glm::vec3& pos) const { float half_width = m_size.x / 2.0f; float half_depth = m_size.z / 2.0f; - glm::vec3 min{m_player_pos.x - half_width, m_player_pos.y, - m_player_pos.z - half_depth}; + glm::vec3 min{pos.x - half_width, pos.y, pos.z - half_depth}; - glm::vec3 max{m_player_pos.x + half_width, m_player_pos.y + m_size.y, - m_player_pos.z + half_depth}; + glm::vec3 max{pos.x + half_width, pos.y + m_size.y, pos.z + half_depth}; return AABB{min, max}; } @@ -293,7 +291,7 @@ void ClientPlayer::update_lookup_block() { glm::vec3{static_cast(x + 1), static_cast(y + 1), static_cast(z + 1)}}; - AABB player_box = get_aabb(); + AABB player_box = get_aabb(get_player_pos()); if (!player_box.intersects(block_box)) { m_world.report_block_change(near_pos, m_place_block); } @@ -394,12 +392,12 @@ void ClientPlayer::update_move(float delta_time) { } } -void ClientPlayer::update_x_move(glm::vec3& m_player_pos) { - m_player_pos.x += move_distance.x; +void ClientPlayer::update_x_move(glm::vec3& player_pos) { + player_pos.x += move_distance.x; if (m_game_mode == SPECTATOR) { return; } - AABB player_box = get_aabb(); + AABB player_box = get_aabb(player_pos); int minx = std::floor(player_box.min.x); int maxx = std::floor(player_box.max.x); int miny = std::floor(player_box.min.y); @@ -419,7 +417,7 @@ void ClientPlayer::update_x_move(glm::vec3& m_player_pos) { static_cast(z + 1)}}; if (player_box.intersects(block_box)) { m_gait = Gait::WALK; - m_player_pos.x -= move_distance.x; + player_pos.x -= move_distance.x; return; } } @@ -428,12 +426,12 @@ void ClientPlayer::update_x_move(glm::vec3& m_player_pos) { } } -void ClientPlayer::update_y_move(glm::vec3& m_player_pos) { - m_player_pos.y += move_distance.y; +void ClientPlayer::update_y_move(glm::vec3& player_pos) { + player_pos.y += move_distance.y; if (m_game_mode == SPECTATOR) { return; } - AABB player_box = get_aabb(); + AABB player_box = get_aabb(player_pos); int minx = std::floor(player_box.min.x); int maxx = std::floor(player_box.max.x); int miny = std::floor(player_box.min.y); @@ -452,7 +450,7 @@ void ClientPlayer::update_y_move(glm::vec3& m_player_pos) { static_cast(y + 1), static_cast(z + 1)}}; if (player_box.intersects(block_box)) { - m_player_pos.y -= move_distance.y; + player_pos.y -= move_distance.y; m_y_speed = 0.0f; if (move_distance.y < 0) { can_up = true; @@ -466,12 +464,12 @@ void ClientPlayer::update_y_move(glm::vec3& m_player_pos) { } } -void ClientPlayer::update_z_move(glm::vec3& m_player_pos) { - m_player_pos.z += move_distance.z; +void ClientPlayer::update_z_move(glm::vec3& player_pos) { + player_pos.z += move_distance.z; if (m_game_mode == SPECTATOR) { return; } - AABB player_box = get_aabb(); + AABB player_box = get_aabb(player_pos); int minx = std::floor(player_box.min.x); int maxx = std::floor(player_box.max.x); int miny = std::floor(player_box.min.y); @@ -491,7 +489,7 @@ void ClientPlayer::update_z_move(glm::vec3& m_player_pos) { static_cast(z + 1)}}; if (player_box.intersects(block_box)) { m_gait = Gait::WALK; - m_player_pos.z -= move_distance.z; + player_pos.z -= move_distance.z; return; } } diff --git a/src/gameplay/client_world.cpp b/src/gameplay/client_world.cpp index 2f33846..9f40bef 100644 --- a/src/gameplay/client_world.cpp +++ b/src/gameplay/client_world.cpp @@ -197,7 +197,7 @@ void ClientWorld::init(std::string_view player_name, m_client = client; // timer register_timer("player_pos", 2, [this]() { report_player_pos(); }); - + // register_timer("chunk_request", 20, [this]() { request_chunk(); }); LoginReq req; req.set_name(m_player.get_name()); while (!client->is_connected()) { @@ -219,6 +219,7 @@ void ClientWorld::start_client_thread(std::string_view uuid) { m_game_running = true; client_run(token); }); + request_chunk(); } void ClientWorld::stop_client_thread() { @@ -317,6 +318,7 @@ void ClientWorld::receive_chunk(const ChunkDataRsp& data) { { std::lock_guard lock(m_pending_queue_mutex); m_pending_queue.emplace_back(std::move(chunk)); + Logger::info("ClientWorld Add a new pending chunk"); } } @@ -341,8 +343,10 @@ void ClientWorld::update(float delta_time) { { std::lock_guard lock(m_pending_queue_mutex); for (auto& c : m_pending_queue) { + // Logger::info("{} {}", c.get_chunk_pos().x, c.get_chunk_pos().z); new_chunks.emplace_back(std::move(c)); } + m_pending_queue.clear(); } for (auto& c : new_chunks) { c.upload_to_gpu(); diff --git a/src/gameplay/network_client.cpp b/src/gameplay/network_client.cpp index 6663071..68febaa 100644 --- a/src/gameplay/network_client.cpp +++ b/src/gameplay/network_client.cpp @@ -64,11 +64,12 @@ asio::awaitable NetworkClient::read_loop() { co_await asio::async_read(m_socket, asio::buffer(body_data), asio::use_awaitable); } - Logger::info("Client: Receive cmd {}", cmd_id); + constexpr auto& to_num = std::to_underlying; switch (cmd_id) { case to_num(PacketEnum::LOGIN_RSP): { LoginRsp rsp; + Logger::info("Client: Receive Login rsp"); if (rsp.ParseFromArray(body_data.data(), body_data.size())) { if (rsp.success()) { m_world.start_client_thread(rsp.uuid()); @@ -79,16 +80,24 @@ asio::awaitable NetworkClient::read_loop() { } break; case to_num(PacketEnum::CHUNK_DATA_RSP): { ChunkDataRsp rsp; + Logger::info("Client: Receive Chunk Data rsp"); if (rsp.ParseFromArray(body_data.data(), body_data.size())) { m_world.receive_chunk(rsp); } } break; case to_num(PacketEnum::BLOCK_CHANGE_RSP): { BlockChangeRsp rsp; + Logger::info("Client: Receive Block Change rsp"); if (rsp.ParseFromArray(body_data.data(), body_data.size())) { m_world.receive_block_change(rsp); } } break; + case to_num(PacketEnum::UPDATE_TIME): { + UpdateTime rsp; + if (rsp.ParseFromArray(body_data.data(), body_data.size())) { + m_world.receive_time(rsp); + } + } } } } catch (const asio::system_error& e) { diff --git a/src/gameplay/server_chunk.cpp b/src/gameplay/server_chunk.cpp index aba890e..619f880 100644 --- a/src/gameplay/server_chunk.cpp +++ b/src/gameplay/server_chunk.cpp @@ -8,21 +8,29 @@ ServerChunk::ServerChunk(ServerWorld& world, ChunkPos chunk_pos, : m_temp_chunk(temp_chunk), m_chunk_pos(chunk_pos), m_world(world) {} ServerChunk::ServerChunk(ServerChunk&& other) noexcept - : m_biome(other.m_biome.load()), m_chunk_pos(std::move(other.m_chunk_pos)), + : m_gening(other.m_gening.load()), m_has_cave(other.m_has_cave), + m_biome(other.m_biome.load()), m_chunk_pos(std::move(other.m_chunk_pos)), m_world(other.m_world), m_heightmap(std::move(other.m_heightmap)), - m_blocks(std::move(other.m_blocks)), m_seed(other.m_seed), - m_conditions(other.m_conditions) {} + m_blocks(std::move(other.m_blocks)), + m_neightbor_blocks(std::move(other.m_neightbor_blocks)), + m_seed(other.m_seed), m_conditions(other.m_conditions) {} ServerChunk& ServerChunk::operator=(ServerChunk&& other) noexcept { // Logger::info("other Chunk pos {} {} in Chunk& Chunk::operator=(Chunk&& // other) this {}", other.m_chunk_pos.x, other.m_chunk_pos.z, // static_cast(&other)); + if (this == &other) { + return *this; + } m_chunk_pos = std::move(other.m_chunk_pos); m_heightmap = std::move(other.m_heightmap); m_blocks = std::move(other.m_blocks); m_biome = other.m_biome.load(); m_seed = other.m_seed; m_conditions = other.m_conditions; + m_neightbor_blocks = std::move(other.m_neightbor_blocks); + m_has_cave = other.m_has_cave; + m_gening = other.m_gening.load(); return *this; } diff --git a/src/gameplay/server_world.cpp b/src/gameplay/server_world.cpp index 96eb110..e0cc255 100644 --- a/src/gameplay/server_world.cpp +++ b/src/gameplay/server_world.cpp @@ -477,10 +477,10 @@ void ServerWorld::handle_chunk_req(const std::string& uuid, ChunkPos pos) { auto* nb2 = rsq.mutable_neighbor_blocks_2(); auto* nb3 = rsq.mutable_neighbor_blocks_3(); auto* nb4 = rsq.mutable_neighbor_blocks_4(); - assign(nb1, neighbor_blocks[1]); - assign(nb2, neighbor_blocks[2]); - assign(nb3, neighbor_blocks[3]); - assign(nb4, neighbor_blocks[4]); + assign(nb1, neighbor_blocks[0]); + assign(nb2, neighbor_blocks[1]); + assign(nb3, neighbor_blocks[2]); + assign(nb4, neighbor_blocks[3]); } std::shared_ptr s; { @@ -494,6 +494,7 @@ void ServerWorld::handle_chunk_req(const std::string& uuid, ChunkPos pos) { Logger::error("Player {} session not exist", uuid); return; } + s->send(make_packet(rsq)); } diff --git a/src/gameplay/session.cpp b/src/gameplay/session.cpp index 7e85aa0..11a4cae 100644 --- a/src/gameplay/session.cpp +++ b/src/gameplay/session.cpp @@ -58,10 +58,10 @@ asio::awaitable Session::read_loop() { co_await asio::async_read(m_socket, asio::buffer(body_data), asio::use_awaitable); } - Logger::info("Session: Receive cmd {}", cmd_id); constexpr auto& to_num = std::to_underlying; if (cmd_id == to_num(PacketEnum::LOGIN_REQ)) { LoginReq req; + Logger::info("Session: Receive Login req"); if (req.ParseFromArray(body_data.data(), body_data.size())) { m_server_world.handle_player_login(req.name(), shared_from_this()); @@ -77,6 +77,7 @@ asio::awaitable Session::read_loop() { } if (cmd_id == to_num(PacketEnum::CHUNK_DATA_REQ)) { ChunkDataReq req; + Logger::info("Session: Receive Chunk Data req"); if (req.ParseFromArray(body_data.data(), body_data.size())) { m_server_world.handle_chunk_req( req.uuid(), ChunkPos(req.pos().x(), req.pos().z())); @@ -84,6 +85,7 @@ asio::awaitable Session::read_loop() { } if (cmd_id == to_num(PacketEnum::BLOCK_CHANGE_REQ)) { BlockChangeReq req; + Logger::info("Session: Receive Block Change req"); if (req.ParseFromArray(body_data.data(), body_data.size())) { m_server_world.handle_block_change(req); }