Moves blob chunk effects to artifact effects. (#8783)

* Sweating Reagents

* Hot & Cold

* Faraday

* Electric Snakebite

* Blast shielding

* Knock out all the other trivial/already-existing-artifact-effect types

* Extinguisher

* 2fort

* Sprinting

* This artifact qualifies as a member of the police.

* Noxious gases

* Necromancy!

* Necromancy 2!

* Delete blob chunk
This commit is contained in:
Atermonera
2023-01-15 10:55:52 -08:00
committed by GitHub
parent 2903c367bd
commit f473ed9717
42 changed files with 509 additions and 572 deletions
-3
View File
@@ -110,9 +110,6 @@ var/global/list/blob_cores = list()
point_rate = new_rate
/obj/structure/blob/core/Destroy()
var/turf/T = get_turf(src)
new /obj/item/blobcore_chunk(T, overmind.blob_type)
blob_cores -= src
if(overmind)
overmind.blob_core = null
-153
View File
@@ -1,153 +0,0 @@
/obj/item/blobcore_chunk
name = "core chunk"
desc = "The remains of some strange life-form. It smells awful."
description_info = "Some blob types will have core effects when the chunk is used in-hand, toggled with an alt click, or constantly active."
icon = 'icons/mob/blob.dmi'
icon_state = "blobcore"
atom_flags = ATOM_REAGENTS_IS_OPEN
var/datum/blob_type/blob_type // The blob type this dropped from.
var/active_ability_cooldown = 20 SECONDS
var/last_active_use = 0
var/should_tick = TRUE // Incase it's a toggle.
var/passive_ability_cooldown = 5 SECONDS
var/last_passive_use = 0
var/can_genesis = TRUE // Can the core chunk be used to grow a new blob?
drop_sound = 'sound/effects/slime_squish.ogg'
/obj/item/blobcore_chunk/is_open_container()
return 1
/obj/item/blobcore_chunk/Initialize(var/ml, var/datum/blob_type/parentblob = null)
. = ..(ml)
create_reagents(120)
setup_blobtype(parentblob)
/obj/item/blobcore_chunk/Destroy()
STOP_PROCESSING(SSobj, src)
blob_type = null
..()
/obj/item/blobcore_chunk/proc/setup_blobtype(var/datum/blob_type/parentblob = null)
if(!parentblob)
name = "inert [initial(name)]"
else
blob_type = parentblob
name = "[blob_type.name] [initial(name)]"
if(blob_type)
color = blob_type.color
if(LAZYLEN(blob_type.core_tech))
origin_tech = blob_type.core_tech.Copy()
if(blob_type.chunk_active_type == BLOB_CHUNK_CONSTANT)
should_tick = TRUE
else if(blob_type.chunk_active_type == BLOB_CHUNK_TOGGLE)
should_tick = FALSE
active_ability_cooldown = blob_type.chunk_active_ability_cooldown
passive_ability_cooldown = blob_type.chunk_passive_ability_cooldown
blob_type.chunk_setup(src)
START_PROCESSING(SSobj, src)
/obj/item/blobcore_chunk/proc/call_chunk_unique()
if(blob_type)
blob_type.chunk_unique(src, args)
return
/obj/item/blobcore_chunk/proc/get_carrier(var/atom/target)
var/atom/A = target ? target.loc : src
if(isturf(A) || isarea(A)) // Something has gone horribly wrong if the second is true.
return FALSE // No mob is carrying us.
if(!istype(A, /mob/living))
A = get_carrier(A)
return A
/obj/item/blobcore_chunk/blob_act(obj/structure/blob/B)
if(B.overmind && !blob_type)
setup_blobtype(B.overmind.blob_type)
return
/obj/item/blobcore_chunk/attack_self(var/mob/user)
if(blob_type && world.time > active_ability_cooldown + last_active_use)
last_active_use = world.time
to_chat(user, "<span class='alien'>\icon [src] \The [src] gesticulates.</span>")
blob_type.on_chunk_use(src, user)
else
to_chat(user, "<span class='notice'>\The [src] doesn't seem to respond.</span>")
..()
/obj/item/blobcore_chunk/process()
if(blob_type && should_tick && world.time > passive_ability_cooldown + last_passive_use)
last_passive_use = world.time
blob_type.on_chunk_tick(src)
/obj/item/blobcore_chunk/AltClick(mob/living/carbon/user)
if(blob_type && blob_type.chunk_active_type == BLOB_CHUNK_TOGGLE)
should_tick = !should_tick
if(should_tick)
to_chat(user, "<span class='alien'>\The [src] shudders with life.</span>")
else
to_chat(user, "<span class='alien'>\The [src] stills, returning to a death-like state.</span>")
/obj/item/blobcore_chunk/proc/regen(var/newfaction = null)
if(istype(blob_type))
if(newfaction)
blob_type.faction = newfaction
var/obj/structure/blob/core/NC = new (get_turf(src))
NC.overmind.blob_type = blob_type
NC.overmind.blob_core.update_icon()
return TRUE
return FALSE
/decl/chemical_reaction/instant/blob_reconstitution
name = "Hostile Blob Revival"
id = "blob_revival"
result = null
required_reagents = list("phoron" = 60)
result_amount = 1
/decl/chemical_reaction/instant/blob_reconstitution/can_happen(var/datum/reagents/holder)
if(holder.my_atom && istype(holder.my_atom, /obj/item/blobcore_chunk))
return ..()
return FALSE
/decl/chemical_reaction/instant/blob_reconstitution/on_reaction(var/datum/reagents/holder)
var/obj/item/blobcore_chunk/chunk = holder.my_atom
if(chunk.can_genesis && chunk.regen())
chunk.visible_message("<span class='notice'>[chunk] bubbles, surrounding itself with a rapidly expanding mass of [chunk.blob_type.name]!</span>")
chunk.can_genesis = FALSE
else
chunk.visible_message("<span class='warning'>[chunk] shifts strangely, but falls still.</span>")
/decl/chemical_reaction/instant/blob_reconstitution/domination
name = "Allied Blob Revival"
id = "blob_friend"
result = null
required_reagents = list("hydrophoron" = 40, "peridaxon" = 20, "mutagen" = 20)
result_amount = 1
/decl/chemical_reaction/instant/blob_reconstitution/domination/on_reaction(var/datum/reagents/holder)
var/obj/item/blobcore_chunk/chunk = holder.my_atom
if(chunk.can_genesis && chunk.regen("neutral"))
chunk.visible_message("<span class='notice'>[chunk] bubbles, surrounding itself with a rapidly expanding mass of [chunk.blob_type.name]!</span>")
chunk.can_genesis = FALSE
else
chunk.visible_message("<span class='warning'>[chunk] shifts strangely, but falls still.</span>")
-16
View File
@@ -95,19 +95,3 @@
// Spore handle_special call.
/datum/blob_type/proc/on_spore_lifetick(mob/living/simple_mob/blob/spore/S)
return
// Blob core chunk process.
/datum/blob_type/proc/on_chunk_tick(obj/item/blobcore_chunk/B)
return
// Blob core chunk use in-hand.
/datum/blob_type/proc/on_chunk_use(obj/item/blobcore_chunk/B, mob/user)
return
// Proc that is unique to the blob type.
/datum/blob_type/proc/chunk_unique(obj/item/blobcore_chunk/B, var/list/extra_args = null)
return
// Set up the blob type for the chunk.
/datum/blob_type/proc/chunk_setup(obj/item/blobcore_chunk/B)
return
@@ -13,28 +13,3 @@
brute_multiplier = 0.35
burn_multiplier = 0.8
/datum/blob_type/barnacle/on_chunk_use(obj/item/blobcore_chunk/B, mob/living/user)
var/turf/T = get_turf(B)
to_chat(user, "<span class='alien'>\The [B] produces a cauterizing ooze!</span>")
T.visible_message("<span class='alium'>\The [B] shudders at \the [user]'s touch, before disgorging a disgusting ooze.</span>", "<span class='notice'>A fleshy slop hits the ground.</span>", list(user))
for(var/turf/simulated/floor/F in view(2, T))
spawn()
var/obj/effect/vfx/water/splash = new(T)
splash.create_reagents(15)
splash.reagents.add_reagent("blood", 10,list("blood_colour" = color))
splash.set_color()
splash.set_up(F, 2, 3)
var/obj/effect/decal/cleanable/chemcoating/blood = locate() in T
if(!istype(blood))
blood = new(T)
blood.reagents.add_reagent("blood", 10,list("blood_colour" = color))
blood.reagents.add_reagent("dermalaze", 5)
blood.update_icon()
return
@@ -23,25 +23,3 @@
/datum/blob_type/blazing_oil/on_water(obj/structure/blob/B, amount)
spawn(1)
B.adjust_integrity(-(amount * 5))
/datum/blob_type/blazing_oil/on_pulse(var/obj/structure/blob/B)
var/turf/T = get_turf(B)
if(!T)
return
var/datum/gas_mixture/env = T.return_air()
if(env)
env.add_thermal_energy(10 * 1000)
/datum/blob_type/blazing_oil/on_chunk_tick(obj/item/blobcore_chunk/B)
B.reagents.add_reagent("thermite_v", 0.5)
var/turf/T = get_turf(B)
if(!T)
return
var/datum/gas_mixture/env = T.return_air()
if(env)
env.add_thermal_energy(10 * 1000)
/datum/blob_type/blazing_oil/on_chunk_use(obj/item/blobcore_chunk/B, mob/living/user)
user.add_modifier(/datum/modifier/exothermic, 5 MINUTES)
return
@@ -10,28 +10,3 @@
can_build_nodes = FALSE
spread_modifier = 1.0
ai_aggressiveness = 0
/datum/blob_type/classic/on_chunk_use(obj/item/blobcore_chunk/B, mob/living/user)
var/turf/T = get_turf(B)
to_chat(user, "<span class='alien'>\The [B] produces a soothing ooze!</span>")
T.visible_message("<span class='alium'>\The [B] shudders at \the [user]'s touch, before disgorging a disgusting ooze.</span>")
for(var/turf/simulated/floor/F in view(2, T))
spawn()
var/obj/effect/vfx/water/splash = new(T)
splash.create_reagents(15)
splash.reagents.add_reagent("blood", 10,list("blood_colour" = color))
splash.set_color()
splash.set_up(F, 2, 3)
var/obj/effect/decal/cleanable/chemcoating/blood = locate() in T
if(!istype(blood))
blood = new(T)
blood.reagents.add_reagent("blood", 10,list("blood_colour" = color))
blood.reagents.add_reagent("tricorlidaze", 5)
blood.update_icon()
return
@@ -35,27 +35,3 @@
H.bodytemperature = max(H.bodytemperature - temp_change, temp_cap)
else // Just do some extra burn for mobs who don't process bodytemp
victim.adjustFireLoss(20)
/datum/blob_type/cryogenic_goo/on_pulse(var/obj/structure/blob/B)
var/turf/simulated/T = get_turf(B)
if(!istype(T))
return
T.freeze_floor()
var/datum/gas_mixture/env = T.return_air()
if(env)
env.add_thermal_energy(-10 * 1000)
/datum/blob_type/cryogenic_goo/on_chunk_tick(obj/item/blobcore_chunk/B)
B.reagents.add_reagent("cryoslurry", 0.5)
var/turf/simulated/T = get_turf(B)
if(!istype(T))
return
T.freeze_floor()
var/datum/gas_mixture/env = T.return_air()
if(env)
env.add_thermal_energy(-10 * 1000)
/datum/blob_type/cryogenic_goo/on_chunk_use(obj/item/blobcore_chunk/B, mob/living/user)
user.add_modifier(/datum/modifier/endothermic, 5 MINUTES)
return
@@ -67,62 +67,3 @@
animate(B,alpha = 10, alpha = initial_alpha, time = 10)
return 0
return ..()
/datum/blob_type/ectoplasmic_horror/on_chunk_tick(obj/item/blobcore_chunk/B)
var/mob/living/carrier = B.get_carrier()
if(!carrier)
return
var/list/nearby_mobs = list()
for(var/mob/living/L in oview(world.view, carrier))
if(L.stat != DEAD)
nearby_mobs |= L
if(nearby_mobs.len)
listclearnulls(active_beams)
for(var/mob/living/L in nearby_mobs)
if(L.stat == DEAD || L.faction == faction)
continue
if(prob(5))
var/beamtarget_exists = FALSE
if(active_beams.len)
for(var/datum/beam/Beam in active_beams)
if(Beam.target == L)
beamtarget_exists = TRUE
break
if(!beamtarget_exists && GetAnomalySusceptibility(L) >= 0.5)
carrier.visible_message("<span class='danger'>\icon [B] \The [B] lashes out at \the [L]!</span>")
var/datum/beam/drain_beam = carrier.Beam(L, icon_state = "drain_life", time = 10 SECONDS)
active_beams |= drain_beam
spawn(9 SECONDS)
if(B && drain_beam)
carrier.visible_message("<span class='alien'>\The [B] siphons energy from \the [L]</span>")
L.add_modifier(/datum/modifier/berserk_exhaustion, 30 SECONDS)
var/total_heal = 0
if(carrier.getBruteLoss())
carrier.adjustBruteLoss(-5)
total_heal += 5
if(carrier.getFireLoss())
carrier.adjustFireLoss(-5)
total_heal += 5
if(carrier.getToxLoss())
carrier.adjustToxLoss(-5)
total_heal += 5
if(carrier.getOxyLoss())
carrier.adjustOxyLoss(-5)
total_heal += 5
if(carrier.getCloneLoss())
carrier.adjustCloneLoss(-5)
total_heal += 5
carrier.add_modifier(/datum/modifier/berserk_exhaustion, total_heal SECONDS)
if(!QDELETED(drain_beam))
qdel(drain_beam)
@@ -24,11 +24,3 @@
/datum/blob_type/electromagnetic_web/on_attack(obj/structure/blob/B, mob/living/victim)
victim.emp_act(2)
/datum/blob_type/electromagnetic_web/on_chunk_tick(obj/item/blobcore_chunk/B)
var/turf/T = get_turf(B)
if(!T)
return
for(var/mob/living/L in view(2, T))
L.add_modifier(/datum/modifier/faraday, 30 SECONDS)
@@ -23,17 +23,3 @@
/datum/blob_type/energized_jelly/on_attack(obj/structure/blob/B, mob/living/victim, def_zone)
victim.electrocute_act(10, src, 1, def_zone)
victim.stun_effect_act(0, 40, BP_TORSO, src)
/datum/blob_type/energized_jelly/on_chunk_tick(obj/item/blobcore_chunk/B)
for(var/mob/living/L in oview(world.view, get_turf(B)))
var/mob/living/carrier = B.get_carrier()
if(istype(carrier) && carrier == L)
continue
var/obj/item/projectile/P = new spore_projectile(get_turf(B))
carrier.visible_message("<span class='danger'>\The [B] discharges energy toward \the [L]!</span>")
P.launch_projectile(L, BP_TORSO, carrier)
return
@@ -48,11 +48,3 @@
M << 'sound/effects/explosionfar.ogg'
exploding = FALSE
/datum/blob_type/explosive_lattice/on_chunk_tick(obj/item/blobcore_chunk/B)
var/turf/T = get_turf(B)
if(!T)
return
for(var/mob/living/L in view(1, T))
L.add_modifier(/datum/modifier/blastshield, 30 SECONDS)
@@ -31,14 +31,3 @@
new/obj/structure/blob/shield(get_turf(B), B.overmind)
qdel(B)
return ..()
/datum/blob_type/fabrication_swarm/on_emp(obj/structure/blob/B, severity)
B.adjust_integrity(-(30 / severity))
/datum/blob_type/fabrication_swarm/on_chunk_tick(obj/item/blobcore_chunk/B)
var/turf/T = get_turf(B)
for(var/mob/living/L in view(world.view, T))
if(L.stat != DEAD && L.isSynthetic())
L.adjustBruteLoss(-1)
L.adjustFireLoss(-1)
return
@@ -41,12 +41,3 @@
else
S.faction = faction
S.update_icons()
/datum/blob_type/fulminant_organism/on_chunk_use(obj/item/blobcore_chunk/B, mob/living/user)
for(var/I = 1 to rand(3,4))
var/mob/living/simple_mob/blob/spore/S = new spore_type(get_turf(B))
S.faction = user.faction
S.blob_type = src
S.update_icons()
S.ai_holder.forget_everything()
S.add_modifier(/datum/modifier/doomed, 2 MINUTES)
@@ -28,10 +28,3 @@
else
B = new /obj/structure/blob/normal(T, S.overmind) // Otherwise spread it.
B.visible_message("<span class='danger'>\A [B] forms on \the [T] as \the [S] bursts!</span>")
/datum/blob_type/fungal_bloom/on_chunk_use(obj/item/blobcore_chunk/B, mob/living/user)
var/mob/living/simple_mob/blob/spore/S = new spore_type(get_turf(B))
S.faction = user.faction
S.blob_type = src
S.update_icons()
S.ai_holder.forget_everything()
@@ -18,11 +18,3 @@
/datum/blob_type/grey_goo/on_emp(obj/structure/blob/B, severity)
B.adjust_integrity(-(20 / severity))
/datum/blob_type/grey_goo/on_chunk_tick(obj/item/blobcore_chunk/B)
var/turf/T = get_turf(B)
for(var/mob/living/L in view(world.view, T))
if(L.stat != DEAD)
L.adjustBruteLoss(-1)
L.adjustFireLoss(-1)
return
@@ -46,11 +46,3 @@
T.wet_floor()
for(var/atom/movable/AM in T)
AM.water_act(2)
/datum/blob_type/pressurized_slime/on_chunk_tick(obj/item/blobcore_chunk/B)
wet_surroundings(B, 10)
/datum/blob_type/pressurized_slime/on_chunk_use(obj/item/blobcore_chunk/B, mob/living/user) // Drenches you in water.
if(user)
user.ExtinguishMob()
user.fire_stacks = clamp(user.fire_stacks - 1, -25, 25)
@@ -22,6 +22,3 @@
/datum/blob_type/radioactive_ooze/on_pulse(var/obj/structure/blob/B)
SSradiation.radiate(B, 200)
/datum/blob_type/radioactive_ooze/on_chunk_tick(obj/item/blobcore_chunk/B)
SSradiation.radiate(B, rand(25,100))
@@ -37,14 +37,3 @@
B.visible_message("<span class='danger'>The dying mass is rapidly consumed by the nearby [other]!</span>")
if(other.overmind)
other.overmind.add_points(rand(1,4))
/datum/blob_type/ravenous_macrophage/on_chunk_tick(obj/item/blobcore_chunk/B)
var/mob/living/L = locate() in range(world.view, B)
if(prob(5) && !L.stat) // There's some active living thing nearby, produce offgas.
B.visible_message("<span class='alien'>\icon [B] \The [B] disgorches a cloud of noxious gas!</span>")
var/turf/T = get_turf(B)
var/datum/effect_system/smoke_spread/noxious/BS = new /datum/effect_system/smoke_spread/noxious
BS.attach(T)
BS.set_up(3, 0, T)
playsound(T, 'sound/effects/smoke.ogg', 50, 1, -3)
BS.start()
@@ -30,30 +30,3 @@
B.blob_attack_animation(attacker, B.overmind)
attacker.blob_act(B)
return ..()
// We're expecting 1 to be a target, 2 to be an old move loc, and 3 to be a new move loc.
/datum/blob_type/reactive_spines/chunk_unique(obj/item/blobcore_chunk/B, var/list/extra_data = null)
if(!LAZYLEN(extra_data))
return
var/atom/movable/A = extra_data[1]
if(istype(A, /mob/living) && world.time > (B.last_passive_use + B.passive_ability_cooldown) && B.should_tick)
B.last_passive_use = world.time
var/mob/living/L = A
var/mob/living/carrier = B.get_carrier()
if(!istype(carrier) || L.z != carrier.z || L == carrier || get_dist(L, carrier) > 3)
return
var/obj/item/projectile/P = new spore_projectile(get_turf(B))
carrier.visible_message("<span class='danger'>\The [B] fires a spine at \the [L]!</span>")
P.launch_projectile(L, BP_TORSO, carrier)
return
/datum/blob_type/reactive_spines/chunk_setup(obj/item/blobcore_chunk/B)
GLOB.moved_event.register_global(B, /obj/item/blobcore_chunk/proc/call_chunk_unique)
return
@@ -22,43 +22,3 @@
attack_verb = "lashes"
spore_projectile = /obj/item/projectile/arc/spore
factory_type = /obj/structure/blob/factory/turret
/datum/blob_type/roiling_mold/proc/find_target(var/obj/structure/blob/B, var/tries = 0, var/list/previous_targets = null)
if(tries > 3)
return
var/mob/living/L = locate() in (view(world.view + 3, get_turf(B)) - view(2,get_turf(B)) - previous_targets) // No adjacent mobs.
if(!check_trajectory(L, B, PASSTABLE))
if(!LAZYLEN(previous_targets))
previous_targets = list()
previous_targets |= L
return find_target(B, tries + 1, previous_targets)
return L
/datum/blob_type/roiling_mold/on_pulse(var/obj/structure/blob/B)
var/mob/living/L = find_target(B)
if(!istype(L))
return
if(istype(B, /obj/structure/blob/factory) && L.stat != DEAD && prob(ai_aggressiveness) && L.faction != faction)
var/obj/item/projectile/arc/spore/P = new(get_turf(B))
P.launch_projectile(L, BP_TORSO, B)
/datum/blob_type/roiling_mold/on_chunk_use(obj/item/blobcore_chunk/B, mob/living/user)
for(var/mob/living/L in oview(world.view, get_turf(B)))
if(istype(user) && user == L)
continue
if(!check_trajectory(L, B, PASSTABLE)) // Can't fire at things on the other side of walls / windows.
continue
var/obj/item/projectile/P = new spore_projectile(get_turf(B))
user.visible_message("<span class='danger'>\icon [B] \The [B] discharges energy toward \the [L]!</span>")
P.launch_projectile(L, BP_TORSO, user)
return
@@ -34,7 +34,3 @@
if(istype(B, /obj/structure/blob/normal) || (istype(B, /obj/structure/blob/shield) && prob(25)))
new_B.forceMove(get_turf(B))
B.forceMove(T)
/datum/blob_type/shifting_fragments/on_chunk_use(obj/item/blobcore_chunk/B, mob/living/user)
user.add_modifier(/datum/modifier/sprinting, 2 MINUTES)
return
@@ -42,32 +42,3 @@
C.adjust_integrity(-(damage / blobs_to_hurt.len))
return damage / max(blobs_to_hurt.len, 1) // To hurt the blob that got hit.
/datum/blob_type/synchronous_mesh/on_chunk_tick(obj/item/blobcore_chunk/B)
var/mob/living/carrier = B.get_carrier()
if(!carrier)
return
var/list/nearby_mobs = list()
for(var/mob/living/L in oview(world.view, carrier))
if(L.stat != DEAD)
nearby_mobs |= L
if(nearby_mobs.len)
for(var/mob/living/victim in nearby_mobs)
var/need_beam = FALSE
if(carrier.getBruteLoss())
need_beam = TRUE
victim.adjustBruteLoss(3 / nearby_mobs.len)
carrier.adjustBruteLoss(-3 / nearby_mobs.len)
if(carrier.getFireLoss())
need_beam = TRUE
victim.adjustFireLoss(3 / nearby_mobs.len)
carrier.adjustFireLoss(-3 / nearby_mobs.len)
if(need_beam)
carrier.visible_message("<span class='alien'>\icon [B] \The [B] sends noxious spores toward \the [victim]!</span>")
carrier.Beam(victim, icon_state = "lichbeam", time = 2 SECONDS)
@@ -49,7 +49,3 @@
B.adjust_integrity(-(damage))
if(B && prob(damage))
B.visible_message("<span class='danger'>The [name] begins to crumble!</span>")
/datum/blob_type/volatile_alluvium/on_chunk_use(obj/item/blobcore_chunk/B, mob/living/user)
if(user)
user.add_modifier(/datum/modifier/fortify, 60 SECONDS)