mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
fix: correct neighbor block indexing and add time update support
This commit is contained in:
@@ -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<const void*>(&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<BlockType>(b));
|
||||
}
|
||||
// temp neighbor block data
|
||||
if (data.neighbor_blocks_1_size() == BLOCK_SIZE) {
|
||||
neighbor[0] = std::vector<BlockType>();
|
||||
neighbor[0]->reserve(BLOCK_SIZE);
|
||||
for (const auto& b : data.chunk_blocks()) {
|
||||
neighbor[0]->push_back(static_cast<BlockType>(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<BlockType>(b));
|
||||
}
|
||||
}
|
||||
if (data.neighbor_blocks_2_size() == BLOCK_SIZE) {
|
||||
neighbor[1] = std::vector<BlockType>();
|
||||
neighbor[1]->reserve(BLOCK_SIZE);
|
||||
for (const auto& b : data.chunk_blocks()) {
|
||||
neighbor[1]->push_back(static_cast<BlockType>(b));
|
||||
}
|
||||
}
|
||||
if (data.neighbor_blocks_3_size() == BLOCK_SIZE) {
|
||||
neighbor[2] = std::vector<BlockType>();
|
||||
neighbor[2]->reserve(BLOCK_SIZE);
|
||||
for (const auto& b : data.chunk_blocks()) {
|
||||
neighbor[2]->push_back(static_cast<BlockType>(b));
|
||||
}
|
||||
}
|
||||
if (data.neighbor_blocks_3_size() == BLOCK_SIZE) {
|
||||
neighbor[3] = std::vector<BlockType>();
|
||||
neighbor[3]->reserve(BLOCK_SIZE);
|
||||
for (const auto& b : data.chunk_blocks()) {
|
||||
neighbor[3]->push_back(static_cast<BlockType>(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();
|
||||
|
||||
@@ -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<float>(x + 1),
|
||||
static_cast<float>(y + 1),
|
||||
static_cast<float>(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<float>(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<float>(y + 1),
|
||||
static_cast<float>(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<float>(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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -64,11 +64,12 @@ asio::awaitable<void> 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<PacketEnum>;
|
||||
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<void> 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) {
|
||||
|
||||
@@ -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<const void*>(&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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Session> 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));
|
||||
}
|
||||
|
||||
|
||||
@@ -58,10 +58,10 @@ asio::awaitable<void> 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<PacketEnum>;
|
||||
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<void> 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<void> 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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user