Merge pull request 'hearts' (#20) from hearts into master
Reviewed-on: #20
This commit is contained in:
commit
f28de5f2be
BIN
Opis_Projektu.pdf
Normal file
BIN
Opis_Projektu.pdf
Normal file
Binary file not shown.
@ -61,7 +61,6 @@ public:
|
|||||||
bool checkCollisionWithGameEntities(std::vector<GameEntity*>& gameEntities, glm::mat4 bulletModelMatrix, float attackerDmg) {
|
bool checkCollisionWithGameEntities(std::vector<GameEntity*>& gameEntities, glm::mat4 bulletModelMatrix, float attackerDmg) {
|
||||||
for (const auto& entity : gameEntities) {
|
for (const auto& entity : gameEntities) {
|
||||||
glm::mat4 entityModelMatrix = entity->getModelMatrix();
|
glm::mat4 entityModelMatrix = entity->getModelMatrix();
|
||||||
|
|
||||||
if (checkAABBCollision(bulletModelMatrix, entityModelMatrix)) {
|
if (checkAABBCollision(bulletModelMatrix, entityModelMatrix)) {
|
||||||
entity->applyDamage(attackerDmg);
|
entity->applyDamage(attackerDmg);
|
||||||
return true;
|
return true;
|
||||||
|
@ -82,6 +82,9 @@ public:
|
|||||||
this->dmg = this->initDMG;
|
this->dmg = this->initDMG;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
void heal() override {
|
||||||
|
this->currentHP = this->currentHP + 5.0f;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
void requestShoot(float time) {
|
void requestShoot(float time) {
|
||||||
if (canShoot(time)) {
|
if (canShoot(time)) {
|
||||||
|
@ -10,11 +10,12 @@ public:
|
|||||||
float initDMG;
|
float initDMG;
|
||||||
|
|
||||||
GameEntity(float currentHP, float maxHP, float initialDmg)
|
GameEntity(float currentHP, float maxHP, float initialDmg)
|
||||||
: currentHP(currentHP), maxHP(maxHP), dmg(initialDmg),initDMG(initialDmg)
|
: currentHP(currentHP), maxHP(maxHP), dmg(initialDmg), initDMG(initialDmg)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void applyDamage(float attackerDmg) {
|
virtual void applyDamage(float attackerDmg) {
|
||||||
currentHP = currentHP - attackerDmg;
|
currentHP = currentHP - attackerDmg;
|
||||||
};
|
};
|
||||||
@ -27,5 +28,6 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
virtual void respawn() = 0;
|
virtual void respawn() = 0;
|
||||||
|
virtual void heal() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
55
grk/project/Heart.h
Normal file
55
grk/project/Heart.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#include "glm.hpp"
|
||||||
|
#include "ext.hpp"
|
||||||
|
#include "src/Render_Utils.h"
|
||||||
|
#include "./GameEntity.h"
|
||||||
|
#include "Spaceship.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
class Heart : public GameEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
glm::mat4 modelMatrix;
|
||||||
|
glm::mat4 initialModelMatrix;
|
||||||
|
float healAmount = 10;
|
||||||
|
bool isCollected;
|
||||||
|
|
||||||
|
|
||||||
|
Heart(glm::mat4 initialModelMatrix, float healAmount)
|
||||||
|
:
|
||||||
|
modelMatrix(initialModelMatrix),
|
||||||
|
initialModelMatrix(initialModelMatrix),
|
||||||
|
healAmount(healAmount),
|
||||||
|
isCollected(false),
|
||||||
|
GameEntity(1, 1, 0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
virtual ~Heart() = default;
|
||||||
|
|
||||||
|
virtual bool isAlive() {
|
||||||
|
if (this->currentHP <= 0) {
|
||||||
|
isCollected = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 getPosition() const override
|
||||||
|
{
|
||||||
|
return modelMatrix[3];
|
||||||
|
}
|
||||||
|
glm::mat4 getModelMatrix() override
|
||||||
|
{
|
||||||
|
return modelMatrix;
|
||||||
|
}
|
||||||
|
void respawn() override {
|
||||||
|
this->currentHP = this->maxHP;
|
||||||
|
this->modelMatrix = this->initialModelMatrix;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void heal() override {
|
||||||
|
this->currentHP = this->currentHP + 5.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
55
grk/project/Nitro.h
Normal file
55
grk/project/Nitro.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#include "glm.hpp"
|
||||||
|
#include "ext.hpp"
|
||||||
|
#include "src/Render_Utils.h"
|
||||||
|
#include "./GameEntity.h"
|
||||||
|
#include "Spaceship.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
class Nitro : public GameEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
glm::mat4 modelMatrix;
|
||||||
|
glm::mat4 initialModelMatrix;
|
||||||
|
float healAmount = 10;
|
||||||
|
bool isCollected;
|
||||||
|
|
||||||
|
|
||||||
|
Nitro(glm::mat4 initialModelMatrix, float healAmount)
|
||||||
|
:
|
||||||
|
modelMatrix(initialModelMatrix),
|
||||||
|
initialModelMatrix(initialModelMatrix),
|
||||||
|
healAmount(healAmount),
|
||||||
|
isCollected(false),
|
||||||
|
GameEntity(1, 1, 0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
virtual ~Nitro() = default;
|
||||||
|
|
||||||
|
virtual bool isAlive() {
|
||||||
|
if (this->currentHP <= 0) {
|
||||||
|
isCollected = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 getPosition() const override
|
||||||
|
{
|
||||||
|
return modelMatrix[3];
|
||||||
|
}
|
||||||
|
glm::mat4 getModelMatrix() override
|
||||||
|
{
|
||||||
|
return modelMatrix;
|
||||||
|
}
|
||||||
|
void respawn() override {
|
||||||
|
this->currentHP = this->maxHP;
|
||||||
|
this->modelMatrix = this->initialModelMatrix;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void heal() override {
|
||||||
|
this->currentHP = this->currentHP + 5.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -394,4 +394,12 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void heal() override {
|
||||||
|
this->currentHP = this->currentHP + 3.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void turboBoost() {
|
||||||
|
this->turbo = this->turboMAX;
|
||||||
|
}
|
||||||
};
|
};
|
@ -32,6 +32,8 @@
|
|||||||
<ClInclude Include="GameEntity.h" />
|
<ClInclude Include="GameEntity.h" />
|
||||||
<ClInclude Include="GameObject.h" />
|
<ClInclude Include="GameObject.h" />
|
||||||
<ClInclude Include="GameUtils.h" />
|
<ClInclude Include="GameUtils.h" />
|
||||||
|
<ClInclude Include="Heart.h" />
|
||||||
|
<ClInclude Include="Nitro.h" />
|
||||||
<ClInclude Include="ParticleSystem.h" />
|
<ClInclude Include="ParticleSystem.h" />
|
||||||
<ClInclude Include="Planet.h" />
|
<ClInclude Include="Planet.h" />
|
||||||
<ClInclude Include="Spaceship.h" />
|
<ClInclude Include="Spaceship.h" />
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="SpriteRenderer.cpp">
|
<ClCompile Include="SpriteRenderer.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Source.cpp">
|
<ClCompile Include="Source.cpp">
|
||||||
<Filter>Shader Files</Filter>
|
<Filter>Shader Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -123,14 +123,20 @@
|
|||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="SpriteRenderer.h">
|
<ClInclude Include="SpriteRenderer.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="ParticleSystem.h">
|
<ClInclude Include="ParticleSystem.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="GameEntity.h">
|
<ClInclude Include="GameEntity.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Heart.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Nitro.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="shaders\shader_8_sun.vert">
|
<None Include="shaders\shader_8_sun.vert">
|
||||||
@ -163,14 +169,14 @@
|
|||||||
<Filter>Shader Files</Filter>
|
<Filter>Shader Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
<None Include="shaders\shader_sprite.vert">
|
<None Include="shaders\shader_sprite.vert">
|
||||||
<Filter>Shader Files</Filter>
|
<Filter>Shader Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
<None Include="shaders\shader_tex.frag">
|
<None Include="shaders\shader_tex.frag">
|
||||||
<Filter>Shader Files</Filter>
|
<Filter>Shader Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
<None Include="shaders\shader_tex.vert">
|
<None Include="shaders\shader_tex.vert">
|
||||||
<Filter>Shader Files</Filter>
|
<Filter>Shader Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
<None Include="particle.frag">
|
<None Include="particle.frag">
|
||||||
<Filter>Shader Files</Filter>
|
<Filter>Shader Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#include "../GameUtils.h"
|
#include "../GameUtils.h"
|
||||||
#include "../SpriteRenderer.h"
|
#include "../SpriteRenderer.h"
|
||||||
#include "../Enemy.h"
|
#include "../Enemy.h"
|
||||||
|
#include "../Heart.h"
|
||||||
|
#include "../Nitro.h"
|
||||||
|
|
||||||
#include "../ParticleSystem.h"
|
#include "../ParticleSystem.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
@ -54,6 +56,8 @@ namespace texture {
|
|||||||
GLuint earthTexture;
|
GLuint earthTexture;
|
||||||
GLuint asteroidTexture;
|
GLuint asteroidTexture;
|
||||||
GLuint asteroidNormal;
|
GLuint asteroidNormal;
|
||||||
|
GLuint heartTexture;
|
||||||
|
GLuint boosterTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TextureTuple {
|
struct TextureTuple {
|
||||||
@ -82,6 +86,8 @@ std::list<Planet*> planets;
|
|||||||
Sun* sun;
|
Sun* sun;
|
||||||
GLuint VAO,VBO;
|
GLuint VAO,VBO;
|
||||||
|
|
||||||
|
std::vector<Nitro*> nitros;
|
||||||
|
std::vector<Heart*> hearts;
|
||||||
std::vector<Enemy*> enemies;
|
std::vector<Enemy*> enemies;
|
||||||
std::vector<GameEntity*> gameEntities;
|
std::vector<GameEntity*> gameEntities;
|
||||||
|
|
||||||
@ -236,6 +242,46 @@ void renderEnemies() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void renderHeartsAndNitro() {
|
||||||
|
//if (heart->isAlive()) {
|
||||||
|
//spriteRenderer->DrawSprite(texture::heartTexture, heart->modelMatrix, programSprite);
|
||||||
|
//}
|
||||||
|
|
||||||
|
glUseProgram(programSprite);
|
||||||
|
for (auto it = hearts.begin(); it != hearts.end();) {
|
||||||
|
Heart* heart = *it;
|
||||||
|
if (heart->isAlive()) {
|
||||||
|
spriteRenderer->DrawSprite(texture::heartTexture, heart->modelMatrix, programSprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (heart->isCollected) {
|
||||||
|
spaceship->heal();
|
||||||
|
it = hearts.erase(it);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = nitros.begin(); it != nitros.end();) {
|
||||||
|
Nitro* nitro = *it;
|
||||||
|
if (nitro->isAlive()) {
|
||||||
|
spriteRenderer->DrawSprite(texture::boosterTexture, nitro->modelMatrix, programSprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nitro->isCollected) {
|
||||||
|
spaceship->turboBoost();
|
||||||
|
it = nitros.erase(it);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TextureTuple getRandomPlanetTexture() {
|
TextureTuple getRandomPlanetTexture() {
|
||||||
int textureIndex = rand() % planetTextures.size();
|
int textureIndex = rand() % planetTextures.size();
|
||||||
TextureTuple selectedTextures = planetTextures[textureIndex];
|
TextureTuple selectedTextures = planetTextures[textureIndex];
|
||||||
@ -280,8 +326,13 @@ void renderScene(GLFWwindow* window)
|
|||||||
glUseProgram(program);
|
glUseProgram(program);
|
||||||
|
|
||||||
std::vector<GameEntity*> gameEntities(enemies.begin(), enemies.end());
|
std::vector<GameEntity*> gameEntities(enemies.begin(), enemies.end());
|
||||||
|
//spaceship->renderBullets(glfwGetTime(), program, gameEntities);
|
||||||
|
|
||||||
|
gameEntities.insert(gameEntities.end(), hearts.begin(), hearts.end());
|
||||||
|
gameEntities.insert(gameEntities.end(), nitros.begin(), nitros.end());
|
||||||
spaceship->renderBullets(glfwGetTime(), program, gameEntities);
|
spaceship->renderBullets(glfwGetTime(), program, gameEntities);
|
||||||
|
|
||||||
|
|
||||||
drawObjectPBR(models::sphereContext,
|
drawObjectPBR(models::sphereContext,
|
||||||
glm::translate(pointlightPos) * glm::scale(glm::vec3(0.1)) * glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::eulerAngleY(time) * glm::translate(glm::vec3(1.f, 0, 0)) * glm::scale(glm::vec3(0.1f)),
|
glm::translate(pointlightPos) * glm::scale(glm::vec3(0.1)) * glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::eulerAngleY(time) * glm::translate(glm::vec3(1.f, 0, 0)) * glm::scale(glm::vec3(0.1f)),
|
||||||
glm::vec3(0.5, 0.5, 0.5), 0.7, 0.0, program);
|
glm::vec3(0.5, 0.5, 0.5), 0.7, 0.0, program);
|
||||||
@ -333,7 +384,7 @@ void renderScene(GLFWwindow* window)
|
|||||||
|
|
||||||
renderHUD(window);
|
renderHUD(window);
|
||||||
renderEnemies();
|
renderEnemies();
|
||||||
|
renderHeartsAndNitro();
|
||||||
//drawObjectPBR(sphereContext, glm::translate(pointlightPos) * glm::scale(glm::vec3(1)) * glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(10.f, 0, 0)) * glm::scale(glm::vec3(0.3f)), glm::vec3(0.2, 0.7, 0.3), 0.3, 0.0, program);
|
//drawObjectPBR(sphereContext, glm::translate(pointlightPos) * glm::scale(glm::vec3(1)) * glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(10.f, 0, 0)) * glm::scale(glm::vec3(0.3f)), glm::vec3(0.2, 0.7, 0.3), 0.3, 0.0, program);
|
||||||
|
|
||||||
|
|
||||||
@ -365,7 +416,7 @@ void createAsteroids() {
|
|||||||
float maxDistanceFromCenter = 26.f;
|
float maxDistanceFromCenter = 26.f;
|
||||||
float rotationSpeed = 0.05f;
|
float rotationSpeed = 0.05f;
|
||||||
float scale = 0.002f;
|
float scale = 0.002f;
|
||||||
int numAsteroids = 160;
|
int numAsteroids = 80;
|
||||||
float distanceIncrement = 2.f / (minDistanceFromCenter + 1);
|
float distanceIncrement = 2.f / (minDistanceFromCenter + 1);
|
||||||
|
|
||||||
for (int j = -1; j < 2; j++) {
|
for (int j = -1; j < 2; j++) {
|
||||||
@ -413,20 +464,31 @@ void createEnemies() {
|
|||||||
//enemies.push_back(new Enemy(100.0f,100.0f, glm::mat4(1.0f), 1.0f, 5.0f));
|
//enemies.push_back(new Enemy(100.0f,100.0f, glm::mat4(1.0f), 1.0f, 5.0f));
|
||||||
//enemies.push_back(new Enemy(100.0f,100.0f, glm::translate(glm::mat4(1.0f) , glm::vec3(1.f,1.f,1.f)), 1.0f, 5.0f));
|
//enemies.push_back(new Enemy(100.0f,100.0f, glm::translate(glm::mat4(1.0f) , glm::vec3(1.f,1.f,1.f)), 1.0f, 5.0f));
|
||||||
//enemies.push_back(new Enemy(100.0f,100.0f, glm::translate(glm::mat4(1.0f), glm::vec3(-1.f, 2.f, -0.9f)), 1.0f, 5.0f));
|
//enemies.push_back(new Enemy(100.0f,100.0f, glm::translate(glm::mat4(1.0f), glm::vec3(-1.f, 2.f, -0.9f)), 1.0f, 5.0f));
|
||||||
|
int j = 0;
|
||||||
enemies.push_back(new Enemy(100.0f, 100.0f, glm::translate(glm::translate(glm::mat4(1.0f), spaceship->getPosition()), glm::vec3(1.f, 1.f, 2.f)), 1.0f, 5.0f));
|
enemies.push_back(new Enemy(100.0f, 100.0f, glm::translate(glm::translate(glm::mat4(1.0f), spaceship->getPosition()), glm::vec3(1.f, 1.f, 2.f)), 1.0f, 5.0f));
|
||||||
for (int i = 0; i < ENEMY_COUNT; ++i) {
|
for (int i = 0; i < ENEMY_COUNT; ++i) {
|
||||||
|
|
||||||
glm::mat4 randomModelMatrix = generateRandomMatrix(glm::mat4(1.0f));
|
glm::mat4 randomModelMatrix = generateRandomMatrix(glm::mat4(1.0f));
|
||||||
enemies.push_back(new Enemy(100.0f, 100.0f, randomModelMatrix, 1.0f, 8.0f));
|
enemies.push_back(new Enemy(100.0f, 100.0f, randomModelMatrix, 1.0f, 8.0f));
|
||||||
|
|
||||||
|
if (j % 4 == 0) {
|
||||||
|
hearts.push_back(new Heart(glm::translate(randomModelMatrix, glm::vec3(6.f, 5.f, 8.f)), -5.0f));
|
||||||
|
nitros.push_back(new Nitro(glm::translate(randomModelMatrix, glm::vec3(2.f, -9.f, 3.f)), 10.0f));
|
||||||
|
}
|
||||||
|
j = j + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hearts.push_back(new Heart(glm::translate(glm::mat4(1.0f), glm::vec3(25.f, 20.f, 25.f)), 10.0f));
|
||||||
|
nitros.push_back(new Nitro(glm::translate(glm::mat4(1.0f), glm::vec3(20.f, 20.f, 25.f)), 10.0f));
|
||||||
|
|
||||||
//obiekty do ktorych bedzie sprawdzana kolizja dla pociskow enemy
|
//obiekty do ktorych bedzie sprawdzana kolizja dla pociskow enemy
|
||||||
gameEntities.push_back(spaceship);
|
gameEntities.push_back(spaceship);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void loadPlanetsAndSunTextures() {
|
void loadPlanetsAndSunTextures() {
|
||||||
planetTextures.clear();
|
planetTextures.clear();
|
||||||
|
|
||||||
@ -504,6 +566,8 @@ void init(GLFWwindow* window)
|
|||||||
texture::earthTexture = Core::LoadTexture("./textures/planets/8k_earth_daymap.jpg");
|
texture::earthTexture = Core::LoadTexture("./textures/planets/8k_earth_daymap.jpg");
|
||||||
texture::asteroidTexture = Core::LoadTexture("./textures/asteroids/asteroidtx.jpg");
|
texture::asteroidTexture = Core::LoadTexture("./textures/asteroids/asteroidtx.jpg");
|
||||||
texture::asteroidNormal = Core::LoadTexture("./textures/asteroids/asteroidnn.png");
|
texture::asteroidNormal = Core::LoadTexture("./textures/asteroids/asteroidnn.png");
|
||||||
|
texture::heartTexture = Core::LoadTexture("textures/heart.png");
|
||||||
|
texture::boosterTexture = Core::LoadTexture("textures/boooster.png");
|
||||||
|
|
||||||
spaceship->createParticles();
|
spaceship->createParticles();
|
||||||
createSuns();
|
createSuns();
|
||||||
|
BIN
grk/project/textures/boooster.png
Normal file
BIN
grk/project/textures/boooster.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
grk/project/textures/heart.png
Normal file
BIN
grk/project/textures/heart.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
Loading…
Reference in New Issue
Block a user