mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2025-12-30 12:03:11 +00:00
Third refactor for examine system! This time we go back to atom-var based system, but because strings are tabled, it's apparently okay.
The entire system is now self-contained inside a module folder. Also fixes a runtime I made because ghosts lack a mind (and so do I)
This commit is contained in:
166
code/modules/examine/descriptions/atmospherics.dm
Normal file
166
code/modules/examine/descriptions/atmospherics.dm
Normal file
@@ -0,0 +1,166 @@
|
||||
/obj/machinery/atmospherics/pipe
|
||||
description_info = "This pipe, and all other pipes, can be connected or disconnected by a wrench. The internal pressure of the pipe must \
|
||||
be below 300 kPa to do this. More pipes can be obtained from the pipe dispenser."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/New() //This is needed or else 20+ lines of copypasta to dance around inheritence.
|
||||
..()
|
||||
description_info += "<br>Most pipes and atmospheric devices can be connected or disconnected with a wrench. The pipe's pressure must not be too high, \
|
||||
or if it is a device, it must be turned off first."
|
||||
|
||||
//HE pipes
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging
|
||||
description_info = "This radiates heat from the pipe's gas to space, cooling it down."
|
||||
|
||||
//Supply/Scrubber pipes
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/supply
|
||||
description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply
|
||||
description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
//Universal adapters
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/universal
|
||||
description_info = "This allows you to connect 'normal' pipes, red 'scrubber' pipes, and blue 'supply' pipes."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/universal
|
||||
description_info = "This allows you to connect 'normal' pipes, red 'scrubber' pipes, and blue 'supply' pipes."
|
||||
|
||||
//Three way manifolds
|
||||
/obj/machinery/atmospherics/pipe/manifold
|
||||
description_info = "A normal pipe with three ends to connect to."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/visible/supply
|
||||
description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/hidden/supply
|
||||
description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
//Insulated pipes
|
||||
/obj/machinery/atmospherics/pipe/simple/insulated
|
||||
description_info = "This is completely useless, use a normal pipe." //Sorry, but it's true.
|
||||
|
||||
//Four way manifolds
|
||||
/obj/machinery/atmospherics/pipe/manifold4w
|
||||
description_info = "This is a four-way pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/visible/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply
|
||||
description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
//Endcaps
|
||||
/obj/machinery/atmospherics/pipe/cap
|
||||
description_info = "This is a cosmetic attachment, as pipes currently do not spill their contents into the air."
|
||||
|
||||
//T-shaped valves
|
||||
/obj/machinery/atmospherics/tvalve
|
||||
description_info = "Click this to toggle the mode. The direction with the green light is where the gas will flow."
|
||||
|
||||
//Normal valves
|
||||
/obj/machinery/atmospherics/valve
|
||||
description_info = "Click this to turn the valve. If red, the pipes on each end are seperated. Otherwise, they are connected."
|
||||
|
||||
//TEG ports
|
||||
/obj/machinery/atmospherics/binary/circulator
|
||||
description_info = "This generates electricity, depending on the difference in temperature between each side of the machine. The meter in \
|
||||
the center of the machine gives an indicator of how much elecrtricity is being generated."
|
||||
|
||||
//Passive gates
|
||||
/obj/machinery/atmospherics/binary/passive_gate
|
||||
description_info = "This is a one-way regulator, allowing gas to flow only at a specific pressure and flow rate. If the light is green, it is flowing."
|
||||
|
||||
//Normal pumps (high power one inherits from this)
|
||||
/obj/machinery/atmospherics/binary/pump
|
||||
description_info = "This moves gas from one pipe to another. A higher target pressure demands more energy. The side with the red end is the output."
|
||||
|
||||
//Vents
|
||||
/obj/machinery/atmospherics/unary/vent_pump
|
||||
description_info = "This pumps the contents of the attached pipe out into the atmosphere, if needed. It can be controlled from an Air Alarm."
|
||||
|
||||
//Freezers
|
||||
/obj/machinery/atmospherics/unary/freezer
|
||||
description_info = "Cools down the gas of the pipe it is connected to. It uses massive amounts of electricity while on. \
|
||||
It can be upgraded by replacing the capacitors, manipulators, and matter bins. It can be deconstructed by screwing the maintenance panel open with a \
|
||||
screwdriver, and then using a crowbar."
|
||||
|
||||
//Heaters
|
||||
/obj/machinery/atmospherics/unary/heater
|
||||
description_info = "Heats up the gas of the pipe it is connected to. It uses massive amounts of electricity while on. \
|
||||
It can be upgraded by replacing the capacitors, manipulators, and matter bins. It can be deconstructed by screwing the maintenance panel open with a \
|
||||
screwdriver, and then using a crowbar."
|
||||
|
||||
//Gas injectors
|
||||
/obj/machinery/atmospherics/unary/outlet_injector
|
||||
description_info = "Outputs the pipe's gas into the atmosphere, similar to an airvent. It can be controlled by a nearby atmospherics computer. \
|
||||
A green light on it means it is on."
|
||||
|
||||
//Scrubbers
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber
|
||||
description_info = "This filters the atmosphere of harmful gas. Filtered gas goes to the pipes connected to it, typically a scrubber pipe. \
|
||||
It can be controlled from an Air Alarm. It can be configured to drain all air rapidly with a 'panic syphon' from an air alarm."
|
||||
|
||||
//Omni filters
|
||||
/obj/machinery/atmospherics/omni/filter
|
||||
description_info = "Filters gas from a custom input direction, with up to two filtered outputs and a 'everything else' \
|
||||
output. The filtered output's arrows glow orange."
|
||||
|
||||
//Omni mixers
|
||||
/obj/machinery/atmospherics/omni/mixer
|
||||
description_info = "Combines gas from custom input and output directions. The percentage of combined gas can be defined."
|
||||
|
||||
//Canisters
|
||||
/obj/machinery/portable_atmospherics/canister
|
||||
description_info = "The canister can be connected to a connector port with a wrench. Tanks of gas (the kind you can hold in your hand) \
|
||||
can be filled by the canister, by using the tank on the canister, increasing the release pressure, then opening the valve until it is full, and then close it. \
|
||||
*DO NOT* remove the tank until the valve is closed. A gas analyzer can be used to check the contents of the canister."
|
||||
|
||||
description_antag = "Canisters can be damaged, spilling their contents into the air, or you can just leave the release valve open."
|
||||
|
||||
//Portable pumps
|
||||
/obj/machinery/portable_atmospherics/powered/pump
|
||||
description_info = "Invaluable for filling air in a room rapidly after a breach repair. The internal gas container can be filled by \
|
||||
connecting it to a connector port. The pump can pump the air in (sucking) or out (blowing), at a specific target pressure. The powercell inside can be \
|
||||
replaced by using a screwdriver, and then adding a new cell. A tank of gas can also be attached to the air pump."
|
||||
|
||||
//Portable scrubbers
|
||||
/obj/machinery/portable_atmospherics/powered/scrubber
|
||||
description_info = "Filters the air, placing harmful gases into the internal gas container. The container can be emptied by \
|
||||
connecting it to a connector port. The pump can pump the air in (sucking) or out (blowing), at a specific target pressure. The powercell inside can be \
|
||||
replaced by using a screwdriver, and then adding a new cell. A tank of gas can also be attached to the scrubber. "
|
||||
|
||||
//Meters
|
||||
/obj/machinery/meter
|
||||
description_info = "Measures the volume and temperature of the pipe under the meter."
|
||||
|
||||
//Pipe dispensers
|
||||
/obj/machinery/pipedispenser
|
||||
description_info = "This can be moved by using a wrench. You will need to wrench it again when you want to use it. You can put \
|
||||
excess (atmospheric) pipes into the dispenser, as well. The dispenser requires electricity to function."
|
||||
|
||||
35
code/modules/examine/descriptions/engineering.dm
Normal file
35
code/modules/examine/descriptions/engineering.dm
Normal file
@@ -0,0 +1,35 @@
|
||||
/obj/machinery/power/supermatter
|
||||
description_info = "When energized by a laser (or something hitting it), it emits radiation and heat. If the heat reaches above 7000 kelvin, it will send an alert and start taking damage. \
|
||||
After integrity falls to zero percent, it will delaminate, causing a massive explosion, station-wide radiation spikes, and hallucinations. \
|
||||
Supermatter reacts badly to oxygen in the atmosphere. It'll also heat up really quick if it is in vacuum.<br>\
|
||||
<br>\
|
||||
Supermatter cores are extremely dangerous to be close to, and requires protection to handle properly. The protection you will need is:<br>\
|
||||
Optical meson scanners on your eyes, to prevent hallucinations when looking at the supermatter.<br>\
|
||||
Radiation helmet and suit, as the supermatter is radioactive.<br>\
|
||||
<br>\
|
||||
Touching the supermatter will result in *instant death*, with no corpse left behind! You can drag the supermatter, but anything else will kill you. \
|
||||
It is advised to obtain a genetic backup before trying to drag it."
|
||||
|
||||
description_antag = "Exposing the supermatter to oxygen or vaccum will cause it to start rapidly heating up. Sabotaging the supermatter and making it explode will \
|
||||
cause a period of lag as the explosion is processed by the server, as well as irradiating the entire station and causing hallucinations to happen. \
|
||||
Wearing radiation equipment will protect you from most of the delamination effects sans explosion."
|
||||
|
||||
/obj/machinery/power/apc
|
||||
description_info = "An APC (Area Power Controller) regulates and supplies backup power for the area they are in. Their power channels are divided \
|
||||
out into 'environmental' (Items that manipulate airflow and temperature), 'lighting' (the lights), and 'equipment' (Everything else that consumes power). \
|
||||
Power consumption and backup power cell charge can be seen from the interface, further controls (turning a specific channel on, off or automatic, \
|
||||
toggling the APC's ability to charge the backup cell, or toggling power for the entire area via master breaker) first requires the interface to be unlocked \
|
||||
with an ID with Engineering access or by one of the station's robots or the artificial intelligence."
|
||||
|
||||
description_antag = "This can be emagged to unlock it. It will cause the APC to have a blue error screen. \
|
||||
Wires can be pulsed remotely with a signaler attached to it. A powersink will also drain any APCs connected to the same wire the powersink is on."
|
||||
|
||||
/obj/item/inflatable
|
||||
description_info = "Inflate by using it in your hand. The inflatable barrier will inflate on your tile. To deflate it, use the 'deflate' verb."
|
||||
|
||||
/obj/structure/inflatable
|
||||
description_info = "To remove these safely, use the 'deflate' verb. Hitting these with any objects will probably puncture and break it forever."
|
||||
|
||||
/obj/structure/inflatable/door
|
||||
description_info = "Click the door to open or close it. It only stops air while closed.<br>\
|
||||
To remove these safely, use the 'deflate' verb. Hitting these with any objects will probably puncture and break it forever."
|
||||
8
code/modules/examine/descriptions/mobs.dm
Normal file
8
code/modules/examine/descriptions/mobs.dm
Normal file
@@ -0,0 +1,8 @@
|
||||
/mob/living/silicon/robot/drone
|
||||
description_info = "Drones are player-controlled synthetics which are lawed to maintain the station and not \
|
||||
interact with anyone else, except for other drones. They hold a wide array of tools to build, repair, maintain, and clean. \
|
||||
They fuction similarly to other synthetics, in that they require recharging regularly, have laws, and are resilient to many hazards, \
|
||||
such as fire, radiation, vacuum, and more. Ghosts can join the round as a maintenance drone by using the appropriate verb in the 'ghost' tab. \
|
||||
An inactive drone can be rebooted by swiping an ID card on it with engineering or robotics access."
|
||||
|
||||
description_antag = "An Electromagnetic Sequencer can be used to subvert the drone to your cause."
|
||||
24
code/modules/examine/descriptions/stacks.dm
Normal file
24
code/modules/examine/descriptions/stacks.dm
Normal file
@@ -0,0 +1,24 @@
|
||||
/obj/item/stack/rods
|
||||
description_info = "Made from metal sheets. You can build a grille by using it in your hand. \
|
||||
Clicking on a floor without any tiles will reinforce the floor. You can make reinforced glass by combining rods and normal glass sheets."
|
||||
|
||||
/obj/item/stack/sheet/glass
|
||||
description_info = "Use in your hand to build a window. Can be upgraded to reinforced glass by adding metal rods, which are made from metal sheets."
|
||||
|
||||
/obj/item/stack/sheet/glass/cyborg
|
||||
description_info = "Use in your hand to build a window. Can be upgraded to reinforced glass by adding metal rods, which are made from metal sheets.<br>\
|
||||
As a synthetic, you can acquire more sheets of glass by recharging."
|
||||
|
||||
/obj/item/stack/sheet/glass/reinforced
|
||||
description_info = "Use in your hand to build a window. Reinforced glass is much stronger against damage."
|
||||
|
||||
/obj/item/stack/sheet/glass/reinforced/cyborg
|
||||
description_info = "Use in your hand to build a window. Reinforced glass is much stronger against damage.<br>\
|
||||
As a synthetic, you can gain more reinforced glass by recharging."
|
||||
|
||||
/obj/item/stack/sheet/metal/cyborg
|
||||
description_info = "Use in your hand to bring up the recipe menu. If you have enough sheets, click on something on the list to build it.<br>\
|
||||
You can replenish your supply of metal as a synthetic by recharging."
|
||||
|
||||
/obj/item/stack/sheet
|
||||
description_info = "Use in your hand to bring up the recipe menu. If you have enough sheets, click on something on the list to build it."
|
||||
15
code/modules/examine/descriptions/structures.dm
Normal file
15
code/modules/examine/descriptions/structures.dm
Normal file
@@ -0,0 +1,15 @@
|
||||
/obj/structure/girder
|
||||
description_info = "Use metal sheets on this to build a normal wall. Adding plasteel instead will make a reinforced wall.<br>\
|
||||
A false wall can be made by using a crowbar on this girder, and then adding metal or plasteel.<br>\
|
||||
You can dismantle the grider with a wrench."
|
||||
|
||||
/obj/structure/girder/reinforced
|
||||
description_info = "Add another sheet of plasteel to finish."
|
||||
|
||||
/obj/structure/grille
|
||||
description_info = "A powered and knotted wire underneath this will cause the grille to shock anyone not wearing insulated gloves.<br>\
|
||||
Wirecutters will turn the grille into metal rods instantly. Grilles are made with metal rods."
|
||||
|
||||
/obj/structure/lattice
|
||||
description_info = "Add a metal floor tile to build a floor on top of the lattice.<br>\
|
||||
Lattices can be made by applying metal rods to a space tile."
|
||||
3
code/modules/examine/descriptions/turfs.dm
Normal file
3
code/modules/examine/descriptions/turfs.dm
Normal file
@@ -0,0 +1,3 @@
|
||||
/turf/simulated/wall
|
||||
description_info = "You can deconstruct this by welding it, and then wrenching the girder.<br>\
|
||||
You can build a wall by using metal sheets and making a girder, then adding more metal or plasteel."
|
||||
71
code/modules/examine/examine.dm
Normal file
71
code/modules/examine/examine.dm
Normal file
@@ -0,0 +1,71 @@
|
||||
/* This code is responsible for the examine tab. When someone examines something, it copies the examined object's description_info,
|
||||
description_fluff, and description_antag, and shows it in a new tab.
|
||||
|
||||
In this file, some atom and mob stuff is defined here. It is defined here instead of in the normal files, to keep the whole system self-contained.
|
||||
This means that this file can be unchecked, along with the other examine files, and can be removed entirely with no effort.
|
||||
*/
|
||||
|
||||
|
||||
/atom/
|
||||
var/description_info = null //Helpful blue text.
|
||||
var/description_fluff = null //Green text about the atom's fluff, if any exists.
|
||||
var/description_antag = null //Malicious red text, for the antags.
|
||||
|
||||
/atom/examine(mob/user)
|
||||
..()
|
||||
user.description_holders["info"] = get_description_info()
|
||||
user.description_holders["fluff"] = get_description_fluff()
|
||||
if(user.mind && user.mind.special_role || isobserver(user)) //Runtime prevention, as ghosts don't have minds.
|
||||
user.description_holders["antag"] = get_description_antag()
|
||||
|
||||
if(name) //This shouldn't be needed but I'm paranoid.
|
||||
user.description_holders["name"] = "[src.name]" //\icon[src]
|
||||
|
||||
user.description_holders["icon"] = "\icon[src]"
|
||||
|
||||
if(desc)
|
||||
user << desc
|
||||
user.description_holders["desc"] = src.desc
|
||||
else
|
||||
user.description_holders["desc"] = null //This is needed, or else if you examine one thing with a desc, then another without, the panel will retain the first examined's desc.
|
||||
|
||||
//Override these if you need special behaviour for a specific type.
|
||||
|
||||
/atom/proc/get_description_info()
|
||||
if(description_info)
|
||||
return description_info
|
||||
return
|
||||
|
||||
/atom/proc/get_description_fluff()
|
||||
if(description_fluff)
|
||||
return description_fluff
|
||||
return
|
||||
|
||||
/atom/proc/get_description_antag()
|
||||
if(description_antag)
|
||||
return description_antag
|
||||
return
|
||||
|
||||
/mob/
|
||||
var/description_holders[0]
|
||||
|
||||
/mob/Stat()
|
||||
..()
|
||||
if(statpanel("Examine"))
|
||||
stat(null,"[description_holders["icon"]] <font size='5'>[description_holders["name"]]</font>") //The name, written in big letters.
|
||||
stat(null,"[description_holders["desc"]]") //the default examine text.
|
||||
if(description_holders["info"])
|
||||
stat(null,"<font color='#084B8A'><b>[description_holders["info"]]</b></font>") //Blue, informative text.
|
||||
if(description_holders["fluff"])
|
||||
stat(null,"<font color='#298A08'><b>[description_holders["fluff"]]</b></font>") //Yellow, fluff-related text.
|
||||
if(description_holders["antag"])
|
||||
stat(null,"<font color='#8A0808'><b>[description_holders["antag"]]</b></font>") //Red, malicious antag-related text
|
||||
|
||||
/mob/living/get_description_fluff()
|
||||
if(flavor_text) //Get flavor text for the green text.
|
||||
return flavor_text
|
||||
else //No flavor text? Try for hardcoded fluff instead.
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/get_description_fluff()
|
||||
return print_flavor_text(0)
|
||||
@@ -1280,9 +1280,6 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/get_descriptions_fluff()
|
||||
return print_flavor_text(0)
|
||||
|
||||
/mob/living/carbon/human/getDNA()
|
||||
if(species.flags & NO_SCAN)
|
||||
return null
|
||||
|
||||
@@ -171,13 +171,6 @@
|
||||
|
||||
// ++++ROCKDTBEN++++ MOB PROCS //END
|
||||
|
||||
|
||||
/mob/living/get_descriptions_fluff()
|
||||
if(flavor_text) //Get flavor text for the green text.
|
||||
return flavor_text
|
||||
else //No flavor text? Try for hardcoded fluff instead.
|
||||
return ..()
|
||||
|
||||
/mob/proc/get_contents()
|
||||
|
||||
|
||||
|
||||
@@ -3,13 +3,6 @@
|
||||
real_name = "drone"
|
||||
icon = 'icons/mob/robots.dmi'
|
||||
icon_state = "repairbot"
|
||||
descriptions = new/datum/descriptions("Drones are player-controlled synthetics which are lawed to maintain the station and not \
|
||||
interact with anyone else, except for other drones. They hold a wide array of tools to build, repair, maintain, and clean. \
|
||||
They fuction similarly to other synthetics, in that they require recharging regularly, have laws, and are resilient to many hazards, \
|
||||
such as fire, radiation, vacuum, and more. Ghosts can join the round as a maintenance drone by using the appropriate verb in the 'ghost' tab. \
|
||||
An inactive drone can be rebooted by swiping an ID card on it with engineering or robotics access.",\
|
||||
,"An <u>Electromagnetic Sequencer</u> can be used to subvert the drone to your cause.")
|
||||
//desc_fluff is already provided with flavor_text.
|
||||
maxHealth = 35
|
||||
health = 35
|
||||
universal_speak = 0
|
||||
|
||||
@@ -834,16 +834,6 @@ note dizziness decrements automatically in the mob's Life() proc.
|
||||
statpanel("Spells","[S.charge_counter]/[S.charge_max]",S)
|
||||
if("holdervar")
|
||||
statpanel("Spells","[S.holder_var_type] [S.holder_var_amount]",S)
|
||||
if(statpanel("Examine"))
|
||||
stat(null,"[description_holders["icon"]] <font size='5'>[description_holders["name"]]</font>") //The name, written in big letters.
|
||||
stat(null,"[description_holders["desc"]]") //the default examine text.
|
||||
if(description_holders["info"])
|
||||
stat(null,"<font color='#084B8A'><b>[description_holders["info"]]</b></font>") //Blue, informative text.
|
||||
if(description_holders["fluff"])
|
||||
stat(null,"<font color='#298A08'><b>[description_holders["fluff"]]</b></font>") //Yellow, fluff-related text.
|
||||
if(mind.special_role)
|
||||
if(description_holders["antag"])
|
||||
stat(null,"<font color='#8A0808'><b>[description_holders["antag"]]</b></font>") //Red, malicious antag-related text
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -224,7 +224,4 @@
|
||||
|
||||
var/list/active_genes=list()
|
||||
|
||||
//Examine tab vars
|
||||
//These hold the descriptions and other info, to relay to the actual tab.
|
||||
var/description_holders[0]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user