diff --git a/code/datums/saymode.dm b/code/datums/saymode.dm
index 57ef7701e32..9f2c758710c 100644
--- a/code/datums/saymode.dm
+++ b/code/datums/saymode.dm
@@ -86,7 +86,7 @@
return FALSE
-/datum/saymode/binary //everything that uses .b (silicons, drones, blobbernauts/spores, swarmers)
+/datum/saymode/binary //everything that uses .b (silicons, drones, swarmers)
key = MODE_KEY_BINARY
mode = MODE_BINARY
@@ -95,10 +95,6 @@
var/mob/living/simple_animal/hostile/swarmer/S = user
S.swarmer_chat(message)
return FALSE
- if(isblobmonster(user))
- var/mob/living/simple_animal/hostile/blob/B = user
- B.blob_chat(message)
- return FALSE
if(isdrone(user))
var/mob/living/simple_animal/drone/D = user
D.drone_chat(message)
diff --git a/code/modules/antagonists/blob/blob_mobs.dm b/code/modules/antagonists/blob/blob_mobs.dm
index 93c18c56313..bb79a4e9eef 100644
--- a/code/modules/antagonists/blob/blob_mobs.dm
+++ b/code/modules/antagonists/blob/blob_mobs.dm
@@ -15,8 +15,12 @@
maxbodytemp = 360
unique_name = 1
a_intent = INTENT_HARM
+ see_in_dark = 8
+ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
+ initial_language_holder = /datum/language_holder/empty
var/mob/camera/blob/overmind = null
var/obj/structure/blob/factory/factory = null
+ var/independent = FALSE
/mob/living/simple_animal/hostile/blob/update_icons()
if(overmind)
@@ -24,6 +28,13 @@
else
remove_atom_colour(FIXED_COLOUR_PRIORITY)
+/mob/living/simple_animal/hostile/blob/Initialize()
+ . = ..()
+ if(!independent) //no pulling people deep into the blob
+ verbs -= /mob/living/verb/pulled
+ else
+ pass_flags &= ~PASSBLOB
+
/mob/living/simple_animal/hostile/blob/Destroy()
if(overmind)
overmind.blob_mobs -= src
@@ -56,8 +67,11 @@
return 1
return ..()
-/mob/living/simple_animal/hostile/blob/proc/blob_chat(msg)
- var/spanned_message = say_quote(msg)
+/mob/living/simple_animal/hostile/blob/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
+ if(!overmind)
+ ..()
+ return
+ var/spanned_message = say_quote(message)
var/rendered = "\[Blob Telepathy\] [real_name] [spanned_message]"
for(var/M in GLOB.mob_list)
if(isovermind(M) || istype(M, /mob/living/simple_animal/hostile/blob))
@@ -75,6 +89,7 @@
desc = "A floating, fragile spore."
icon_state = "blobpod"
icon_living = "blobpod"
+ health_doll_icon = "blobpod"
health = 30
maxHealth = 30
verb_say = "psychically pulses"
@@ -89,18 +104,20 @@
attack_verb_simple = "hit"
attack_sound = 'sound/weapons/genhit1.ogg'
movement_type = FLYING
- del_on_death = 1
+ del_on_death = TRUE
deathmessage = "explodes into a cloud of gas!"
+ gold_core_spawnable = HOSTILE_SPAWN
var/death_cloud_size = 1 //size of cloud produced from a dying spore
var/mob/living/carbon/human/oldguy
- var/is_zombie = 0
- gold_core_spawnable = HOSTILE_SPAWN
+ var/is_zombie = FALSE
/mob/living/simple_animal/hostile/blob/blobspore/Initialize(mapload, obj/structure/blob/factory/linked_node)
if(istype(linked_node))
factory = linked_node
factory.spores += src
. = ..()
+ if(linked_node.overmind && istype(linked_node.overmind.blobstrain, /datum/blobstrain/reagent/distributed_neurons) && !istype(src, /mob/living/simple_animal/hostile/blob/blobspore/weak))
+ notify_ghosts("A controllable spore has been created in \the [get_area(src)].", source = src, action = NOTIFY_ORBIT, flashwindow = FALSE, header = "Sentient Spore Created")
/mob/living/simple_animal/hostile/blob/blobspore/Life()
if(!is_zombie && isturf(src.loc))
@@ -111,6 +128,26 @@
if(factory && z != factory.z)
death()
..()
+
+/mob/living/simple_animal/hostile/blob/blobspore/attack_ghost(mob/user)
+ . = ..()
+ if(.)
+ return
+ humanize_pod(user)
+
+/mob/living/simple_animal/hostile/blob/blobspore/proc/humanize_pod(mob/user)
+ if((!overmind || istype(src, /mob/living/simple_animal/hostile/blob/blobspore/weak) || !istype(overmind.blobstrain, /datum/blobstrain/reagent/distributed_neurons)) && !is_zombie)
+ return
+ if(key || stat)
+ return
+ var/pod_ask = alert("Become a blob spore?", "Are you bulbous enough?", "Yes", "No")
+ if(pod_ask == "No" || !src || QDELETED(src))
+ return
+ if(key)
+ to_chat(user, "Someone else already took this spore!")
+ return
+ key = user.key
+ log_game("[key_name(src)] took control of [name].")
/mob/living/simple_animal/hostile/blob/blobspore/proc/Zombify(mob/living/carbon/human/H)
is_zombie = 1
@@ -134,6 +171,8 @@
oldguy = H
update_icons()
visible_message("The corpse of [H.name] suddenly rises!")
+ if(!key)
+ notify_ghosts("\A [src] has been created in \the [get_area(src)].", source = src, action = NOTIFY_ORBIT, flashwindow = FALSE, header = "Blob Zombie Created")
/mob/living/simple_animal/hostile/blob/blobspore/death(gibbed)
// On death, create a small smoke of harmful gas (s-Acid)
@@ -215,17 +254,7 @@
force_threshold = 10
pressure_resistance = 50
mob_size = MOB_SIZE_LARGE
- see_in_dark = 8
- lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
hud_type = /datum/hud/blobbernaut
- var/independent = FALSE
-
-/mob/living/simple_animal/hostile/blob/blobbernaut/Initialize()
- . = ..()
- if(!independent) //no pulling people deep into the blob
- verbs -= /mob/living/verb/pulled
- else
- pass_flags &= ~PASSBLOB
/mob/living/simple_animal/hostile/blob/blobbernaut/Life()
if(..())
diff --git a/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm b/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm
new file mode 100644
index 00000000000..27edb0f205f
--- /dev/null
+++ b/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm
@@ -0,0 +1,39 @@
+//kills unconscious targets and turns them into blob zombies, produces fragile spores when killed. Spore produced by factories are sentient.
+/datum/blobstrain/reagent/distributed_neurons
+ name = "Distributed Neurons"
+ description = "will do very low toxin damage and turns unconscious targets into blob zombies."
+ effectdesc = "will also produce fragile spores when killed. Spores produced by factories are sentient."
+ shortdesc = "will do very low toxin damage and will turn unconscious targets into blob zombies for additional resources(for your overmind). Spores produced by factories are sentient."
+ analyzerdescdamage = "Does very low toxin damage and kills unconscious humans, turning them into blob zombies."
+ analyzerdesceffect = "Produces spores when killed. Spores produced by factories are sentient."
+ color = "#E88D5D"
+ complementary_color = "#823ABB"
+ message_living = ", and you feel tired"
+ reagent = /datum/reagent/blob/distributed_neurons
+
+/datum/blobstrain/reagent/distributed_neurons/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
+ if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") && damage <= 20 && B.obj_integrity - damage <= 0 && prob(15)) //if the cause isn't fire or a bomb, the damage is less than 21, we're going to die from that damage, 15% chance of a shitty spore.
+ B.visible_message("A spore floats free of the blob!")
+ var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(B.loc)
+ BS.overmind = B.overmind
+ BS.update_icons()
+ B.overmind.blob_mobs.Add(BS)
+ return ..()
+
+/datum/reagent/blob/distributed_neurons
+ name = "Distributed Neurons"
+ color = "#E88D5D"
+
+/datum/reagent/blob/distributed_neurons/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+ reac_volume = ..()
+ M.apply_damage(0.6*reac_volume, TOX)
+ if(O && ishuman(M) && M.stat == UNCONSCIOUS)
+ M.death() //sleeping in a fight? bad plan.
+ var/points = rand(5, 10)
+ var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(get_turf(M))
+ BS.overmind = O
+ BS.update_icons()
+ O.blob_mobs.Add(BS)
+ BS.Zombify(M)
+ O.add_points(points)
+ to_chat(O, "Gained [points] resources from the zombification of [M].")
diff --git a/code/modules/antagonists/blob/blobstrains/zombifying_pods.dm b/code/modules/antagonists/blob/blobstrains/zombifying_pods.dm
deleted file mode 100644
index b2bb9d51157..00000000000
--- a/code/modules/antagonists/blob/blobstrains/zombifying_pods.dm
+++ /dev/null
@@ -1,46 +0,0 @@
-//kills sleeping targets and turns them into blob zombies, produces fragile spores when killed or on expanding
-/datum/blobstrain/reagent/zombifying_pods
- name = "Zombifying Pods"
- description = "will do very low toxin damage and harvest sleeping targets for additional resources and a blob zombie."
- effectdesc = "will also produce fragile spores when killed and on expanding."
- shortdesc = "will do very low toxin damage and harvest sleeping targets for additional resources(for your overmind) and a blob zombie."
- analyzerdescdamage = "Does very low toxin damage and kills unconscious humans, turning them into blob zombies."
- analyzerdesceffect = "Produces spores when expanding and when killed."
- color = "#E88D5D"
- complementary_color = "#823ABB"
- message_living = ", and you feel tired"
- reagent = /datum/reagent/blob/zombifying_pods
-
-/datum/blobstrain/reagent/zombifying_pods/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
- if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") && damage <= 20 && B.obj_integrity - damage <= 0 && prob(30)) //if the cause isn't fire or a bomb, the damage is less than 21, we're going to die from that damage, 20% chance of a shitty spore.
- B.visible_message("A spore floats free of the blob!")
- var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(B.loc)
- BS.overmind = B.overmind
- BS.update_icons()
- B.overmind.blob_mobs.Add(BS)
- return ..()
-
-/datum/blobstrain/reagent/zombifying_pods/expand_reaction(obj/structure/blob/B, obj/structure/blob/newB, turf/T, mob/camera/blob/O)
- if(prob(10))
- var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(T)
- BS.overmind = B.overmind
- BS.update_icons()
- newB.overmind.blob_mobs.Add(BS)
-
-/datum/reagent/blob/zombifying_pods
- name = "Zombifying Pods"
- color = "#E88D5D"
-
-/datum/reagent/blob/zombifying_pods/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- reac_volume = ..()
- M.apply_damage(0.6*reac_volume, TOX)
- if(O && ishuman(M) && M.stat == UNCONSCIOUS)
- M.death() //sleeping in a fight? bad plan.
- var/points = rand(5, 10)
- var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(get_turf(M))
- BS.overmind = O
- BS.update_icons()
- O.blob_mobs.Add(BS)
- BS.Zombify(M)
- O.add_points(points)
- to_chat(O, "Gained [points] resources from the zombification of [M].")
diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm
index e2567e091cc..a2b38e0b1be 100644
--- a/code/modules/antagonists/blob/overmind.dm
+++ b/code/modules/antagonists/blob/overmind.dm
@@ -39,6 +39,9 @@ GLOBAL_LIST_EMPTY(blob_nodes)
var/blobwincount = 400
var/victory_in_progress = FALSE
var/rerolling = FALSE
+ var/announcement_size = 75
+ var/announcement_time
+ var/has_announced = FALSE
/mob/camera/blob/Initialize(mapload, starting_points = 60)
validate_location()
@@ -56,6 +59,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
if(blob_core)
blob_core.update_icon()
SSshuttle.registerHostileEnvironment(src)
+ announcement_time = world.time + 6000
. = ..()
START_PROCESSING(SSobj, src)
@@ -117,6 +121,10 @@ GLOBAL_LIST_EMPTY(blob_nodes)
if(!victory_in_progress && max_count < blobs_legit.len)
max_count = blobs_legit.len
+
+ if((world.time >= announcement_time || blobs_legit.len >= announcement_size) && !has_announced)
+ priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg')
+ has_announced = TRUE
/mob/camera/blob/proc/victory()
sound_to_playing_players('sound/machines/alarm.ogg')
diff --git a/code/modules/antagonists/blob/powers.dm b/code/modules/antagonists/blob/powers.dm
index 794819db9b8..2289e163052 100644
--- a/code/modules/antagonists/blob/powers.dm
+++ b/code/modules/antagonists/blob/powers.dm
@@ -318,7 +318,7 @@
if(!surrounding_turfs.len)
return
for(var/mob/living/simple_animal/hostile/blob/blobspore/BS in blob_mobs)
- if(isturf(BS.loc) && get_dist(BS, T) <= 35)
+ if(isturf(BS.loc) && get_dist(BS, T) <= 35 && !BS.key)
BS.LoseTarget()
BS.Goto(pick(surrounding_turfs), BS.move_to_delay)
diff --git a/code/modules/antagonists/blob/structures/core.dm b/code/modules/antagonists/blob/structures/core.dm
index c2ae02c5ce3..0dc9d8b43df 100644
--- a/code/modules/antagonists/blob/structures/core.dm
+++ b/code/modules/antagonists/blob/structures/core.dm
@@ -8,6 +8,7 @@
explosion_block = 6
point_return = -1
health_regen = 0 //we regen in Life() instead of when pulsed
+ resistance_flags = LAVA_PROOF
/obj/structure/blob/core/Initialize(mapload, client/new_overmind = null, placed = 0)
GLOB.blob_cores += src
@@ -18,12 +19,8 @@
return INITIALIZE_HINT_QDEL
if(overmind)
update_icon()
- addtimer(CALLBACK(src, .proc/generate_announcement), 1800)
. = ..()
-/obj/structure/blob/core/proc/generate_announcement()
- priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg')
-
/obj/structure/blob/core/scannerreport()
return "Directs the blob's expansion, gradually expands, and sustains nearby blob spores and blobbernauts."
diff --git a/code/modules/antagonists/blob/structures/factory.dm b/code/modules/antagonists/blob/structures/factory.dm
index 3d955036b01..756d1b03fab 100644
--- a/code/modules/antagonists/blob/structures/factory.dm
+++ b/code/modules/antagonists/blob/structures/factory.dm
@@ -6,6 +6,7 @@
max_integrity = 200
health_regen = 1
point_return = 25
+ resistance_flags = LAVA_PROOF
var/list/spores = list()
var/mob/living/simple_animal/hostile/blob/blobbernaut/naut = null
var/max_spores = 3
diff --git a/code/modules/antagonists/blob/structures/node.dm b/code/modules/antagonists/blob/structures/node.dm
index 14fbc741c0b..8a8645c1518 100644
--- a/code/modules/antagonists/blob/structures/node.dm
+++ b/code/modules/antagonists/blob/structures/node.dm
@@ -7,6 +7,7 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 65, "acid" = 90)
health_regen = 3
point_return = 25
+ resistance_flags = LAVA_PROOF
/obj/structure/blob/node/Initialize()
diff --git a/code/modules/antagonists/blob/structures/resource.dm b/code/modules/antagonists/blob/structures/resource.dm
index 5024d0984c1..81eda7f4edd 100644
--- a/code/modules/antagonists/blob/structures/resource.dm
+++ b/code/modules/antagonists/blob/structures/resource.dm
@@ -5,6 +5,7 @@
desc = "A thin spire of slightly swaying tendrils."
max_integrity = 60
point_return = 15
+ resistance_flags = LAVA_PROOF
var/resource_delay = 0
/obj/structure/blob/resource/scannerreport()
diff --git a/tgstation.dme b/tgstation.dme
index a6d482b40d4..b00e0e14596 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1367,6 +1367,7 @@
#include "code\modules\antagonists\blob\blobstrains\blazing_oil.dm"
#include "code\modules\antagonists\blob\blobstrains\cryogenic_poison.dm"
#include "code\modules\antagonists\blob\blobstrains\debris_devourer.dm"
+#include "code\modules\antagonists\blob\blobstrains\distributed_neurons.dm"
#include "code\modules\antagonists\blob\blobstrains\electromagnetic_web.dm"
#include "code\modules\antagonists\blob\blobstrains\energized_jelly.dm"
#include "code\modules\antagonists\blob\blobstrains\explosive_lattice.dm"
@@ -1378,7 +1379,6 @@
#include "code\modules\antagonists\blob\blobstrains\replicating_foam.dm"
#include "code\modules\antagonists\blob\blobstrains\shifting_fragments.dm"
#include "code\modules\antagonists\blob\blobstrains\synchronous_mesh.dm"
-#include "code\modules\antagonists\blob\blobstrains\zombifying_pods.dm"
#include "code\modules\antagonists\blob\structures\_blob.dm"
#include "code\modules\antagonists\blob\structures\core.dm"
#include "code\modules\antagonists\blob\structures\factory.dm"