mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
[MIRROR] Gets rid of sleep in Fire and Fire_userless (#10086)
Co-authored-by: Cameron Lennox <killer65311@gmail.com> Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
fac2a2e52a
commit
15de0ed49d
@@ -52,7 +52,6 @@
|
|||||||
drop_sound = 'sound/items/drop/gun.ogg'
|
drop_sound = 'sound/items/drop/gun.ogg'
|
||||||
pickup_sound = 'sound/items/pickup/gun.ogg'
|
pickup_sound = 'sound/items/pickup/gun.ogg'
|
||||||
|
|
||||||
var/recoil_mode = 1 //0 = no micro recoil, 1 = regular, anything higher than 1 is a multiplier //YAWN Addition, ported from CHOMP
|
|
||||||
var/automatic = 0
|
var/automatic = 0
|
||||||
var/burst = 1
|
var/burst = 1
|
||||||
var/fire_delay = 6 //delay after shooting before the gun can be used again
|
var/fire_delay = 6 //delay after shooting before the gun can be used again
|
||||||
@@ -95,6 +94,7 @@
|
|||||||
var/obj/item/dnalockingchip/attached_lock
|
var/obj/item/dnalockingchip/attached_lock
|
||||||
|
|
||||||
var/last_shot = 0 //records the last shot fired
|
var/last_shot = 0 //records the last shot fired
|
||||||
|
var/recoil_mode = 1 //If the gun will hurt micros if shot or not. Disabled on Virgo, used downstream. //CHOMPEDIT - Enabled
|
||||||
|
|
||||||
//VOREStation Add - /tg/ icon system
|
//VOREStation Add - /tg/ icon system
|
||||||
var/charge_sections = 4
|
var/charge_sections = 4
|
||||||
@@ -311,15 +311,13 @@
|
|||||||
if(!canremove)
|
if(!canremove)
|
||||||
return
|
return
|
||||||
|
|
||||||
//CHOMPEdit start - move these around so that nonhumans can actually click-drag guns at all
|
|
||||||
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech. why?
|
|
||||||
return
|
|
||||||
|
|
||||||
if (!( istype(over_object, /obj/screen) ))
|
|
||||||
return ..()
|
|
||||||
|
|
||||||
if (ishuman(usr) || issmall(usr)) //so monkeys can take off their backpacks -- Urist
|
if (ishuman(usr) || issmall(usr)) //so monkeys can take off their backpacks -- Urist
|
||||||
//CHOMPEdit End
|
|
||||||
|
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech. why?
|
||||||
|
return
|
||||||
|
|
||||||
|
if (!( istype(over_object, /obj/screen) ))
|
||||||
|
return ..()
|
||||||
|
|
||||||
//makes sure that the thing is equipped, so that we can't drag it into our hand from miles away.
|
//makes sure that the thing is equipped, so that we can't drag it into our hand from miles away.
|
||||||
//there's got to be a better way of doing this.
|
//there's got to be a better way of doing this.
|
||||||
@@ -364,99 +362,83 @@
|
|||||||
user.setMoveCooldown(shoot_time) //no moving while shooting either
|
user.setMoveCooldown(shoot_time) //no moving while shooting either
|
||||||
|
|
||||||
next_fire_time = world.time + shoot_time
|
next_fire_time = world.time + shoot_time
|
||||||
|
handle_gunfire(target, user, clickparams, pointblank, reflex, 1, FALSE)
|
||||||
|
|
||||||
var/held_twohanded = (user.can_wield_item(src) && src.is_held_twohanded(user))
|
/obj/item/gun/proc/handle_gunfire(atom/target, mob/living/user, clickparams, pointblank=0, reflex=0, var/ticker, var/recursive = FALSE)
|
||||||
|
PRIVATE_PROC(TRUE)
|
||||||
|
SHOULD_NOT_OVERRIDE(TRUE)
|
||||||
|
if(ticker > burst)
|
||||||
|
return //we're done here
|
||||||
|
if(!ismob(loc)) //We've been dropped.
|
||||||
|
return
|
||||||
|
if(user.stat) //We've been KO'd or have died. No shooting while dead.
|
||||||
|
return
|
||||||
|
if(ticker >= 250) //If you go too far above this, your game will kick you and force you to reconnect. This is already EXTREMELY leninent.
|
||||||
|
return //In testing, I reached 937 bullets out of 1000 being fired with a delay of 0.1 before being kicked.
|
||||||
|
var/held_twohanded = (user.can_wield_item(src) && is_held_twohanded(user))
|
||||||
|
|
||||||
//actually attempt to shoot
|
//actually attempt to shoot
|
||||||
var/turf/targloc = get_turf(target) //cache this in case target gets deleted during shooting, e.g. if it was a securitron that got destroyed.
|
var/turf/targloc = get_turf(target) //cache this in case target gets deleted during shooting, e.g. if it was a securitron that got destroyed.
|
||||||
|
|
||||||
/* // Commented out for quality control and testing.
|
|
||||||
shooting = 1
|
|
||||||
if(automatic == 1 && auto_target && auto_target.active)//When we are going to shoot and have an auto_target AND its active meaning we clicked on it we tell it to burstfire 1000 rounds
|
|
||||||
burst = 1000//Yes its not EXACTLY full auto but when are we shooting more than 1000 normally and it can easily be made higher
|
|
||||||
*/
|
|
||||||
for(var/i in 1 to burst)
|
|
||||||
/* // Commented out for quality control and testing.
|
|
||||||
if(!reflex && automatic)//If we are shooting automatic then check our target, however if we are shooting reflex we dont use automatic
|
|
||||||
//extra sanity checking.
|
|
||||||
if(user.incapacitated())
|
|
||||||
return
|
|
||||||
if(user.get_active_hand() != src)
|
|
||||||
break
|
|
||||||
if(!auto_target) break//Stopped shooting
|
|
||||||
else if(auto_target.loc)
|
|
||||||
target = auto_target.loc
|
|
||||||
//Lastly just update our dir if needed
|
|
||||||
if(user.dir != get_dir(user, auto_target))
|
|
||||||
user.face_atom(auto_target)
|
|
||||||
*/
|
|
||||||
var/obj/projectile = consume_next_projectile(user)
|
|
||||||
if(!projectile)
|
|
||||||
handle_click_empty(user)
|
|
||||||
break
|
|
||||||
|
|
||||||
if(i == 1) // So one burst only makes one message and not 3+ messages.
|
|
||||||
handle_firing_text(user, target, pointblank, reflex)
|
|
||||||
|
|
||||||
process_accuracy(projectile, user, target, i, held_twohanded)
|
|
||||||
|
|
||||||
if(pointblank)
|
|
||||||
process_point_blank(projectile, user, target)
|
|
||||||
|
|
||||||
if(process_projectile(projectile, user, target, user.zone_sel.selecting, clickparams))
|
|
||||||
handle_post_fire(user, target, pointblank, reflex)
|
|
||||||
update_icon()
|
|
||||||
|
|
||||||
if(i < burst)
|
|
||||||
sleep(burst_delay)
|
|
||||||
|
|
||||||
if(!(target && target.loc))
|
|
||||||
target = targloc
|
|
||||||
pointblank = 0
|
|
||||||
|
|
||||||
last_shot = world.time
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Commented out for quality control and testing.
|
|
||||||
shooting = 0
|
|
||||||
*/
|
|
||||||
|
|
||||||
// We do this down here, so we don't get the message if we fire an empty gun.
|
|
||||||
if(user.item_is_in_hands(src) && user.hands_are_full())
|
|
||||||
if(one_handed_penalty >= 20)
|
|
||||||
to_chat(user, span_warning("You struggle to keep \the [src] pointed at the correct position with just one hand!"))
|
|
||||||
|
|
||||||
//update timing
|
//update timing
|
||||||
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
|
if(recursive)
|
||||||
user.setMoveCooldown(move_delay)
|
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
|
||||||
next_fire_time = world.time + fire_delay
|
next_fire_time = world.time + fire_delay
|
||||||
|
if(muzzle_flash)
|
||||||
|
if(gun_light)
|
||||||
|
set_light(light_brightness)
|
||||||
|
else
|
||||||
|
set_light(0)
|
||||||
|
|
||||||
accuracy = initial(accuracy) //Reset the gun's accuracy
|
if(ticker <= burst)
|
||||||
|
var/obj/projectile = consume_next_projectile(user)
|
||||||
|
if(!projectile) //click, out of bullets
|
||||||
|
handle_click_empty(user)
|
||||||
|
return
|
||||||
|
|
||||||
if(muzzle_flash)
|
|
||||||
//VOREStation Edit - Flashlights
|
|
||||||
if(gun_light)
|
|
||||||
set_light(light_brightness)
|
|
||||||
else
|
else
|
||||||
set_light(0)
|
if(ticker == 1) // So one burst only makes one message and not 3+ messages.
|
||||||
//VOREStation Edit End
|
handle_firing_text(user, target, pointblank, reflex)
|
||||||
|
|
||||||
//YAWNEDIT: Recoil knockdown for micros, ported from CHOMPStation
|
process_accuracy(projectile, user, target, ticker, held_twohanded)
|
||||||
if(recoil_mode && iscarbon(user))
|
|
||||||
var/mob/living/carbon/nerd = user
|
if(pointblank)
|
||||||
var/mysize = nerd.size_multiplier
|
process_point_blank(projectile, user, target)
|
||||||
if(recoil_mode > 0)
|
|
||||||
if(mysize <= 0.60)
|
if(process_projectile(projectile, user, target, user.zone_sel.selecting, clickparams))
|
||||||
nerd.Weaken(1*recoil_mode)
|
handle_post_fire(user, target, pointblank, reflex)
|
||||||
if(!istype(src,/obj/item/gun/energy))
|
update_icon()
|
||||||
nerd.adjustBruteLoss((5-mysize*4)*recoil_mode)
|
|
||||||
to_chat(nerd, span_danger("You're so tiny that you drop the gun and hurt yourself from the recoil!"))
|
// We do this down here, so we don't get the message if we fire an empty gun.
|
||||||
else
|
if(user.item_is_in_hands(src) && user.hands_are_full())
|
||||||
to_chat(nerd, span_danger("You're so tiny that the pull of the trigger causes you to drop the gun!"))
|
if(one_handed_penalty >= 20)
|
||||||
|
to_chat(user, span_warning("You struggle to keep \the [src] pointed at the correct position with just one hand!"))
|
||||||
|
|
||||||
|
accuracy = initial(accuracy) //Reset our accuracy
|
||||||
|
last_shot = world.time
|
||||||
|
user.hud_used.update_ammo_hud(user, src)
|
||||||
|
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
|
||||||
|
|
||||||
|
if(recoil_mode && iscarbon(user))
|
||||||
|
var/mob/living/carbon/micro = user
|
||||||
|
var/mysize = micro.size_multiplier
|
||||||
|
if(recoil_mode > 0)
|
||||||
|
if(mysize <= 0.60)
|
||||||
|
micro.Weaken(1*recoil_mode)
|
||||||
|
if(!istype(src,/obj/item/gun/energy))
|
||||||
|
micro.adjustBruteLoss((5-mysize*4)*recoil_mode)
|
||||||
|
to_chat(micro, span_danger("You're so tiny that you drop the gun and hurt yourself from the recoil!"))
|
||||||
|
else
|
||||||
|
to_chat(micro, span_danger("You're so tiny that the pull of the trigger causes you to drop the gun!"))
|
||||||
|
|
||||||
|
if(!(target && target.loc))
|
||||||
|
target = targloc
|
||||||
|
pointblank = 0
|
||||||
|
|
||||||
|
if(ticker < burst)
|
||||||
|
addtimer(CALLBACK(src, PROC_REF(handle_gunfire),target, user, clickparams, pointblank, reflex, ++ticker, TRUE), burst_delay, TIMER_DELETE_ME)
|
||||||
|
|
||||||
//YAWNEDIT: Knockdown code end
|
|
||||||
|
|
||||||
user.hud_used.update_ammo_hud(user, src)
|
|
||||||
|
|
||||||
// Similar to the above proc, but does not require a user, which is ideal for things like turrets.
|
// Similar to the above proc, but does not require a user, which is ideal for things like turrets.
|
||||||
/obj/item/gun/proc/Fire_userless(atom/target)
|
/obj/item/gun/proc/Fire_userless(atom/target)
|
||||||
@@ -468,19 +450,34 @@
|
|||||||
|
|
||||||
var/shoot_time = (burst - 1)* burst_delay
|
var/shoot_time = (burst - 1)* burst_delay
|
||||||
next_fire_time = world.time + shoot_time
|
next_fire_time = world.time + shoot_time
|
||||||
|
handle_userless_gunfire(target, 1, FALSE)
|
||||||
|
|
||||||
|
// This is horrible. I tried to keep the old way it had because if I try to use the fancy procs above like handle_post_fire, it expects a user.
|
||||||
|
// Which this doesn't have. It's ugly but whatever. This is used in literally one place (sawn off shotguns) and should honestly just be axed.
|
||||||
|
/obj/item/gun/proc/handle_userless_gunfire(atom/target, var/ticker, var/recursive = FALSE)
|
||||||
|
PRIVATE_PROC(TRUE)
|
||||||
|
SHOULD_NOT_OVERRIDE(TRUE)
|
||||||
|
if(ticker > burst)
|
||||||
|
return //we're done here
|
||||||
|
|
||||||
|
//actually attempt to shoot
|
||||||
var/turf/targloc = get_turf(target) //cache this in case target gets deleted during shooting, e.g. if it was a securitron that got destroyed.
|
var/turf/targloc = get_turf(target) //cache this in case target gets deleted during shooting, e.g. if it was a securitron that got destroyed.
|
||||||
for(var/i in 1 to burst)
|
|
||||||
var/obj/projectile = consume_next_projectile()
|
//update timing
|
||||||
if(!projectile)
|
if(recursive)
|
||||||
|
next_fire_time = world.time + fire_delay
|
||||||
|
if(muzzle_flash)
|
||||||
|
set_light(0)
|
||||||
|
|
||||||
|
if(ticker <= burst)
|
||||||
|
var/obj/item/projectile/P = consume_next_projectile()
|
||||||
|
if(!P) //click, out of bullets
|
||||||
handle_click_empty()
|
handle_click_empty()
|
||||||
break
|
return
|
||||||
|
|
||||||
if(istype(projectile, /obj/item/projectile))
|
else
|
||||||
var/obj/item/projectile/P = projectile
|
var/acc = burst_accuracy[min(ticker, burst_accuracy.len)]
|
||||||
|
var/disp = dispersion[min(ticker, dispersion.len)]
|
||||||
var/acc = burst_accuracy[min(i, burst_accuracy.len)]
|
|
||||||
var/disp = dispersion[min(i, dispersion.len)]
|
|
||||||
|
|
||||||
P.accuracy = accuracy + acc
|
P.accuracy = accuracy + acc
|
||||||
P.dispersion = disp
|
P.dispersion = disp
|
||||||
@@ -491,6 +488,7 @@
|
|||||||
P.old_style_target(target)
|
P.old_style_target(target)
|
||||||
P.fire()
|
P.fire()
|
||||||
|
|
||||||
|
accuracy = initial(accuracy)
|
||||||
last_shot = world.time
|
last_shot = world.time
|
||||||
|
|
||||||
play_fire_sound()
|
play_fire_sound()
|
||||||
@@ -499,22 +497,11 @@
|
|||||||
set_light(muzzle_flash)
|
set_light(muzzle_flash)
|
||||||
update_icon()
|
update_icon()
|
||||||
|
|
||||||
//process_accuracy(projectile, user, target, acc, disp)
|
if(!(target && target.loc))
|
||||||
|
target = targloc
|
||||||
|
|
||||||
// if(pointblank)
|
if(ticker < burst)
|
||||||
// process_point_blank(projectile, user, target)
|
addtimer(CALLBACK(src, PROC_REF(handle_gunfire),target, ++ticker, TRUE), burst_delay, TIMER_DELETE_ME)
|
||||||
|
|
||||||
// if(process_projectile(projectile, null, target, user.zone_sel.selecting, clickparams))
|
|
||||||
// handle_post_fire(null, target, pointblank, reflex)
|
|
||||||
|
|
||||||
// update_icon()
|
|
||||||
|
|
||||||
if(i < burst)
|
|
||||||
sleep(burst_delay)
|
|
||||||
|
|
||||||
if(!(target && target.loc))
|
|
||||||
target = targloc
|
|
||||||
//pointblank = 0
|
|
||||||
|
|
||||||
var/target_for_log
|
var/target_for_log
|
||||||
if(ismob(target))
|
if(ismob(target))
|
||||||
@@ -524,13 +511,6 @@
|
|||||||
|
|
||||||
add_attack_logs("Unmanned",target_for_log,"Fired [src.name]")
|
add_attack_logs("Unmanned",target_for_log,"Fired [src.name]")
|
||||||
|
|
||||||
//update timing
|
|
||||||
next_fire_time = world.time + fire_delay
|
|
||||||
|
|
||||||
accuracy = initial(accuracy) //Reset the gun's accuracy
|
|
||||||
|
|
||||||
if(muzzle_flash)
|
|
||||||
set_light(0)
|
|
||||||
|
|
||||||
//obtains the next projectile to fire
|
//obtains the next projectile to fire
|
||||||
/obj/item/gun/proc/consume_next_projectile()
|
/obj/item/gun/proc/consume_next_projectile()
|
||||||
@@ -789,7 +769,7 @@
|
|||||||
var/datum/firemode/new_mode = firemodes[sel_mode]
|
var/datum/firemode/new_mode = firemodes[sel_mode]
|
||||||
new_mode.apply_to(src)
|
new_mode.apply_to(src)
|
||||||
to_chat(user, span_notice("\The [src] is now set to [new_mode.name]."))
|
to_chat(user, span_notice("\The [src] is now set to [new_mode.name]."))
|
||||||
user.hud_used.update_ammo_hud(user, src)
|
user.hud_used.update_ammo_hud(user, src) // TGMC Ammo HUD
|
||||||
|
|
||||||
return new_mode
|
return new_mode
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
charge_cost = 200 //slightly more shots than lasers
|
charge_cost = 200 //slightly more shots than lasers
|
||||||
var/safetycatch = 0 //if 1, won't let you fire in pressurised environment, rather than malfunctioning
|
var/safetycatch = 0 //if 1, won't let you fire in pressurised environment, rather than malfunctioning
|
||||||
var/obj/item/pressurelock/attached_safety
|
var/obj/item/pressurelock/attached_safety
|
||||||
recoil_mode = 0 //CHOMP Addition: Removes recoil for micros.
|
recoil_mode = 0
|
||||||
|
|
||||||
|
|
||||||
/obj/item/gun/energy/particle/advanced //particle equivalent of AEG
|
/obj/item/gun/energy/particle/advanced //particle equivalent of AEG
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
charge_cost = 160 //Chompedit Bringing charge cost down for all phase weapons. 15 shots on normal cell
|
charge_cost = 160 //Chompedit Bringing charge cost down for all phase weapons. 15 shots on normal cell
|
||||||
projectile_type = /obj/item/projectile/energy/phase
|
projectile_type = /obj/item/projectile/energy/phase
|
||||||
one_handed_penalty = 15
|
one_handed_penalty = 15
|
||||||
recoil_mode = 0 //CHOMP Addition: Removes recoil for micros.
|
recoil_mode = 0
|
||||||
|
|
||||||
/obj/item/gun/energy/locked/phasegun/unlocked
|
/obj/item/gun/energy/locked/phasegun/unlocked
|
||||||
desc = "The RayZar EW26 Artemis, also known as the 'phase carbine', is a downsized energy-based weapon specifically designed for use against wildlife." //ChompEDIT
|
desc = "The RayZar EW26 Artemis, also known as the 'phase carbine', is a downsized energy-based weapon specifically designed for use against wildlife." //ChompEDIT
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
list(mode_name="lethal", fire_delay=12, projectile_type=/obj/item/projectile/beam/phaser, charge_cost = 300),
|
list(mode_name="lethal", fire_delay=12, projectile_type=/obj/item/projectile/beam/phaser, charge_cost = 300),
|
||||||
list(mode_name="low-power", fire_delay=8, projectile_type=/obj/item/projectile/beam/phaser/light, charge_cost = 80),
|
list(mode_name="low-power", fire_delay=8, projectile_type=/obj/item/projectile/beam/phaser/light, charge_cost = 80),
|
||||||
)
|
)
|
||||||
recoil_mode = 0 //CHOMP Addition: Removes recoil for micros.
|
recoil_mode = 0
|
||||||
|
|
||||||
/obj/item/gun/energy/locked/frontier/unload_ammo(var/mob/user)
|
/obj/item/gun/energy/locked/frontier/unload_ammo(var/mob/user)
|
||||||
if(recharging)
|
if(recharging)
|
||||||
|
|||||||
@@ -138,7 +138,7 @@
|
|||||||
list(mode_name="lethal", fire_delay=10, projectile_type=/obj/item/projectile/beam/phaser, charge_cost = 80), //Chompedit Reduced cost
|
list(mode_name="lethal", fire_delay=10, projectile_type=/obj/item/projectile/beam/phaser, charge_cost = 80), //Chompedit Reduced cost
|
||||||
list(mode_name="low-power", fire_delay=5, projectile_type=/obj/item/projectile/beam/phaser/light, charge_cost = 40), //Chompedit Reduced cost
|
list(mode_name="low-power", fire_delay=5, projectile_type=/obj/item/projectile/beam/phaser/light, charge_cost = 40), //Chompedit Reduced cost
|
||||||
) //CHOMPedit Adjusts cost and fire delay to match adjusted beams.
|
) //CHOMPedit Adjusts cost and fire delay to match adjusted beams.
|
||||||
recoil_mode = 0 //CHOMP Addition: Removes recoil for micros.
|
recoil_mode = 0
|
||||||
|
|
||||||
/obj/item/gun/energy/locked/frontier/unload_ammo(var/mob/user)
|
/obj/item/gun/energy/locked/frontier/unload_ammo(var/mob/user)
|
||||||
if(recharging)
|
if(recharging)
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
battery_lock = 1
|
battery_lock = 1
|
||||||
|
|
||||||
var/decl/plantgene/gene = null
|
var/decl/plantgene/gene = null
|
||||||
recoil_mode = 0 //CHOMP Addition
|
recoil_mode = 0
|
||||||
var/obj/item/stock_parts/micro_laser/emitter
|
var/obj/item/stock_parts/micro_laser/emitter
|
||||||
|
|
||||||
firemodes = list(
|
firemodes = list(
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
description_fluff = "An easy to use weapon designed by NanoTrasen, for NanoTrasen. This weapon is based on the NT Mk30 NL, \
|
description_fluff = "An easy to use weapon designed by NanoTrasen, for NanoTrasen. This weapon is based on the NT Mk30 NL, \
|
||||||
it's core components swaped out for a new design made to subdue lesser slime-based xeno lifeforms at a distance. It is \
|
it's core components swaped out for a new design made to subdue lesser slime-based xeno lifeforms at a distance. It is \
|
||||||
ineffective at stunning non-slimy lifeforms such as humanoids."
|
ineffective at stunning non-slimy lifeforms such as humanoids."
|
||||||
recoil_mode = 0 //CHOMP Addition
|
recoil_mode = 0
|
||||||
|
|
||||||
/obj/item/gun/energy/taser/xeno/robot // Borg version
|
/obj/item/gun/energy/taser/xeno/robot // Borg version
|
||||||
self_recharge = 1
|
self_recharge = 1
|
||||||
|
|||||||
@@ -209,4 +209,4 @@
|
|||||||
|
|
||||||
/obj/item/projectile/energy/spikeenergy_ball/slow
|
/obj/item/projectile/energy/spikeenergy_ball/slow
|
||||||
speed = 15
|
speed = 15
|
||||||
range = 20
|
range = 20
|
||||||
|
|||||||
Reference in New Issue
Block a user