mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-11 08:06:33 +01:00
Cleans up blob code, removes a lot of hardcoded stuff, many new defines (#56306)
Cleaned up, commented on, and (hopefully) improves a lot of blob code. Put pretty much everything balance-related (except for the strains themselves) into a define file, for easier viewing, changing, and balancing. Added a bunch of new functionality that new strains (some of which I plan to add in the future) could use: from increased expansion range to more spores per factory.
This commit is contained in:
@@ -6,8 +6,7 @@
|
||||
job_rank = ROLE_BLOB
|
||||
|
||||
var/datum/action/innate/blobpop/pop_action
|
||||
var/starting_points_human_blob = 60
|
||||
var/point_rate_human_blob = 2
|
||||
var/starting_points_human_blob = OVERMIND_STARTING_POINTS
|
||||
|
||||
/datum/antagonist/blob/roundend_report()
|
||||
var/basic_report = ..()
|
||||
@@ -57,7 +56,7 @@
|
||||
var/mob/camera/blob/B = new /mob/camera/blob(get_turf(old_body), blobtag.starting_points_human_blob)
|
||||
owner.mind.transfer_to(B)
|
||||
old_body.gib()
|
||||
B.place_blob_core(blobtag.point_rate_human_blob, pop_override = TRUE)
|
||||
B.place_blob_core(placement_override = TRUE, pop_override = TRUE)
|
||||
|
||||
/datum/antagonist/blob/antag_listing_status()
|
||||
. = ..()
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
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/obj/structure/blob/special/factory = null
|
||||
var/independent = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/update_icons()
|
||||
@@ -53,7 +53,7 @@
|
||||
H.color = overmind.blobstrain.complementary_color
|
||||
else
|
||||
H.color = "#000000"
|
||||
adjustHealth(-maxHealth*0.0125)
|
||||
adjustHealth(-maxHealth*BLOBMOB_HEALING_MULTIPLIER)
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/fire_act(exposed_temperature, exposed_volume)
|
||||
..()
|
||||
@@ -92,14 +92,14 @@
|
||||
icon_state = "blobpod"
|
||||
icon_living = "blobpod"
|
||||
health_doll_icon = "blobpod"
|
||||
health = 30
|
||||
maxHealth = 30
|
||||
health = BLOBMOB_SPORE_HEALTH
|
||||
maxHealth = BLOBMOB_SPORE_HEALTH
|
||||
verb_say = "psychically pulses"
|
||||
verb_ask = "psychically probes"
|
||||
verb_exclaim = "psychically yells"
|
||||
verb_yell = "psychically screams"
|
||||
melee_damage_lower = 2
|
||||
melee_damage_upper = 4
|
||||
melee_damage_lower = BLOBMOB_SPORE_DMG_LOWER
|
||||
melee_damage_upper = BLOBMOB_SPORE_DMG_UPPER
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
obj_damage = 0
|
||||
attack_verb_continuous = "hits"
|
||||
@@ -115,7 +115,7 @@
|
||||
///Whether or not this is a fragile spore from Distributed Neurons
|
||||
var/is_weak = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobspore/Initialize(mapload, obj/structure/blob/factory/linked_node)
|
||||
/mob/living/simple_animal/hostile/blob/blobspore/Initialize(mapload, obj/structure/blob/special/linked_node)
|
||||
. = ..()
|
||||
if(istype(linked_node))
|
||||
factory = linked_node
|
||||
@@ -253,12 +253,12 @@
|
||||
icon_state = "blobbernaut"
|
||||
icon_living = "blobbernaut"
|
||||
icon_dead = "blobbernaut_dead"
|
||||
health = 200
|
||||
maxHealth = 200
|
||||
health = BLOBMOB_BLOBBERNAUT_HEALTH
|
||||
maxHealth = BLOBMOB_BLOBBERNAUT_HEALTH
|
||||
damage_coeff = list(BRUTE = 0.5, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 20
|
||||
obj_damage = 60
|
||||
melee_damage_lower = BLOBMOB_BLOBBERNAUT_DMG_SOLO_LOWER
|
||||
melee_damage_upper = BLOBMOB_BLOBBERNAUT_DMG_SOLO_UPPER
|
||||
obj_damage = BLOBMOB_BLOBBERNAUT_DMG_OBJ
|
||||
attack_verb_continuous = "slams"
|
||||
attack_verb_simple = "slam"
|
||||
attack_sound = 'sound/effects/blobattack.ogg'
|
||||
@@ -289,15 +289,15 @@
|
||||
if(!factory)
|
||||
damagesources++
|
||||
else
|
||||
if(locate(/obj/structure/blob/core) in blobs_in_area)
|
||||
adjustHealth(-maxHealth*0.1)
|
||||
if(locate(/obj/structure/blob/special/core) in blobs_in_area)
|
||||
adjustHealth(-maxHealth*BLOBMOB_BLOBBERNAUT_HEALING_CORE)
|
||||
var/obj/effect/temp_visual/heal/H = new /obj/effect/temp_visual/heal(get_turf(src)) //hello yes you are being healed
|
||||
if(overmind)
|
||||
H.color = overmind.blobstrain.complementary_color
|
||||
else
|
||||
H.color = "#000000"
|
||||
if(locate(/obj/structure/blob/node) in blobs_in_area)
|
||||
adjustHealth(-maxHealth*0.05)
|
||||
if(locate(/obj/structure/blob/special/node) in blobs_in_area)
|
||||
adjustHealth(-maxHealth*BLOBMOB_BLOBBERNAUT_HEALING_NODE)
|
||||
var/obj/effect/temp_visual/heal/H = new /obj/effect/temp_visual/heal(get_turf(src))
|
||||
if(overmind)
|
||||
H.color = overmind.blobstrain.complementary_color
|
||||
@@ -305,7 +305,7 @@
|
||||
H.color = "#000000"
|
||||
if(damagesources)
|
||||
for(var/i in 1 to damagesources)
|
||||
adjustHealth(maxHealth*0.025) //take 2.5% of max health as damage when not near the blob or if the naut has no factory, 5% if both
|
||||
adjustHealth(maxHealth*BLOBMOB_BLOBBERNAUT_HEALTH_DECAY) //take 2.5% of max health as damage when not near the blob or if the naut has no factory, 5% if both
|
||||
var/image/I = new('icons/mob/blob.dmi', src, "nautdamage", MOB_LAYER+0.01)
|
||||
I.appearance_flags = RESET_COLOR
|
||||
if(overmind)
|
||||
@@ -329,8 +329,8 @@
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/update_icons()
|
||||
..()
|
||||
if(overmind) //if we have an overmind, we're doing chemical reactions instead of pure damage
|
||||
melee_damage_lower = 4
|
||||
melee_damage_upper = 4
|
||||
melee_damage_lower = BLOBMOB_BLOBBERNAUT_DMG_LOWER
|
||||
melee_damage_upper = BLOBMOB_BLOBBERNAUT_DMG_UPPER
|
||||
attack_verb_continuous = overmind.blobstrain.blobbernaut_message
|
||||
else
|
||||
melee_damage_lower = initial(melee_damage_lower)
|
||||
|
||||
@@ -3,19 +3,67 @@ GLOBAL_LIST_INIT(valid_blobstrains, subtypesof(/datum/blobstrain) - list(/datum/
|
||||
/datum/blobstrain
|
||||
var/name
|
||||
var/description
|
||||
var/color = "#000000"
|
||||
var/complementary_color = "#000000" //a color that's complementary to the normal blob color
|
||||
var/shortdesc = null //just damage and on_mob effects, doesn't include special, blob-tile only effects
|
||||
var/effectdesc = null //any long, blob-tile specific effects
|
||||
var/color = COLOR_BLACK
|
||||
/// The color that stuff like healing effects and the overmind camera gets
|
||||
var/complementary_color = COLOR_BLACK
|
||||
/// A short description of the power and its effects
|
||||
var/shortdesc = null
|
||||
/// Any long, blob-tile specific effects
|
||||
var/effectdesc = null
|
||||
/// Short descriptor of what the strain does damage-wise, generally seen in the reroll menu
|
||||
var/analyzerdescdamage = "Unknown. Report this bug to a coder, or just adminhelp."
|
||||
/// Short descriptor of what the strain does in general, generally seen in the reroll menu
|
||||
var/analyzerdesceffect
|
||||
var/blobbernaut_message = "slams" //blobbernaut attack verb
|
||||
var/message = "The blob strikes you" //message sent to any mob hit by the blob
|
||||
var/message_living = null //extension to first mob sent to only living mobs i.e. silicons have no skin to be burnt
|
||||
var/core_regen = 2
|
||||
/// Blobbernaut attack verb
|
||||
var/blobbernaut_message = "slams"
|
||||
/// Message sent to any mob hit by the blob
|
||||
var/message = "The blob strikes you"
|
||||
/// Gets added onto 'message' if the mob stuck is of type living
|
||||
var/message_living = null
|
||||
/// Stores world.time to figure out when to next give resources
|
||||
var/resource_delay = 0
|
||||
var/point_rate = 2
|
||||
/// For blob-mobs and extinguishing-based effects
|
||||
var/fire_based = FALSE
|
||||
var/mob/camera/blob/overmind
|
||||
/// The amount of health regenned on core_process
|
||||
var/base_core_regen = BLOB_CORE_HP_REGEN
|
||||
/// The amount of points gained on core_process
|
||||
var/point_rate = BLOB_BASE_POINT_RATE
|
||||
|
||||
// Various vars that strains can buff the blob with
|
||||
/// HP regen bonus added by strain
|
||||
var/core_regen_bonus = 0
|
||||
/// resource point bonus added by strain
|
||||
var/point_rate_bonus = 0
|
||||
|
||||
/// Adds to claim, pulse, and expand range
|
||||
var/core_range_bonus = 0
|
||||
/// The core can sustain this many extra spores with this strain
|
||||
var/core_spore_bonus = 0
|
||||
/// Extra range up to which the core reinforces blobs
|
||||
var/core_strong_reinforcement_range_bonus = 0
|
||||
/// Extra range up to which the core reinforces blobs into reflectors
|
||||
var/core_reflector_reinforcement_range_bonus = 0
|
||||
|
||||
/// Adds to claim, pulse, and expand range
|
||||
var/node_range_bonus = 0
|
||||
/// Nodes can sustain this any extra spores with this strain
|
||||
var/node_spore_bonus = 0
|
||||
/// Extra range up to which the node reinforces blobs
|
||||
var/node_strong_reinforcement_range_bonus = 0
|
||||
/// Extra range up to which the node reinforces blobs into reflectors
|
||||
var/node_reflector_reinforcement_range_bonus = 0
|
||||
|
||||
/// Extra spores produced by factories with this strain
|
||||
var/factory_spore_bonus = 0
|
||||
|
||||
/// Multiplies the max and current health of every blob with this value upon selecting this strain.
|
||||
var/max_structure_health_multiplier = 1
|
||||
/// Multiplies the max and current health of every mob with this value upon selecting this strain.
|
||||
var/max_mob_health_multiplier = 1
|
||||
|
||||
/// Makes blobbernauts inject a bonus amount of reagents, making their attacks more powerful
|
||||
var/blobbernaut_reagentatk_bonus = 0
|
||||
|
||||
/datum/blobstrain/New(mob/camera/blob/new_overmind)
|
||||
if (!istype(new_overmind))
|
||||
@@ -24,16 +72,66 @@ GLOBAL_LIST_INIT(valid_blobstrains, subtypesof(/datum/blobstrain) - list(/datum/
|
||||
|
||||
/datum/blobstrain/proc/on_gain()
|
||||
overmind.color = complementary_color
|
||||
for(var/BL in GLOB.blobs)
|
||||
var/obj/structure/blob/B = BL
|
||||
|
||||
if(overmind.blob_core)
|
||||
overmind.blob_core.max_spores += core_spore_bonus
|
||||
overmind.blob_core.claim_range += core_range_bonus
|
||||
overmind.blob_core.pulse_range += core_range_bonus
|
||||
overmind.blob_core.expand_range += core_range_bonus
|
||||
overmind.blob_core.strong_reinforce_range += core_strong_reinforcement_range_bonus
|
||||
overmind.blob_core.reflector_reinforce_range += core_reflector_reinforcement_range_bonus
|
||||
|
||||
for(var/obj/structure/blob/special/node/N as anything in overmind.node_blobs)
|
||||
N.max_spores += node_spore_bonus
|
||||
N.claim_range += node_range_bonus
|
||||
N.pulse_range += node_range_bonus
|
||||
N.expand_range += node_range_bonus
|
||||
N.strong_reinforce_range += node_strong_reinforcement_range_bonus
|
||||
N.reflector_reinforce_range += node_reflector_reinforcement_range_bonus
|
||||
|
||||
for(var/obj/structure/blob/special/factory/F as anything in overmind.factory_blobs)
|
||||
F.max_spores += factory_spore_bonus
|
||||
|
||||
for(var/obj/structure/blob/B as anything in overmind.all_blobs)
|
||||
B.max_integrity *= max_structure_health_multiplier
|
||||
B.obj_integrity *= max_structure_health_multiplier
|
||||
B.update_icon()
|
||||
for(var/BLO in overmind.blob_mobs)
|
||||
var/mob/living/simple_animal/hostile/blob/BM = BLO
|
||||
|
||||
for(var/mob/living/simple_animal/hostile/blob/BM as anything in overmind.blob_mobs)
|
||||
BM.maxHealth *= max_mob_health_multiplier
|
||||
BM.health *= max_mob_health_multiplier
|
||||
BM.update_icons() //If it's getting a new strain, tell it what it does!
|
||||
to_chat(BM, "Your overmind's blob strain is now: <b><font color=\"[color]\">[name]</b></font>!")
|
||||
to_chat(BM, "The <b><font color=\"[color]\">[name]</b></font> strain [shortdesc ? "[shortdesc]" : "[description]"]")
|
||||
|
||||
/datum/blobstrain/proc/on_lose()
|
||||
if(overmind.blob_core)
|
||||
overmind.blob_core.max_spores -= core_spore_bonus
|
||||
overmind.blob_core.claim_range -= core_range_bonus
|
||||
overmind.blob_core.pulse_range -= core_range_bonus
|
||||
overmind.blob_core.expand_range -= core_range_bonus
|
||||
overmind.blob_core.strong_reinforce_range -= core_strong_reinforcement_range_bonus
|
||||
overmind.blob_core.reflector_reinforce_range -= core_reflector_reinforcement_range_bonus
|
||||
|
||||
for(var/obj/structure/blob/special/node/N as anything in overmind.node_blobs)
|
||||
N.max_spores -= node_spore_bonus
|
||||
N.claim_range -= node_range_bonus
|
||||
N.pulse_range -= node_range_bonus
|
||||
N.expand_range -= node_range_bonus
|
||||
N.strong_reinforce_range -= node_strong_reinforcement_range_bonus
|
||||
N.reflector_reinforce_range -= node_reflector_reinforcement_range_bonus
|
||||
|
||||
for(var/obj/structure/blob/special/factory/F as anything in overmind.factory_blobs)
|
||||
F.max_spores -= factory_spore_bonus
|
||||
|
||||
for(var/obj/structure/blob/B as anything in overmind.all_blobs)
|
||||
B.max_integrity /= max_structure_health_multiplier
|
||||
B.obj_integrity /= max_structure_health_multiplier
|
||||
|
||||
for(var/mob/living/simple_animal/hostile/blob/BM as anything in overmind.blob_mobs)
|
||||
BM.maxHealth /= max_mob_health_multiplier
|
||||
BM.health /= max_mob_health_multiplier
|
||||
|
||||
|
||||
/datum/blobstrain/proc/on_sporedeath(mob/living/spore)
|
||||
|
||||
@@ -47,8 +145,8 @@ GLOBAL_LIST_INIT(valid_blobstrains, subtypesof(/datum/blobstrain) - list(/datum/
|
||||
/datum/blobstrain/proc/core_process()
|
||||
if(resource_delay <= world.time)
|
||||
resource_delay = world.time + 10 // 1 second
|
||||
overmind.add_points(point_rate)
|
||||
overmind.blob_core.obj_integrity = min(overmind.blob_core.max_integrity, overmind.blob_core.obj_integrity+core_regen)
|
||||
overmind.add_points(point_rate+point_rate_bonus)
|
||||
overmind.blob_core.obj_integrity = min(overmind.blob_core.max_integrity, overmind.blob_core.obj_integrity+base_core_regen+core_regen_bonus)
|
||||
|
||||
/datum/blobstrain/proc/attack_living(mob/living/L, list/nearby_blobs) // When the blob attacks people
|
||||
send_message(L)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/datum/blobstrain/reagent // Blobs that mess with reagents, all "legacy" ones
|
||||
/datum/blobstrain/reagent // Blobs that mess with reagents, all "legacy" ones // what do you mean "legacy" you never added an alternative
|
||||
var/datum/reagent/reagent
|
||||
|
||||
/datum/blobstrain/reagent/New(mob/camera/blob/new_overmind)
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
/datum/blobstrain/reagent/attack_living(mob/living/L)
|
||||
var/mob_protection = L.get_permeability_protection()
|
||||
reagent.expose_mob(L, VAPOR, 25, 1, mob_protection, overmind)
|
||||
reagent.expose_mob(L, VAPOR, BLOB_REAGENTATK_VOL, 1, mob_protection, overmind)
|
||||
send_message(L)
|
||||
|
||||
/datum/blobstrain/reagent/blobbernaut_attack(mob/living/L)
|
||||
var/mob_protection = L.get_permeability_protection()
|
||||
reagent.expose_mob(L, VAPOR, 20, 0, mob_protection, overmind)//this will do between 10 and 20 damage(reduced by mob protection), depending on chemical, plus 4 from base brute damage.
|
||||
reagent.expose_mob(L, VAPOR, BLOBMOB_BLOBBERNAUT_REAGENTATK_VOL+blobbernaut_reagentatk_bonus, 0, mob_protection, overmind)//this will do between 10 and 20 damage(reduced by mob protection), depending on chemical, plus 4 from base brute damage.
|
||||
|
||||
/datum/blobstrain/reagent/on_sporedeath(mob/living/spore)
|
||||
spore.reagents.add_reagent(reagent.type, 10)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
message = "The blob splashes you with burning oil"
|
||||
message_living = ", and you feel your skin char and melt"
|
||||
reagent = /datum/reagent/blob/blazing_oil
|
||||
fire_based = TRUE
|
||||
|
||||
/datum/blobstrain/reagent/blazing_oil/extinguish_reaction(obj/structure/blob/B)
|
||||
B.take_damage(1.5, BURN, ENERGY)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
debris_attack(L, blob)
|
||||
|
||||
/datum/blobstrain/debris_devourer/on_sporedeath(mob/living/spore)
|
||||
var/obj/structure/blob/core/core = overmind.blob_core
|
||||
var/obj/structure/blob/special/core/core = overmind.blob_core
|
||||
for(var/i in 1 to 3)
|
||||
var/obj/item/I = pick(core.contents)
|
||||
if (I && !QDELETED(I))
|
||||
@@ -30,7 +30,7 @@
|
||||
I.forceMove(overmind.blob_core)
|
||||
|
||||
/datum/blobstrain/debris_devourer/proc/debris_attack(mob/living/L, source)
|
||||
var/obj/structure/blob/core/core = overmind.blob_core
|
||||
var/obj/structure/blob/special/core/core = overmind.blob_core
|
||||
if (prob(40 * DEBRIS_DENSITY)) // Pretend the items are spread through the blob and its mobs and not in the core.
|
||||
var/obj/item/I = pick(core.contents)
|
||||
if (I && !QDELETED(I))
|
||||
@@ -41,12 +41,12 @@
|
||||
debris_attack(L,blobbernaut)
|
||||
|
||||
/datum/blobstrain/debris_devourer/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag, coefficient = 1) //when the blob takes damage, do this
|
||||
var/obj/structure/blob/core/core = overmind.blob_core
|
||||
var/obj/structure/blob/special/core/core = overmind.blob_core
|
||||
return round(max((coefficient*damage)-min(coefficient*DEBRIS_DENSITY, 10), 0)) // reduce damage taken by items per blob, up to 10
|
||||
|
||||
/datum/blobstrain/debris_devourer/examine(mob/user)
|
||||
. = ..()
|
||||
var/obj/structure/blob/core/core = overmind.blob_core
|
||||
var/obj/structure/blob/special/core/core = overmind.blob_core
|
||||
if (isobserver(user))
|
||||
. += "<span class='notice'>Absorbed debris is currently reducing incoming damage by [round(max(min(DEBRIS_DENSITY, 10),0))]</span>"
|
||||
else
|
||||
|
||||
@@ -10,14 +10,8 @@
|
||||
reagent = /datum/reagent/blob/electromagnetic_web
|
||||
|
||||
/datum/blobstrain/reagent/electromagnetic_web/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
|
||||
if(damage_type == BRUTE) //take full brute
|
||||
switch(B.brute_resist)
|
||||
if(0.5)
|
||||
return damage * 2
|
||||
if(0.25)
|
||||
return damage * 4
|
||||
if(0.1)
|
||||
return damage * 10
|
||||
if(damage_type == BRUTE) // take full brute, divide by the multiplier to get full value
|
||||
return damage / B.brute_resist
|
||||
return damage * 1.25 //a laser will do 25 damage, which will kill any normal blob
|
||||
|
||||
/datum/blobstrain/reagent/electromagnetic_web/death_reaction(obj/structure/blob/B, damage_flag)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
color = "#4F4441"
|
||||
complementary_color = "#414C4F"
|
||||
reagent = /datum/reagent/blob/networked_fibers
|
||||
core_regen = 5
|
||||
core_regen_bonus = 5
|
||||
|
||||
/datum/blobstrain/reagent/networked_fibers/expand_reaction(obj/structure/blob/spawning_blob, obj/structure/blob/new_blob, turf/chosen_turf, mob/camera/blob/overmind)
|
||||
if(!overmind && new_blob.overmind)
|
||||
@@ -19,7 +19,7 @@
|
||||
if(isspaceturf(chosen_turf))
|
||||
return
|
||||
for(var/obj/structure/blob/possible_expander in range(1, new_blob))
|
||||
if(possible_expander.overmind == overmind && (istype(possible_expander, /obj/structure/blob/core) || istype(possible_expander, /obj/structure/blob/node)))
|
||||
if(possible_expander.overmind == overmind && (istype(possible_expander, /obj/structure/blob/special/core) || istype(possible_expander, /obj/structure/blob/special/node)))
|
||||
new_blob.forceMove(get_turf(possible_expander))
|
||||
possible_expander.forceMove(chosen_turf)
|
||||
possible_expander.setDir(get_dir(new_blob, possible_expander))
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
complementary_color = "#AF7B8D"
|
||||
message_living = ", and you feel <i>alive</i>"
|
||||
reagent = /datum/reagent/blob/regenerative_materia
|
||||
core_regen = 20
|
||||
point_rate = 3
|
||||
core_regen_bonus = 20
|
||||
point_rate_bonus = 1
|
||||
|
||||
/datum/reagent/blob/regenerative_materia
|
||||
name = "Regenerative Materia"
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
if(damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) //the cause isn't fire or bombs, so split the damage
|
||||
var/damagesplit = 1 //maximum split is 9, reducing the damage each blob takes to 11% but doing that damage to 9 blobs
|
||||
for(var/obj/structure/blob/C in orange(1, B))
|
||||
if(!istype(C, /obj/structure/blob/core) && !istype(C, /obj/structure/blob/node) && C.overmind && C.overmind.blobstrain.type == B.overmind.blobstrain.type) //if it doesn't have the same chemical or is a core or node, don't split damage to it
|
||||
if(!C.ignore_syncmesh_share && C.overmind && C.overmind.blobstrain.type == B.overmind.blobstrain.type) //if it doesn't have the same chemical or is a core or node, don't split damage to it
|
||||
damagesplit += 1
|
||||
for(var/obj/structure/blob/C in orange(1, B))
|
||||
if(!istype(C, /obj/structure/blob/core) && !istype(C, /obj/structure/blob/node) && C.overmind && C.overmind.blobstrain.type == B.overmind.blobstrain.type) //only hurt blobs that have the same overmind chemical and aren't cores or nodes
|
||||
if(!C.ignore_syncmesh_share && C.overmind && C.overmind.blobstrain.type == B.overmind.blobstrain.type) //only hurt blobs that have the same overmind chemical and aren't cores or nodes
|
||||
C.take_damage(damage/damagesplit, CLONE, 0, 0)
|
||||
return damage / damagesplit
|
||||
else
|
||||
|
||||
@@ -21,32 +21,36 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
faction = list(ROLE_BLOB)
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
hud_type = /datum/hud/blob_overmind
|
||||
var/obj/structure/blob/core/blob_core = null // The blob overmind's core
|
||||
var/obj/structure/blob/special/core/blob_core = null // The blob overmind's core
|
||||
var/blob_points = 0
|
||||
var/max_blob_points = 100
|
||||
var/max_blob_points = OVERMIND_MAX_POINTS_DEFAULT
|
||||
var/last_attack = 0
|
||||
var/datum/blobstrain/blobstrain
|
||||
var/datum/blobstrain/reagent/blobstrain
|
||||
var/list/blob_mobs = list()
|
||||
/// A list of all blob structures
|
||||
var/list/all_blobs = list()
|
||||
var/list/resource_blobs = list()
|
||||
var/free_strain_rerolls = 1 //one free strain reroll
|
||||
var/list/factory_blobs = list()
|
||||
var/list/node_blobs = list()
|
||||
var/free_strain_rerolls = OVERMIND_STARTING_REROLLS
|
||||
var/last_reroll_time = 0 //time since we last rerolled, used to give free rerolls
|
||||
var/nodes_required = TRUE //if the blob needs nodes to place resource and factory blobs
|
||||
var/placed = FALSE
|
||||
var/manualplace_min_time = 600 //in deciseconds //a minute, to get bearings
|
||||
var/autoplace_max_time = 3600 //six minutes, as long as should be needed
|
||||
var/manualplace_min_time = OVERMIND_STARTING_MIN_PLACE_TIME // Some time to get your bearings
|
||||
var/autoplace_max_time = OVERMIND_STARTING_AUTO_PLACE_TIME // Automatically place the core in a random spot
|
||||
var/list/blobs_legit = list()
|
||||
var/max_count = 0 //The biggest it got before death
|
||||
var/blobwincount = 400
|
||||
var/blobwincount = OVERMIND_WIN_CONDITION_AMOUNT
|
||||
var/victory_in_progress = FALSE
|
||||
var/rerolling = FALSE
|
||||
var/announcement_size = 75
|
||||
var/announcement_size = OVERMIND_ANNOUNCEMENT_MIN_SIZE // Announce the biohazard when this size is reached
|
||||
var/announcement_time
|
||||
var/has_announced = FALSE
|
||||
|
||||
/// The list of strains the blob can reroll for.
|
||||
var/list/strain_choices
|
||||
|
||||
/mob/camera/blob/Initialize(mapload, starting_points = 60)
|
||||
/mob/camera/blob/Initialize(mapload, starting_points = OVERMIND_STARTING_POINTS)
|
||||
validate_location()
|
||||
blob_points = starting_points
|
||||
manualplace_min_time += world.time
|
||||
@@ -117,7 +121,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
max_blob_points = INFINITY
|
||||
blob_points = INFINITY
|
||||
addtimer(CALLBACK(src, .proc/victory), 450)
|
||||
else if(!free_strain_rerolls && (last_reroll_time + BLOB_REROLL_TIME<world.time))
|
||||
else if(!free_strain_rerolls && (last_reroll_time + BLOB_POWER_REROLL_FREE_TIME<world.time))
|
||||
to_chat(src, "<b><span class='big'><font color=\"#EE4000\">You have gained another free strain re-roll.</font></span></b>")
|
||||
free_strain_rerolls = 1
|
||||
|
||||
@@ -184,6 +188,13 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
if(BM)
|
||||
BM.overmind = null
|
||||
BM.update_icons()
|
||||
for(var/obj/structure/blob/blob_structure as anything in all_blobs)
|
||||
blob_structure.overmind = null
|
||||
all_blobs = null
|
||||
resource_blobs = null
|
||||
factory_blobs = null
|
||||
node_blobs = null
|
||||
blob_mobs = null
|
||||
GLOB.overminds -= src
|
||||
QDEL_LIST_ASSOC_VAL(strain_choices)
|
||||
|
||||
@@ -270,7 +281,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
|
||||
/mob/camera/blob/Move(NewLoc, Dir = 0)
|
||||
if(placed)
|
||||
var/obj/structure/blob/B = locate() in range("3x3", NewLoc)
|
||||
var/obj/structure/blob/B = locate() in range(OVERMIND_MAX_CAMERA_STRAY, NewLoc)
|
||||
if(B)
|
||||
forceMove(NewLoc)
|
||||
else
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#define BLOB_REROLL_CHOICES 6
|
||||
#define BLOB_REROLL_RADIUS 60
|
||||
|
||||
/mob/camera/blob/proc/can_buy(cost = 15)
|
||||
@@ -8,8 +7,6 @@
|
||||
add_points(-cost)
|
||||
return TRUE
|
||||
|
||||
// Power verbs
|
||||
|
||||
/mob/camera/blob/proc/place_blob_core(placement_override, pop_override = FALSE)
|
||||
if(placed && placement_override != -1)
|
||||
return TRUE
|
||||
@@ -54,34 +51,28 @@
|
||||
if(placed && blob_core)
|
||||
blob_core.forceMove(loc)
|
||||
else
|
||||
var/obj/structure/blob/core/core = new(get_turf(src), src, 1)
|
||||
var/obj/structure/blob/special/core/core = new(get_turf(src), src, 1)
|
||||
core.overmind = src
|
||||
blobs_legit += src
|
||||
blob_core = core
|
||||
core.update_icon()
|
||||
update_health_hud()
|
||||
placed = 1
|
||||
announcement_time = world.time + 6000
|
||||
placed = TRUE
|
||||
announcement_time = world.time + OVERMIND_ANNOUNCEMENT_MAX_TIME
|
||||
return TRUE
|
||||
|
||||
/mob/camera/blob/verb/transport_core()
|
||||
set category = "Blob"
|
||||
set name = "Jump to Core"
|
||||
set desc = "Move your camera to your core."
|
||||
/mob/camera/blob/proc/transport_core()
|
||||
if(blob_core)
|
||||
forceMove(blob_core.drop_location())
|
||||
|
||||
/mob/camera/blob/verb/jump_to_node()
|
||||
set category = "Blob"
|
||||
set name = "Jump to Node"
|
||||
set desc = "Move your camera to a selected node."
|
||||
/mob/camera/blob/proc/jump_to_node()
|
||||
if(GLOB.blob_nodes.len)
|
||||
var/list/nodes = list()
|
||||
for(var/i in 1 to GLOB.blob_nodes.len)
|
||||
var/obj/structure/blob/node/B = GLOB.blob_nodes[i]
|
||||
var/obj/structure/blob/special/node/B = GLOB.blob_nodes[i]
|
||||
nodes["Blob Node #[i] ([get_area_name(B)])"] = B
|
||||
var/node_name = input(src, "Choose a node to jump to.", "Node Jump") in nodes
|
||||
var/obj/structure/blob/node/chosen_node = nodes[node_name]
|
||||
var/obj/structure/blob/special/node/chosen_node = nodes[node_name]
|
||||
if(chosen_node)
|
||||
forceMove(chosen_node.loc)
|
||||
|
||||
@@ -100,7 +91,7 @@
|
||||
if(!(A.area_flags & BLOBS_ALLOWED)) //factory and resource blobs must be legit
|
||||
to_chat(src, "<span class='warning'>This type of blob must be placed on the station!</span>")
|
||||
return
|
||||
if(nodes_required && !(locate(/obj/structure/blob/node) in orange(3, T)) && !(locate(/obj/structure/blob/core) in orange(4, T)))
|
||||
if(nodes_required && !(locate(/obj/structure/blob/special/node) in orange(BLOB_NODE_PULSE_RANGE, T)) && !(locate(/obj/structure/blob/special/core) in orange(BLOB_CORE_PULSE_RANGE, T)))
|
||||
to_chat(src, "<span class='warning'>You need to place this blob closer to a node or core!</span>")
|
||||
return //handholdotron 2000
|
||||
if(minSeparation)
|
||||
@@ -113,60 +104,30 @@
|
||||
var/obj/structure/blob/N = B.change_to(blobstrain, src)
|
||||
return N
|
||||
|
||||
/mob/camera/blob/verb/toggle_node_req()
|
||||
set category = "Blob"
|
||||
set name = "Toggle Node Requirement"
|
||||
set desc = "Toggle requiring nodes to place resource and factory blobs."
|
||||
/mob/camera/blob/proc/toggle_node_req()
|
||||
nodes_required = !nodes_required
|
||||
if(nodes_required)
|
||||
to_chat(src, "<span class='warning'>You now require a nearby node or core to place factory and resource blobs.</span>")
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You no longer require a nearby node or core to place factory and resource blobs.</span>")
|
||||
|
||||
/mob/camera/blob/verb/create_shield_power()
|
||||
set category = "Blob"
|
||||
set name = "Create/Upgrade Shield Blob (15)"
|
||||
set desc = "Create a shield blob, which will block fire and is hard to kill. Using this on an existing shield blob turns it into a reflective blob, capable of reflecting most projectiles but making it twice as weak to brute attacks."
|
||||
create_shield()
|
||||
|
||||
/mob/camera/blob/proc/create_shield(turf/T)
|
||||
var/obj/structure/blob/shield/S = locate(/obj/structure/blob/shield) in T
|
||||
if(S)
|
||||
if(!can_buy(BLOB_REFLECTOR_COST))
|
||||
if(!can_buy(BLOB_UPGRADE_REFLECTOR_COST))
|
||||
return
|
||||
if(S.obj_integrity < S.max_integrity * 0.5)
|
||||
add_points(BLOB_REFLECTOR_COST)
|
||||
add_points(BLOB_UPGRADE_REFLECTOR_COST)
|
||||
to_chat(src, "<span class='warning'>This shield blob is too damaged to be modified properly!</span>")
|
||||
return
|
||||
to_chat(src, "<span class='warning'>You secrete a reflective ooze over the shield blob, allowing it to reflect projectiles at the cost of reduced integrity.</span>")
|
||||
S.change_to(/obj/structure/blob/shield/reflective, src)
|
||||
else
|
||||
createSpecial(15, /obj/structure/blob/shield, 0, FALSE, T)
|
||||
createSpecial(BLOB_UPGRADE_STRONG_COST, /obj/structure/blob/shield, 0, FALSE, T)
|
||||
|
||||
/mob/camera/blob/verb/create_resource()
|
||||
set category = "Blob"
|
||||
set name = "Create Resource Blob (40)"
|
||||
set desc = "Create a resource tower which will generate resources for you."
|
||||
createSpecial(40, /obj/structure/blob/resource, 4, TRUE)
|
||||
|
||||
/mob/camera/blob/verb/create_node()
|
||||
set category = "Blob"
|
||||
set name = "Create Node Blob (50)"
|
||||
set desc = "Create a node, which will power nearby factory and resource blobs."
|
||||
createSpecial(50, /obj/structure/blob/node, 5, FALSE)
|
||||
|
||||
/mob/camera/blob/verb/create_factory()
|
||||
set category = "Blob"
|
||||
set name = "Create Factory Blob (60)"
|
||||
set desc = "Create a spore tower that will spawn spores to harass your enemies."
|
||||
createSpecial(60, /obj/structure/blob/factory, 7, TRUE)
|
||||
|
||||
/mob/camera/blob/verb/create_blobbernaut()
|
||||
set category = "Blob"
|
||||
set name = "Create Blobbernaut (40)"
|
||||
set desc = "Create a powerful blobbernaut which is mildly smart and will attack enemies."
|
||||
/mob/camera/blob/proc/create_blobbernaut()
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/structure/blob/factory/B = locate(/obj/structure/blob/factory) in T
|
||||
var/obj/structure/blob/special/factory/B = locate(/obj/structure/blob/special/factory) in T
|
||||
if(!B)
|
||||
to_chat(src, "<span class='warning'>You must be on a factory blob!</span>")
|
||||
return
|
||||
@@ -176,7 +137,7 @@
|
||||
if(B.obj_integrity < B.max_integrity * 0.5)
|
||||
to_chat(src, "<span class='warning'>This factory blob is too damaged to sustain a blobbernaut.</span>")
|
||||
return
|
||||
if(!can_buy(40))
|
||||
if(!can_buy(BLOBMOB_BLOBBERNAUT_RESOURCE_COST))
|
||||
return
|
||||
|
||||
B.naut = TRUE //temporary placeholder to prevent creation of more than one per factory.
|
||||
@@ -207,15 +168,12 @@
|
||||
to_chat(blobber, "The <b><font color=\"[blobstrain.color]\">[blobstrain.name]</b></font> reagent [blobstrain.shortdesc ? "[blobstrain.shortdesc]" : "[blobstrain.description]"]")
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You could not conjure a sentience for your blobbernaut. Your points have been refunded. Try again later.</span>")
|
||||
add_points(40)
|
||||
add_points(BLOBMOB_BLOBBERNAUT_RESOURCE_COST)
|
||||
B.naut = null
|
||||
|
||||
/mob/camera/blob/verb/relocate_core()
|
||||
set category = "Blob"
|
||||
set name = "Relocate Core (80)"
|
||||
set desc = "Swaps the locations of your core and the selected node."
|
||||
/mob/camera/blob/proc/relocate_core()
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/structure/blob/node/B = locate(/obj/structure/blob/node) in T
|
||||
var/obj/structure/blob/special/node/B = locate(/obj/structure/blob/special/node) in T
|
||||
if(!B)
|
||||
to_chat(src, "<span class='warning'>You must be on a blob node!</span>")
|
||||
return
|
||||
@@ -226,7 +184,7 @@
|
||||
if(isspaceturf(T) || A && !(A.area_flags & BLOBS_ALLOWED))
|
||||
to_chat(src, "<span class='warning'>You cannot relocate your core here!</span>")
|
||||
return
|
||||
if(!can_buy(80))
|
||||
if(!can_buy(BLOB_POWER_RELOCATE_COST))
|
||||
return
|
||||
var/turf/old_turf = get_turf(blob_core)
|
||||
var/olddir = blob_core.dir
|
||||
@@ -235,13 +193,6 @@
|
||||
B.forceMove(old_turf)
|
||||
B.setDir(olddir)
|
||||
|
||||
/mob/camera/blob/verb/revert()
|
||||
set category = "Blob"
|
||||
set name = "Remove Blob"
|
||||
set desc = "Removes a blob, giving you back some resources."
|
||||
var/turf/T = get_turf(src)
|
||||
remove_blob(T)
|
||||
|
||||
/mob/camera/blob/proc/remove_blob(turf/T)
|
||||
var/obj/structure/blob/B = locate() in T
|
||||
if(!B)
|
||||
@@ -258,13 +209,6 @@
|
||||
to_chat(src, "<span class='notice'>Gained [B.point_return] resources from removing \the [B].</span>")
|
||||
qdel(B)
|
||||
|
||||
/mob/camera/blob/verb/expand_blob_power()
|
||||
set category = "Blob"
|
||||
set name = "Expand/Attack Blob ([BLOB_SPREAD_COST])"
|
||||
set desc = "Attempts to create a new blob in this tile. If the tile isn't clear, instead attacks it, damaging mobs and objects and refunding [BLOB_ATTACK_REFUND] points."
|
||||
var/turf/T = get_turf(src)
|
||||
expand_blob(T)
|
||||
|
||||
/mob/camera/blob/proc/expand_blob(turf/T)
|
||||
if(world.time < last_attack)
|
||||
return
|
||||
@@ -274,7 +218,7 @@
|
||||
if(!possibleblobs.len)
|
||||
to_chat(src, "<span class='warning'>There is no blob adjacent to the target tile!</span>")
|
||||
return
|
||||
if(can_buy(BLOB_SPREAD_COST))
|
||||
if(can_buy(BLOB_EXPAND_COST))
|
||||
var/attacksuccess = FALSE
|
||||
for(var/mob/living/L in T)
|
||||
if(ROLE_BLOB in L.faction) //no friendly/dead fire
|
||||
@@ -289,7 +233,7 @@
|
||||
add_points(BLOB_ATTACK_REFUND)
|
||||
else
|
||||
to_chat(src, "<span class='warning'>There is a blob there!</span>")
|
||||
add_points(BLOB_SPREAD_COST) //otherwise, refund all of the cost
|
||||
add_points(BLOB_EXPAND_COST) //otherwise, refund all of the cost
|
||||
else
|
||||
var/list/cardinalblobs = list()
|
||||
var/list/diagonalblobs = list()
|
||||
@@ -311,19 +255,12 @@
|
||||
playsound(OB, 'sound/effects/splat.ogg', 50, TRUE)
|
||||
add_points(BLOB_ATTACK_REFUND)
|
||||
else
|
||||
add_points(BLOB_SPREAD_COST) //if we're attacking diagonally and didn't hit anything, refund
|
||||
add_points(BLOB_EXPAND_COST) //if we're attacking diagonally and didn't hit anything, refund
|
||||
if(attacksuccess)
|
||||
last_attack = world.time + CLICK_CD_MELEE
|
||||
else
|
||||
last_attack = world.time + CLICK_CD_RAPID
|
||||
|
||||
/mob/camera/blob/verb/rally_spores_power()
|
||||
set category = "Blob"
|
||||
set name = "Rally Spores"
|
||||
set desc = "Rally your spores to move to a target location."
|
||||
var/turf/T = get_turf(src)
|
||||
rally_spores(T)
|
||||
|
||||
/mob/camera/blob/proc/rally_spores(turf/T)
|
||||
to_chat(src, "You rally your spores.")
|
||||
var/list/surrounding_turfs = block(locate(T.x - 1, T.y - 1, T.z), locate(T.x + 1, T.y + 1, T.z))
|
||||
@@ -334,27 +271,9 @@
|
||||
BS.LoseTarget()
|
||||
BS.Goto(pick(surrounding_turfs), BS.move_to_delay)
|
||||
|
||||
/mob/camera/blob/verb/blob_broadcast()
|
||||
set category = "Blob"
|
||||
set name = "Blob Broadcast"
|
||||
set desc = "Speak with your blob spores and blobbernauts as your mouthpieces."
|
||||
var/speak_text = stripped_input(src, "What would you like to say with your minions?", "Blob Broadcast", null)
|
||||
if(!speak_text)
|
||||
return
|
||||
else
|
||||
to_chat(src, "You broadcast with your minions, <B>[speak_text]</B>")
|
||||
for(var/BLO in blob_mobs)
|
||||
var/mob/living/simple_animal/hostile/blob/BM = BLO
|
||||
if(BM.stat == CONSCIOUS)
|
||||
BM.say(speak_text)
|
||||
|
||||
/mob/camera/blob/verb/strain_reroll()
|
||||
set category = "Blob"
|
||||
set name = "Reactive Strain Adaptation (40)"
|
||||
set desc = "Replaces your strain with a random, different one."
|
||||
|
||||
if (!free_strain_rerolls && blob_points < BLOB_REROLL_COST)
|
||||
to_chat(src, "<span class='warning'>You need at least [BLOB_REROLL_COST] resources to reroll your strain again!</span>")
|
||||
/mob/camera/blob/proc/strain_reroll()
|
||||
if (!free_strain_rerolls && blob_points < BLOB_POWER_REROLL_COST)
|
||||
to_chat(src, "<span class='warning'>You need at least [BLOB_POWER_REROLL_COST] resources to reroll your strain again!</span>")
|
||||
return
|
||||
|
||||
open_reroll_menu()
|
||||
@@ -365,7 +284,7 @@
|
||||
strain_choices = list()
|
||||
|
||||
var/list/new_strains = GLOB.valid_blobstrains.Copy() - blobstrain.type
|
||||
for (var/_ in 1 to BLOB_REROLL_CHOICES)
|
||||
for (var/_ in 1 to BLOB_POWER_REROLL_CHOICES)
|
||||
var/datum/blobstrain/strain = pick_n_take(new_strains)
|
||||
|
||||
var/image/strain_icon = image('icons/mob/blob.dmi', "blob_core")
|
||||
@@ -386,7 +305,7 @@
|
||||
if (isnull(strain_result))
|
||||
return
|
||||
|
||||
if (!free_strain_rerolls && !can_buy(BLOB_REROLL_COST))
|
||||
if (!free_strain_rerolls && !can_buy(BLOB_POWER_REROLL_COST))
|
||||
return
|
||||
|
||||
for (var/_other_strain in GLOB.valid_blobstrains)
|
||||
@@ -402,10 +321,7 @@
|
||||
|
||||
return
|
||||
|
||||
/mob/camera/blob/verb/blob_help()
|
||||
set category = "Blob"
|
||||
set name = "*Blob Help*"
|
||||
set desc = "Help on how to blob."
|
||||
/mob/camera/blob/proc/blob_help()
|
||||
to_chat(src, "<b>As the overmind, you can control the blob!</b>")
|
||||
to_chat(src, "Your blob reagent is: <b><font color=\"[blobstrain.color]\">[blobstrain.name]</b></font>!")
|
||||
to_chat(src, "The <b><font color=\"[blobstrain.color]\">[blobstrain.name]</b></font> reagent [blobstrain.description]")
|
||||
@@ -426,5 +342,4 @@
|
||||
to_chat(src, "<span class='big'><font color=\"#EE4000\">You will automatically place your blob core in [DisplayTimeText(autoplace_max_time - world.time)].</font></span>")
|
||||
to_chat(src, "<span class='big'><font color=\"#EE4000\">You [manualplace_min_time ? "will be able to":"can"] manually place your blob core by pressing the Place Blob Core button in the bottom right corner of the screen.</font></span>")
|
||||
|
||||
#undef BLOB_REROLL_CHOICES
|
||||
#undef BLOB_REROLL_RADIUS
|
||||
|
||||
@@ -10,21 +10,32 @@
|
||||
layer = BELOW_MOB_LAYER
|
||||
pass_flags_self = PASSBLOB
|
||||
CanAtmosPass = ATMOS_PASS_PROC
|
||||
var/point_return = 0 //How many points the blob gets back when it removes a blob of that type. If less than 0, blob cannot be removed.
|
||||
/// How many points the blob gets back when it removes a blob of that type. If less than 0, blob cannot be removed.
|
||||
var/point_return = 0
|
||||
max_integrity = 30
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 70)
|
||||
var/health_regen = 2 //how much health this blob regens when pulsed
|
||||
var/pulse_timestamp = 0 //we got pulsed when?
|
||||
var/heal_timestamp = 0 //we got healed when?
|
||||
var/brute_resist = 0.5 //multiplies brute damage by this
|
||||
var/fire_resist = 1 //multiplies burn damage by this
|
||||
var/atmosblock = FALSE //if the blob blocks atmos and heat spread
|
||||
/// how much health this blob regens when pulsed
|
||||
var/health_regen = BLOB_REGULAR_HP_REGEN
|
||||
/// We got pulsed when?
|
||||
COOLDOWN_DECLARE(pulse_timestamp)
|
||||
/// we got healed when?
|
||||
COOLDOWN_DECLARE(heal_timestamp)
|
||||
/// Multiplies brute damage by this
|
||||
var/brute_resist = BLOB_BRUTE_RESIST
|
||||
/// Multiplies burn damage by this
|
||||
var/fire_resist = BLOB_FIRE_RESIST
|
||||
/// Only used by the synchronous mesh strain. If set to true, these blobs won't share or receive damage taken with others.
|
||||
var/ignore_syncmesh_share = 0
|
||||
/// If the blob blocks atmos and heat spread
|
||||
var/atmosblock = FALSE
|
||||
var/mob/camera/blob/overmind
|
||||
|
||||
|
||||
/obj/structure/blob/Initialize(mapload, owner_overmind)
|
||||
. = ..()
|
||||
if(owner_overmind)
|
||||
overmind = owner_overmind
|
||||
overmind.all_blobs += src
|
||||
var/area/Ablob = get_area(src)
|
||||
if(Ablob.area_flags & BLOBS_ALLOWED) //Is this area allowed for winning as blob?
|
||||
overmind.blobs_legit += src
|
||||
@@ -44,7 +55,9 @@
|
||||
atmosblock = FALSE
|
||||
air_update_turf(TRUE, FALSE)
|
||||
if(overmind)
|
||||
overmind.all_blobs -= src
|
||||
overmind.blobs_legit -= src //if it was in the legit blobs list, it isn't now
|
||||
overmind = null
|
||||
GLOB.blobs -= src //it's no longer in the all blobs list either
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, TRUE) //Expand() is no longer broken, no check necessary.
|
||||
return ..()
|
||||
@@ -78,47 +91,14 @@
|
||||
else
|
||||
remove_atom_colour(FIXED_COLOUR_PRIORITY)
|
||||
|
||||
/obj/structure/blob/proc/Pulse_Area(mob/camera/blob/pulsing_overmind, claim_range = 10, pulse_range = 3, expand_range = 2)
|
||||
if(QDELETED(pulsing_overmind))
|
||||
pulsing_overmind = overmind
|
||||
Be_Pulsed()
|
||||
var/expanded = FALSE
|
||||
if(prob(70) && expand())
|
||||
expanded = TRUE
|
||||
var/list/blobs_to_affect = list()
|
||||
for(var/obj/structure/blob/B in urange(claim_range, src, 1))
|
||||
blobs_to_affect += B
|
||||
shuffle_inplace(blobs_to_affect)
|
||||
for(var/L in blobs_to_affect)
|
||||
var/obj/structure/blob/B = L
|
||||
if(!B.overmind && !istype(B, /obj/structure/blob/core) && prob(30))
|
||||
B.overmind = pulsing_overmind //reclaim unclaimed, non-core blobs.
|
||||
B.update_icon()
|
||||
var/distance = get_dist(get_turf(src), get_turf(B))
|
||||
var/expand_probablity = max(20 - distance * 8, 1)
|
||||
if(B.Adjacent(src))
|
||||
expand_probablity = 20
|
||||
if(distance <= expand_range)
|
||||
var/can_expand = TRUE
|
||||
if(blobs_to_affect.len >= 120 && B.heal_timestamp > world.time)
|
||||
can_expand = FALSE
|
||||
if(can_expand && B.pulse_timestamp <= world.time && prob(expand_probablity))
|
||||
var/obj/structure/blob/newB = B.expand(null, null, !expanded) //expansion falls off with range but is faster near the blob causing the expansion
|
||||
if(newB)
|
||||
if(expanded)
|
||||
qdel(newB)
|
||||
expanded = TRUE
|
||||
if(distance <= pulse_range)
|
||||
B.Be_Pulsed()
|
||||
|
||||
/obj/structure/blob/proc/Be_Pulsed()
|
||||
if(pulse_timestamp <= world.time)
|
||||
if(COOLDOWN_FINISHED(src, pulse_timestamp))
|
||||
ConsumeTile()
|
||||
if(heal_timestamp <= world.time)
|
||||
if(COOLDOWN_FINISHED(src, heal_timestamp))
|
||||
obj_integrity = min(max_integrity, obj_integrity+health_regen)
|
||||
heal_timestamp = world.time + 20
|
||||
COOLDOWN_START(src, heal_timestamp, 20)
|
||||
update_icon()
|
||||
pulse_timestamp = world.time + 10
|
||||
COOLDOWN_START(src, pulse_timestamp, 10)
|
||||
return TRUE//we did it, we were pulsed!
|
||||
return FALSE //oh no we failed
|
||||
|
||||
@@ -326,10 +306,9 @@
|
||||
name = "normal blob"
|
||||
icon_state = "blob"
|
||||
light_range = 0
|
||||
obj_integrity = 21 //doesn't start at full health
|
||||
max_integrity = 25
|
||||
health_regen = 1
|
||||
brute_resist = 0.25
|
||||
max_integrity = BLOB_REGULAR_MAX_HP
|
||||
health_regen = BLOB_REGULAR_HP_REGEN
|
||||
brute_resist = BLOB_BRUTE_RESIST * 0.5
|
||||
|
||||
/obj/structure/blob/normal/scannerreport()
|
||||
if(obj_integrity <= 15)
|
||||
@@ -342,14 +321,92 @@
|
||||
icon_state = "blob_damaged"
|
||||
name = "fragile blob"
|
||||
desc = "A thin lattice of slightly twitching tendrils."
|
||||
brute_resist = 0.5
|
||||
brute_resist = BLOB_BRUTE_RESIST
|
||||
else if (overmind)
|
||||
icon_state = "blob"
|
||||
name = "blob"
|
||||
desc = "A thick wall of writhing tendrils."
|
||||
brute_resist = 0.25
|
||||
brute_resist = BLOB_BRUTE_RESIST * 0.5
|
||||
else
|
||||
icon_state = "blob"
|
||||
name = "dead blob"
|
||||
desc = "A thick wall of lifeless tendrils."
|
||||
brute_resist = 0.25
|
||||
brute_resist = BLOB_BRUTE_RESIST * 0.5
|
||||
|
||||
/obj/structure/blob/special // Generic type for nodes/factories/cores/resource
|
||||
// Core and node vars: claiming, pulsing and expanding
|
||||
/// The radius inside which (previously dead) blob tiles are 'claimed' again by the pulsing overmind. Very rarely used.
|
||||
var/claim_range = 0
|
||||
/// The radius inside which blobs are pulsed by this overmind. Does stuff like expanding, making blob spores from factories, make resources from nodes etc.
|
||||
var/pulse_range = 0
|
||||
/// The radius up to which this special structure naturally grows normal blobs.
|
||||
var/expand_range = 0
|
||||
|
||||
// Spore production vars: for core, factories, and nodes (with strains)
|
||||
var/mob/living/simple_animal/hostile/blob/blobbernaut/naut = null
|
||||
var/max_spores = 0
|
||||
var/list/spores = list()
|
||||
COOLDOWN_DECLARE(spore_delay)
|
||||
var/spore_cooldown = BLOBMOB_SPORE_SPAWN_COOLDOWN
|
||||
|
||||
// Area reinforcement vars: used by cores and nodes, for strains to modify
|
||||
/// Range this blob free upgrades to strong blobs at: for the core, and for strains
|
||||
var/strong_reinforce_range = 0
|
||||
/// Range this blob free upgrades to reflector blobs at: for the core, and for strains
|
||||
var/reflector_reinforce_range = 0
|
||||
|
||||
/obj/structure/blob/special/proc/reinforce_area(delta_time) // Used by cores and nodes to upgrade their surroundings
|
||||
if(strong_reinforce_range)
|
||||
for(var/obj/structure/blob/normal/B in range(strong_reinforce_range, src))
|
||||
if(DT_PROB(BLOB_REINFORCE_CHANCE, delta_time))
|
||||
B.change_to(/obj/structure/blob/shield/core, overmind)
|
||||
if(reflector_reinforce_range)
|
||||
for(var/obj/structure/blob/shield/B in range(reflector_reinforce_range, src))
|
||||
if(DT_PROB(BLOB_REINFORCE_CHANCE, delta_time))
|
||||
B.change_to(/obj/structure/blob/shield/reflective/core, overmind)
|
||||
|
||||
/obj/structure/blob/special/proc/pulse_area(mob/camera/blob/pulsing_overmind, claim_range = 10, pulse_range = 3, expand_range = 2)
|
||||
if(QDELETED(pulsing_overmind))
|
||||
pulsing_overmind = overmind
|
||||
Be_Pulsed()
|
||||
var/expanded = FALSE
|
||||
if(prob(70*(1/BLOB_EXPAND_CHANCE_MULTIPLIER)) && expand())
|
||||
expanded = TRUE
|
||||
var/list/blobs_to_affect = list()
|
||||
for(var/obj/structure/blob/B in urange(claim_range, src, 1))
|
||||
blobs_to_affect += B
|
||||
shuffle_inplace(blobs_to_affect)
|
||||
for(var/L in blobs_to_affect)
|
||||
var/obj/structure/blob/B = L
|
||||
if(!B.overmind && prob(30))
|
||||
B.overmind = pulsing_overmind //reclaim unclaimed, non-core blobs.
|
||||
B.update_icon()
|
||||
var/distance = get_dist(get_turf(src), get_turf(B))
|
||||
var/expand_probablity = max(20 - distance * 8, 1)
|
||||
if(B.Adjacent(src))
|
||||
expand_probablity = 20
|
||||
if(distance <= expand_range)
|
||||
var/can_expand = TRUE
|
||||
if(blobs_to_affect.len >= 120 && !(COOLDOWN_FINISHED(B, heal_timestamp)))
|
||||
can_expand = FALSE
|
||||
if(can_expand && COOLDOWN_FINISHED(B, pulse_timestamp) && prob(expand_probablity*BLOB_EXPAND_CHANCE_MULTIPLIER))
|
||||
if(!expanded)
|
||||
var/obj/structure/blob/newB = B.expand(null, null, !expanded) //expansion falls off with range but is faster near the blob causing the expansion
|
||||
if(newB)
|
||||
expanded = TRUE
|
||||
if(distance <= pulse_range)
|
||||
B.Be_Pulsed()
|
||||
|
||||
/obj/structure/blob/special/proc/produce_spores()
|
||||
if(naut)
|
||||
return
|
||||
if(spores.len >= max_spores)
|
||||
return
|
||||
if(!COOLDOWN_FINISHED(src, spore_delay))
|
||||
return
|
||||
COOLDOWN_START(src, spore_delay, spore_cooldown)
|
||||
var/mob/living/simple_animal/hostile/blob/blobspore/BS = new (loc, src)
|
||||
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)
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
/obj/structure/blob/core
|
||||
/obj/structure/blob/special/core
|
||||
name = "blob core"
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
icon_state = "blank_blob"
|
||||
desc = "A huge, pulsating yellow mass."
|
||||
max_integrity = 400
|
||||
max_integrity = BLOB_CORE_MAX_HP
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 75, ACID = 90)
|
||||
explosion_block = 6
|
||||
point_return = -1
|
||||
health_regen = 0 //we regen in Life() instead of when pulsed
|
||||
resistance_flags = LAVA_PROOF
|
||||
strong_reinforce_range = BLOB_CORE_STRONG_REINFORCE_RANGE
|
||||
reflector_reinforce_range = BLOB_CORE_REFLECTOR_REINFORCE_RANGE
|
||||
claim_range = BLOB_CORE_CLAIM_RANGE
|
||||
pulse_range = BLOB_CORE_PULSE_RANGE
|
||||
expand_range = BLOB_CORE_EXPAND_RANGE
|
||||
max_spores = BLOB_CORE_MAX_SPORES
|
||||
ignore_syncmesh_share = TRUE
|
||||
|
||||
/obj/structure/blob/core/Initialize(mapload, client/new_overmind = null, placed = 0)
|
||||
/obj/structure/blob/special/core/Initialize(mapload, client/new_overmind = null, placed = 0)
|
||||
GLOB.blob_cores += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
AddElement(/datum/element/point_of_interest)
|
||||
@@ -18,13 +25,14 @@
|
||||
if(!placed && !overmind)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
if(overmind)
|
||||
overmind.blobstrain.on_gain()
|
||||
update_icon()
|
||||
. = ..()
|
||||
|
||||
/obj/structure/blob/core/scannerreport()
|
||||
/obj/structure/blob/special/core/scannerreport()
|
||||
return "Directs the blob's expansion, gradually expands, and sustains nearby blob spores and blobbernauts."
|
||||
|
||||
/obj/structure/blob/core/update_icon()
|
||||
/obj/structure/blob/special/core/update_icon()
|
||||
cut_overlays()
|
||||
color = null
|
||||
var/mutable_appearance/blob_overlay = mutable_appearance('icons/mob/blob.dmi', "blob")
|
||||
@@ -33,7 +41,7 @@
|
||||
add_overlay(blob_overlay)
|
||||
add_overlay(mutable_appearance('icons/mob/blob.dmi', "blob_core_overlay"))
|
||||
|
||||
/obj/structure/blob/core/Destroy()
|
||||
/obj/structure/blob/special/core/Destroy()
|
||||
GLOB.blob_cores -= src
|
||||
if(overmind)
|
||||
overmind.blob_core = null
|
||||
@@ -41,17 +49,17 @@
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/structure/blob/core/ex_act(severity, target)
|
||||
/obj/structure/blob/special/core/ex_act(severity, target)
|
||||
var/damage = 50 - 10 * severity //remember, the core takes half brute damage, so this is 20/15/10 damage based on severity
|
||||
take_damage(damage, BRUTE, BOMB, 0)
|
||||
|
||||
/obj/structure/blob/core/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir, overmind_reagent_trigger = 1)
|
||||
/obj/structure/blob/special/core/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir, overmind_reagent_trigger = 1)
|
||||
. = ..()
|
||||
if(obj_integrity > 0)
|
||||
if(overmind) //we should have an overmind, but...
|
||||
overmind.update_health_hud()
|
||||
|
||||
/obj/structure/blob/core/process(delta_time)
|
||||
/obj/structure/blob/special/core/process(delta_time)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
if(!overmind)
|
||||
@@ -59,17 +67,16 @@
|
||||
if(overmind)
|
||||
overmind.blobstrain.core_process()
|
||||
overmind.update_health_hud()
|
||||
Pulse_Area(overmind, 12, 4, 3)
|
||||
for(var/obj/structure/blob/normal/B in range(1, src))
|
||||
if(DT_PROB(2.5, delta_time))
|
||||
B.change_to(/obj/structure/blob/shield/core, overmind)
|
||||
pulse_area(overmind, claim_range, pulse_range, expand_range)
|
||||
reinforce_area(delta_time)
|
||||
produce_spores()
|
||||
..()
|
||||
|
||||
/obj/structure/blob/core/ComponentInitialize()
|
||||
/obj/structure/blob/special/core/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/stationloving, FALSE, TRUE)
|
||||
|
||||
/obj/structure/blob/core/onTransitZ(old_z, new_z)
|
||||
/obj/structure/blob/special/core/onTransitZ(old_z, new_z)
|
||||
if(overmind && is_station_level(new_z))
|
||||
overmind.forceMove(get_turf(src))
|
||||
return ..()
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
/obj/structure/blob/factory
|
||||
/obj/structure/blob/special/factory
|
||||
name = "factory blob"
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
icon_state = "blob_factory"
|
||||
desc = "A thick spire of tendrils."
|
||||
max_integrity = 200
|
||||
health_regen = 1
|
||||
point_return = 25
|
||||
max_integrity = BLOB_FACTORY_MAX_HP
|
||||
health_regen = BLOB_FACTORY_HP_REGEN
|
||||
point_return = BLOB_REFUND_FACTORY_COST
|
||||
resistance_flags = LAVA_PROOF
|
||||
var/list/spores = list()
|
||||
var/mob/living/simple_animal/hostile/blob/blobbernaut/naut = null
|
||||
var/max_spores = 3
|
||||
var/spore_delay = 0
|
||||
var/spore_cooldown = 80 //8 seconds between spores and after spore death
|
||||
max_spores = BLOB_FACTORY_MAX_SPORES
|
||||
|
||||
|
||||
/obj/structure/blob/factory/scannerreport()
|
||||
/obj/structure/blob/special/factory/scannerreport()
|
||||
if(naut)
|
||||
return "It is currently sustaining a blobbernaut, making it fragile and unable to produce blob spores."
|
||||
return "Will produce a blob spore every few seconds."
|
||||
|
||||
/obj/structure/blob/factory/Destroy()
|
||||
/obj/structure/blob/special/factory/creation_action()
|
||||
if(overmind)
|
||||
overmind.factory_blobs += src
|
||||
|
||||
/obj/structure/blob/special/factory/Destroy()
|
||||
for(var/mob/living/simple_animal/hostile/blob/blobspore/spore in spores)
|
||||
if(spore.factory == src)
|
||||
spore.factory = null
|
||||
@@ -28,20 +27,10 @@
|
||||
to_chat(naut, "<span class='userdanger'>Your factory was destroyed! You feel yourself dying!</span>")
|
||||
naut.throw_alert("nofactory", /atom/movable/screen/alert/nofactory)
|
||||
spores = null
|
||||
if(overmind)
|
||||
overmind.factory_blobs -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/blob/factory/Be_Pulsed()
|
||||
/obj/structure/blob/special/factory/Be_Pulsed()
|
||||
. = ..()
|
||||
if(naut)
|
||||
return
|
||||
if(spores.len >= max_spores)
|
||||
return
|
||||
if(spore_delay > world.time)
|
||||
return
|
||||
flick("blob_factory_glow", src)
|
||||
spore_delay = world.time + spore_cooldown
|
||||
var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore(src.loc, src)
|
||||
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)
|
||||
produce_spores()
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
/obj/structure/blob/node
|
||||
/obj/structure/blob/special/node
|
||||
name = "blob node"
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
icon_state = "blank_blob"
|
||||
desc = "A large, pulsating yellow mass."
|
||||
max_integrity = 200
|
||||
max_integrity = BLOB_NODE_MAX_HP
|
||||
health_regen = BLOB_NODE_HP_REGEN
|
||||
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
|
||||
point_return = BLOB_REFUND_NODE_COST
|
||||
claim_range = BLOB_NODE_CLAIM_RANGE
|
||||
pulse_range = BLOB_NODE_PULSE_RANGE
|
||||
expand_range = BLOB_NODE_EXPAND_RANGE
|
||||
resistance_flags = LAVA_PROOF
|
||||
max_spores = BLOB_NODE_MAX_SPORES
|
||||
ignore_syncmesh_share = TRUE
|
||||
|
||||
|
||||
/obj/structure/blob/node/Initialize()
|
||||
/obj/structure/blob/special/node/Initialize()
|
||||
GLOB.blob_nodes += src
|
||||
START_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/structure/blob/node/scannerreport()
|
||||
/obj/structure/blob/special/node/scannerreport()
|
||||
return "Gradually expands and sustains nearby blob spores and blobbernauts."
|
||||
|
||||
/obj/structure/blob/node/update_icon()
|
||||
/obj/structure/blob/special/node/update_icon()
|
||||
cut_overlays()
|
||||
color = null
|
||||
var/mutable_appearance/blob_overlay = mutable_appearance('icons/mob/blob.dmi', "blob")
|
||||
@@ -27,11 +32,19 @@
|
||||
add_overlay(blob_overlay)
|
||||
add_overlay(mutable_appearance('icons/mob/blob.dmi', "blob_node_overlay"))
|
||||
|
||||
/obj/structure/blob/node/Destroy()
|
||||
/obj/structure/blob/special/node/creation_action()
|
||||
if(overmind)
|
||||
overmind.node_blobs += src
|
||||
|
||||
/obj/structure/blob/special/node/Destroy()
|
||||
GLOB.blob_nodes -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
if(overmind)
|
||||
overmind.node_blobs -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/blob/node/process()
|
||||
/obj/structure/blob/special/node/process(delta_time)
|
||||
if(overmind)
|
||||
Pulse_Area(overmind, 10, 3, 2)
|
||||
pulse_area(overmind, claim_range, pulse_range, expand_range)
|
||||
reinforce_area(delta_time)
|
||||
produce_spores()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/structure/blob/resource
|
||||
/obj/structure/blob/special/resource
|
||||
name = "resource blob"
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
icon_state = "blob_resource"
|
||||
@@ -8,25 +8,25 @@
|
||||
resistance_flags = LAVA_PROOF
|
||||
var/resource_delay = 0
|
||||
|
||||
/obj/structure/blob/resource/scannerreport()
|
||||
/obj/structure/blob/special/resource/scannerreport()
|
||||
return "Gradually supplies the blob with resources, increasing the rate of expansion."
|
||||
|
||||
/obj/structure/blob/resource/creation_action()
|
||||
/obj/structure/blob/special/resource/creation_action()
|
||||
if(overmind)
|
||||
overmind.resource_blobs += src
|
||||
|
||||
/obj/structure/blob/resource/Destroy()
|
||||
/obj/structure/blob/special/resource/Destroy()
|
||||
if(overmind)
|
||||
overmind.resource_blobs -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/blob/resource/Be_Pulsed()
|
||||
/obj/structure/blob/special/resource/Be_Pulsed()
|
||||
. = ..()
|
||||
if(resource_delay > world.time)
|
||||
return
|
||||
flick("blob_resource_glow", src)
|
||||
if(overmind)
|
||||
overmind.add_points(1)
|
||||
resource_delay = world.time + 40 + overmind.resource_blobs.len * 2.5 //4 seconds plus a quarter second for each resource blob the overmind has
|
||||
overmind.add_points(BLOB_RESOURCE_GATHER_AMOUNT)
|
||||
resource_delay = world.time + BLOB_RESOURCE_GATHER_DELAY + overmind.resource_blobs.len * BLOB_RESOURCE_GATHER_ADDED_DELAY //4 seconds plus a quarter second for each resource blob the overmind has
|
||||
else
|
||||
resource_delay = world.time + 40
|
||||
resource_delay = world.time + BLOB_RESOURCE_GATHER_DELAY
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
desc = "A solid wall of slightly twitching tendrils."
|
||||
var/damaged_desc = "A wall of twitching tendrils."
|
||||
max_integrity = 150
|
||||
brute_resist = 0.25
|
||||
health_regen = BLOB_STRONG_HP_REGEN
|
||||
brute_resist = BLOB_BRUTE_RESIST * 0.5
|
||||
explosion_block = 3
|
||||
point_return = 4
|
||||
point_return = BLOB_REFUND_STRONG_COST
|
||||
atmosblock = TRUE
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 90, ACID = 90)
|
||||
|
||||
@@ -16,7 +17,7 @@
|
||||
return "Will prevent the spread of atmospheric changes."
|
||||
return "N/A"
|
||||
|
||||
/obj/structure/blob/shield/core
|
||||
/obj/structure/blob/shield/core // Automatically generated by the core
|
||||
point_return = 0
|
||||
|
||||
/obj/structure/blob/shield/update_icon()
|
||||
@@ -40,5 +41,10 @@
|
||||
damaged_desc = "A wall of twitching tendrils with a reflective glow."
|
||||
icon_state = "blob_glow"
|
||||
flags_ricochet = RICOCHET_SHINY
|
||||
point_return = 8
|
||||
point_return = BLOB_REFUND_REFLECTOR_COST
|
||||
explosion_block = 2
|
||||
max_integrity = BLOB_REFLECTOR_MAX_HP
|
||||
health_regen = BLOB_REFLECTOR_HP_REGEN
|
||||
|
||||
/obj/structure/blob/shield/reflective/core // Automatically generated by the core
|
||||
point_return = 0
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
. = new_slime
|
||||
qdel(src)
|
||||
|
||||
/mob/proc/become_overmind(starting_points = 60)
|
||||
/mob/proc/become_overmind(starting_points = OVERMIND_STARTING_POINTS)
|
||||
var/mob/camera/blob/B = new /mob/camera/blob(get_turf(src), starting_points)
|
||||
B.key = key
|
||||
. = B
|
||||
|
||||
Reference in New Issue
Block a user