add SkillButtonNode, Attack and Defence Skill -change Unit enum to UnitType
This commit is contained in:
parent
d80e80783a
commit
28fa86c25c
@ -16,10 +16,11 @@
|
|||||||
110360EE244B101B008610AF /* GoldWarsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110360ED244B101B008610AF /* GoldWarsTests.swift */; };
|
110360EE244B101B008610AF /* GoldWarsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 110360ED244B101B008610AF /* GoldWarsTests.swift */; };
|
||||||
11036113244B3E30008610AF /* MenuScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11036112244B3E30008610AF /* MenuScene.swift */; };
|
11036113244B3E30008610AF /* MenuScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11036112244B3E30008610AF /* MenuScene.swift */; };
|
||||||
116060F7245C57D2004E5A36 /* EntityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 116060F6245C57D2004E5A36 /* EntityManager.swift */; };
|
116060F7245C57D2004E5A36 /* EntityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 116060F6245C57D2004E5A36 /* EntityManager.swift */; };
|
||||||
11738A3B24508F68004426F1 /* Unit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11738A3A24508F68004426F1 /* Unit.swift */; };
|
11738A3B24508F68004426F1 /* UnitType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11738A3A24508F68004426F1 /* UnitType.swift */; };
|
||||||
2086465C2461B66200817C23 /* TimerComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2086465B2461B66200817C23 /* TimerComponent.swift */; };
|
2086465C2461B66200817C23 /* TimerComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2086465B2461B66200817C23 /* TimerComponent.swift */; };
|
||||||
3EBD242C245D8044003CECE7 /* GameCenterHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */; };
|
3EBD242C245D8044003CECE7 /* GameCenterHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */; };
|
||||||
3EBD242E245D9332003CECE7 /* Team.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBD242D245D9332003CECE7 /* Team.swift */; };
|
3EBD242E245D9332003CECE7 /* Team.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EBD242D245D9332003CECE7 /* Team.swift */; };
|
||||||
|
8BB6FF402472B8F000162BBD /* SkillButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BB6FF3F2472B8F000162BBD /* SkillButtonNode.swift */; };
|
||||||
9E04AFAF245E2B73002D5CFC /* AttackActionComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04AFAE245E2B73002D5CFC /* AttackActionComponent.swift */; };
|
9E04AFAF245E2B73002D5CFC /* AttackActionComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E04AFAE245E2B73002D5CFC /* AttackActionComponent.swift */; };
|
||||||
9E11FF79245CD81100EED3BE /* Fire.sks in Resources */ = {isa = PBXBuildFile; fileRef = 9E11FF77245CD81100EED3BE /* Fire.sks */; };
|
9E11FF79245CD81100EED3BE /* Fire.sks in Resources */ = {isa = PBXBuildFile; fileRef = 9E11FF77245CD81100EED3BE /* Fire.sks */; };
|
||||||
9E174C82245DD81D00209FF0 /* ButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C81245DD81D00209FF0 /* ButtonNode.swift */; };
|
9E174C82245DD81D00209FF0 /* ButtonNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E174C81245DD81D00209FF0 /* ButtonNode.swift */; };
|
||||||
@ -80,10 +81,11 @@
|
|||||||
110360EF244B101B008610AF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
110360EF244B101B008610AF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
11036112244B3E30008610AF /* MenuScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuScene.swift; sourceTree = "<group>"; };
|
11036112244B3E30008610AF /* MenuScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuScene.swift; sourceTree = "<group>"; };
|
||||||
116060F6245C57D2004E5A36 /* EntityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntityManager.swift; sourceTree = "<group>"; };
|
116060F6245C57D2004E5A36 /* EntityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntityManager.swift; sourceTree = "<group>"; };
|
||||||
11738A3A24508F68004426F1 /* Unit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Unit.swift; sourceTree = "<group>"; };
|
11738A3A24508F68004426F1 /* UnitType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnitType.swift; sourceTree = "<group>"; };
|
||||||
2086465B2461B66200817C23 /* TimerComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerComponent.swift; sourceTree = "<group>"; };
|
2086465B2461B66200817C23 /* TimerComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerComponent.swift; sourceTree = "<group>"; };
|
||||||
3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameCenterHelper.swift; sourceTree = "<group>"; };
|
3EBD242B245D8044003CECE7 /* GameCenterHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameCenterHelper.swift; sourceTree = "<group>"; };
|
||||||
3EBD242D245D9332003CECE7 /* Team.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Team.swift; sourceTree = "<group>"; };
|
3EBD242D245D9332003CECE7 /* Team.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Team.swift; sourceTree = "<group>"; };
|
||||||
|
8BB6FF3F2472B8F000162BBD /* SkillButtonNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkillButtonNode.swift; sourceTree = "<group>"; };
|
||||||
9E04AFAE245E2B73002D5CFC /* AttackActionComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttackActionComponent.swift; sourceTree = "<group>"; };
|
9E04AFAE245E2B73002D5CFC /* AttackActionComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttackActionComponent.swift; sourceTree = "<group>"; };
|
||||||
9E11FF77245CD81100EED3BE /* Fire.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Fire.sks; sourceTree = "<group>"; };
|
9E11FF77245CD81100EED3BE /* Fire.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Fire.sks; sourceTree = "<group>"; };
|
||||||
9E174C81245DD81D00209FF0 /* ButtonNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonNode.swift; sourceTree = "<group>"; };
|
9E174C81245DD81D00209FF0 /* ButtonNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonNode.swift; sourceTree = "<group>"; };
|
||||||
@ -214,6 +216,7 @@
|
|||||||
2086465B2461B66200817C23 /* TimerComponent.swift */,
|
2086465B2461B66200817C23 /* TimerComponent.swift */,
|
||||||
9EBFD7542462CF5A00E1E219 /* SliderComponent.swift */,
|
9EBFD7542462CF5A00E1E219 /* SliderComponent.swift */,
|
||||||
9EC7E48A2461FBF700396BCD /* SliderNode.swift */,
|
9EC7E48A2461FBF700396BCD /* SliderNode.swift */,
|
||||||
|
8BB6FF3F2472B8F000162BBD /* SkillButtonNode.swift */,
|
||||||
);
|
);
|
||||||
path = Components;
|
path = Components;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -251,7 +254,7 @@
|
|||||||
9EC86BA2245C89B200796EF3 /* Enums */ = {
|
9EC86BA2245C89B200796EF3 /* Enums */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
11738A3A24508F68004426F1 /* Unit.swift */,
|
11738A3A24508F68004426F1 /* UnitType.swift */,
|
||||||
9EC86BA5245C8AD000796EF3 /* ModalType.swift */,
|
9EC86BA5245C8AD000796EF3 /* ModalType.swift */,
|
||||||
3EBD242D245D9332003CECE7 /* Team.swift */,
|
3EBD242D245D9332003CECE7 /* Team.swift */,
|
||||||
);
|
);
|
||||||
@ -404,12 +407,13 @@
|
|||||||
9E174C88245DF1FF00209FF0 /* BackgroundComponent.swift in Sources */,
|
9E174C88245DF1FF00209FF0 /* BackgroundComponent.swift in Sources */,
|
||||||
9E78ACBA245CBDAF00526FF7 /* HUD.swift in Sources */,
|
9E78ACBA245CBDAF00526FF7 /* HUD.swift in Sources */,
|
||||||
9EEDE02D246FCD770096C735 /* SpinningLogoEntity.swift in Sources */,
|
9EEDE02D246FCD770096C735 /* SpinningLogoEntity.swift in Sources */,
|
||||||
11738A3B24508F68004426F1 /* Unit.swift in Sources */,
|
11738A3B24508F68004426F1 /* UnitType.swift in Sources */,
|
||||||
9E174C86245DD91500209FF0 /* ButtonComponent.swift in Sources */,
|
9E174C86245DD91500209FF0 /* ButtonComponent.swift in Sources */,
|
||||||
AE151589245F18EF001D363E /* MatchmakingHelper.swift in Sources */,
|
AE151589245F18EF001D363E /* MatchmakingHelper.swift in Sources */,
|
||||||
11036113244B3E30008610AF /* MenuScene.swift in Sources */,
|
11036113244B3E30008610AF /* MenuScene.swift in Sources */,
|
||||||
9EA3ABE9245C6DAA006BC61D /* DefaultBaseComponent.swift in Sources */,
|
9EA3ABE9245C6DAA006BC61D /* DefaultBaseComponent.swift in Sources */,
|
||||||
9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */,
|
9E174C8A245E1A0A00209FF0 /* Background.swift in Sources */,
|
||||||
|
8BB6FF402472B8F000162BBD /* SkillButtonNode.swift in Sources */,
|
||||||
9EA3ABED245C8143006BC61D /* ModalBackgroundComponent.swift in Sources */,
|
9EA3ABED245C8143006BC61D /* ModalBackgroundComponent.swift in Sources */,
|
||||||
C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */,
|
C064E9A8246C0EA50022B228 /* LabelNode.swift in Sources */,
|
||||||
3EBD242C245D8044003CECE7 /* GameCenterHelper.swift in Sources */,
|
3EBD242C245D8044003CECE7 /* GameCenterHelper.swift in Sources */,
|
||||||
|
@ -10,22 +10,28 @@ import GameplayKit
|
|||||||
|
|
||||||
class AtkBoostSkillComponent: GKComponent{
|
class AtkBoostSkillComponent: GKComponent{
|
||||||
|
|
||||||
let shapeNode: SKShapeNode
|
var skillButtonNode: SkillButtonNode
|
||||||
let labelNode: SKLabelNode
|
|
||||||
|
|
||||||
init(text: String, texture: SKTexture?, anchorPoint: CGPoint) {
|
init(iconName: String, text: String, position: CGPoint, isEnabled:Bool) {
|
||||||
self.labelNode = SKLabelNode(text: text)
|
skillButtonNode = SkillButtonNode(iconName: iconName,
|
||||||
self.shapeNode = SKShapeNode(circleOfRadius: 30)
|
text: text,
|
||||||
self.shapeNode.position = anchorPoint
|
isEnabled: isEnabled,
|
||||||
self.labelNode.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 15)
|
position: position,
|
||||||
if texture != nil {
|
onButtonPress: {
|
||||||
shapeNode.fillTexture = texture
|
var bases: Set<Base> = EntityManager.sharedInstance.getBasesByTeam(for: .team2)
|
||||||
|
bases.forEach{ base in
|
||||||
|
if(base.unitType == .Defence){
|
||||||
|
base.unitType = .AttackDefence
|
||||||
}else {
|
}else {
|
||||||
shapeNode.fillColor = SKColor.gray
|
base.unitType = .Attack
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
@ -10,19 +10,23 @@ import GameplayKit
|
|||||||
|
|
||||||
class DefBoostSkillComponent: GKComponent{
|
class DefBoostSkillComponent: GKComponent{
|
||||||
|
|
||||||
let shapeNode: SKShapeNode
|
var skillButtonNode: SkillButtonNode
|
||||||
let labelNode: SKLabelNode
|
|
||||||
|
|
||||||
init(text: String, texture: SKTexture?, anchorPoint: CGPoint) {
|
init(iconName: String, text: String, position: CGPoint, isEnabled:Bool) {
|
||||||
self.labelNode = SKLabelNode(text: text)
|
skillButtonNode = SkillButtonNode(iconName: iconName,
|
||||||
self.shapeNode = SKShapeNode(circleOfRadius: 30)
|
text: text,
|
||||||
self.shapeNode.position = anchorPoint
|
isEnabled: isEnabled,
|
||||||
self.labelNode.position = CGPoint(x: anchorPoint.x, y: anchorPoint.y - 15)
|
position: position,
|
||||||
if texture != nil {
|
onButtonPress: {
|
||||||
shapeNode.fillTexture = texture
|
var bases: Set<Base> = EntityManager.sharedInstance.getBasesByTeam(for: .team2)
|
||||||
|
bases.forEach{ base in
|
||||||
|
if(base.unitType == .Attack){
|
||||||
|
base.unitType = .AttackDefence
|
||||||
}else {
|
}else {
|
||||||
shapeNode.fillColor = SKColor.gray
|
base.unitType = .Defence
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
76
GoldWars/GoldWars/Components/SkillButtonNode.swift
Normal file
76
GoldWars/GoldWars/Components/SkillButtonNode.swift
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
//
|
||||||
|
// SkillButtonNode.swift
|
||||||
|
// GoldWars
|
||||||
|
//
|
||||||
|
// Created by Simon Kellner on 18.05.20.
|
||||||
|
// Copyright © 2020 SP2. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SpriteKit
|
||||||
|
|
||||||
|
class SkillButtonNode: SKSpriteNode {
|
||||||
|
|
||||||
|
var isEnabled: Bool{
|
||||||
|
didSet{
|
||||||
|
if isEnabled {
|
||||||
|
self.alpha = 1
|
||||||
|
self.childNode(withName: "label")?.alpha = 1
|
||||||
|
} else {
|
||||||
|
self.alpha = 0.3
|
||||||
|
self.childNode(withName: "label")?.alpha = 0.3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let onButtonPress: () -> ()
|
||||||
|
|
||||||
|
init(iconName: String, text: String, isEnabled: Bool, position: CGPoint, onButtonPress: @escaping () -> ()) {
|
||||||
|
self.onButtonPress = onButtonPress
|
||||||
|
self.isEnabled = isEnabled
|
||||||
|
let texture = SKTexture(imageNamed: "yellow_circle")
|
||||||
|
super.init(texture: texture, color: SKColor.white, size: texture.size())
|
||||||
|
self.position = position
|
||||||
|
|
||||||
|
let label = SKLabelNode(fontNamed: "Courier-Bold")
|
||||||
|
label.fontSize = 30
|
||||||
|
label.fontColor = SKColor.black
|
||||||
|
label.zPosition = 1
|
||||||
|
label.verticalAlignmentMode = .center
|
||||||
|
label.text = text
|
||||||
|
label.name = "label"
|
||||||
|
|
||||||
|
if iconName.isEmpty {
|
||||||
|
label.position = CGPoint(x: 0, y: 0)
|
||||||
|
} else {
|
||||||
|
label.position = CGPoint(x: size.width * 0.5, y: 0)
|
||||||
|
let icon = SKSpriteNode(imageNamed: iconName)
|
||||||
|
icon.position = CGPoint(x: -size.width * 0.5, y: 0)
|
||||||
|
icon.zPosition = 1
|
||||||
|
self.addChild(icon)
|
||||||
|
}
|
||||||
|
self.addChild(label)
|
||||||
|
isUserInteractionEnabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
|
if isEnabled {
|
||||||
|
let action = SKAction.sequence(
|
||||||
|
[
|
||||||
|
SKAction.scale(by: (3/4), duration: 0.3),
|
||||||
|
SKAction.scale(by: (4/3), duration: 0.3),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.childNode(withName: "label")?.run(action)
|
||||||
|
self.run(action)
|
||||||
|
self.isEnabled = false
|
||||||
|
onButtonPress()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
required init?(coder aDecoder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -13,12 +13,14 @@ import GameKit
|
|||||||
class Base: GKEntity {
|
class Base: GKEntity {
|
||||||
|
|
||||||
var unitCount: Int
|
var unitCount: Int
|
||||||
|
var unitType: UnitType
|
||||||
var adjacencyList: Array<Base>
|
var adjacencyList: Array<Base>
|
||||||
var changeOwnership: Bool
|
var changeOwnership: Bool
|
||||||
var ownershipPlayer: GKPlayer?
|
var ownershipPlayer: GKPlayer?
|
||||||
|
|
||||||
init(position: CGPoint, player: GKPlayer! = nil, team: Team! = nil) {
|
init(position: CGPoint, player: GKPlayer! = nil, team: Team! = nil) {
|
||||||
self.unitCount = 0
|
self.unitCount = 0
|
||||||
|
self.unitType = .General
|
||||||
self.adjacencyList = [Base]()
|
self.adjacencyList = [Base]()
|
||||||
self.changeOwnership = false
|
self.changeOwnership = false
|
||||||
self.ownershipPlayer = player
|
self.ownershipPlayer = player
|
||||||
|
@ -44,13 +44,12 @@ class EntityManager {
|
|||||||
scene.addChild(modal.body)
|
scene.addChild(modal.body)
|
||||||
scene.addChild(modal.footer)
|
scene.addChild(modal.footer)
|
||||||
}
|
}
|
||||||
if let skill = entity.component(ofType: AtkBoostSkillComponent.self) {
|
if let skillButtonNode = entity.component(ofType: AtkBoostSkillComponent.self)?.skillButtonNode {
|
||||||
scene.addChild(skill.shapeNode)
|
scene.addChild(skillButtonNode)
|
||||||
scene.addChild(skill.labelNode)
|
isModal = true
|
||||||
}
|
}
|
||||||
if let skill = entity.component(ofType: DefBoostSkillComponent.self) {
|
if let skillButtonNode = entity.component(ofType: DefBoostSkillComponent.self)?.skillButtonNode {
|
||||||
scene.addChild(skill.shapeNode)
|
scene.addChild(skillButtonNode)
|
||||||
scene.addChild(skill.labelNode)
|
|
||||||
}
|
}
|
||||||
if let skill = entity.component(ofType: SpySkillComponent.self) {
|
if let skill = entity.component(ofType: SpySkillComponent.self) {
|
||||||
scene.addChild(skill.shapeNode)
|
scene.addChild(skill.shapeNode)
|
||||||
|
@ -17,14 +17,10 @@ class HUD: GKEntity {
|
|||||||
anchorPoint: CGPoint(x: size.width * 0.75, y: size.height * 0.1)))
|
anchorPoint: CGPoint(x: size.width * 0.75, y: size.height * 0.1)))
|
||||||
|
|
||||||
|
|
||||||
addComponent(AtkBoostSkillComponent(text: "Atk",
|
addComponent(AtkBoostSkillComponent(iconName: "", text: "Atk", position: CGPoint(x: size.width * 0.85, y: size.height * 0.1), isEnabled: true))
|
||||||
texture: nil,
|
|
||||||
anchorPoint: CGPoint(x: size.width * 0.85, y: size.height * 0.1)))
|
|
||||||
|
|
||||||
|
|
||||||
addComponent(DefBoostSkillComponent(text: "Def",
|
addComponent(DefBoostSkillComponent(iconName: "", text: "Def", position: CGPoint(x: size.width * 0.95, y: size.height * 0.1), isEnabled: true))
|
||||||
texture: nil,
|
|
||||||
anchorPoint: CGPoint(x: size.width * 0.95, y: size.height * 0.1)))
|
|
||||||
|
|
||||||
addComponent(TimerComponent(text: "",
|
addComponent(TimerComponent(text: "",
|
||||||
anchorPoint: CGPoint(x: size.width * 0.5, y: size.height * 0.9), duration: 30))
|
anchorPoint: CGPoint(x: size.width * 0.5, y: size.height * 0.9), duration: 30))
|
||||||
|
@ -6,8 +6,9 @@
|
|||||||
// Copyright © 2020 SP2. All rights reserved.
|
// Copyright © 2020 SP2. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
enum Unit{
|
enum UnitType{
|
||||||
case General
|
case General
|
||||||
case Defence
|
case Defence
|
||||||
case Attack
|
case Attack
|
||||||
|
case AttackDefence
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user