mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-30 07:27:57 +01:00
Hydroponics rewrite, details will be in PR. Big commit.
Conflicts: baystation12.dme code/controllers/master_controller.dm code/game/gamemodes/events/spacevines.dm code/game/machinery/seed_extractor.dm code/modules/mob/living/carbon/brain/posibrain.dm code/modules/mob/mob.dm code/modules/reagents/Chemistry-Reagents.dm code/modules/reagents/reagent_containers/food/snacks/grown.dm icons/obj/hydroponics.dmi maps/tgstation2.dmm
This commit is contained in:
@@ -1,260 +1,16 @@
|
||||
// SPACE VINES (Note that this code is very similar to Biomass code)
|
||||
/obj/effect/spacevine
|
||||
name = "space vines"
|
||||
desc = "An extremely expansionistic species of vine."
|
||||
icon = 'icons/effects/spacevines.dmi'
|
||||
icon_state = "Light1"
|
||||
anchored = 1
|
||||
density = 0
|
||||
layer = 5
|
||||
pass_flags = PASSTABLE | PASSGRILLE
|
||||
var/energy = 0
|
||||
var/obj/effect/spacevine_controller/master = null
|
||||
var/mob/living/buckled_mob
|
||||
|
||||
New()
|
||||
return
|
||||
|
||||
Del()
|
||||
if(master)
|
||||
master.vines -= src
|
||||
master.growth_queue -= src
|
||||
..()
|
||||
|
||||
|
||||
/obj/effect/spacevine/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if (!W || !user || !W.type) return
|
||||
switch(W.type)
|
||||
if(/obj/item/weapon/circular_saw) del src
|
||||
if(/obj/item/weapon/kitchen/utensil/knife) del src
|
||||
if(/obj/item/weapon/scalpel) del src
|
||||
if(/obj/item/weapon/twohanded/fireaxe) del src
|
||||
if(/obj/item/weapon/hatchet) del src
|
||||
if(/obj/item/weapon/melee/energy) del src
|
||||
|
||||
//less effective weapons
|
||||
if(/obj/item/weapon/wirecutters)
|
||||
if(prob(25)) del src
|
||||
if(/obj/item/weapon/shard)
|
||||
if(prob(25)) del src
|
||||
|
||||
else //weapons with subtypes
|
||||
if(istype(W, /obj/item/weapon/melee/energy/sword)) del src
|
||||
else if(istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if(WT.remove_fuel(0, user)) del src
|
||||
else
|
||||
manual_unbuckle(user)
|
||||
return
|
||||
//Plant-b-gone damage is handled in its entry in chemistry-reagents.dm
|
||||
..()
|
||||
|
||||
|
||||
/obj/effect/spacevine/attack_hand(mob/user as mob)
|
||||
manual_unbuckle(user)
|
||||
|
||||
|
||||
/obj/effect/spacevine/attack_paw(mob/user as mob)
|
||||
manual_unbuckle(user)
|
||||
|
||||
/obj/effect/spacevine/proc/unbuckle()
|
||||
if(buckled_mob)
|
||||
if(buckled_mob.buckled == src) //this is probably unneccesary, but it doesn't hurt
|
||||
buckled_mob.buckled = null
|
||||
buckled_mob.anchored = initial(buckled_mob.anchored)
|
||||
buckled_mob.update_canmove()
|
||||
buckled_mob = null
|
||||
return
|
||||
|
||||
/obj/effect/spacevine/proc/manual_unbuckle(mob/user as mob)
|
||||
if(buckled_mob)
|
||||
if(prob(50))
|
||||
if(buckled_mob.buckled == src)
|
||||
if(buckled_mob != user)
|
||||
buckled_mob.visible_message(\
|
||||
"<span class='notice'>[user.name] frees [buckled_mob.name] from the vines.</span>",\
|
||||
"<span class='notice'>[user.name] frees you from the vines.</span>",\
|
||||
"<span class='warning'>You hear shredding and ripping.</span>")
|
||||
else
|
||||
buckled_mob.visible_message(\
|
||||
"<span class='notice'>[buckled_mob.name] struggles free of the vines.</span>",\
|
||||
"<span class='notice'>You untangle the vines from around yourself.</span>",\
|
||||
"<span class='warning'>You hear shredding and ripping.</span>")
|
||||
unbuckle()
|
||||
else
|
||||
var/text = pick("rips","tears","pulls")
|
||||
user.visible_message(\
|
||||
"<span class='notice'>[user.name] [text] at the vines.</span>",\
|
||||
"<span class='notice'>You [text] at the vines.</span>",\
|
||||
"<span class='warning'>You hear shredding and ripping.</span>")
|
||||
return
|
||||
|
||||
/obj/effect/spacevine_controller
|
||||
var/list/obj/effect/spacevine/vines = list()
|
||||
var/list/growth_queue = list()
|
||||
var/reached_collapse_size
|
||||
var/reached_slowdown_size
|
||||
//What this does is that instead of having the grow minimum of 1, required to start growing, the minimum will be 0,
|
||||
//meaning if you get the spacevines' size to something less than 20 plots, it won't grow anymore.
|
||||
|
||||
New()
|
||||
if(!istype(src.loc,/turf/simulated/floor))
|
||||
del(src)
|
||||
|
||||
spawn_spacevine_piece(src.loc)
|
||||
processing_objects.Add(src)
|
||||
|
||||
Del()
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
|
||||
proc/spawn_spacevine_piece(var/turf/location)
|
||||
var/obj/effect/spacevine/SV = new(location)
|
||||
growth_queue += SV
|
||||
vines += SV
|
||||
SV.master = src
|
||||
|
||||
process()
|
||||
if(!vines)
|
||||
del(src) //space vines exterminated. Remove the controller
|
||||
return
|
||||
if(!growth_queue)
|
||||
del(src) //Sanity check
|
||||
return
|
||||
if(vines.len >= 250 && !reached_collapse_size)
|
||||
reached_collapse_size = 1
|
||||
if(vines.len >= 30 && !reached_slowdown_size )
|
||||
reached_slowdown_size = 1
|
||||
|
||||
var/length = 0
|
||||
if(reached_collapse_size)
|
||||
length = 0
|
||||
else if(reached_slowdown_size)
|
||||
if(prob(25))
|
||||
length = 1
|
||||
else
|
||||
length = 0
|
||||
else
|
||||
length = 1
|
||||
length = min( 30 , max( length , vines.len / 5 ) )
|
||||
var/i = 0
|
||||
var/list/obj/effect/spacevine/queue_end = list()
|
||||
|
||||
for( var/obj/effect/spacevine/SV in growth_queue )
|
||||
i++
|
||||
queue_end += SV
|
||||
growth_queue -= SV
|
||||
if(SV.energy < 2) //If tile isn't fully grown
|
||||
if(prob(20))
|
||||
SV.grow()
|
||||
else //If tile is fully grown
|
||||
SV.buckle_mob()
|
||||
|
||||
//if(prob(25))
|
||||
SV.spread()
|
||||
if(i >= length)
|
||||
break
|
||||
|
||||
growth_queue = growth_queue + queue_end
|
||||
//sleep(5)
|
||||
//src.process()
|
||||
|
||||
/obj/effect/spacevine/proc/grow()
|
||||
if(!energy)
|
||||
src.icon_state = pick("Med1", "Med2", "Med3")
|
||||
energy = 1
|
||||
src.opacity = 1
|
||||
layer = 5
|
||||
else
|
||||
src.icon_state = pick("Hvy1", "Hvy2", "Hvy3")
|
||||
energy = 2
|
||||
|
||||
/obj/effect/spacevine/proc/buckle_mob()
|
||||
if(!buckled_mob && prob(25))
|
||||
for(var/mob/living/carbon/V in src.loc)
|
||||
if((V.stat != DEAD) && (V.buckled != src)) //if mob not dead or captured
|
||||
V.buckled = src
|
||||
V.loc = src.loc
|
||||
V.update_canmove()
|
||||
src.buckled_mob = V
|
||||
V << "<span class='danger'>The vines [pick("wind", "tangle", "tighten")] around you!</span>"
|
||||
break //only capture one mob at a time.
|
||||
|
||||
/obj/effect/spacevine/proc/spread()
|
||||
var/direction = pick(cardinal)
|
||||
var/step = get_step(src,direction)
|
||||
if(istype(step,/turf/simulated/floor))
|
||||
var/turf/simulated/floor/F = step
|
||||
if(!locate(/obj/effect/spacevine,F))
|
||||
if(F.Enter(src))
|
||||
if(master)
|
||||
master.spawn_spacevine_piece( F )
|
||||
|
||||
/*
|
||||
/obj/effect/spacevine/proc/Life()
|
||||
if (!src) return
|
||||
var/Vspread
|
||||
if (prob(50)) Vspread = locate(src.x + rand(-1,1),src.y,src.z)
|
||||
else Vspread = locate(src.x,src.y + rand(-1, 1),src.z)
|
||||
var/dogrowth = 1
|
||||
if (!istype(Vspread, /turf/simulated/floor)) dogrowth = 0
|
||||
for(var/obj/O in Vspread)
|
||||
if (istype(O, /obj/structure/window) || istype(O, /obj/effect/forcefield) || istype(O, /obj/effect/blob) || istype(O, /obj/effect/alien/weeds) || istype(O, /obj/effect/spacevine)) dogrowth = 0
|
||||
if (istype(O, /obj/machinery/door/))
|
||||
if(O:p_open == 0 && prob(50)) O:open()
|
||||
else dogrowth = 0
|
||||
if (dogrowth == 1)
|
||||
var/obj/effect/spacevine/B = new /obj/effect/spacevine(Vspread)
|
||||
B.icon_state = pick("vine-light1", "vine-light2", "vine-light3")
|
||||
spawn(20)
|
||||
if(B)
|
||||
B.Life()
|
||||
src.growth += 1
|
||||
if (src.growth == 10)
|
||||
src.name = "Thick Space Kudzu"
|
||||
src.icon_state = pick("vine-med1", "vine-med2", "vine-med3")
|
||||
src.opacity = 1
|
||||
src.waittime = 80
|
||||
if (src.growth == 20)
|
||||
src.name = "Dense Space Kudzu"
|
||||
src.icon_state = pick("vine-hvy1", "vine-hvy2", "vine-hvy3")
|
||||
src.density = 1
|
||||
spawn(src.waittime)
|
||||
if (src.growth < 20) src.Life()
|
||||
|
||||
*/
|
||||
|
||||
/obj/effect/spacevine/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
qdel(src)
|
||||
return
|
||||
if(2.0)
|
||||
if (prob(90))
|
||||
qdel(src)
|
||||
return
|
||||
if(3.0)
|
||||
if (prob(50))
|
||||
qdel(src)
|
||||
return
|
||||
return
|
||||
|
||||
/obj/effect/spacevine/fire_act(null, temp, volume) //hotspots kill vines
|
||||
del src
|
||||
|
||||
//Carn: Spacevines random event.
|
||||
/proc/spacevine_infestation()
|
||||
|
||||
spawn() //to stop the secrets panel hanging
|
||||
var/list/turf/simulated/floor/turfs = list() //list of all the empty floor turfs in the hallway areas
|
||||
for(var/areapath in typesof(/area/hallway))
|
||||
var/area/A = locate(areapath)
|
||||
for(var/area/B in A.related)
|
||||
for(var/turf/simulated/floor/F in B.contents)
|
||||
if(!F.contents.len)
|
||||
turfs += F
|
||||
|
||||
if(turfs.len) //Pick a turf to spawn at if we can
|
||||
var/turf/simulated/floor/T = pick(turfs)
|
||||
new/obj/effect/spacevine_controller(T) //spawn a controller at turf
|
||||
message_admins("\blue Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])")
|
||||
//Carn: Spacevines random event.
|
||||
/proc/spacevine_infestation()
|
||||
|
||||
spawn() //to stop the secrets panel hanging
|
||||
var/list/turf/simulated/floor/turfs = list() //list of all the empty floor turfs in the hallway areas
|
||||
for(var/areapath in typesof(/area/hallway))
|
||||
var/area/A = locate(areapath)
|
||||
for(var/area/B in A.related)
|
||||
for(var/turf/simulated/floor/F in B.contents)
|
||||
if(!F.contents.len)
|
||||
turfs += F
|
||||
|
||||
if(turfs.len) //Pick a turf to spawn at if we can
|
||||
var/turf/simulated/floor/T = pick(turfs)
|
||||
new/obj/effect/plant_controller(T) //spawn a controller at turf
|
||||
message_admins("\blue Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])")
|
||||
|
||||
@@ -170,13 +170,13 @@
|
||||
|
||||
//find some plants, harvest
|
||||
for(var/obj/machinery/hydroponics/H in view(7, src))
|
||||
if(H.planted && !H.dead && H.myseed && prob(owned_bee_swarms.len * 10))
|
||||
if(H.seed && !H.dead && prob(owned_bee_swarms.len * 10))
|
||||
src.nutrilevel++
|
||||
H.nutrilevel++
|
||||
if(mut < H.mutmod - 1)
|
||||
mut = H.mutmod - 1
|
||||
else if(mut > H.mutmod - 1)
|
||||
H.mutmod = mut
|
||||
if(mut < H.mutation_mod - 1)
|
||||
mut = H.mutation_mod - 1
|
||||
else if(mut > H.mutation_mod - 1)
|
||||
H.mutation_mod = mut
|
||||
|
||||
//flowers give us pollen (nutrients)
|
||||
/* - All plants should be giving nutrients to the hive.
|
||||
@@ -188,11 +188,11 @@
|
||||
if(prob(10))
|
||||
H.lastcycle -= 5
|
||||
if(prob(10))
|
||||
H.myseed.lifespan = max(initial(H.myseed.lifespan) * 1.5, H.myseed.lifespan + 1)
|
||||
H.seed.lifespan = max(initial(H.seed.lifespan) * 1.5, H.seed.lifespan + 1)
|
||||
if(prob(10))
|
||||
H.myseed.endurance = max(initial(H.myseed.endurance) * 1.5, H.myseed.endurance + 1)
|
||||
if(H.toxic && prob(10))
|
||||
H.toxic = min(0, H.toxic - 1)
|
||||
H.seed.endurance = max(initial(H.seed.endurance) * 1.5, H.seed.endurance + 1)
|
||||
if(H.toxins && prob(10))
|
||||
H.toxins = min(0, H.toxins - 1)
|
||||
toxic++
|
||||
|
||||
/obj/machinery/apiary/proc/die()
|
||||
|
||||
@@ -1,48 +1,3 @@
|
||||
/proc/seedify(var/obj/item/O as obj, var/t_max)
|
||||
var/t_amount = 0
|
||||
if(t_max == -1)
|
||||
t_max = rand(1,4)
|
||||
|
||||
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown/))
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/grown/F = O
|
||||
while(t_amount < t_max)
|
||||
var/obj/item/seeds/t_prod = new F.seed(O.loc)
|
||||
t_prod.species = F.species
|
||||
t_prod.lifespan = F.lifespan
|
||||
t_prod.endurance = F.endurance
|
||||
t_prod.maturation = F.maturation
|
||||
t_prod.production = F.production
|
||||
t_prod.yield = F.yield
|
||||
t_prod.potency = F.potency
|
||||
t_amount++
|
||||
del(O)
|
||||
return 1
|
||||
|
||||
else if(istype(O, /obj/item/weapon/grown/))
|
||||
var/obj/item/weapon/grown/F = O
|
||||
while(t_amount < t_max)
|
||||
var/obj/item/seeds/t_prod = new F.seed(O.loc)
|
||||
t_prod.species = F.species
|
||||
t_prod.lifespan = F.lifespan
|
||||
t_prod.endurance = F.endurance
|
||||
t_prod.maturation = F.maturation
|
||||
t_prod.production = F.production
|
||||
t_prod.yield = F.yield
|
||||
t_prod.potency = F.potency
|
||||
t_amount++
|
||||
del(O)
|
||||
return 1
|
||||
|
||||
else if(istype(O, /obj/item/stack/tile/grass))
|
||||
var/obj/item/stack/tile/grass/S = O
|
||||
new /obj/item/seeds/grassseed(O.loc)
|
||||
S.use(1)
|
||||
return 1
|
||||
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/seed_extractor
|
||||
name = "seed extractor"
|
||||
desc = "Extracts and bags seeds from produce."
|
||||
@@ -52,14 +7,37 @@
|
||||
anchored = 1
|
||||
|
||||
obj/machinery/seed_extractor/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(isrobot(user))
|
||||
return
|
||||
user.drop_item()
|
||||
if(O && O.loc)
|
||||
O.loc = src.loc
|
||||
if(seedify(O,-1))
|
||||
user << "<span class='notice'>You extract some seeds.</span>"
|
||||
else
|
||||
user << "<span class='notice'>You can't extract any seeds from that!</span>"
|
||||
|
||||
// Fruits and vegetables.
|
||||
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown) || istype(O, /obj/item/weapon/grown))
|
||||
|
||||
user.drop_item(O)
|
||||
|
||||
var/datum/seed/new_seed_type
|
||||
if(istype(O, /obj/item/weapon/grown))
|
||||
var/obj/item/weapon/grown/F = O
|
||||
new_seed_type = seed_types[F.plantname]
|
||||
else
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/grown/F = O
|
||||
new_seed_type = seed_types[F.plantname]
|
||||
|
||||
if(new_seed_type)
|
||||
user << "<span class='notice'>You extract some seeds from [O].</span>"
|
||||
var/produce = rand(1,4)
|
||||
for(var/i = 0;i<=produce;i++)
|
||||
var/obj/item/seeds/seeds = new(get_turf(src))
|
||||
seeds.seed_type = new_seed_type.name
|
||||
seeds.update_seed()
|
||||
else
|
||||
user << "[O] doesn't seem to have any usable seeds inside it."
|
||||
|
||||
del(O)
|
||||
|
||||
//Grass.
|
||||
else if(istype(O, /obj/item/stack/tile/grass))
|
||||
var/obj/item/stack/tile/grass/S = O
|
||||
user << "<span class='notice'>You extract some seeds from the [S.name].</span>"
|
||||
S.use(1)
|
||||
new /obj/item/seeds/grassseed(loc)
|
||||
|
||||
return
|
||||
@@ -758,7 +758,7 @@
|
||||
product_ads = "We like plants!;Don't you want some?;The greenest thumbs ever.;We like big plants.;Soft soil..."
|
||||
icon_state = "nutri"
|
||||
icon_deny = "nutri-deny"
|
||||
products = list(/obj/item/nutrient/ez = 35,/obj/item/nutrient/l4z = 25,/obj/item/nutrient/rh = 15,/obj/item/weapon/pestspray = 20,
|
||||
products = list(/obj/item/nutrient/ez = 35,/obj/item/nutrient/l4z = 25,/obj/item/nutrient/rh = 15,/obj/item/weapon/plantspray/pests = 20,
|
||||
/obj/item/weapon/reagent_containers/syringe = 5,/obj/item/weapon/storage/bag/plants = 5)
|
||||
contraband = list(/obj/item/weapon/reagent_containers/glass/bottle/ammonia = 10,/obj/item/weapon/reagent_containers/glass/bottle/diethylamine = 5)
|
||||
|
||||
@@ -775,8 +775,7 @@
|
||||
/obj/item/seeds/sunflowerseed = 3,/obj/item/seeds/tomatoseed = 3,/obj/item/seeds/towermycelium = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/appleseed = 3,
|
||||
/obj/item/seeds/poppyseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/whitebeetseed = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/limeseed = 3,
|
||||
/obj/item/seeds/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3,
|
||||
/obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3,
|
||||
/obj/item/seeds/coffee_arabica_seed = 3, /obj/item/seeds/tobacco_seed = 3,/obj/item/seeds/tea_aspera_seed = 3)
|
||||
/obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3)
|
||||
|
||||
contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/nettleseed = 2,
|
||||
/obj/item/seeds/plumpmycelium = 2,/obj/item/seeds/reishimycelium = 2)
|
||||
|
||||
@@ -136,7 +136,6 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \
|
||||
new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("apiary", /obj/item/apiary, 10, time = 25, one_per_turf = 0, on_floor = 0), \
|
||||
new/datum/stack_recipe("drying rack", /obj/machinery/drying_rack, 10, time = 15, one_per_turf = 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
/obj/item/stack/sheet/wood
|
||||
|
||||
@@ -143,14 +143,6 @@
|
||||
M << "\red You are heated by the warmth of the of the [name]!"
|
||||
M.bodytemperature += potency/2 * TEMPERATURE_DAMAGE_COEFFICIENT
|
||||
|
||||
/obj/item/weapon/grown/novaflower/afterattack(atom/A as mob|obj, mob/user as mob,proximity)
|
||||
if(!proximity) return
|
||||
if(endurance > 0)
|
||||
endurance -= rand(1,(endurance/3)+1)
|
||||
else
|
||||
usr << "All the petals have fallen off the [name] from violent whacking."
|
||||
del(src)
|
||||
|
||||
/obj/item/weapon/grown/novaflower/pickup(mob/living/carbon/human/user as mob)
|
||||
if(!user.gloves)
|
||||
user << "\red The [name] burns your bare hand!"
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
w_class = 1
|
||||
can_hold = list("/obj/item/weapon/reagent_containers/food/snacks/grown","/obj/item/seeds","/obj/item/weapon/grown", "/obj/item/stack/tile/grass")
|
||||
|
||||
|
||||
/*
|
||||
/obj/item/weapon/storage/bag/plants/portaseeder
|
||||
name = "Portable Seed Extractor"
|
||||
desc = "For the enterprising botanist on the go. Less efficient than the stationary model, it creates one seed per plant."
|
||||
@@ -140,7 +140,7 @@
|
||||
for(var/mob/M in range(1))
|
||||
if (M.s_active == src)
|
||||
src.close(M)
|
||||
|
||||
*/
|
||||
|
||||
// -----------------------------
|
||||
// Sheet Snatcher
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
|
||||
var/damage = rand(15,30)
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(!istype(M))
|
||||
if(!istype(H))
|
||||
H << "\red You land heavily!"
|
||||
M.adjustBruteLoss(damage)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user