[TerrainGenerator] Added. Lot of code removed from Chunk.
This commit is contained in:
parent
e3736d9176
commit
81368b2a66
@ -1,4 +1,4 @@
|
|||||||
# Generated by YCM Generator at 2018-06-05 01:25:36.562970
|
# Generated by YCM Generator at 2018-06-12 22:44:30.623231
|
||||||
|
|
||||||
# This file is NOT licensed under the GPLv3, which is the license for the rest
|
# This file is NOT licensed under the GPLv3, which is the license for the rest
|
||||||
# of YouCompleteMe.
|
# of YouCompleteMe.
|
||||||
@ -36,19 +36,20 @@ import ycm_core
|
|||||||
flags = [
|
flags = [
|
||||||
'-x',
|
'-x',
|
||||||
'c++',
|
'c++',
|
||||||
'-I/home/bazin_q/rendu/Perso/KubKraft/external',
|
|
||||||
'-I/home/bazin_q/rendu/Perso/KubKraft/include/core',
|
'-I/home/bazin_q/rendu/Perso/KubKraft/include/core',
|
||||||
'-I/home/bazin_q/rendu/Perso/KubKraft/include/display',
|
'-I/home/bazin_q/rendu/Perso/KubKraft/include/display',
|
||||||
'-I/home/bazin_q/rendu/Perso/KubKraft/include/gl',
|
'-I/home/bazin_q/rendu/Perso/KubKraft/include/gl',
|
||||||
'-I/home/bazin_q/rendu/Perso/KubKraft/include/states',
|
'-I/home/bazin_q/rendu/Perso/KubKraft/include/states',
|
||||||
'-I/home/bazin_q/rendu/Perso/KubKraft/include/system',
|
'-I/home/bazin_q/rendu/Perso/KubKraft/include/system',
|
||||||
|
'-I/home/bazin_q/rendu/Perso/KubKraft/include/utils',
|
||||||
'-I/home/bazin_q/rendu/Perso/KubKraft/include/world',
|
'-I/home/bazin_q/rendu/Perso/KubKraft/include/world',
|
||||||
|
'-I/home/bazin_q/rendu/Perso/KubKraft/include/world/gen',
|
||||||
'-I/usr/include/SDL2',
|
'-I/usr/include/SDL2',
|
||||||
'-Wall',
|
'-Wall',
|
||||||
'-Wextra',
|
'-Wextra',
|
||||||
'-Wfatal-errors',
|
'-Wfatal-errors',
|
||||||
'-Wno-variadic-macros',
|
'-Wno-variadic-macros',
|
||||||
'-std=c++11',
|
'-std=c++17',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,12 +18,9 @@
|
|||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
// #ifndef M_PI
|
#ifndef RADIANS_PER_DEGREES
|
||||||
// #define M_PI 3.14159265358979323846
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #define RADIANS_PER_DEGREES 0.0174532925199
|
|
||||||
#define RADIANS_PER_DEGREES (M_PI / 180.0f)
|
#define RADIANS_PER_DEGREES (M_PI / 180.0f)
|
||||||
|
#endif
|
||||||
|
|
||||||
class Camera {
|
class Camera {
|
||||||
public:
|
public:
|
||||||
|
25
include/utils/NonCopyable.hpp
Normal file
25
include/utils/NonCopyable.hpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* Filename: NonCopyable.hpp
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
* Created: 12/06/2018 22:23:46
|
||||||
|
*
|
||||||
|
* Author: Quentin Bazin, <quent42340@gmail.com>
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
#ifndef NONCOPYABLE_HPP_
|
||||||
|
#define NONCOPYABLE_HPP_
|
||||||
|
|
||||||
|
class NonCopyable {
|
||||||
|
protected:
|
||||||
|
NonCopyable() = default;
|
||||||
|
NonCopyable(const NonCopyable &) = delete;
|
||||||
|
|
||||||
|
const NonCopyable &operator=(const NonCopyable &) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NONCOPYABLE_HPP_
|
@ -24,15 +24,14 @@
|
|||||||
|
|
||||||
class Block {
|
class Block {
|
||||||
public:
|
public:
|
||||||
Block(u16 id);
|
Block(u32 id);
|
||||||
~Block();
|
|
||||||
|
|
||||||
glm::vec4 getTexCoords();
|
glm::vec4 getTexCoords();
|
||||||
|
|
||||||
u16 id() const { return m_id; }
|
u32 id() const { return m_id; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u16 m_id;
|
u32 m_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BLOCK_HPP_
|
#endif // BLOCK_HPP_
|
||||||
|
@ -19,19 +19,20 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Block.hpp"
|
#include "Block.hpp"
|
||||||
|
#include "NonCopyable.hpp"
|
||||||
#include "Shader.hpp"
|
#include "Shader.hpp"
|
||||||
#include "Texture.hpp"
|
#include "Texture.hpp"
|
||||||
#include "VertexBuffer.hpp"
|
#include "VertexBuffer.hpp"
|
||||||
|
|
||||||
class Chunk {
|
class Chunk : public NonCopyable {
|
||||||
public:
|
public:
|
||||||
Chunk(s32 x, s32 y, s32 z, Texture &texture);
|
Chunk(s32 x, s32 y, s32 z, Texture &texture);
|
||||||
|
|
||||||
void generate();
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
void draw(Shader &shader);
|
void draw(Shader &shader);
|
||||||
|
|
||||||
|
void addBlock(u32 id);
|
||||||
Block *getBlock(s8 x, s8 y, s8 z);
|
Block *getBlock(s8 x, s8 y, s8 z);
|
||||||
|
|
||||||
u32 getCoordID(u8 x, u8 y, u8 z, u8 i, u8 j, u8 coordinate);
|
u32 getCoordID(u8 x, u8 y, u8 z, u8 i, u8 j, u8 coordinate);
|
||||||
@ -41,16 +42,10 @@ class Chunk {
|
|||||||
|
|
||||||
bool vertexExists(u8 x, u8 y, u8 z, u8 i, u8 j);
|
bool vertexExists(u8 x, u8 y, u8 z, u8 i, u8 j);
|
||||||
|
|
||||||
static float noise2d(float x, float y, int seed, int octaves, float persistence);
|
|
||||||
static float noise3d_abs(float x, float y, float z, int seed, int octaves, float persistence);
|
|
||||||
|
|
||||||
s32 x() const { return m_x; }
|
s32 x() const { return m_x; }
|
||||||
s32 y() const { return m_y; }
|
s32 y() const { return m_y; }
|
||||||
s32 z() const { return m_z; }
|
s32 z() const { return m_z; }
|
||||||
|
|
||||||
bool initialized() const { return m_initialized; }
|
|
||||||
void setInitialized(bool initialized) { m_initialized = initialized; }
|
|
||||||
|
|
||||||
Chunk *left() const { return m_surroundingChunks[0]; }
|
Chunk *left() const { return m_surroundingChunks[0]; }
|
||||||
Chunk *right() const { return m_surroundingChunks[1]; }
|
Chunk *right() const { return m_surroundingChunks[1]; }
|
||||||
Chunk *front() const { return m_surroundingChunks[2]; }
|
Chunk *front() const { return m_surroundingChunks[2]; }
|
||||||
@ -65,6 +60,13 @@ class Chunk {
|
|||||||
void setFront(Chunk *front) { m_surroundingChunks[2] = front; }
|
void setFront(Chunk *front) { m_surroundingChunks[2] = front; }
|
||||||
void setBack(Chunk *back) { m_surroundingChunks[3] = back; }
|
void setBack(Chunk *back) { m_surroundingChunks[3] = back; }
|
||||||
|
|
||||||
|
bool isGenerated() const { return m_isGenerated; }
|
||||||
|
bool isInitialized() const { return m_isInitialized; }
|
||||||
|
|
||||||
|
void setChanged(bool isChanged) { m_isChanged = isChanged; }
|
||||||
|
void setGenerated(bool isGenerated) { m_isGenerated = isGenerated; }
|
||||||
|
void setInitialized(bool isInitialized) { m_isInitialized = isInitialized; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
s32 m_x;
|
s32 m_x;
|
||||||
s32 m_y;
|
s32 m_y;
|
||||||
@ -85,9 +87,9 @@ class Chunk {
|
|||||||
|
|
||||||
Chunk *m_surroundingChunks[4];
|
Chunk *m_surroundingChunks[4];
|
||||||
|
|
||||||
bool m_changed;
|
bool m_isChanged;
|
||||||
bool m_initialized;
|
bool m_isInitialized;
|
||||||
bool m_generated;
|
bool m_isGenerated;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CHUNK_HPP_
|
#endif // CHUNK_HPP_
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "Chunk.hpp"
|
#include "Chunk.hpp"
|
||||||
|
#include "TerrainGenerator.hpp"
|
||||||
|
|
||||||
class World {
|
class World {
|
||||||
public:
|
public:
|
||||||
@ -36,6 +37,8 @@ class World {
|
|||||||
Texture m_texture;
|
Texture m_texture;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Chunk>> m_chunks;
|
std::vector<std::unique_ptr<Chunk>> m_chunks;
|
||||||
|
|
||||||
|
TerrainGenerator m_terrainGenerator;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WORLD_HPP_
|
#endif // WORLD_HPP_
|
||||||
|
27
include/world/gen/TerrainGenerator.hpp
Normal file
27
include/world/gen/TerrainGenerator.hpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* Filename: TerrainGenerator.hpp
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
* Created: 12/06/2018 22:35:59
|
||||||
|
*
|
||||||
|
* Author: Quentin Bazin, <quent42340@gmail.com>
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
#ifndef TERRAINGENERATOR_HPP_
|
||||||
|
#define TERRAINGENERATOR_HPP_
|
||||||
|
|
||||||
|
class Chunk;
|
||||||
|
|
||||||
|
class TerrainGenerator {
|
||||||
|
public:
|
||||||
|
void generate(Chunk &chunk);
|
||||||
|
|
||||||
|
static float noise2d(float x, float y, int octaves, float persistence);
|
||||||
|
static float noise3d_abs(float x, float y, float z, int octaves, float persistence);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TERRAINGENERATOR_HPP_
|
@ -17,16 +17,13 @@
|
|||||||
*/
|
*/
|
||||||
#include "Block.hpp"
|
#include "Block.hpp"
|
||||||
|
|
||||||
Block::Block(u16 id) {
|
Block::Block(u32 id) {
|
||||||
m_id = id;
|
m_id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
Block::~Block() {
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec4 Block::getTexCoords() {
|
glm::vec4 Block::getTexCoords() {
|
||||||
u16 textureWidth = 256;
|
const u16 textureWidth = 256;
|
||||||
u16 textureHeight = 256;
|
const u16 textureHeight = 256;
|
||||||
|
|
||||||
float textureX = m_id % (textureWidth / 16) * 16.0f / textureWidth;
|
float textureX = m_id % (textureWidth / 16) * 16.0f / textureWidth;
|
||||||
float textureY = m_id / (textureWidth / 16) * 16.0f / textureHeight;
|
float textureY = m_id / (textureWidth / 16) * 16.0f / textureHeight;
|
||||||
|
@ -11,12 +11,6 @@
|
|||||||
*
|
*
|
||||||
* =====================================================================================
|
* =====================================================================================
|
||||||
*/
|
*/
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
#include <ctime>
|
|
||||||
|
|
||||||
#include <glm/gtc/noise.hpp>
|
|
||||||
|
|
||||||
#include "Chunk.hpp"
|
#include "Chunk.hpp"
|
||||||
|
|
||||||
Chunk::Chunk(s32 x, s32 y, s32 z, Texture &texture) : m_texture(texture) {
|
Chunk::Chunk(s32 x, s32 y, s32 z, Texture &texture) : m_texture(texture) {
|
||||||
@ -24,9 +18,9 @@ Chunk::Chunk(s32 x, s32 y, s32 z, Texture &texture) : m_texture(texture) {
|
|||||||
m_y = y;
|
m_y = y;
|
||||||
m_z = z;
|
m_z = z;
|
||||||
|
|
||||||
m_changed = false;
|
m_isChanged = false;
|
||||||
m_initialized = false;
|
m_isInitialized = false;
|
||||||
m_generated = false;
|
m_isGenerated = false;
|
||||||
|
|
||||||
m_surroundingChunks[0] = nullptr;
|
m_surroundingChunks[0] = nullptr;
|
||||||
m_surroundingChunks[1] = nullptr;
|
m_surroundingChunks[1] = nullptr;
|
||||||
@ -34,32 +28,8 @@ Chunk::Chunk(s32 x, s32 y, s32 z, Texture &texture) : m_texture(texture) {
|
|||||||
m_surroundingChunks[3] = nullptr;
|
m_surroundingChunks[3] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chunk::generate() {
|
|
||||||
if(m_generated) return;
|
|
||||||
else m_generated = true;
|
|
||||||
|
|
||||||
time_t seed = time(NULL);
|
|
||||||
|
|
||||||
for(u8 z = 0 ; z < depth ; z++) {
|
|
||||||
for(u8 x = 0 ; x < width ; x++) {
|
|
||||||
float n = noise2d((x + m_x * width) / 256.0, (z + m_z * depth) / 256.0, seed, 5, 0.5) * 4;
|
|
||||||
float h = 10 + n * 2;
|
|
||||||
|
|
||||||
for(u8 y = 0 ; y < height ; y++) {
|
|
||||||
if(y + m_y * height < h) {
|
|
||||||
m_data.push_back(std::unique_ptr<Block>(new Block(1)));
|
|
||||||
} else {
|
|
||||||
m_data.push_back(std::unique_ptr<Block>(new Block(0)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Chunk::update() {
|
void Chunk::update() {
|
||||||
m_changed = false;
|
m_isChanged = false;
|
||||||
|
|
||||||
static const float cubeCoords[6 * 4 * 3] = {
|
static const float cubeCoords[6 * 4 * 3] = {
|
||||||
0, 1, 1,
|
0, 1, 1,
|
||||||
@ -242,7 +212,7 @@ void Chunk::update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Chunk::draw(Shader &shader) {
|
void Chunk::draw(Shader &shader) {
|
||||||
if(m_changed) update();
|
if(m_isChanged) update();
|
||||||
|
|
||||||
if(m_vertices.size() == 0) return;
|
if(m_vertices.size() == 0) return;
|
||||||
|
|
||||||
@ -273,6 +243,10 @@ void Chunk::draw(Shader &shader) {
|
|||||||
VertexBuffer::bind(nullptr);
|
VertexBuffer::bind(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Chunk::addBlock(u32 id) {
|
||||||
|
m_data.push_back(std::unique_ptr<Block>(new Block(id)));
|
||||||
|
}
|
||||||
|
|
||||||
Block *Chunk::getBlock(s8 x, s8 y, s8 z) {
|
Block *Chunk::getBlock(s8 x, s8 y, s8 z) {
|
||||||
u16 i = y + x * height + z * height * width;
|
u16 i = y + x * height + z * height * width;
|
||||||
if(i < m_data.size()) {
|
if(i < m_data.size()) {
|
||||||
@ -305,31 +279,3 @@ bool Chunk::vertexExists(u8 x, u8 y, u8 z, u8 i, u8 j) {
|
|||||||
|| m_extendedFaces.count(getCoordID(x, y, z, i, j, 0)));
|
|| m_extendedFaces.count(getCoordID(x, y, z, i, j, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
float Chunk::noise2d(float x, float y, int seed, int octaves, float persistence) {
|
|
||||||
float sum = 0;
|
|
||||||
float strength = 1.0;
|
|
||||||
float scale = 1.0;
|
|
||||||
|
|
||||||
for(int i = 0 ; i < octaves ; i++) {
|
|
||||||
sum += strength * glm::simplex(glm::vec2(x, y) * scale);
|
|
||||||
scale *= 2.0;
|
|
||||||
strength *= persistence;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Chunk::noise3d_abs(float x, float y, float z, int seed, int octaves, float persistence) {
|
|
||||||
float sum = 0;
|
|
||||||
float strength = 1.0;
|
|
||||||
float scale = 1.0;
|
|
||||||
|
|
||||||
for(int i = 0 ; i < octaves ; i++) {
|
|
||||||
sum += strength * fabs(glm::simplex(glm::vec3(x, y, z) * scale));
|
|
||||||
scale *= 2.0;
|
|
||||||
strength *= persistence;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ void World::draw(Shader &shader, const glm::mat4 &projectionMatrix, const glm::m
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!it->initialized()) {
|
if(!it->isInitialized()) {
|
||||||
if(d < ud) {
|
if(d < ud) {
|
||||||
ud = d;
|
ud = d;
|
||||||
ux = it->x();
|
ux = it->x();
|
||||||
@ -95,13 +95,14 @@ void World::draw(Shader &shader, const glm::mat4 &projectionMatrix, const glm::m
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(ud < 1000) {
|
if(ud < 1000) {
|
||||||
getChunk(ux, uz)->generate();
|
m_terrainGenerator.generate(*getChunk(ux, uz));
|
||||||
|
|
||||||
getChunk(ux, uz)->setInitialized(true);
|
getChunk(ux, uz)->setInitialized(true);
|
||||||
|
|
||||||
if(getChunk(ux, uz)->left()) getChunk(ux, uz)->left()->generate();
|
if(getChunk(ux, uz)->left()) m_terrainGenerator.generate(*getChunk(ux, uz)->left());
|
||||||
if(getChunk(ux, uz)->right()) getChunk(ux, uz)->right()->generate();
|
if(getChunk(ux, uz)->right()) m_terrainGenerator.generate(*getChunk(ux, uz)->right());
|
||||||
if(getChunk(ux, uz)->front()) getChunk(ux, uz)->front()->generate();
|
if(getChunk(ux, uz)->front()) m_terrainGenerator.generate(*getChunk(ux, uz)->front());
|
||||||
if(getChunk(ux, uz)->back()) getChunk(ux, uz)->back()->generate();
|
if(getChunk(ux, uz)->back()) m_terrainGenerator.generate(*getChunk(ux, uz)->back());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +110,6 @@ Chunk *World::getChunk(s32 x, s32 z) {
|
|||||||
x += m_width / 2;
|
x += m_width / 2;
|
||||||
z += m_depth / 2;
|
z += m_depth / 2;
|
||||||
|
|
||||||
return m_chunks[x + z * m_width].get();
|
return m_chunks.at(x + z * m_width).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
69
source/world/gen/TerrainGenerator.cpp
Normal file
69
source/world/gen/TerrainGenerator.cpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* Filename: TerrainGenerator.cpp
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
* Created: 12/06/2018 22:47:04
|
||||||
|
*
|
||||||
|
* Author: Quentin Bazin, <quent42340@gmail.com>
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
#include <glm/gtc/noise.hpp>
|
||||||
|
|
||||||
|
#include "Chunk.hpp"
|
||||||
|
#include "TerrainGenerator.hpp"
|
||||||
|
|
||||||
|
void TerrainGenerator::generate(Chunk &chunk) {
|
||||||
|
if(chunk.isGenerated()) return;
|
||||||
|
|
||||||
|
for(u8 z = 0 ; z < Chunk::depth ; z++) {
|
||||||
|
for(u8 x = 0 ; x < Chunk::width ; x++) {
|
||||||
|
float n = noise2d((x + chunk.x() * Chunk::width) / 256.0, (z + chunk.z() * Chunk::depth) / 256.0, 5, 0.5) * 4;
|
||||||
|
float h = 10 + n * 2;
|
||||||
|
|
||||||
|
for(u8 y = 0 ; y < Chunk::height ; y++) {
|
||||||
|
if(y + chunk.y() * Chunk::height < h) {
|
||||||
|
chunk.addBlock(1);
|
||||||
|
} else {
|
||||||
|
chunk.addBlock(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk.setGenerated(true);
|
||||||
|
chunk.setChanged(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
float TerrainGenerator::noise2d(float x, float y, int octaves, float persistence) {
|
||||||
|
float sum = 0;
|
||||||
|
float strength = 1.0;
|
||||||
|
float scale = 1.0;
|
||||||
|
|
||||||
|
for(int i = 0 ; i < octaves ; i++) {
|
||||||
|
sum += strength * glm::simplex(glm::vec2(x, y) * scale);
|
||||||
|
scale *= 2.0;
|
||||||
|
strength *= persistence;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
float TerrainGenerator::noise3d_abs(float x, float y, float z, int octaves, float persistence) {
|
||||||
|
float sum = 0;
|
||||||
|
float strength = 1.0;
|
||||||
|
float scale = 1.0;
|
||||||
|
|
||||||
|
for(int i = 0 ; i < octaves ; i++) {
|
||||||
|
sum += strength * fabs(glm::simplex(glm::vec3(x, y, z) * scale));
|
||||||
|
scale *= 2.0;
|
||||||
|
strength *= persistence;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user