mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 18:53:06 +00:00
Works on New Blob
This commit is contained in:
298
code/modules/blob2/blobs/base_blob.dm
Normal file
298
code/modules/blob2/blobs/base_blob.dm
Normal file
@@ -0,0 +1,298 @@
|
||||
var/list/blobs = list()
|
||||
|
||||
/obj/structure/blob
|
||||
name = "blob"
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
desc = "A thick wall of writhing tendrils."
|
||||
light_range = 2
|
||||
density = FALSE // This is false because blob mob AI's walk_to() proc appears to never attempt to move onto dense objects even if allowed by CanPass().
|
||||
opacity = FALSE
|
||||
anchored = TRUE
|
||||
layer = MOB_LAYER + 0.1
|
||||
var/integrity = 0
|
||||
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.
|
||||
var/max_integrity = 30
|
||||
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/mob/observer/blob/overmind = null
|
||||
var/base_name = "blob" // The name that gets appended along with the blob_type's name.
|
||||
|
||||
/obj/structure/blob/New(var/newloc, var/new_overmind)
|
||||
..(newloc)
|
||||
if(new_overmind)
|
||||
overmind = new_overmind
|
||||
update_icon()
|
||||
if(!integrity)
|
||||
integrity = max_integrity
|
||||
set_dir(pick(cardinal))
|
||||
blobs += src
|
||||
consume_tile()
|
||||
|
||||
|
||||
/obj/structure/blob/Destroy()
|
||||
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) //Expand() is no longer broken, no check necessary.
|
||||
blobs -= src
|
||||
overmind = null
|
||||
return ..()
|
||||
|
||||
/obj/structure/blob/update_icon() //Updates color based on overmind color if we have an overmind.
|
||||
if(overmind)
|
||||
name = "[overmind.blob_type.name] [base_name]" // This is in update_icon() because inert blobs can turn into other blobs with magic if another blob core claims it with pulsing.
|
||||
color = overmind.blob_type.color
|
||||
set_light(3, 3, color)
|
||||
else
|
||||
name = "inert [base_name]"
|
||||
color = null
|
||||
set_light(0)
|
||||
|
||||
/obj/structure/blob/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(air_group || (height==0))
|
||||
return TRUE
|
||||
if(istype(mover) && mover.checkpass(PASSBLOB))
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
// return ..()
|
||||
|
||||
/obj/structure/blob/examine(mob/user)
|
||||
..()
|
||||
if(!overmind)
|
||||
to_chat(user, "It seems inert.") // Dead blob.
|
||||
else
|
||||
to_chat(user, overmind.blob_type.desc)
|
||||
|
||||
/obj/structure/blob/get_description_info()
|
||||
if(overmind)
|
||||
return overmind.blob_type.effect_desc
|
||||
return ..()
|
||||
|
||||
/obj/structure/blob/emp_act(severity)
|
||||
if(overmind)
|
||||
overmind.blob_type.on_emp(src, severity)
|
||||
|
||||
/obj/structure/blob/proc/pulsed()
|
||||
if(pulse_timestamp <= world.time)
|
||||
consume_tile()
|
||||
if(heal_timestamp <= world.time)
|
||||
adjust_integrity(health_regen)
|
||||
heal_timestamp = world.time + 2 SECONDS
|
||||
update_icon()
|
||||
pulse_timestamp = world.time + 1 SECOND
|
||||
if(overmind)
|
||||
overmind.blob_type.on_pulse(src)
|
||||
return TRUE //we did it, we were pulsed!
|
||||
return FALSE //oh no we failed
|
||||
|
||||
/obj/structure/blob/proc/pulse_area(pulsing_overmind = overmind, claim_range = 10, pulse_range = 3, expand_range = 2)
|
||||
src.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(50 / (max(distance, 1)), 1)
|
||||
if(overmind)
|
||||
expand_probablity *= overmind.blob_type.spread_modifier
|
||||
if(overmind.blob_type.slow_spread_with_size)
|
||||
expand_probablity /= (blobs.len / 10)
|
||||
|
||||
if(distance <= expand_range)
|
||||
var/can_expand = TRUE
|
||||
if(blobs_to_affect.len >= 120 && B.heal_timestamp > world.time)
|
||||
can_expand = FALSE
|
||||
if(!expanded && 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.pulsed()
|
||||
|
||||
/obj/structure/blob/proc/expand(turf/T = null, controller = null, expand_reaction = 1)
|
||||
if(!T)
|
||||
var/list/dirs = cardinal.Copy()
|
||||
for(var/i = 1 to 4)
|
||||
var/dirn = pick(dirs)
|
||||
dirs.Remove(dirn)
|
||||
T = get_step(src, dirn)
|
||||
if(!(locate(/obj/structure/blob) in T))
|
||||
break
|
||||
else
|
||||
T = null
|
||||
if(!T)
|
||||
return FALSE
|
||||
|
||||
var/make_blob = TRUE //can we make a blob?
|
||||
|
||||
if(istype(T, /turf/space) && !(locate(/obj/structure/lattice) in T) && prob(80))
|
||||
make_blob = FALSE
|
||||
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
|
||||
|
||||
consume_tile() //hit the tile we're in, making sure there are no border objects blocking us
|
||||
|
||||
if(!T.CanPass(src, T)) //is the target turf impassable
|
||||
make_blob = FALSE
|
||||
T.blob_act(src) //hit the turf if it is
|
||||
|
||||
for(var/atom/A in T)
|
||||
if(!A.CanPass(src, T)) //is anything in the turf impassable
|
||||
make_blob = FALSE
|
||||
A.blob_act(src) //also hit everything in the turf
|
||||
|
||||
if(make_blob) //well, can we?
|
||||
var/obj/structure/blob/B = new /obj/structure/blob/normal(src.loc)
|
||||
if(controller)
|
||||
B.overmind = controller
|
||||
else
|
||||
B.overmind = overmind
|
||||
B.density = TRUE
|
||||
if(T.Enter(B,src)) //NOW we can attempt to move into the tile
|
||||
sleep(1) // To have the slide animation work.
|
||||
B.density = initial(B.density)
|
||||
B.forceMove(T)
|
||||
B.update_icon()
|
||||
if(B.overmind && expand_reaction)
|
||||
B.overmind.blob_type.on_expand(src, B, T, B.overmind)
|
||||
return B
|
||||
|
||||
else
|
||||
blob_attack_animation(T, controller)
|
||||
T.blob_act(src) //if we can't move in hit the turf again
|
||||
qdel(B) //we should never get to this point, since we checked before moving in. destroy the blob so we don't have two blobs on one tile
|
||||
return null
|
||||
else
|
||||
blob_attack_animation(T, controller) //if we can't, animate that we attacked
|
||||
return null
|
||||
|
||||
/obj/structure/blob/proc/consume_tile()
|
||||
for(var/atom/A in loc)
|
||||
A.blob_act(src)
|
||||
if(loc && loc.density)
|
||||
loc.blob_act(src) //don't ask how a wall got on top of the core, just eat it
|
||||
|
||||
/obj/structure/blob/proc/blob_glow_animation()
|
||||
flick("[icon_state]_glow", src)
|
||||
|
||||
/obj/structure/blob/proc/blob_attack_animation(atom/A = null, controller) //visually attacks an atom
|
||||
var/obj/effect/temporary_effect/blob_attack/O = new /obj/effect/temporary_effect/blob_attack(src.loc)
|
||||
O.set_dir(dir)
|
||||
if(controller)
|
||||
var/mob/observer/blob/BO = controller
|
||||
O.color = BO.blob_type.color
|
||||
O.alpha = 200
|
||||
else if(overmind)
|
||||
O.color = overmind.blob_type.color
|
||||
if(A)
|
||||
O.do_attack_animation(A) //visually attack the whatever
|
||||
return O //just in case you want to do something to the animation.
|
||||
|
||||
/obj/structure/blob/proc/change_to(type, controller)
|
||||
if(!ispath(type))
|
||||
throw EXCEPTION("change_to(): invalid type for blob")
|
||||
return
|
||||
var/obj/structure/blob/B = new type(src.loc, controller)
|
||||
if(controller)
|
||||
B.overmind = controller
|
||||
B.update_icon()
|
||||
B.set_dir(dir)
|
||||
qdel(src)
|
||||
return B
|
||||
|
||||
/obj/structure/blob/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
playsound(loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
visible_message("<span class='danger'>\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]</span>")
|
||||
var/damage = W.force
|
||||
switch(W.damtype)
|
||||
if(BURN)
|
||||
if(overmind)
|
||||
damage *= overmind.blob_type.burn_multiplier
|
||||
else
|
||||
damage *= 2
|
||||
|
||||
if(damage > 0)
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
|
||||
else
|
||||
playsound(src, 'sound/weapons/tap.ogg', 50, 1)
|
||||
if(BRUTE)
|
||||
if(overmind)
|
||||
damage *= overmind.blob_type.brute_multiplier
|
||||
else
|
||||
damage *= 2
|
||||
|
||||
if(damage > 0)
|
||||
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
else
|
||||
playsound(src, 'sound/weapons/tap.ogg', 50, 1)
|
||||
if(overmind)
|
||||
damage = overmind.blob_type.on_received_damage(src, damage, W.damtype, user)
|
||||
adjust_integrity(-damage)
|
||||
return
|
||||
|
||||
/obj/structure/blob/bullet_act(var/obj/item/projectile/P)
|
||||
if(!P)
|
||||
return
|
||||
|
||||
var/damage = P.damage
|
||||
switch(P.damage_type)
|
||||
if(BRUTE)
|
||||
if(overmind)
|
||||
damage *= overmind.blob_type.brute_multiplier
|
||||
if(BURN)
|
||||
if(overmind)
|
||||
damage *= overmind.blob_type.burn_multiplier
|
||||
|
||||
if(overmind)
|
||||
damage = overmind.blob_type.on_received_damage(src, damage, P.damage_type, P.firer)
|
||||
|
||||
adjust_integrity(-damage)
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/structure/blob/water_act(amount)
|
||||
if(overmind)
|
||||
overmind.blob_type.on_water(src, amount)
|
||||
|
||||
/obj/structure/blob/proc/adjust_integrity(amount)
|
||||
integrity = between(0, integrity + amount, max_integrity)
|
||||
if(integrity == 0)
|
||||
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
if(overmind)
|
||||
overmind.blob_type.on_death(src)
|
||||
qdel(src)
|
||||
else
|
||||
update_icon()
|
||||
|
||||
/obj/effect/temporary_effect/blob_attack
|
||||
name = "blob"
|
||||
desc = "The blob lashing out at something."
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "blob_attack"
|
||||
layer = 5.2
|
||||
time_to_die = 6
|
||||
alpha = 140
|
||||
invisibility = 0
|
||||
mouse_opacity = 0
|
||||
new_light_range = 0
|
||||
new_light_power = 0
|
||||
|
||||
/obj/structure/grille/blob_act()
|
||||
qdel(src)
|
||||
|
||||
/turf/simulated/wall/blob_act()
|
||||
take_damage(100)
|
||||
179
code/modules/blob2/blobs/core.dm
Normal file
179
code/modules/blob2/blobs/core.dm
Normal file
@@ -0,0 +1,179 @@
|
||||
var/list/blob_cores = list()
|
||||
|
||||
/obj/structure/blob/core
|
||||
name = "blob core"
|
||||
base_name = "core"
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
icon_state = "blank_blob"
|
||||
desc = "A huge, pulsating yellow mass."
|
||||
max_integrity = 150
|
||||
point_return = -1
|
||||
health_regen = 0 //we regen in Life() instead of when pulsed
|
||||
var/datum/blob_type/desired_blob_type = null // If this is set, the core always creates an overmind possessing this blob type.
|
||||
var/difficulty_threshold = null // Otherwise if this is set, it picks a random blob_type that is equal or lower in difficulty.
|
||||
var/core_regen = 2
|
||||
var/overmind_get_delay = 0 //we don't want to constantly try to find an overmind, this var tracks when we'll try to get an overmind again
|
||||
var/resource_delay = 0
|
||||
var/point_rate = 2
|
||||
var/ai_controlled = TRUE
|
||||
|
||||
// Spawn this if you want a ghost to be able to play as the blob.
|
||||
/obj/structure/blob/core/player
|
||||
ai_controlled = FALSE
|
||||
|
||||
// Spawn these if you want a semi-random blob.
|
||||
/obj/structure/blob/core/random_easy
|
||||
difficulty_threshold = BLOB_DIFFICULTY_EASY
|
||||
|
||||
/obj/structure/blob/core/random_medium
|
||||
difficulty_threshold = BLOB_DIFFICULTY_MEDIUM
|
||||
|
||||
/obj/structure/blob/core/random_hard
|
||||
difficulty_threshold = BLOB_DIFFICULTY_HARD
|
||||
|
||||
// Spawn these if you want a specific blob.
|
||||
/obj/structure/blob/core/blazing_oil
|
||||
desired_blob_type = /datum/blob_type/blazing_oil
|
||||
|
||||
/obj/structure/blob/core/grey_goo
|
||||
desired_blob_type = /datum/blob_type/grey_goo
|
||||
|
||||
/obj/structure/blob/core/electromagnetic_web
|
||||
desired_blob_type = /datum/blob_type/electromagnetic_web
|
||||
|
||||
/obj/structure/blob/core/fungal_bloom
|
||||
desired_blob_type = /datum/blob_type/fungal_bloom
|
||||
|
||||
/obj/structure/blob/core/fulminant_organism
|
||||
desired_blob_type = /datum/blob_type/fulminant_organism
|
||||
|
||||
/obj/structure/blob/core/reactive_spines
|
||||
desired_blob_type = /datum/blob_type/reactive_spines
|
||||
|
||||
/obj/structure/blob/core/synchronous_mesh
|
||||
desired_blob_type = /datum/blob_type/synchronous_mesh
|
||||
|
||||
/obj/structure/blob/core/shifting_fragments
|
||||
desired_blob_type = /datum/blob_type/shifting_fragments
|
||||
|
||||
/obj/structure/blob/core/cryogenic_goo
|
||||
desired_blob_type = /datum/blob_type/cryogenic_goo
|
||||
|
||||
/obj/structure/blob/core/energized_jelly
|
||||
desired_blob_type = /datum/blob_type/energized_jelly
|
||||
|
||||
/obj/structure/blob/core/explosive_lattice
|
||||
desired_blob_type = /datum/blob_type/explosive_lattice
|
||||
|
||||
/obj/structure/blob/core/pressurized_slime
|
||||
desired_blob_type = /datum/blob_type/pressurized_slime
|
||||
|
||||
/obj/structure/blob/core/radioactive_ooze
|
||||
desired_blob_type = /datum/blob_type/radioactive_ooze
|
||||
|
||||
/obj/structure/blob/core/classic
|
||||
desired_blob_type = /datum/blob_type/classic
|
||||
|
||||
/obj/structure/blob/core/New(var/newloc, var/client/new_overmind = null, new_rate = 2, placed = 0)
|
||||
..(newloc)
|
||||
blob_cores += src
|
||||
processing_objects += src
|
||||
update_icon() //so it atleast appears
|
||||
if(!placed && !overmind)
|
||||
create_overmind(new_overmind)
|
||||
if(overmind)
|
||||
update_icon()
|
||||
point_rate = new_rate
|
||||
|
||||
/obj/structure/blob/core/Destroy()
|
||||
blob_cores -= src
|
||||
if(overmind)
|
||||
overmind.blob_core = null
|
||||
qdel(overmind)
|
||||
overmind = null
|
||||
processing_objects -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/blob/core/update_icon()
|
||||
overlays.Cut()
|
||||
color = null
|
||||
var/mutable_appearance/blob_overlay = mutable_appearance('icons/mob/blob.dmi', "blob")
|
||||
if(overmind)
|
||||
blob_overlay.color = overmind.blob_type.color
|
||||
name = "[overmind.blob_type.name] [base_name]"
|
||||
overlays += blob_overlay
|
||||
overlays += mutable_appearance('icons/mob/blob.dmi', "blob_core_overlay")
|
||||
|
||||
/obj/structure/blob/core/process()
|
||||
set waitfor = FALSE
|
||||
if(QDELETED(src))
|
||||
return
|
||||
if(!overmind)
|
||||
spawn(0)
|
||||
create_overmind()
|
||||
else
|
||||
if(resource_delay <= world.time)
|
||||
resource_delay = world.time + 1 SECOND
|
||||
overmind.add_points(point_rate)
|
||||
integrity = min(max_integrity, integrity + core_regen)
|
||||
// if(overmind)
|
||||
// overmind.update_health_hud()
|
||||
pulse_area(overmind, 15, BLOB_CORE_PULSE_RANGE, BLOB_CORE_EXPAND_RANGE)
|
||||
for(var/obj/structure/blob/normal/B in range(1, src))
|
||||
if(prob(5))
|
||||
B.change_to(/obj/structure/blob/shield/core, overmind)
|
||||
|
||||
/obj/structure/blob/core/proc/create_overmind(client/new_overmind, override_delay)
|
||||
if(overmind_get_delay > world.time && !override_delay)
|
||||
return
|
||||
if(!ai_controlled) // Do we want a bona fide player blob?
|
||||
overmind_get_delay = world.time + 15 SECONDS //if this fails, we'll try again in 15 seconds
|
||||
|
||||
if(overmind)
|
||||
qdel(overmind)
|
||||
|
||||
|
||||
var/client/C = null
|
||||
if(!new_overmind)
|
||||
var/datum/ghost_query/Q = new /datum/ghost_query/blob()
|
||||
var/list/winner = Q.query()
|
||||
if(winner.len)
|
||||
var/mob/observer/dead/D = winner[1]
|
||||
C = D.client
|
||||
|
||||
else
|
||||
C = new_overmind
|
||||
|
||||
if(C)
|
||||
if(!desired_blob_type && !isnull(difficulty_threshold))
|
||||
desired_blob_type = get_random_blob_type()
|
||||
var/mob/observer/blob/B = new(loc, TRUE, 60, desired_blob_type)
|
||||
B.key = C.key
|
||||
B.blob_core = src
|
||||
src.overmind = B
|
||||
update_icon()
|
||||
if(B.mind && !B.mind.special_role)
|
||||
B.mind.special_role = "Blob Overmind"
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
else // An AI opponent.
|
||||
if(!desired_blob_type && !isnull(difficulty_threshold))
|
||||
desired_blob_type = get_random_blob_type()
|
||||
var/mob/observer/blob/B = new(loc, TRUE, 60, desired_blob_type)
|
||||
overmind = B
|
||||
B.blob_core = src
|
||||
B.ai_controlled = TRUE
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/blob/core/proc/get_random_blob_type()
|
||||
if(!difficulty_threshold)
|
||||
return
|
||||
var/list/valid_types = list()
|
||||
for(var/thing in subtypesof(/datum/blob_type))
|
||||
var/datum/blob_type/BT = thing
|
||||
if(initial(BT.difficulty) > difficulty_threshold)
|
||||
continue
|
||||
valid_types += BT
|
||||
return pick(valid_types)
|
||||
37
code/modules/blob2/blobs/factory.dm
Normal file
37
code/modules/blob2/blobs/factory.dm
Normal file
@@ -0,0 +1,37 @@
|
||||
/obj/structure/blob/factory
|
||||
name = "factory blob"
|
||||
base_name = "factory"
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
icon_state = "blob_factory"
|
||||
desc = "A thick spire of tendrils."
|
||||
description_info = "A section of the blob that creates numerous hostile entities to attack enemies of the blob. \
|
||||
It requires a 'node' blob be nearby, or it will cease functioning."
|
||||
max_integrity = 40
|
||||
health_regen = 1
|
||||
point_return = 25
|
||||
var/list/spores = list()
|
||||
var/max_spores = 3
|
||||
var/spore_delay = 0
|
||||
var/spore_cooldown = 8 SECONDS
|
||||
|
||||
/obj/structure/blob/factory/Destroy()
|
||||
for(var/mob/living/simple_animal/hostile/blob/spore/spore in spores)
|
||||
if(spore.factory == src)
|
||||
spore.factory = null
|
||||
spores = null
|
||||
return ..()
|
||||
|
||||
/obj/structure/blob/factory/pulsed()
|
||||
. = ..()
|
||||
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/spore/S = null
|
||||
if(overmind)
|
||||
S = new overmind.blob_type.spore_type(src.loc, src)
|
||||
S.overmind = overmind
|
||||
S.update_icons()
|
||||
overmind.blob_mobs.Add(S)
|
||||
36
code/modules/blob2/blobs/node.dm
Normal file
36
code/modules/blob2/blobs/node.dm
Normal file
@@ -0,0 +1,36 @@
|
||||
var/list/blob_nodes = list()
|
||||
|
||||
/obj/structure/blob/node
|
||||
name = "blob node"
|
||||
base_name = "node"
|
||||
icon_state = "blank_blob"
|
||||
desc = "A large, pulsating yellow mass."
|
||||
max_integrity = 50
|
||||
health_regen = 3
|
||||
point_return = 50
|
||||
|
||||
/obj/structure/blob/node/New(var/newloc)
|
||||
..()
|
||||
blob_nodes += src
|
||||
processing_objects += src
|
||||
update_icon()
|
||||
|
||||
/obj/structure/blob/node/Destroy()
|
||||
blob_nodes -= src
|
||||
processing_objects -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/blob/node/update_icon()
|
||||
overlays.Cut()
|
||||
color = null
|
||||
var/mutable_appearance/blob_overlay = mutable_appearance('icons/mob/blob.dmi', "blob")
|
||||
if(overmind)
|
||||
name = "[overmind.blob_type.name] [base_name]"
|
||||
blob_overlay.color = overmind.blob_type.color
|
||||
overlays += blob_overlay
|
||||
overlays += mutable_appearance('icons/mob/blob.dmi', "blob_node_overlay")
|
||||
|
||||
/obj/structure/blob/node/process()
|
||||
set waitfor = FALSE
|
||||
if(overmind) // This check is so that if the core is killed, the nodes stop.
|
||||
pulse_area(overmind, 10, BLOB_NODE_PULSE_RANGE, BLOB_NODE_EXPAND_RANGE)
|
||||
22
code/modules/blob2/blobs/normal.dm
Normal file
22
code/modules/blob2/blobs/normal.dm
Normal file
@@ -0,0 +1,22 @@
|
||||
/obj/structure/blob/normal
|
||||
name = "normal blob"
|
||||
base_name = "blob"
|
||||
icon_state = "blob"
|
||||
light_range = 0
|
||||
integrity = 21 //doesn't start at full health
|
||||
max_integrity = 25
|
||||
health_regen = 1
|
||||
|
||||
/obj/structure/blob/normal/update_icon()
|
||||
..()
|
||||
if(integrity <= 15)
|
||||
icon_state = "blob_damaged"
|
||||
desc = "A thin lattice of slightly twitching tendrils."
|
||||
else
|
||||
icon_state = "blob"
|
||||
desc = "A thick wall of writhing tendrils."
|
||||
|
||||
if(overmind)
|
||||
name = "[overmind.blob_type.name]"
|
||||
else
|
||||
name = "inert [base_name]"
|
||||
30
code/modules/blob2/blobs/resource.dm
Normal file
30
code/modules/blob2/blobs/resource.dm
Normal file
@@ -0,0 +1,30 @@
|
||||
/obj/structure/blob/resource
|
||||
name = "resource blob"
|
||||
base_name = "resource blob"
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
icon_state = "blob_resource"
|
||||
desc = "A thin spire of slightly swaying tendrils."
|
||||
max_integrity = 40
|
||||
point_return = 15
|
||||
var/resource_delay = 0
|
||||
|
||||
/obj/structure/blob/resource/New(var/newloc, var/new_overmind)
|
||||
..(newloc, new_overmind)
|
||||
if(overmind)
|
||||
overmind.resource_blobs += src
|
||||
|
||||
/obj/structure/blob/resource/Destroy()
|
||||
if(overmind)
|
||||
overmind.resource_blobs -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/blob/resource/pulsed()
|
||||
. = ..()
|
||||
if(resource_delay > world.time)
|
||||
return
|
||||
flick("blob_resource_glow", src)
|
||||
if(overmind)
|
||||
overmind.add_points(1)
|
||||
resource_delay = world.time + 4 SECONDS + (overmind.resource_blobs.len * 2.5) //4 seconds plus a quarter second for each resource blob the overmind has
|
||||
else
|
||||
resource_delay = world.time + 4 SECONDS
|
||||
25
code/modules/blob2/blobs/shield.dm
Normal file
25
code/modules/blob2/blobs/shield.dm
Normal file
@@ -0,0 +1,25 @@
|
||||
/obj/structure/blob/shield
|
||||
name = "thick blob"
|
||||
base_name = "thick"
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
icon_state = "blob_shield"
|
||||
desc = "A solid wall of slightly twitching tendrils."
|
||||
max_integrity = 100
|
||||
point_return = 4
|
||||
|
||||
/obj/structure/blob/shield/core
|
||||
point_return = 0
|
||||
|
||||
/obj/structure/blob/shield/update_icon()
|
||||
..()
|
||||
if(integrity <= 75)
|
||||
icon_state = "blob_shield_damaged"
|
||||
desc = "A wall of twitching tendrils."
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
desc = initial(desc)
|
||||
|
||||
if(overmind)
|
||||
name = "[base_name] [overmind.blob_type.name]"
|
||||
else
|
||||
name = "inert [base_name] blob"
|
||||
Reference in New Issue
Block a user