mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-29 23:17:02 +01:00
Merge remote-tracking branch 'upstream/master' into to_chat
Conflicts: code/game/machinery/door_control.dm
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
|
||||
//////////////////////////////////////
|
||||
// Driver Button //
|
||||
//////////////////////////////////////
|
||||
|
||||
/obj/machinery/driver_button
|
||||
name = "mass driver button"
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
@@ -5,11 +10,17 @@
|
||||
desc = "A remote control switch for a mass driver."
|
||||
var/id_tag = "default"
|
||||
var/active = 0
|
||||
settagwhitelist = list("id_tag")
|
||||
settagwhitelist = list("id_tag", "logic_id_tag")
|
||||
anchored = 1.0
|
||||
use_power = 1
|
||||
idle_power_usage = 2
|
||||
active_power_usage = 4
|
||||
var/range = 7
|
||||
|
||||
var/datum/radio_frequency/radio_connection
|
||||
var/frequency = 0
|
||||
var/logic_id_tag = "default" //Defines the ID tag to send logic signals to, so you don't have to unlink from doors and stuff
|
||||
var/logic_connect = 0 //Set this to allow the button to send out logic signals when pressed in addition to normal stuff
|
||||
|
||||
/obj/machinery/driver_button/New(turf/loc, var/w_dir=null)
|
||||
..()
|
||||
@@ -22,6 +33,123 @@
|
||||
pixel_x = 25
|
||||
if(WEST)
|
||||
pixel_x = -25
|
||||
if(radio_controller)
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/machinery/driver_button/initialize()
|
||||
..()
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/machinery/driver_button/proc/set_frequency(new_frequency)
|
||||
radio_controller.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
radio_connection = radio_controller.add_object(src, frequency, RADIO_LOGIC)
|
||||
return
|
||||
|
||||
/obj/machinery/driver_button/Destroy()
|
||||
if(radio_controller)
|
||||
radio_controller.remove_object(src,frequency)
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/driver_button/attack_ai(mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/driver_button/attackby(obj/item/weapon/W, mob/user as mob, params)
|
||||
|
||||
if(istype(W, /obj/item/device/detective_scanner))
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/device/multitool))
|
||||
update_multitool_menu(user)
|
||||
return 1
|
||||
|
||||
if(istype(W, /obj/item/weapon/wrench))
|
||||
playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
|
||||
if(do_after(user, 30, target = src))
|
||||
user << "<span class='notice'>You detach \the [src] from the wall.</span>"
|
||||
new/obj/item/mounted/frame/driver_button(get_turf(src))
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/driver_button/multitool_menu(var/mob/user, var/obj/item/device/multitool/P)
|
||||
return {"
|
||||
<ul>
|
||||
<li><b>ID Tag:</b> [format_tag("ID Tag","id_tag")]</li>
|
||||
<li><b>Logic Connection:</b> <a href='?src=\ref[src];toggle_logic=1'>[logic_connect ? "On" : "Off"]</a></li>
|
||||
<li><b>Logic ID Tag:</b> [format_tag("Logic ID Tag", "logic_id_tag")]</li>
|
||||
</ul>"}
|
||||
|
||||
/obj/machinery/driver_button/attack_hand(mob/user as mob)
|
||||
|
||||
src.add_fingerprint(usr)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(active)
|
||||
return
|
||||
add_fingerprint(user)
|
||||
|
||||
use_power(5)
|
||||
|
||||
launch_sequence()
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/driver_button/proc/launch_sequence()
|
||||
active = 1
|
||||
icon_state = "launcheract"
|
||||
|
||||
if(logic_connect)
|
||||
if(!radio_connection) //can't output without this
|
||||
return
|
||||
|
||||
if(logic_id_tag == null) //Don't output to an undefined id_tag
|
||||
return
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = 1 //radio signal
|
||||
signal.source = src
|
||||
|
||||
signal.data = list(
|
||||
"tag" = logic_id_tag,
|
||||
"sigtype" = "logic",
|
||||
"state" = LOGIC_FLICKER, //Buttons are a FLICKER source, since they only register as ON when you press it, then turn OFF after you release
|
||||
)
|
||||
|
||||
radio_connection.post_signal(src, signal, filter = RADIO_LOGIC)
|
||||
|
||||
for(var/obj/machinery/door/poddoor/M in range(src,range))
|
||||
if (M.id_tag == src.id_tag && !M.protected)
|
||||
spawn()
|
||||
M.open()
|
||||
|
||||
sleep(20)
|
||||
|
||||
for(var/obj/machinery/mass_driver/M in range(src,range))
|
||||
if(M.id_tag == src.id_tag)
|
||||
M.drive()
|
||||
|
||||
sleep(50)
|
||||
|
||||
for(var/obj/machinery/door/poddoor/M in range(src,range))
|
||||
if (M.id_tag == src.id_tag && !M.protected)
|
||||
spawn()
|
||||
M.close()
|
||||
return
|
||||
|
||||
icon_state = "launcherbtt"
|
||||
active = 0
|
||||
|
||||
/obj/machinery/driver_button/multitool_topic(var/mob/user,var/list/href_list,var/obj/O)
|
||||
..()
|
||||
if("toggle_logic" in href_list)
|
||||
logic_connect = !logic_connect
|
||||
|
||||
//////////////////////////////////////
|
||||
// Ignition Switch //
|
||||
//////////////////////////////////////
|
||||
|
||||
/obj/machinery/ignition_switch
|
||||
name = "ignition switch"
|
||||
@@ -35,6 +163,46 @@
|
||||
idle_power_usage = 2
|
||||
active_power_usage = 4
|
||||
|
||||
/obj/machinery/ignition_switch/attack_ai(mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/ignition_switch/attackby(obj/item/weapon/W, mob/user as mob, params)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/ignition_switch/attack_hand(mob/user as mob)
|
||||
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(active)
|
||||
return
|
||||
|
||||
use_power(5)
|
||||
|
||||
active = 1
|
||||
icon_state = "launcheract"
|
||||
|
||||
for(var/obj/machinery/sparker/M in world)
|
||||
if (M.id == src.id)
|
||||
spawn( 0 )
|
||||
M.spark()
|
||||
|
||||
for(var/obj/machinery/igniter/M in world)
|
||||
if(M.id == src.id)
|
||||
use_power(50)
|
||||
M.on = !( M.on )
|
||||
M.icon_state = text("igniter[]", M.on)
|
||||
|
||||
sleep(50)
|
||||
|
||||
icon_state = "launcherbtt"
|
||||
active = 0
|
||||
|
||||
return
|
||||
|
||||
//////////////////////////////////////
|
||||
// Flasher Button //
|
||||
//////////////////////////////////////
|
||||
|
||||
/obj/machinery/flasher_button
|
||||
name = "flasher button"
|
||||
desc = "A remote control switch for a mounted flasher."
|
||||
@@ -47,6 +215,10 @@
|
||||
idle_power_usage = 2
|
||||
active_power_usage = 4
|
||||
|
||||
//////////////////////////////////////
|
||||
// Crematorium Switch //
|
||||
//////////////////////////////////////
|
||||
|
||||
/obj/machinery/crema_switch
|
||||
desc = "Burn baby burn!"
|
||||
name = "crematorium igniter"
|
||||
|
||||
@@ -878,4 +878,50 @@ obj/item/weapon/circuitboard/rdserver
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/matter_bin = 1,
|
||||
/obj/item/weapon/stock_parts/manipulator = 1,
|
||||
/obj/item/weapon/stock_parts/console_screen = 1)
|
||||
/obj/item/weapon/stock_parts/console_screen = 1)
|
||||
|
||||
|
||||
//Selectable mode board, like vending machine boards
|
||||
/obj/item/weapon/circuitboard/logic_gate
|
||||
name = "circuit board (Logic Connector)"
|
||||
build_path = /obj/machinery/logic_gate
|
||||
board_type = "machine"
|
||||
origin_tech = "programming=1" //This stuff is pretty much the absolute basis of programming, so it's mostly useless for research
|
||||
req_components = list(/obj/item/stack/cable_coil = 1)
|
||||
|
||||
var/list/names_paths = list(
|
||||
"NOT Gate" = /obj/machinery/logic_gate/not,
|
||||
"OR Gate" = /obj/machinery/logic_gate/or,
|
||||
"AND Gate" = /obj/machinery/logic_gate/and,
|
||||
"NAND Gate" = /obj/machinery/logic_gate/nand,
|
||||
"NOR Gate" = /obj/machinery/logic_gate/nor,
|
||||
"XOR Gate" = /obj/machinery/logic_gate/xor,
|
||||
"XNOR Gate" = /obj/machinery/logic_gate/xnor,
|
||||
"STATUS Gate" = /obj/machinery/logic_gate/status,
|
||||
"CONVERT Gate" = /obj/machinery/logic_gate/convert
|
||||
)
|
||||
|
||||
/obj/item/weapon/circuitboard/logic_gate/New()
|
||||
..()
|
||||
if(build_path == /obj/machinery/logic_gate) //If we spawn the base type board (determined by the base type machine as the build path), become a random gate board
|
||||
var/new_path = names_paths[pick(names_paths)]
|
||||
set_type(new_path)
|
||||
|
||||
/obj/item/weapon/circuitboard/logic_gate/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
set_type(null, user)
|
||||
|
||||
/obj/item/weapon/circuitboard/logic_gate/proc/set_type(typepath, mob/user)
|
||||
var/new_name = "Logic Base"
|
||||
if(!typepath)
|
||||
new_name = input("Circuit Setting", "What would you change the board setting to?") in names_paths
|
||||
typepath = names_paths[new_name]
|
||||
else
|
||||
for(var/name in names_paths)
|
||||
if(names_paths[name] == typepath)
|
||||
new_name = name
|
||||
break
|
||||
build_path = typepath
|
||||
name = "circuit board ([new_name])"
|
||||
if(user)
|
||||
user << "<span class='notice'>You set the board to [new_name].</span>"
|
||||
|
||||
@@ -131,74 +131,3 @@
|
||||
icon_state = "doorctrl-p"
|
||||
else
|
||||
icon_state = "doorctrl0"
|
||||
|
||||
/obj/machinery/driver_button/var/range = 7
|
||||
|
||||
/obj/machinery/driver_button/attack_ai(mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/driver_button/attackby(obj/item/weapon/W, mob/user as mob, params)
|
||||
|
||||
if(istype(W, /obj/item/device/detective_scanner))
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/device/multitool))
|
||||
update_multitool_menu(user)
|
||||
return 1
|
||||
|
||||
if(istype(W, /obj/item/weapon/wrench))
|
||||
playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
|
||||
if(do_after(user, 30, target = src))
|
||||
to_chat(user, "<span class='notice'>You detach \the [src] from the wall.</span>")
|
||||
new/obj/item/mounted/frame/driver_button(get_turf(src))
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/driver_button/multitool_menu(var/mob/user, var/obj/item/device/multitool/P)
|
||||
return {"
|
||||
<ul>
|
||||
<li>[format_tag("ID Tag","id_tag")]</li>
|
||||
</ul>"}
|
||||
|
||||
/obj/machinery/driver_button/attack_hand(mob/user as mob)
|
||||
|
||||
src.add_fingerprint(usr)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(active)
|
||||
return
|
||||
add_fingerprint(user)
|
||||
|
||||
use_power(5)
|
||||
|
||||
launch_sequence()
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/driver_button/proc/launch_sequence()
|
||||
active = 1
|
||||
icon_state = "launcheract"
|
||||
|
||||
for(var/obj/machinery/door/poddoor/M in range(src,range))
|
||||
if (M.id_tag == src.id_tag && !M.protected)
|
||||
spawn()
|
||||
M.open()
|
||||
|
||||
sleep(20)
|
||||
|
||||
for(var/obj/machinery/mass_driver/M in range(src,range))
|
||||
if(M.id_tag == src.id_tag)
|
||||
M.drive()
|
||||
|
||||
sleep(50)
|
||||
|
||||
for(var/obj/machinery/door/poddoor/M in range(src,range))
|
||||
if (M.id_tag == src.id_tag && !M.protected)
|
||||
spawn()
|
||||
M.close()
|
||||
return
|
||||
|
||||
icon_state = "launcherbtt"
|
||||
active = 0
|
||||
@@ -114,39 +114,3 @@
|
||||
return
|
||||
spark()
|
||||
..(severity)
|
||||
|
||||
/obj/machinery/ignition_switch/attack_ai(mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/ignition_switch/attackby(obj/item/weapon/W, mob/user as mob, params)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/ignition_switch/attack_hand(mob/user as mob)
|
||||
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(active)
|
||||
return
|
||||
|
||||
use_power(5)
|
||||
|
||||
active = 1
|
||||
icon_state = "launcheract"
|
||||
|
||||
for(var/obj/machinery/sparker/M in world)
|
||||
if (M.id == src.id)
|
||||
spawn( 0 )
|
||||
M.spark()
|
||||
|
||||
for(var/obj/machinery/igniter/M in world)
|
||||
if(M.id == src.id)
|
||||
use_power(50)
|
||||
M.on = !( M.on )
|
||||
M.icon_state = text("igniter[]", M.on)
|
||||
|
||||
sleep(50)
|
||||
|
||||
icon_state = "launcherbtt"
|
||||
active = 0
|
||||
|
||||
return
|
||||
@@ -11,9 +11,27 @@
|
||||
var/area/area = null
|
||||
var/otherarea = null
|
||||
// luminosity = 1
|
||||
settagwhitelist = list("logic_id_tag")
|
||||
var/light_connect = 1 //Allows the switch to control lights in its associated areas. When set to 0, using the switch won't affect the lights.
|
||||
var/datum/radio_frequency/radio_connection
|
||||
var/frequency = 0
|
||||
var/logic_id_tag = "default" //Defines the ID tag to send logic signals to.
|
||||
var/logic_connect = 0 //Set this to allow the switch to send out logic signals.
|
||||
|
||||
/obj/machinery/light_switch/New()
|
||||
|
||||
/obj/machinery/light_switch/New(turf/loc, var/w_dir=null)
|
||||
..()
|
||||
switch(w_dir)
|
||||
if(NORTH)
|
||||
pixel_y = 25
|
||||
if(SOUTH)
|
||||
pixel_y = -25
|
||||
if(EAST)
|
||||
pixel_x = 25
|
||||
if(WEST)
|
||||
pixel_x = -25
|
||||
if(radio_controller)
|
||||
set_frequency(frequency)
|
||||
spawn(5)
|
||||
src.area = src.loc.loc
|
||||
|
||||
@@ -26,7 +44,20 @@
|
||||
src.on = src.area.lightswitch
|
||||
updateicon()
|
||||
|
||||
/obj/machinery/light_switch/initialize()
|
||||
..()
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/machinery/light_switch/proc/set_frequency(new_frequency)
|
||||
radio_controller.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
radio_connection = radio_controller.add_object(src, frequency, RADIO_LOGIC)
|
||||
return
|
||||
|
||||
/obj/machinery/light_switch/Destroy()
|
||||
if(radio_controller)
|
||||
radio_controller.remove_object(src,frequency)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/light_switch/proc/updateicon()
|
||||
if(stat & NOPOWER)
|
||||
@@ -41,22 +72,55 @@
|
||||
if(..(user, 1))
|
||||
to_chat(user, "A light switch. It is [on? "on" : "off"].")
|
||||
|
||||
|
||||
/obj/machinery/light_switch/attack_hand(mob/user)
|
||||
|
||||
on = !on
|
||||
updateicon()
|
||||
|
||||
area.lightswitch = on
|
||||
area.updateicon()
|
||||
if(light_connect)
|
||||
area.lightswitch = on
|
||||
area.updateicon()
|
||||
|
||||
for(var/obj/machinery/light_switch/L in area)
|
||||
L.on = on
|
||||
L.updateicon()
|
||||
if(logic_connect && powered(LIGHT)) //Don't bother sending a signal if we aren't set to send them or we have no power to send with.
|
||||
handle_output()
|
||||
|
||||
area.power_change()
|
||||
if(light_connect)
|
||||
for(var/obj/machinery/light_switch/L in area)
|
||||
L.on = on
|
||||
L.updateicon()
|
||||
|
||||
area.power_change()
|
||||
|
||||
/obj/machinery/light_switch/proc/handle_output()
|
||||
if(!radio_connection) //can't output without this
|
||||
return
|
||||
|
||||
if(logic_id_tag == null) //Don't output to an undefined id_tag
|
||||
return
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = 1 //radio signal
|
||||
signal.source = src
|
||||
|
||||
//Light switches are continuous signal sources, since they register as ON or OFF and stay that way until adjusted again
|
||||
if(on)
|
||||
signal.data = list(
|
||||
"tag" = logic_id_tag,
|
||||
"sigtype" = "logic",
|
||||
"state" = LOGIC_ON,
|
||||
)
|
||||
else
|
||||
signal.data = list(
|
||||
"tag" = logic_id_tag,
|
||||
"sigtype" = "logic",
|
||||
"state" = LOGIC_OFF,
|
||||
)
|
||||
|
||||
radio_connection.post_signal(src, signal, filter = RADIO_LOGIC)
|
||||
if(on)
|
||||
use_power(5, LIGHT) //Use a tiny bit of power every time we send an ON signal. Draws from the local APC's lighting circuit, since this is a LIGHT switch.
|
||||
|
||||
/obj/machinery/light_switch/power_change()
|
||||
|
||||
if(!otherarea)
|
||||
if(powered(LIGHT))
|
||||
stat &= ~NOPOWER
|
||||
@@ -71,3 +135,40 @@
|
||||
return
|
||||
power_change()
|
||||
..(severity)
|
||||
|
||||
/obj/machinery/light_switch/process()
|
||||
if(logic_connect && powered(LIGHT)) //We won't send signals while unpowered, but the last signal will remain valid for anything that received it before we went dark
|
||||
handle_output()
|
||||
|
||||
/obj/machinery/light_switch/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if(istype(W, /obj/item/device/detective_scanner))
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/device/multitool))
|
||||
update_multitool_menu(user)
|
||||
return 1
|
||||
|
||||
if(istype(W, /obj/item/weapon/wrench))
|
||||
playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1)
|
||||
if(do_after(user, 30, target = src))
|
||||
user << "<span class='notice'>You detach \the [src] from the wall.</span>"
|
||||
new/obj/item/mounted/frame/light_switch(get_turf(src))
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/light_switch/multitool_menu(var/mob/user, var/obj/item/device/multitool/P)
|
||||
return {"
|
||||
<ul>
|
||||
<li><b>Light Circuit Connection:</b> <a href='?src=\ref[src];toggle_light_connect=1'>[light_connect ? "On" : "Off"]</a></li>
|
||||
<li><b>Logic Connection:</b> <a href='?src=\ref[src];toggle_logic=1'>[logic_connect ? "On" : "Off"]</a></li>
|
||||
<li><b>Logic ID Tag:</b> [format_tag("Logic ID Tag", "logic_id_tag")]</li>
|
||||
</ul>"}
|
||||
|
||||
/obj/machinery/light_switch/multitool_topic(var/mob/user,var/list/href_list,var/obj/O)
|
||||
..()
|
||||
if("toggle_light_connect" in href_list)
|
||||
light_connect = !light_connect
|
||||
if("toggle_logic" in href_list)
|
||||
logic_connect = !logic_connect
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/obj/item/mounted/frame/driver_button
|
||||
name = "mass driver button frame"
|
||||
desc = "Used for repairing or building mass driver buttons"
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "launcherbtt_frame"
|
||||
mount_reqs = list("simfloor")
|
||||
sheets_refunded = 1
|
||||
|
||||
/obj/item/mounted/frame/driver_button/do_build(turf/on_wall, mob/user)
|
||||
new /obj/machinery/driver_button(get_turf(user), get_dir(user, on_wall))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/mounted/frame/light_switch
|
||||
name = "light switch frame"
|
||||
desc = "Used for repairing or building light switches"
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "light-p"
|
||||
mount_reqs = list("simfloor", "nospace")
|
||||
sheets_refunded = 1
|
||||
|
||||
/obj/item/mounted/frame/light_switch/do_build(turf/on_wall, mob/user)
|
||||
new /obj/machinery/light_switch(get_turf(user), get_dir(user, on_wall))
|
||||
qdel(src)
|
||||
@@ -1,10 +0,0 @@
|
||||
/obj/item/mounted/frame/driver_button
|
||||
name = "mass driver button frame"
|
||||
desc = "Used for repairing or building mass driver buttons"
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "launcherbtt_frame"
|
||||
mount_reqs = list("simfloor")
|
||||
|
||||
/obj/item/mounted/frame/driver_button/do_build(turf/on_wall, mob/user)
|
||||
new /obj/machinery/driver_button(get_turf(user), get_dir(user, on_wall))
|
||||
qdel(src)
|
||||
@@ -73,6 +73,7 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \
|
||||
), 4), \
|
||||
null, \
|
||||
new/datum/stack_recipe("mass driver button frame", /obj/item/mounted/frame/driver_button, 1, time = 50, one_per_turf = 0, on_floor = 1), \
|
||||
new/datum/stack_recipe("light switch frame", /obj/item/mounted/frame/light_switch, 1, time = 50, one_per_turf = 0, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("grenade casing", /obj/item/weapon/grenade/chem_grenade), \
|
||||
new/datum/stack_recipe("light fixture frame", /obj/item/mounted/frame/light_fixture, 2), \
|
||||
|
||||
Reference in New Issue
Block a user