diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm
index f41c8e3ad2c..8e0a96b0271 100644
--- a/code/game/gamemodes/blob/blobs/blob_mobs.dm
+++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm
@@ -13,9 +13,9 @@
maxbodytemp = 360
var/mob/camera/blob/overmind = null
-/mob/living/simple_animal/hostile/blob/proc/adjustcolors(a_color)
- if(a_color)
- color = a_color
+/mob/living/simple_animal/hostile/blob/update_icons()
+ if(overmind)
+ color = overmind.blob_reagent_datum.color
/mob/living/simple_animal/hostile/blob/blob_act()
return
@@ -58,7 +58,6 @@
..()
/mob/living/simple_animal/hostile/blob/blobspore/Life()
-
if(!is_zombie && isturf(src.loc))
for(var/mob/living/carbon/human/H in oview(src,1)) //Only for corpse right next to/on same tile
if(H.stat == DEAD)
@@ -121,19 +120,8 @@
M.loc = src.loc
return ..()
-
/mob/living/simple_animal/hostile/blob/blobspore/update_icons()
..()
-
- if(overmind && overmind.blob_reagent_datum)
- adjustcolors(overmind.blob_reagent_datum.color)
- else
- adjustcolors(color) //to ensure zombie/other overlays update
-
-
-/mob/living/simple_animal/hostile/blob/blobspore/adjustcolors(a_color)
- color = a_color
-
if(is_zombie)
overlays.Cut()
overlays = human_overlays
@@ -166,9 +154,6 @@
mob_size = MOB_SIZE_LARGE
gold_core_spawnable = 1
-/mob/living/simple_animal/hostile/blob/blobbernaut/blob_act()
- return
-
/mob/living/simple_animal/hostile/blob/blobbernaut/death(gibbed)
..(gibbed)
flick("blobbernaut_death", src)
diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm
index 6f9d1d34320..d9b2553e6ea 100644
--- a/code/game/gamemodes/blob/blobs/core.dm
+++ b/code/game/gamemodes/blob/blobs/core.dm
@@ -17,25 +17,28 @@
/obj/effect/blob/core/New(loc, var/h = 200, var/client/new_overmind = null, var/new_rate = 2, offspring)
blob_cores += src
SSobj.processing |= src
- adjustcolors(color) //so it atleast appears
+ update_icon() //so it atleast appears
if(!overmind)
create_overmind(new_overmind)
if(overmind)
- adjustcolors(overmind.blob_reagent_datum.color)
+ update_icon()
if(offspring)
is_offspring = 1
point_rate = new_rate
..(loc, h)
-/obj/effect/blob/core/adjustcolors(a_color)
+/obj/effect/blob/core/update_icon()
overlays.Cut()
color = null
var/image/I = new('icons/mob/blob.dmi', "blob")
- I.color = a_color
+ if(overmind)
+ I.color = overmind.blob_reagent_datum.color
overlays += I
var/image/C = new('icons/mob/blob.dmi', "blob_core_overlay")
overlays += C
+/obj/effect/blob/core/PulseAnimation()
+ return
/obj/effect/blob/core/Destroy()
blob_cores -= src
@@ -69,21 +72,18 @@
health = min(maxhealth, health+health_regen)
if(overmind)
overmind.update_health()
- pulseLoop(0)
+ Pulse_Area(overmind, 12, 4, 3)
for(var/b_dir in alldirs)
if(!prob(5))
continue
var/obj/effect/blob/normal/B = locate() in get_step(src, b_dir)
if(B)
- var/obj/effect/blob/N = B.change_to(/obj/effect/blob/shield)
- if(overmind)
- N.color = overmind.blob_reagent_datum.color
+ B.change_to(/obj/effect/blob/shield, overmind)
color = null
..()
/obj/effect/blob/core/proc/create_overmind(client/new_overmind, override_delay)
-
if(overmind_get_delay > world.time && !override_delay)
return
diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm
index e750d359d27..30ba94d4a37 100644
--- a/code/game/gamemodes/blob/blobs/factory.dm
+++ b/code/game/gamemodes/blob/blobs/factory.dm
@@ -31,8 +31,9 @@
spore_delay = world.time + 100 // 10 seconds
PulseAnimation(1)
var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore(src.loc, src)
- BS.color = color
- BS.overmind = overmind
- overmind.blob_mobs.Add(BS)
+ if(overmind) //if we don't have an overmind, we don't need to do anything but make a spore
+ BS.overmind = overmind
+ BS.update_icons()
+ overmind.blob_mobs.Add(BS)
return 0
diff --git a/code/game/gamemodes/blob/blobs/node.dm b/code/game/gamemodes/blob/blobs/node.dm
index 240f67f5256..3141e98930b 100644
--- a/code/game/gamemodes/blob/blobs/node.dm
+++ b/code/game/gamemodes/blob/blobs/node.dm
@@ -5,6 +5,7 @@
desc = "A large, pulsating yellow mass."
health = 200
maxhealth = 200
+ health_regen = 3
point_return = 25
atmosblock = 1
@@ -14,15 +15,19 @@
SSobj.processing |= src
..(loc, h)
-/obj/effect/blob/node/adjustcolors(a_color)
+/obj/effect/blob/node/update_icon()
overlays.Cut()
color = null
var/image/I = new('icons/mob/blob.dmi', "blob")
- I.color = a_color
+ if(overmind)
+ I.color = overmind.blob_reagent_datum.color
src.overlays += I
var/image/C = new('icons/mob/blob.dmi', "blob_node_overlay")
src.overlays += C
+/obj/effect/blob/node/PulseAnimation()
+ return
+
/obj/effect/blob/node/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
@@ -32,6 +37,5 @@
return ..()
/obj/effect/blob/node/Life()
- pulseLoop(5)
- health = min(initial(health), health + 1)
+ Pulse_Area(overmind, 10, 3, 2)
color = null
diff --git a/code/game/gamemodes/blob/blobs/resource.dm b/code/game/gamemodes/blob/blobs/resource.dm
index 819d991a00c..03bb6164280 100644
--- a/code/game/gamemodes/blob/blobs/resource.dm
+++ b/code/game/gamemodes/blob/blobs/resource.dm
@@ -21,7 +21,7 @@
PulseAnimation(1)
- resource_delay = world.time + 40 // 4 seconds
+ resource_delay = world.time + 45 // 4 and a half seconds
if(overmind)
overmind.add_points(1)
diff --git a/code/game/gamemodes/blob/blobs/storage.dm b/code/game/gamemodes/blob/blobs/storage.dm
index e64d32fd84b..968101b6b14 100644
--- a/code/game/gamemodes/blob/blobs/storage.dm
+++ b/code/game/gamemodes/blob/blobs/storage.dm
@@ -1,7 +1,7 @@
/obj/effect/blob/storage
name = "storage blob"
icon = 'icons/mob/blob.dmi'
- icon_state = "blob_resource"
+ icon_state = "blob_factory"
desc = "A huge, smooth mass supported by tendrils."
health = 60
maxhealth = 60
@@ -12,13 +12,10 @@
/obj/effect/blob/storage/creation_action()
if(overmind)
overmind.max_blob_points += point_bonus
+ overmind.storage_blobs++
/obj/effect/blob/storage/Destroy()
- if(overmind)
+ if(overmind && overmind.storage_blobs) //if the overmind doesn't have any recorded storage blobs, don't TAKE ALL THE POINTS THEY HAVE
overmind.max_blob_points -= point_bonus
+ overmind.storage_blobs--
return ..()
-
-/obj/effect/blob/storage/PulseAnimation(activate = 0)
- if(activate)
- ..()
- return
diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm
index 0d814fd6efb..2af309967a4 100644
--- a/code/game/gamemodes/blob/overmind.dm
+++ b/code/game/gamemodes/blob/overmind.dm
@@ -14,6 +14,7 @@
var/obj/effect/blob/core/blob_core = null // The blob overmind's core
var/blob_points = 0
var/max_blob_points = 100
+ var/storage_blobs = 0
var/last_attack = 0
var/datum/reagent/blob/blob_reagent_datum = new/datum/reagent/blob()
var/list/blob_mobs = list()
@@ -29,7 +30,7 @@
possible_reagents.Add(new type)
blob_reagent_datum = pick(possible_reagents)
if(blob_core)
- blob_core.adjustcolors(blob_reagent_datum.color)
+ blob_core.update_icon()
ghostimage = image(src.icon,src,src.icon_state)
ghost_darkness_images |= ghostimage //so ghosts can see the blob cursor when they disable darkness
@@ -90,7 +91,7 @@
return
var/message_a = say_quote(message, get_spans())
- var/rendered = "Blob Telepathy, [name]([blob_reagent_datum.name]) [message_a]"
+ var/rendered = "Blob Telepathy, [name]([blob_reagent_datum.name]) [message_a]"
for (var/mob/M in mob_list)
if(isovermind(M) || isobserver(M))
diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm
index 41f4788a18c..796ea7ae9d7 100644
--- a/code/game/gamemodes/blob/powers.dm
+++ b/code/game/gamemodes/blob/powers.dm
@@ -60,7 +60,7 @@
/mob/camera/blob/verb/create_resource()
set category = "Blob"
set name = "Create Resource Blob (40)"
- set desc = "Create a resource tower which will generate points for you."
+ set desc = "Create a resource tower which will generate resources for you."
createSpecial(40, /obj/effect/blob/resource, 4)
/mob/camera/blob/verb/create_node()
@@ -137,7 +137,7 @@
return
if(B.point_return)
add_points(B.point_return)
- src << "Gained [B.point_return] resources from removing the [B]."
+ src << "Gained [B.point_return] resources from removing \the [B]."
qdel(B)
/mob/camera/blob/verb/expand_blob_power()
@@ -161,14 +161,13 @@
if(!can_buy(5))
return
last_attack = world.time
- OB.expand(T, 0, blob_reagent_datum.color)
+ OB.expand(T, 0, src)
for(var/mob/living/L in T)
if("blob" in L.faction) //no friendly fire
continue
var/mob_protection = L.get_permeability_protection()
blob_reagent_datum.reaction_mob(L, VAPOR, 25, 1, mob_protection)
blob_reagent_datum.send_message(L)
- OB.color = blob_reagent_datum.color
/mob/camera/blob/verb/rally_spores_power()
set category = "Blob"
@@ -209,13 +208,13 @@
set category = "Blob"
set name = "Blob Broadcast"
set desc = "Speak with your blob spores and blobbernauts as your mouthpieces. This action is free."
- var/speak_text = input(usr, "What would you like to say with your minions?", "Blob Broadcast", null) as text
+ var/speak_text = input(src, "What would you like to say with your minions?", "Blob Broadcast", null) as text
if(!speak_text)
return
else
- usr << "You broadcast with your minions, [speak_text]"
- for(var/mob/living/simple_animal/hostile/blob_minion in blob_mobs)
- if(blob_minion.stat == CONSCIOUS)
+ src << "You broadcast with your minions, [speak_text]"
+ for(var/mob/living/simple_animal/hostile/blob/blob_minion in blob_mobs)
+ if(blob_minion.overmind == src && blob_minion.stat == CONSCIOUS)
blob_minion.say(speak_text)
/mob/camera/blob/verb/chemical_reroll()
@@ -227,9 +226,9 @@
var/datum/reagent/blob/B = pick((subtypesof(/datum/reagent/blob) - blob_reagent_datum.type))
blob_reagent_datum = new B
for(var/obj/effect/blob/BL in blobs)
- BL.adjustcolors(blob_reagent_datum.color)
+ BL.update_icon()
for(var/mob/living/simple_animal/hostile/blob/BLO)
- BLO.adjustcolors(blob_reagent_datum.color)
+ BLO.update_icons()
src << "Your reagent is now: [blob_reagent_datum.name]!"
src << "The [blob_reagent_datum.name] reagent [blob_reagent_datum.description]"
@@ -237,9 +236,9 @@
set category = "Blob"
set name = "*Blob Help*"
set desc = "Help on how to blob."
+ src << "As the overmind, you can control the blob!"
src << "Your blob reagent is: [blob_reagent_datum.name]!"
src << "The [blob_reagent_datum.name] reagent [blob_reagent_datum.description]"
- src << "As the overmind, you can control the blob!"
src << "You can expand, which will attack people, damage objects, or place a Normal Blob if the tile is clear."
src << "Normal Blobs will expand your reach and can be upgraded into special blobs that perform certain functions."
src << "You can upgrade normal blobs into the following types of blob:"
diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm
index 82c6a955d74..2b538a48fc6 100644
--- a/code/game/gamemodes/blob/theblob.dm
+++ b/code/game/gamemodes/blob/theblob.dm
@@ -12,12 +12,14 @@
var/health = 30
var/maxhealth = 30
var/health_regen = 2 //how much health this blob regens when pulsed
- var/health_timestamp = 0
+ var/health_timestamp = 0 //we got healed when?
+ var/pulse_timestamp = 0 //we got pulsed when?
var/brute_resist = 2 //divides brute damage by this
var/fire_resist = 1 //divides burn damage by this
var/atmosblock = 0 //if the blob blocks atmos and heat spread
var/mob/camera/blob/overmind
+
/obj/effect/blob/New(loc)
var/area/Ablob = get_area(loc)
if(Ablob.blob_allowed) //Is this area allowed for winning as blob?
@@ -34,15 +36,6 @@
/obj/effect/blob/proc/creation_action() //When it's created by the overmind, do this.
return
-/obj/effect/blob/proc/check_health()
- if(health <= 0)
- qdel(src)
- return
- return
-
-/obj/effect/blob/update_icon() //Used for normal blobs, to update icon when weakened.
- return
-
/obj/effect/blob/Destroy()
if(atmosblock)
atmosblock = 0
@@ -69,6 +62,20 @@
return 0
+/obj/effect/blob/proc/check_health()
+ if(health <= 0)
+ qdel(src) //we dead now
+ return
+ return
+
+/obj/effect/blob/update_icon() //Updates color based on overmind color if we have an overmind.
+ if(overmind)
+ color = overmind.blob_reagent_datum.color
+ else
+ color = null
+ return
+
+
/obj/effect/blob/process()
Life()
return
@@ -81,70 +88,57 @@
/obj/effect/blob/proc/Life()
return
+/obj/effect/blob/proc/Pulse_Area(pulsing_overmind = overmind, claim_range = 10, pulse_range = 3, expand_range = 2)
+ src.Be_Pulsed()
+ if(claim_range)
+ for(var/obj/effect/blob/B in ultra_range(claim_range, src, 1))
+ B.update_icon()
+ if(!B.overmind && !istype(B, /obj/effect/blob/core) && prob(30))
+ B.overmind = pulsing_overmind //reclaim unclaimed, non-core blobs.
+ B.update_icon()
+ if(pulse_range)
+ for(var/obj/effect/blob/B in orange(pulse_range, src))
+ B.Be_Pulsed()
+ if(expand_range)
+ src.expand()
+ for(var/obj/effect/blob/B in orange(expand_range, src))
+ if(prob(12))
+ B.expand()
+ return
+
+/obj/effect/blob/proc/Be_Pulsed()
+ if(pulse_timestamp <= world.time)
+ PulseAnimation()
+ ConsumeTile()
+ RegenHealth()
+ run_action()
+ pulse_timestamp = world.time + 10
+ return 1 //we did it, we were pulsed!
+ return 0 //oh no we failed
+
/obj/effect/blob/proc/ConsumeTile()
for(var/atom/A in loc)
A.blob_act()
/obj/effect/blob/proc/PulseAnimation()
- if(!istype(src, /obj/effect/blob/core) || !istype(src, /obj/effect/blob/node))
- flick("[icon_state]_glow", src)
- return
-
-/obj/effect/blob/proc/RegenHealth()
- // All blobs heal over time when pulsed, but it has a cool down
- if(health_timestamp > world.time)
- return 0
- health = min(maxhealth, health+health_regen)
- update_icon()
- health_timestamp = world.time + 10 // 1 seconds
-
-/obj/effect/blob/proc/pulseLoop(num)
- var/a_color
- if(overmind)
- a_color = overmind.blob_reagent_datum.color
- for(var/i = 1; i < 8; i += i)
- Pulse(num, i, a_color)
-
-/obj/effect/blob/proc/Pulse(pulse = 0, origin_dir = 0, a_color)//Todo: Fix spaceblob expand
-
- set background = BACKGROUND_ENABLED
-
- PulseAnimation()
- ConsumeTile()
- RegenHealth()
-
- if(run_action())//If we can do something here then we dont need to pulse more
- return
-
- if(pulse > 30)
- return//Inf loop check
-
- //Looking for another blob to pulse
- var/list/dirs = list(1,2,4,8)
- dirs.Remove(origin_dir)//Dont pulse the guy who pulsed us
- for(var/i = 1 to 4)
- if(!dirs.len)
- break
- var/dirn = pick(dirs)
- dirs.Remove(dirn)
- var/turf/T = get_step(src, dirn)
- var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
- if(!B)
- expand(T,1,a_color)//No blob here so try and expand
- return
- B.adjustcolors(a_color)
-
- B.Pulse((pulse+1),get_dir(src.loc,T), a_color)
- return
+ flick("[icon_state]_glow", src)
return
+/obj/effect/blob/proc/RegenHealth() //when pulsed, heal!
+ if(health_timestamp <= world.time)
+ health = min(maxhealth, health+health_regen)
+ update_icon()
+ health_timestamp = world.time + 10 //1 second between heals
+ return 1
+ return 0
/obj/effect/blob/proc/run_action()
return 0
-/obj/effect/blob/proc/expand(turf/T = null, prob = 1, a_color)
- if(prob && !prob(health)) return
+/obj/effect/blob/proc/expand(turf/T = null, prob = 1, controller = null)
+ if(prob && !prob(health))
+ return
if(!T)
var/list/dirs = list(1,2,4,8)
for(var/i = 1 to 4)
@@ -157,20 +151,23 @@
T = null
if(!T)
return 0
- var/Blob_spawnable = 1
+ var/make_blob = 1 //can we make a blob?
if(istype(T, /turf/space) && prob(65))
- Blob_spawnable = 0
+ make_blob = 0
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) //Let's give some feedback that we DID try to spawn in space, since players are used to it
for(var/atom/A in T)
- if(A.density) //Unless density is 0, don't spawn a blob
- Blob_spawnable = 0
+ if(A.density)
+ make_blob = 0
A.blob_act() //Hit everything
if(T.density) //Check for walls and such dense turfs
- Blob_spawnable = 0
+ make_blob = 0
T.blob_act() //Hit the turf
- if(Blob_spawnable)
+ if(make_blob) //well, can we?
var/obj/effect/blob/B = new /obj/effect/blob/normal(src.loc)
- B.color = a_color
+ if(controller)
+ B.overmind = controller
+ else
+ B.overmind = overmind
B.density = 1
if(T.Enter(B,src)) //NOW we can attempt to move into the tile
B.density = initial(B.density)
@@ -240,25 +237,19 @@
if(controller)
B.overmind = controller
B.creation_action()
- B.adjustcolors(color)
+ B.update_icon()
qdel(src)
return B
-/obj/effect/blob/proc/adjustcolors(a_color)
- if(a_color)
- color = a_color
- return
-
/obj/effect/blob/examine(mob/user)
..()
user << "It seems to be made of [get_chem_name()]."
return
/obj/effect/blob/proc/get_chem_name()
- for(var/mob/camera/blob/B in mob_list)
- if(lowertext(B.blob_reagent_datum.color) == lowertext(src.color)) // Goddamit why we use strings for these
- return B.blob_reagent_datum.name
- return "unknown"
+ if(overmind)
+ return overmind.blob_reagent_datum.name
+ return "an unknown variant"
/obj/effect/blob/normal
icon_state = "blob"
@@ -269,6 +260,7 @@
brute_resist = 4
/obj/effect/blob/normal/update_icon()
+ ..()
if(health <= 10)
icon_state = "blob_damaged"
name = "fragile blob"