110 lines
4.1 KiB
C++
110 lines
4.1 KiB
C++
#include <deerith/server/internals/world.h>
|
|
|
|
#include <deerith/world/environment.h>
|
|
#include <deerith/network/packets_voxel.h>
|
|
#include <deerith/network/router.h>
|
|
#include <unordered_map>
|
|
|
|
namespace deerith
|
|
{
|
|
struct component_client_environment_knowledge_t
|
|
{
|
|
std::unordered_map<glm::ivec3, int32_t, ivec3_hash_t> cluster_knowledge;
|
|
};
|
|
|
|
void check_client_surface_knowledge(client_t *, component_client_environment_knowledge_t &knowledge, glm::ivec3 position);
|
|
bool check_client_cluster_knowledge(client_t *client, component_client_environment_knowledge_t &knowledge, surface_t *surface);
|
|
|
|
void send_cluster_info_to_client(client_t *, voxel_cluster_t *);
|
|
}
|
|
|
|
void deerith::send_voxel_data_to_client(client_t *client)
|
|
{
|
|
packet_voxel_data_definition_t voxel_data_definition;
|
|
voxel_data_definition.voxel_materials = get_voxel_material_vector();
|
|
voxel_data_definition.voxel_types = get_voxel_type_vector();
|
|
|
|
router_send_packet(voxel_data_definition, client);
|
|
}
|
|
|
|
void deerith::send_clients_environment_data()
|
|
{
|
|
// temp solution to assign this component to clients that don't have it
|
|
{
|
|
auto no_surface_knowledge_component_clients = get_entity_registry().view<component_client_link_t>(entt::exclude<component_client_environment_knowledge_t>);
|
|
for (auto [entity, client_link] : no_surface_knowledge_component_clients.each())
|
|
{
|
|
add_component<component_client_environment_knowledge_t>(entity);
|
|
}
|
|
}
|
|
|
|
auto update_surface_knowledge_to_clients = get_entity_registry().view<component_client_link_t, component_sync_coordinates_t, component_client_environment_knowledge_t>();
|
|
for (auto [entity, client_link, entity_position, surface_knowledge] : update_surface_knowledge_to_clients.each())
|
|
{
|
|
check_client_surface_knowledge(client_link.client, surface_knowledge, entity_position.position.read_value());
|
|
}
|
|
}
|
|
|
|
void deerith::check_client_surface_knowledge(client_t *client, component_client_environment_knowledge_t &knowledge, glm::ivec3 position)
|
|
{
|
|
const int surface_x = static_cast<int>(std::floor(position.x / CLUSTER_SIZE));
|
|
const int surface_z = static_cast<int>(std::floor(position.z / CLUSTER_SIZE));
|
|
|
|
const int SURFACE_RADIUS = 4;
|
|
|
|
for (int x = -SURFACE_RADIUS; x <= SURFACE_RADIUS; x++)
|
|
{
|
|
for (int z = -SURFACE_RADIUS; z <= SURFACE_RADIUS; z++)
|
|
{
|
|
glm::ivec2 surface_id = {surface_x + x, surface_z + z};
|
|
surface_t *surface = get_surface(surface_id);
|
|
|
|
if (surface != nullptr)
|
|
{
|
|
if (check_client_cluster_knowledge(client, knowledge, surface))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool deerith::check_client_cluster_knowledge(client_t *client, component_client_environment_knowledge_t &knowledge, surface_t *surface)
|
|
{
|
|
for (int i = 0; i < surface->voxel_clusters.size(); i++)
|
|
{
|
|
voxel_cluster_t *cluster = surface->voxel_clusters[i].get();
|
|
int32_t cluster_last_update = cluster->last_update_tick_id;
|
|
|
|
int32_t actual_cluster_kknowledge = -1;
|
|
glm::ivec3 cluster_id = glm::ivec3(surface->surface_id.x, cluster->layer, surface->surface_id.y);
|
|
if (knowledge.cluster_knowledge.contains(cluster_id))
|
|
{
|
|
actual_cluster_kknowledge = knowledge.cluster_knowledge[cluster_id];
|
|
}
|
|
|
|
if (actual_cluster_kknowledge < cluster_last_update)
|
|
{
|
|
knowledge.cluster_knowledge[cluster_id] = cluster_last_update;
|
|
send_cluster_info_to_client(client, cluster);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void deerith::send_cluster_info_to_client(client_t *client, voxel_cluster_t *cluster)
|
|
{
|
|
start_chrono();
|
|
packet_cluster_data_t cluster_data;
|
|
cluster_data.surface_id = cluster->surface_id;
|
|
cluster_data.layer = cluster->layer;
|
|
cluster_data.__cluster_data = std::make_unique<cluster_voxel_type_id_data_t>();
|
|
|
|
*cluster_data.__cluster_data = cluster->__data;
|
|
|
|
router_send_packet(cluster_data, client);
|
|
deerith_trace("sent cluster data to client in {} ms", get_chrono_ms());
|
|
} |