diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 5599be46862..8ead4b96bad 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -127,6 +127,7 @@ var/list/sacrificed = list()
if(target.getFireLoss() < 100)
target.hallucination = min(target.hallucination, 500)
return 0
+
target.take_overall_damage(0, rand(5, 20)) // You dirty resister cannot handle the damage to your mind. Easily. - even cultists who accept right away should experience some effects
// Resist messages go!
if(initial_message) //don't do this stuff right away, only if they resist or hesitate.
@@ -417,6 +418,7 @@ var/list/sacrificed = list()
var/mob/dead/observer/ghost
for(var/mob/dead/observer/O in this_rune.loc)
if(!O.client) continue
+ if(!O.MayRespawn()) continue
if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue
ghost = O
break
diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm
index 150f77e5e2d..4f2c491d6b4 100644
--- a/code/game/objects/items/weapons/implants/implanter.dm
+++ b/code/game/objects/items/weapons/implants/implanter.dm
@@ -32,9 +32,7 @@
for (var/mob/O in viewers(M, null))
O.show_message("\red [M] has been implanted by [user].", 1)
- M.attack_log += text("\[[time_stamp()]\] Implanted with [src.name] ([src.imp.name]) by [user.name] ([user.ckey])")
- user.attack_log += text("\[[time_stamp()]\] Used the [src.name] ([src.imp.name]) to implant [M.name] ([M.ckey])")
- msg_admin_attack("[user.name] ([user.ckey]) implanted [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)")
+ admin_attack_log(user, M, "Implanted using \the [src.name] ([src.imp.name])", "Implanted with \the [src.name] ([src.imp.name])", "used an implanter, [src.name] ([src.imp.name]), on")
user.show_message("\red You implanted the implant into [M].")
if(src.imp.implanted(M))
diff --git a/code/game/objects/structures/curtains.dm b/code/game/objects/structures/curtains.dm
index 5fd82b27f0c..dc5e309f17f 100644
--- a/code/game/objects/structures/curtains.dm
+++ b/code/game/objects/structures/curtains.dm
@@ -1,5 +1,5 @@
-#define SHOWER_OPEN_LAYER MOB_LAYER + 0.1
-#define SHOWER_CLOSED_LAYER OBJ_LAYER + 0.4
+#define SHOWER_OPEN_LAYER OBJ_LAYER + 0.4
+#define SHOWER_CLOSED_LAYER MOB_LAYER + 0.1
/obj/structure/curtain
name = "curtain"
diff --git a/code/game/response_team.dm b/code/game/response_team.dm
index 23e5f764a39..61f69216980 100644
--- a/code/game/response_team.dm
+++ b/code/game/response_team.dm
@@ -37,10 +37,12 @@ var/can_call_ert
log_admin("[key_name(usr)] used Dispatch Response Team.")
trigger_armed_response_team(1)
-
client/verb/JoinResponseTeam()
set category = "IC"
+ if(!MayRespawn(1))
+ return
+
if(istype(usr,/mob/dead/observer) || istype(usr,/mob/new_player))
if(!send_emergency_team)
usr << "No emergency response team is currently being sent."
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index e1095e55b06..b02875304e8 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -305,3 +305,14 @@
'icons/spideros_icons/sos_13.png',
'icons/spideros_icons/sos_14.png'
)
+
+
+mob/proc/MayRespawn()
+ return 0
+
+client/proc/MayRespawn()
+ if(mob)
+ return mob.MayRespawn()
+
+ // Something went wrong, client is usually kicked or transfered to a new mob at this point
+ return 0
diff --git a/code/modules/hydroponics/seed_mobs.dm b/code/modules/hydroponics/seed_mobs.dm
index 3e0e8994c2f..ec2a88b6da2 100644
--- a/code/modules/hydroponics/seed_mobs.dm
+++ b/code/modules/hydroponics/seed_mobs.dm
@@ -13,7 +13,7 @@
spawn(75)
if(!host.ckey && !host.client)
host.death() // This seems redundant, but a lot of mobs don't
- host.stat = 2 // handle death() properly. Better safe than etc.
+ host.stat = DEAD // handle death() properly. Better safe than etc.
host.visible_message("[host] is malformed and unable to survive. It expires pitifully, leaving behind some seeds.")
var/total_yield = rand(1,3)
@@ -27,7 +27,7 @@
for(var/mob/dead/observer/O in player_list)
if(jobban_isbanned(O, "Dionaea"))
continue
- if(O.client)
+ if(O.client && O.MayRespawn())
if(O.client.prefs.be_special & BE_PLANT && !(O.client in currently_querying))
currently_querying |= O.client
question(O.client,host)
diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm
index 09cf13bad2c..8990d309a08 100644
--- a/code/modules/hydroponics/spreading/spreading.dm
+++ b/code/modules/hydroponics/spreading/spreading.dm
@@ -1,7 +1,7 @@
#define DEFAULT_SEED "glowshroom"
#define VINE_GROWTH_STAGES 5
-/proc/spacevine_infestation()
+/proc/spacevine_infestation(var/potency_min=70, var/potency_max=100, var/maturation_min=5, var/maturation_max=15)
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))
@@ -14,8 +14,15 @@
var/turf/simulated/floor/T = pick(turfs)
var/datum/seed/seed = plant_controller.create_random_seed(1)
seed.set_trait(TRAIT_SPREAD,2) // So it will function properly as vines.
- seed.set_trait(TRAIT_POTENCY,rand(70,100)) // Guarantee a wide spread and powerful effects.
- new /obj/effect/plant(T,seed)
+ seed.set_trait(TRAIT_POTENCY,rand(potency_min, potency_max)) // 70-100 potency will help guarantee a wide spread and powerful effects.
+ seed.set_trait(TRAIT_MATURATION,rand(maturation_min, maturation_max))
+
+ //make vine zero start off fully matured
+ var/obj/effect/plant/vine = new(T,seed)
+ vine.health = vine.max_health
+ vine.mature_time = 0
+ vine.process()
+
message_admins("Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])")
/obj/effect/dead_plant
@@ -56,6 +63,7 @@
var/spread_chance = 40
var/spread_distance = 3
var/evolve_chance = 2
+ var/mature_time //minimum maturation time
var/last_tick = 0
var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/plant
@@ -111,6 +119,7 @@
if(max_growth > 2 && prob(50))
max_growth-- //Ensure some variation in final sprite, makes the carpet of crap look less wonky.
+ mature_time = world.time + seed.get_trait(TRAIT_MATURATION) + 15 //prevent vines from maturing until at least a few seconds after they've been created.
spread_chance = seed.get_trait(TRAIT_POTENCY)
spread_distance = ((growth_type>0) ? round(spread_chance*0.6) : round(spread_chance*0.3))
update_icon()
@@ -254,4 +263,4 @@
die_off()
/obj/effect/plant/proc/is_mature()
- return (health >= (max_health/3))
+ return (health >= (max_health/3) && world.time > mature_time)
diff --git a/code/modules/hydroponics/spreading/spreading_growth.dm b/code/modules/hydroponics/spreading/spreading_growth.dm
index 2346956d1fa..80b55b72275 100644
--- a/code/modules/hydroponics/spreading/spreading_growth.dm
+++ b/code/modules/hydroponics/spreading/spreading_growth.dm
@@ -70,7 +70,10 @@
update_neighbors()
if(is_mature() && neighbors.len && prob(spread_chance))
- for(var/i=1,i<=seed.get_trait(TRAIT_YIELD),i++)
+ //spread to 1-3 adjacent turfs depending on yield trait.
+ var/max_spread = between(1, round(seed.get_trait(TRAIT_YIELD)*3/14), 3)
+
+ for(var/i in 1 to max_spread)
if(prob(spread_chance))
sleep(rand(3,5))
if(!neighbors.len)
diff --git a/code/modules/hydroponics/spreading/spreading_response.dm b/code/modules/hydroponics/spreading/spreading_response.dm
index d175fdda221..6a93ecaeea1 100644
--- a/code/modules/hydroponics/spreading/spreading_response.dm
+++ b/code/modules/hydroponics/spreading/spreading_response.dm
@@ -7,8 +7,11 @@
if(!istype(M))
return
- if(!buckled_mob && !M.buckled && !M.anchored && (M.small || prob(round(seed.get_trait(TRAIT_POTENCY)/2))))
- entangle(M)
+ if(!buckled_mob && !M.buckled && !M.anchored && (M.small || prob(round(seed.get_trait(TRAIT_POTENCY)/6))))
+ //wait a tick for the Entered() proc that called HasProximity() to finish (and thus the moving animation),
+ //so we don't appear to teleport from two tiles away when moving into a turf adjacent to vines.
+ spawn(1)
+ entangle(M)
/obj/effect/plant/attack_hand(mob/user as mob)
// Todo, cause damage.
@@ -60,13 +63,11 @@
if(buckled_mob)
return
- if(!Adjacent(victim))
+ if(victim.buckled)
return
- victim.buckled = src
- victim.update_canmove()
- buckled_mob = victim
- if(!victim.anchored && !victim.buckled && victim.loc != get_turf(src))
+ //grabbing people
+ if(!victim.anchored && Adjacent(victim) && victim.loc != get_turf(src))
var/can_grab = 1
if(istype(victim, /mob/living/carbon/human))
var/mob/living/carbon/human/H = victim
@@ -75,4 +76,9 @@
if(can_grab)
src.visible_message("Tendrils lash out from \the [src] and drag \the [victim] in!")
victim.loc = src.loc
- victim << "Tendrils [pick("wind", "tangle", "tighten")] around you!"
+
+ //entangling people
+ if(victim.loc == src.loc)
+ buckle_mob(victim)
+ victim.set_dir(pick(cardinal))
+ victim << "Tendrils [pick("wind", "tangle", "tighten")] around you!"
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 4ce1b6edd3c..56927f56bfb 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -436,9 +436,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
src << "Spawning as a mouse is currently disabled."
return
- var/mob/dead/observer/M = usr
- if(config.antag_hud_restricted && M.has_enabled_antagHUD == 1)
- src << "antagHUD restrictions prevent you from spawning in as a mouse."
+ if(!MayRespawn(1))
return
var/timedifference = world.time - client.time_died_as_mouse
@@ -677,3 +675,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
client.images |= ghost_darkness_images
if (ghostimage)
client.images -= ghostimage //remove ourself
+
+mob/dead/observer/MayRespawn(var/feedback = 0)
+ if(config.antag_hud_restricted && has_enabled_antagHUD == 1)
+ if(feedback)
+ src << "antagHUD restrictions prevent you from respawning."
+ return 0
+ return 1
diff --git a/code/modules/mob/living/carbon/alien/diona/diona.dm b/code/modules/mob/living/carbon/alien/diona/diona.dm
index 5faeadbdcc3..981e2507494 100644
--- a/code/modules/mob/living/carbon/alien/diona/diona.dm
+++ b/code/modules/mob/living/carbon/alien/diona/diona.dm
@@ -31,4 +31,4 @@
/mob/living/carbon/alien/diona/put_in_hands(var/obj/item/W) // No hands.
W.loc = get_turf(src)
- return 1
\ No newline at end of file
+ return 1
diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm
index 08f2e34243b..4f4543b3b98 100644
--- a/code/modules/mob/living/carbon/brain/posibrain.dm
+++ b/code/modules/mob/living/carbon/brain/posibrain.dm
@@ -26,7 +26,7 @@
/obj/item/device/mmi/digital/posibrain/proc/request_player()
for(var/mob/dead/observer/O in player_list)
- if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
+ if(!O.MayRespawn())
continue
if(jobban_isbanned(O, "AI") && jobban_isbanned(O, "Cyborg"))
continue
diff --git a/code/modules/mob/living/silicon/pai/recruit.dm b/code/modules/mob/living/silicon/pai/recruit.dm
index 294ee515625..91a10bf3e50 100644
--- a/code/modules/mob/living/silicon/pai/recruit.dm
+++ b/code/modules/mob/living/silicon/pai/recruit.dm
@@ -234,7 +234,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
if(c.ready)
var/found = 0
for(var/mob/dead/observer/o in player_list)
- if(o.key == c.key)
+ if(o.key == c.key && o.MayRespawn())
found = 1
if(found)
available.Add(c)
@@ -347,7 +347,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
/datum/paiController/proc/requestRecruits(var/mob/user)
inquirer = user
for(var/mob/dead/observer/O in player_list)
- if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
+ if(!O.MayRespawn())
continue
if(jobban_isbanned(O, "pAI"))
continue
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
index 247334c2eab..a292ead1b14 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
@@ -108,6 +108,9 @@
if(jobban_isbanned(src,"Cyborg"))
usr << "You are banned from playing synthetics and cannot spawn as a drone."
return
+
+ if(!MayRespawn(1))
+ return
var/deathtime = world.time - src.timeofdeath
if(istype(src,/mob/dead/observer))
@@ -145,4 +148,4 @@
var/choice = input(src,"Which fabricator do you wish to use?") as null|anything in all_fabricators
if(choice)
var/obj/machinery/drone_fabricator/chosen_fabricator = all_fabricators[choice]
- chosen_fabricator.create_drone(src.client)
\ No newline at end of file
+ chosen_fabricator.create_drone(src.client)
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 360699b991d..d233ecea400 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -527,3 +527,6 @@
/mob/new_player/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/mob/speaker = null, var/hard_to_hear = 0)
return
+
+mob/new_player/MayRespawn()
+ return 1
diff --git a/html/changelogs/PsiOmegaDelta-AntagHUDRestrictions.yml b/html/changelogs/PsiOmegaDelta-AntagHUDRestrictions.yml
new file mode 100644
index 00000000000..d4e90bd1ac8
--- /dev/null
+++ b/html/changelogs/PsiOmegaDelta-AntagHUDRestrictions.yml
@@ -0,0 +1,5 @@
+author: PsiOmegaDelta
+delete-after: True
+
+changes:
+ - bugfix: "As an observer, using antagHUD should now always restrict you from respawning without admin intervention."