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

View File

@@ -110,9 +110,6 @@ var/global/list/blob_cores = list()
point_rate = new_rate point_rate = new_rate
/obj/structure/blob/core/Destroy() /obj/structure/blob/core/Destroy()
var/turf/T = get_turf(src)
new /obj/item/blobcore_chunk(T, overmind.blob_type)
blob_cores -= src blob_cores -= src
if(overmind) if(overmind)
overmind.blob_core = null overmind.blob_core = null

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>")

View File

@@ -95,19 +95,3 @@
// Spore handle_special call. // Spore handle_special call.
/datum/blob_type/proc/on_spore_lifetick(mob/living/simple_mob/blob/spore/S) /datum/blob_type/proc/on_spore_lifetick(mob/living/simple_mob/blob/spore/S)
return 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

View File

@@ -13,28 +13,3 @@
brute_multiplier = 0.35 brute_multiplier = 0.35
burn_multiplier = 0.8 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

View File

@@ -23,25 +23,3 @@
/datum/blob_type/blazing_oil/on_water(obj/structure/blob/B, amount) /datum/blob_type/blazing_oil/on_water(obj/structure/blob/B, amount)
spawn(1) spawn(1)
B.adjust_integrity(-(amount * 5)) 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

View File

@@ -10,28 +10,3 @@
can_build_nodes = FALSE can_build_nodes = FALSE
spread_modifier = 1.0 spread_modifier = 1.0
ai_aggressiveness = 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

View File

@@ -35,27 +35,3 @@
H.bodytemperature = max(H.bodytemperature - temp_change, temp_cap) H.bodytemperature = max(H.bodytemperature - temp_change, temp_cap)
else // Just do some extra burn for mobs who don't process bodytemp else // Just do some extra burn for mobs who don't process bodytemp
victim.adjustFireLoss(20) 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

View File

@@ -67,62 +67,3 @@
animate(B,alpha = 10, alpha = initial_alpha, time = 10) animate(B,alpha = 10, alpha = initial_alpha, time = 10)
return 0 return 0
return ..() 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)

View File

@@ -24,11 +24,3 @@
/datum/blob_type/electromagnetic_web/on_attack(obj/structure/blob/B, mob/living/victim) /datum/blob_type/electromagnetic_web/on_attack(obj/structure/blob/B, mob/living/victim)
victim.emp_act(2) 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)

View File

@@ -23,17 +23,3 @@
/datum/blob_type/energized_jelly/on_attack(obj/structure/blob/B, mob/living/victim, def_zone) /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.electrocute_act(10, src, 1, def_zone)
victim.stun_effect_act(0, 40, BP_TORSO, src) 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

View File

@@ -48,11 +48,3 @@
M << 'sound/effects/explosionfar.ogg' M << 'sound/effects/explosionfar.ogg'
exploding = FALSE 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)

View File

@@ -31,14 +31,3 @@
new/obj/structure/blob/shield(get_turf(B), B.overmind) new/obj/structure/blob/shield(get_turf(B), B.overmind)
qdel(B) qdel(B)
return ..() 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

View File

@@ -41,12 +41,3 @@
else else
S.faction = faction S.faction = faction
S.update_icons() 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)

View File

@@ -28,10 +28,3 @@
else else
B = new /obj/structure/blob/normal(T, S.overmind) // Otherwise spread it. 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>") 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()

View File

@@ -18,11 +18,3 @@
/datum/blob_type/grey_goo/on_emp(obj/structure/blob/B, severity) /datum/blob_type/grey_goo/on_emp(obj/structure/blob/B, severity)
B.adjust_integrity(-(20 / 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

View File

@@ -46,11 +46,3 @@
T.wet_floor() T.wet_floor()
for(var/atom/movable/AM in T) for(var/atom/movable/AM in T)
AM.water_act(2) 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)

View File

@@ -22,6 +22,3 @@
/datum/blob_type/radioactive_ooze/on_pulse(var/obj/structure/blob/B) /datum/blob_type/radioactive_ooze/on_pulse(var/obj/structure/blob/B)
SSradiation.radiate(B, 200) SSradiation.radiate(B, 200)
/datum/blob_type/radioactive_ooze/on_chunk_tick(obj/item/blobcore_chunk/B)
SSradiation.radiate(B, rand(25,100))

View File

@@ -37,14 +37,3 @@
B.visible_message("<span class='danger'>The dying mass is rapidly consumed by the nearby [other]!</span>") B.visible_message("<span class='danger'>The dying mass is rapidly consumed by the nearby [other]!</span>")
if(other.overmind) if(other.overmind)
other.overmind.add_points(rand(1,4)) 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()

View File

@@ -30,30 +30,3 @@
B.blob_attack_animation(attacker, B.overmind) B.blob_attack_animation(attacker, B.overmind)
attacker.blob_act(B) attacker.blob_act(B)
return ..() 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

View File

@@ -22,43 +22,3 @@
attack_verb = "lashes" attack_verb = "lashes"
spore_projectile = /obj/item/projectile/arc/spore spore_projectile = /obj/item/projectile/arc/spore
factory_type = /obj/structure/blob/factory/turret 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

View File

@@ -34,7 +34,3 @@
if(istype(B, /obj/structure/blob/normal) || (istype(B, /obj/structure/blob/shield) && prob(25))) if(istype(B, /obj/structure/blob/normal) || (istype(B, /obj/structure/blob/shield) && prob(25)))
new_B.forceMove(get_turf(B)) new_B.forceMove(get_turf(B))
B.forceMove(T) 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

View File

@@ -42,32 +42,3 @@
C.adjust_integrity(-(damage / blobs_to_hurt.len)) C.adjust_integrity(-(damage / blobs_to_hurt.len))
return damage / max(blobs_to_hurt.len, 1) // To hurt the blob that got hit. 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)

View File

@@ -49,7 +49,3 @@
B.adjust_integrity(-(damage)) B.adjust_integrity(-(damage))
if(B && prob(damage)) if(B && prob(damage))
B.visible_message("<span class='danger'>The [name] begins to crumble!</span>") 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)

View File

@@ -72,18 +72,5 @@
return TRUE return TRUE
return ..() return ..()
/mob/living/simple_mob/blob/IIsAlly(mob/living/L)
var/ally = ..(L)
if(!ally)
var/list/items = L.get_all_held_items()
for(var/obj/item/I in items)
if(istype(I, /obj/item/blobcore_chunk))
var/obj/item/blobcore_chunk/BC = I
if(!overmind || (BC.blob_type && overmind.blob_type.type == BC.blob_type.type) || BC.blob_type.faction == faction)
ally = TRUE
break
return ally
/decl/mob_organ_names/blob /decl/mob_organ_names/blob
hit_zones = list("mass") hit_zones = list("mass")

View File

@@ -26,7 +26,9 @@
/mob/living/simple_mob/animal/space/alien, /mob/living/simple_mob/animal/space/alien,
/mob/living/simple_mob/animal/space/bear, /mob/living/simple_mob/animal/space/bear,
/mob/living/simple_mob/creature, /mob/living/simple_mob/creature,
/mob/living/simple_mob/slime/xenobio) /mob/living/simple_mob/slime/xenobio,
/mob/living/simple_mob/blob/spore/weak,
/mob/living/simple_mob/blob/spore/infesting)
else else
spawn_type = pick(\ spawn_type = pick(\
/mob/living/simple_mob/animal/passive/cat, /mob/living/simple_mob/animal/passive/cat,

View File

@@ -68,29 +68,31 @@
/datum/artifact_effect/proc/ToggleActivate(reveal_toggle = TRUE) /datum/artifact_effect/proc/ToggleActivate(reveal_toggle = TRUE)
set waitfor = FALSE set waitfor = FALSE
var/atom/target = get_master_holder() var/atom/target = get_master_holder()
if (world.time - last_activation > 1 SECOND) if (world.time - last_activation < 1 SECOND)
last_activation = world.time return FALSE
last_activation = world.time
if (activated)
activated = 0
else
activated = 1
if (reveal_toggle && target)
if (!isliving(target))
target.update_icon()
var/display_msg
if (activated) if (activated)
activated = 0 display_msg = pick("momentarily glows brightly!","distorts slightly for a moment!","flickers slightly!","vibrates!","shimmers slightly for a moment!")
else else
activated = 1 display_msg = pick("grows dull!","fades in intensity!","suddenly becomes very still!","suddenly becomes very quiet!")
if (reveal_toggle && target) if (active_effect)
if (!isliving(target))
target.update_icon()
var/display_msg
if (activated) if (activated)
display_msg = pick("momentarily glows brightly!","distorts slightly for a moment!","flickers slightly!","vibrates!","shimmers slightly for a moment!") target.underlays.Add(active_effect)
else else
display_msg = pick("grows dull!","fades in intensity!","suddenly becomes very still!","suddenly becomes very quiet!") target.underlays.Remove(active_effect)
if (active_effect) var/atom/toplevelholder = target
if (activated) while (!istype(toplevelholder.loc, /turf))
target.underlays.Add(active_effect) toplevelholder = toplevelholder.loc
else toplevelholder.visible_message("<font color='red'>[bicon(toplevelholder)] [toplevelholder] [display_msg]</font>")
target.underlays.Remove(active_effect) return TRUE
var/atom/toplevelholder = target
while (!istype(toplevelholder.loc, /turf))
toplevelholder = toplevelholder.loc
toplevelholder.visible_message("<font color='red'>[bicon(toplevelholder)] [toplevelholder] [display_msg]</font>")
/datum/artifact_effect/proc/DoEffectTouch(mob/living/user) /datum/artifact_effect/proc/DoEffectTouch(mob/living/user)
@@ -105,10 +107,13 @@
return return
/datum/artifact_effect/proc/UpdateMove() /datum/artifact_effect/proc/UpdateMove(var/turf/old_loc)
return return
/datum/artifact_effect/proc/attackby(mob/living/user, obj/item/I)
return FALSE
/datum/artifact_effect/proc/getDescription() /datum/artifact_effect/proc/getDescription()
. = "<b>" . = "<b>"
switch (effect_type) switch (effect_type)

View File

@@ -294,37 +294,39 @@
/datum/component/artifact_master/proc/on_attackby() /datum/component/artifact_master/proc/on_attackby()
var/obj/item/W = args[2] var/obj/item/W = args[0]
for(var/datum/artifact_effect/my_effect in my_effects) for(var/datum/artifact_effect/my_effect in my_effects)
if (istype(W, /obj/item/reagent_containers)) if (istype(W, /obj/item/reagent_containers))
if(W.reagents.has_reagent("hydrogen", 1) || W.reagents.has_reagent("water", 1)) if(W.reagents.has_reagent("hydrogen", 1) || W.reagents.has_reagent("water", 1))
if(my_effect.trigger == TRIGGER_WATER) if(my_effect.trigger == TRIGGER_WATER)
my_effect.ToggleActivate() return my_effect.ToggleActivate()
else if(W.reagents.has_reagent("sacid", 1) || W.reagents.has_reagent("pacid", 1) || W.reagents.has_reagent("diethylamine", 1)) else if(W.reagents.has_reagent("sacid", 1) || W.reagents.has_reagent("pacid", 1) || W.reagents.has_reagent("diethylamine", 1))
if(my_effect.trigger == TRIGGER_ACID) if(my_effect.trigger == TRIGGER_ACID)
my_effect.ToggleActivate() return my_effect.ToggleActivate()
else if(W.reagents.has_reagent("phoron", 1) || W.reagents.has_reagent("thermite", 1)) else if(W.reagents.has_reagent("phoron", 1) || W.reagents.has_reagent("thermite", 1))
if(my_effect.trigger == TRIGGER_VOLATILE) if(my_effect.trigger == TRIGGER_VOLATILE)
my_effect.ToggleActivate() return my_effect.ToggleActivate()
else if(W.reagents.has_reagent("toxin", 1) || W.reagents.has_reagent("cyanide", 1) || W.reagents.has_reagent("amatoxin", 1) || W.reagents.has_reagent("neurotoxin", 1)) else if(W.reagents.has_reagent("toxin", 1) || W.reagents.has_reagent("cyanide", 1) || W.reagents.has_reagent("amatoxin", 1) || W.reagents.has_reagent("neurotoxin", 1))
if(my_effect.trigger == TRIGGER_TOXIN) if(my_effect.trigger == TRIGGER_TOXIN)
my_effect.ToggleActivate() return my_effect.ToggleActivate()
else if(istype(W,/obj/item/melee/baton) && W:status ||\ else if(istype(W,/obj/item/melee/baton) && W:status ||\
istype(W,/obj/item/melee/energy) ||\ istype(W,/obj/item/melee/energy) ||\
istype(W,/obj/item/melee/cultblade) ||\ istype(W,/obj/item/melee/cultblade) ||\
istype(W,/obj/item/card/emag) ||\ istype(W,/obj/item/card/emag) ||\
istype(W,/obj/item/multitool)) istype(W,/obj/item/multitool))
if (my_effect.trigger == TRIGGER_ENERGY) if (my_effect.trigger == TRIGGER_ENERGY)
my_effect.ToggleActivate() return my_effect.ToggleActivate()
else if (istype(W,/obj/item/flame) && W:lit ||\ else if (istype(W,/obj/item/flame) && W:lit ||\
istype(W,/obj/item/weldingtool) && W:welding) istype(W,/obj/item/weldingtool) && W:welding)
if(my_effect.trigger == TRIGGER_HEAT) if(my_effect.trigger == TRIGGER_HEAT)
my_effect.ToggleActivate() return my_effect.ToggleActivate()
else else
if (my_effect.trigger == TRIGGER_FORCE && W.force >= 10) if (my_effect.trigger == TRIGGER_FORCE && W.force >= 10)
my_effect.ToggleActivate() return my_effect.ToggleActivate()
return my_effect.attackby(args[1], args[0])
/datum/component/artifact_master/proc/on_reagent() /datum/component/artifact_master/proc/on_reagent()
var/datum/reagent/Touching = args[2] var/datum/reagent/Touching = args[2]
@@ -348,10 +350,13 @@
if(my_effect.trigger == TRIGGER_TOXIN) if(my_effect.trigger == TRIGGER_TOXIN)
my_effect.ToggleActivate() my_effect.ToggleActivate()
/datum/component/artifact_master/proc/on_moved() /datum/component/artifact_master/proc/on_moved(var/list/arguments)
var/turf/old_loc = get_turf(holder) // If we don't get an oldturf, at least try to use the new one.
if(LAZYLEN(arguments) && isturf(arguments[0]))
old_loc = arguments[0]
for(var/datum/artifact_effect/my_effect in my_effects) for(var/datum/artifact_effect/my_effect in my_effects)
if(my_effect) if(my_effect)
my_effect.UpdateMove() my_effect.UpdateMove(old_loc)
/datum/component/artifact_master/process() /datum/component/artifact_master/process()
if(!holder) // Some instances can be created and rapidly lose their holder, if they are destroyed rapidly on creation. IE, during excavation. if(!holder) // Some instances can be created and rapidly lose their holder, if they are destroyed rapidly on creation. IE, during excavation.
@@ -369,10 +374,6 @@
if(HA.pulledby) if(HA.pulledby)
on_bumped(holder, HA.pulledby) on_bumped(holder, HA.pulledby)
for(var/datum/artifact_effect/my_effect in my_effects)
if(my_effect)
my_effect.UpdateMove()
//if any of our effects rely on environmental factors, work that out //if any of our effects rely on environmental factors, work that out
var/trigger_cold = 0 var/trigger_cold = 0
var/trigger_hot = 0 var/trigger_hot = 0
@@ -426,4 +427,3 @@
//NITROGEN GAS ACTIVATION //NITROGEN GAS ACTIVATION
if(my_effect.trigger == TRIGGER_NITRO && (trigger_nitro ^ my_effect.activated)) if(my_effect.trigger == TRIGGER_NITRO && (trigger_nitro ^ my_effect.activated))
my_effect.ToggleActivate() my_effect.ToggleActivate()

View File

@@ -12,7 +12,7 @@
/datum/artifact_effect/common/animate_anomaly/ToggleActivate(reveal_toggle = TRUE) /datum/artifact_effect/common/animate_anomaly/ToggleActivate(reveal_toggle = TRUE)
..() . = ..()
find_target() find_target()

View File

@@ -0,0 +1,26 @@
/datum/artifact_effect/uncommon/blast_shielding
name = "blast_shielding"
effect_color = "#c09951"
effect_type = EFFECT_ENERGY
/datum/artifact_effect/uncommon/blast_shielding/DoEffectTouch(mob/living/user)
if (user && isliving(user))
user.add_modifier(/datum/modifier/blastshield, 2 MINUTES)
/datum/artifact_effect/uncommon/blast_shielding/DoEffectAura()
var/atom/holder = get_master_holder()
if (holder)
var/turf/T = get_turf(holder)
for (var/mob/living/L in range(src.effectrange,T))
if (prob(10))
L.add_modifier(/datum/modifier/blastshield, 10 SECONDS)
/datum/artifact_effect/uncommon/blast_shielding/DoEffectPulse()
var/atom/holder = get_master_holder()
if (holder)
var/turf/T = get_turf(holder)
for (var/mob/living/L in range(src.effectrange,T))
L.add_modifier(/datum/modifier/blastshield, 30 SECONDS)

View File

@@ -19,6 +19,9 @@
if (env) if (env)
env.temperature = max(env.temperature - rand(5,50), 0) env.temperature = max(env.temperature - rand(5,50), 0)
var/turf/simulated/T = get_turf(holder)
if(istype(T))
T.freeze_floor()
/datum/artifact_effect/common/cold/DoEffectAura() /datum/artifact_effect/common/cold/DoEffectAura()
var/atom/holder = get_master_holder() var/atom/holder = get_master_holder()
@@ -26,3 +29,6 @@
var/datum/gas_mixture/env = holder.loc.return_air() var/datum/gas_mixture/env = holder.loc.return_air()
if (env && env.temperature > target_temp) if (env && env.temperature > target_temp)
env.temperature -= pick(0, 0, 1) env.temperature -= pick(0, 0, 1)
var/turf/simulated/T = get_turf(holder)
if(istype(T))
T.freeze_floor()

View File

@@ -0,0 +1,28 @@
/datum/artifact_effect/common/extinguisher
name = "Extinguisher"
effect_color = "#AAAABB"
effect_state = "splashes"
effect_type = EFFECT_UNKNOWN
/datum/artifact_effect/common/extinguisher/New()
. = ..()
effect = pick(EFFECT_PULSE, EFFECT_TOUCH)
/datum/artifact_effect/common/extinguisher/DoEffectTouch(mob/living/user)
if(user)
user.ExtinguishMob()
user.fire_stacks = clamp(user.fire_stacks - 1, -25, 25)
/datum/artifact_effect/common/sweating/UpdateMove()
DoEffectPulse()
/datum/artifact_effect/common/extinguisher/DoEffectPulse()
for(var/turf/simulated/T in range(1, get_turf(get_master_holder())))
if(prob(10))
T.wet_floor()
for(var/atom/movable/AM in T)
AM.water_act(2)

View File

@@ -0,0 +1,26 @@
/datum/artifact_effect/uncommon/faraday
name = "faraday"
effect_color = "#31f5f5"
effect_type = EFFECT_ELECTRO
/datum/artifact_effect/uncommon/faraday/DoEffectTouch(mob/living/user)
if (user && isliving(user))
user.add_modifier(/datum/modifier/faraday, 2 MINUTES)
/datum/artifact_effect/uncommon/faraday/DoEffectAura()
var/atom/holder = get_master_holder()
if (holder)
var/turf/T = get_turf(holder)
for (var/mob/living/L in range(src.effectrange,T))
if (prob(10))
L.add_modifier(/datum/modifier/faraday, 10 SECONDS)
/datum/artifact_effect/uncommon/faraday/DoEffectPulse()
var/atom/holder = get_master_holder()
if (holder)
var/turf/T = get_turf(holder)
for (var/mob/living/L in range(src.effectrange,T))
L.add_modifier(/datum/modifier/faraday, 30 SECONDS)

View File

@@ -13,7 +13,7 @@
/datum/artifact_effect/uncommon/forcefield/ToggleActivate() /datum/artifact_effect/uncommon/forcefield/ToggleActivate()
var/atom/holder = get_master_holder() var/atom/holder = get_master_holder()
..() . = ..()
if (created_field.len) if (created_field.len)
for (var/obj/effect/energy_field/F in created_field) for (var/obj/effect/energy_field/F in created_field)
created_field.Remove(F) created_field.Remove(F)
@@ -29,7 +29,6 @@
E.invisibility = 0 E.invisibility = 0
spawn(10) spawn(10)
UpdateMove() UpdateMove()
return 1
/datum/artifact_effect/uncommon/forcefield/process() /datum/artifact_effect/uncommon/forcefield/process()

View File

@@ -0,0 +1,26 @@
/datum/artifact_effect/uncommon/fortify
name = "fortify"
effect_color = "#84ad87"
effect_type = EFFECT_ENERGY
/datum/artifact_effect/uncommon/fortify/DoEffectTouch(mob/living/user)
if (user && isliving(user))
user.add_modifier(/datum/modifier/fortify, 2 MINUTES)
/datum/artifact_effect/uncommon/fortify/DoEffectAura()
var/atom/holder = get_master_holder()
if (holder)
var/turf/T = get_turf(holder)
for (var/mob/living/L in range(src.effectrange,T))
if (prob(10))
L.add_modifier(/datum/modifier/fortify, 10 SECONDS)
/datum/artifact_effect/uncommon/fortify/DoEffectPulse()
var/atom/holder = get_master_holder()
if (holder)
var/turf/T = get_turf(holder)
for (var/mob/living/L in range(src.effectrange,T))
L.add_modifier(/datum/modifier/fortify, 30 SECONDS)

View File

@@ -0,0 +1,35 @@
/datum/artifact_effect/rare/spines
name = "spines"
effect_color = "#8db6b2"
effect_type = EFFECT_ORGANIC
/datum/artifact_effect/extreme/spines/New()
. = ..()
effect = pick(EFFECT_TOUCH, EFFECT_PULSE)
/datum/artifact_effect/extreme/spines/proc/shoot(var/list/exempt = list())
var/atom/A = get_master_holder()
A.visible_message("<span class='danger'>\The [get_master_holder()] fires spines wildly in all directions!</span>")
for(var/i in range(1, round(chargelevel / 3)))
var/atom/target = pick(oview(world.view, get_turf(get_master_holder())))
if(target in exempt)
continue
var/obj/item/projectile/P = new /obj/item/projectile/bullet/thorn(get_turf(get_master_holder()))
P.launch_projectile(target, BP_TORSO, get_master_holder())
chargelevel -= 3
/datum/artifact_effect/extreme/spines/DoEffectTouch(mob/living/user)
if(chargelevel < 3)
return
shoot(list(user))
/datum/artifact_effect/extreme/spines/DoEffectPulse()
if(chargelevel < 3)
return
shoot()

View File

@@ -0,0 +1,87 @@
/datum/artifact_effect/rare/lifedrain
name = "lifesteal"
effect_color = "#3b1f3b"
effect_type = EFFECT_ENERGY
var/list/active_beams
/datum/artifact_effect/rare/lifedrain/New()
. = ..()
effect = pick(EFFECT_TOUCH, EFFECT_PULSE)
/datum/artifact_effect/rare/lifedrain/proc/steal(var/mob/living/carrier)
if(!istype(carrier))
return
var/list/nearby_mobs = list()
for(var/mob/living/L in oview(world.view, get_master_holder()))
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)
continue
if(!prob(5))
continue
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)
continue
carrier.visible_message(
"<span class='danger'>A sickly beam lashes out from [bicon(get_master_holder())] \the [get_master_holder()] 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(get_master_holder() && drain_beam)
carrier.visible_message(
"<span class='alien'>\The [get_master_holder()] 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)
var/atom/A = get_master_holder()
A.visible_message(
"<span class='alien'>A sickly beam lashes out from [bicon(get_master_holder())] \the [get_master_holder()] at \the [carrier]!</span>")
/datum/artifact_effect/rare/lifedrain/DoEffectTouch(mob/living/user)
if (user && isliving(user))
steal(user)
/datum/artifact_effect/rare/lifedrain/DoEffectPulse()
var/mob/living/target = locate() in oview(world.view, get_turf(get_master_holder()))
if(target)
steal(target)

View File

@@ -0,0 +1,50 @@
/datum/artifact_effect/extreme/lifesteal
name = "lifesteal"
effect_color = "#3b1f3b"
effect_type = EFFECT_ENERGY
/datum/artifact_effect/extreme/lifesteal/New()
. = ..()
effect = pick(EFFECT_TOUCH, EFFECT_PULSE)
/datum/artifact_effect/extreme/lifesteal/proc/steal(var/mob/living/carrier)
if(!istype(carrier))
return
var/list/nearby_mobs = list()
for(var/mob/living/L in oview(world.view, get_master_holder()))
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.Beam(victim, icon_state = "lichbeam", time = 2 SECONDS)
var/atom/A = get_master_holder()
A.visible_message(
"<span class='alien'>[bicon(get_master_holder())] \The [get_master_holder()] sends noxious spores toward \the [carrier]. A sickly light emanates from them!</span>")
/datum/artifact_effect/extreme/lifesteal/DoEffectTouch(mob/living/user)
if (user && isliving(user))
steal(user)
/datum/artifact_effect/extreme/lifesteal/DoEffectPulse()
var/mob/living/target = locate() in oview(world.view, get_turf(get_master_holder()))
if(target)
steal(target)

View File

@@ -0,0 +1,33 @@
/datum/artifact_effect/common/noxious
name = "sweating"
var/list/reagents = list()
effect_type = EFFECT_PARTICLE
effect_color = "#5f7a5f"
effect_state = "puffs"
/datum/artifact_effect/common/noxious/proc/offgas()
var/mob/living/L = locate() in oview(get_master_holder())
if(!istype(L))
return
if(prob(20) && !L.stat) // There's some active living thing nearby, produce offgas.
var/atom/A = get_master_holder()
A.visible_message("<span class='alien'>[bicon(get_master_holder())] \The [get_master_holder()] disgorches a cloud of noxious gas!</span>")
var/turf/T = get_turf(get_master_holder())
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()
/datum/artifact_effect/common/noxious/DoEffectTouch()
offgas()
/datum/artifact_effect/common/noxious/DoEffectAura()
offgas()
/datum/artifact_effect/common/noxious/DoEffectPulse()
offgas()

View File

@@ -0,0 +1,26 @@
/datum/artifact_effect/common/sprinting
name = "fortify"
effect_color = "#84ad87"
effect_type = EFFECT_ENERGY
/datum/artifact_effect/common/sprinting/DoEffectTouch(mob/living/user)
if (user && isliving(user))
user.add_modifier(/datum/modifier/sprinting, 2 MINUTES)
/datum/artifact_effect/common/sprinting/DoEffectAura()
var/atom/holder = get_master_holder()
if (holder)
var/turf/T = get_turf(holder)
for (var/mob/living/L in range(src.effectrange,T))
if (prob(10))
L.add_modifier(/datum/modifier/sprinting, 10 SECONDS)
/datum/artifact_effect/common/sprinting/DoEffectPulse()
var/atom/holder = get_master_holder()
if (holder)
var/turf/T = get_turf(holder)
for (var/mob/living/L in range(src.effectrange,T))
L.add_modifier(/datum/modifier/sprinting, 30 SECONDS)

View File

@@ -0,0 +1,72 @@
/datum/artifact_effect/common/sweating
name = "sweating"
var/list/reagents = list()
effect_type = EFFECT_ORGANIC
effect_state = "oozes"
/datum/artifact_effect/common/sweating/New(datum/component/artifact_master/newmaster)
reagents += list(list(pick(SSchemistry.chemical_reagents), 0.4, list()))
if(prob(33))
reagents += list(list("blood",
0.6,
list("blood_colour" = rgb(rand(1,255),rand(1,255),rand(1,255)))))
// Sample the color of the combined reagents
var/datum/reagents/R = new(120)
for(var/list/chem in reagents)
R.add_reagent(chem[1], chem[2], chem[3])
effect_color = R.get_color()
qdel(R)
..()
effect = EFFECT_TOUCH
/datum/artifact_effect/common/sweating/proc/disgorge(var/turf/T, var/min_chargelevel = 0.25)
if(chargelevel < chargelevelmax * min_chargelevel)
return
spawn()
var/obj/effect/vfx/water/splash = new(T)
splash.create_reagents(15)
splash.reagents.add_reagent("blood", 10, list("blood_colour" = effect_color))
splash.set_color()
splash.set_up(T, 2, 3)
var/obj/effect/decal/cleanable/chemcoating/blood = locate() in T
if(!istype(blood))
blood = new(T)
for(var/list/chem in reagents)
blood.reagents.add_reagent(chem[0], chem[1] * chargelevel, LAZYLEN(chem) > 2 ? chem[2] : null)
blood.update_icon()
chargelevel = round(0.8 * chargelevel)
// Leave a trail of "disgusting ooze"
/datum/artifact_effect/common/sweating/UpdateMove(var/turf/old_loc)
disgorge(old_loc)
/datum/artifact_effect/common/sweating/DoEffectTouch(mob/living/carbon/human/user)
if(ishuman(user))
user.bloody_hands()
if(chargelevel >= 40 && prob(20))
user.visible_message(
"<span class='alium'>\The [get_master_holder()] shudders at \the [user]'s touch, before spraying a disgusting ooze everywhere.</span>",
"<span class='alium'>\The [get_master_holder()] shudders at your touch, before spraying a disgusting ooze all over you!</span>",
"<span class='notice'>A spray of liquid is followed by a fleshy slop hitting the ground.</span>")
if(ishuman(user))
user.bloody_body()
disgorge(get_turf(user), 0)
/datum/artifact_effect/common/sweating/attackby(mob/living/user, obj/item/I)
if(I.is_open_container())
to_chat(user, "<span class='alien'>You hold \the [I] against \the [get_master_holder()], and a disgusting pus dribbles into \the [I].</span>")
for(var/list/chem in reagents)
I.reagents.add_reagent(chem[0], chem[1] * chargelevel, LAZYLEN(chem) > 2 ? chem[2] : null)
return TRUE
else
I.add_blood(src)
return FALSE

View File

@@ -0,0 +1,37 @@
/datum/artifact_effect/extreme/tesla
name = "tesla"
effect_color = "#f5f231"
effect_type = EFFECT_ELECTRO
effect_state = "sparks"
/datum/artifact_effect/extreme/tesla/New()
. = ..()
effect = pick(EFFECT_TOUCH, EFFECT_PULSE)
/datum/artifact_effect/extreme/tesla/proc/arc(var/list/exempt = list())
var/atom/A = get_master_holder()
A.visible_message("<span class='danger'>\The [get_master_holder()] discharges energy wildly in all directions!</span>")
for(var/mob/living/L in oview(world.view, get_turf(get_master_holder())))
if(chargelevel < 3)
break
if(L in exempt)
continue
var/obj/item/projectile/P = new /obj/item/projectile/beam/shock(get_turf(get_master_holder()))
P.launch_projectile(L, BP_TORSO, get_master_holder())
chargelevel -= 3
/datum/artifact_effect/extreme/tesla/DoEffectTouch(mob/living/user)
if(chargelevel < 3)
return
arc(list(user))
/datum/artifact_effect/extreme/tesla/DoEffectPulse()
if(chargelevel < 3)
return
arc()

View File

@@ -1525,7 +1525,6 @@
#include "code\modules\awaymissions\trigger.dm" #include "code\modules\awaymissions\trigger.dm"
#include "code\modules\awaymissions\zlevel.dm" #include "code\modules\awaymissions\zlevel.dm"
#include "code\modules\blob2\_defines.dm" #include "code\modules\blob2\_defines.dm"
#include "code\modules\blob2\core_chunk.dm"
#include "code\modules\blob2\blobs\base_blob.dm" #include "code\modules\blob2\blobs\base_blob.dm"
#include "code\modules\blob2\blobs\core.dm" #include "code\modules\blob2\blobs\core.dm"
#include "code\modules\blob2\blobs\factory.dm" #include "code\modules\blob2\blobs\factory.dm"
@@ -3225,14 +3224,18 @@
#include "code\modules\xenoarcheaology\effects\animate_anomaly.dm" #include "code\modules\xenoarcheaology\effects\animate_anomaly.dm"
#include "code\modules\xenoarcheaology\effects\badfeeling.dm" #include "code\modules\xenoarcheaology\effects\badfeeling.dm"
#include "code\modules\xenoarcheaology\effects\berserk.dm" #include "code\modules\xenoarcheaology\effects\berserk.dm"
#include "code\modules\xenoarcheaology\effects\blast_shielding.dm"
#include "code\modules\xenoarcheaology\effects\cannibal.dm" #include "code\modules\xenoarcheaology\effects\cannibal.dm"
#include "code\modules\xenoarcheaology\effects\cellcharge.dm" #include "code\modules\xenoarcheaology\effects\cellcharge.dm"
#include "code\modules\xenoarcheaology\effects\celldrain.dm" #include "code\modules\xenoarcheaology\effects\celldrain.dm"
#include "code\modules\xenoarcheaology\effects\cold.dm" #include "code\modules\xenoarcheaology\effects\cold.dm"
#include "code\modules\xenoarcheaology\effects\electric_field.dm" #include "code\modules\xenoarcheaology\effects\electric_field.dm"
#include "code\modules\xenoarcheaology\effects\emp.dm" #include "code\modules\xenoarcheaology\effects\emp.dm"
#include "code\modules\xenoarcheaology\effects\extinguisher.dm"
#include "code\modules\xenoarcheaology\effects\faraday.dm"
#include "code\modules\xenoarcheaology\effects\feysight.dm" #include "code\modules\xenoarcheaology\effects\feysight.dm"
#include "code\modules\xenoarcheaology\effects\forcefield.dm" #include "code\modules\xenoarcheaology\effects\forcefield.dm"
#include "code\modules\xenoarcheaology\effects\fortify.dm"
#include "code\modules\xenoarcheaology\effects\gaia.dm" #include "code\modules\xenoarcheaology\effects\gaia.dm"
#include "code\modules\xenoarcheaology\effects\gasco2.dm" #include "code\modules\xenoarcheaology\effects\gasco2.dm"
#include "code\modules\xenoarcheaology\effects\gasnitro.dm" #include "code\modules\xenoarcheaology\effects\gasnitro.dm"
@@ -3244,14 +3247,21 @@
#include "code\modules\xenoarcheaology\effects\heal.dm" #include "code\modules\xenoarcheaology\effects\heal.dm"
#include "code\modules\xenoarcheaology\effects\heat.dm" #include "code\modules\xenoarcheaology\effects\heat.dm"
#include "code\modules\xenoarcheaology\effects\hurt.dm" #include "code\modules\xenoarcheaology\effects\hurt.dm"
#include "code\modules\xenoarcheaology\effects\indiscriminate_spines.dm"
#include "code\modules\xenoarcheaology\effects\lifedrain.dm"
#include "code\modules\xenoarcheaology\effects\lifesteal.dm"
#include "code\modules\xenoarcheaology\effects\noxious.dm"
#include "code\modules\xenoarcheaology\effects\poltergeist.dm" #include "code\modules\xenoarcheaology\effects\poltergeist.dm"
#include "code\modules\xenoarcheaology\effects\radiate.dm" #include "code\modules\xenoarcheaology\effects\radiate.dm"
#include "code\modules\xenoarcheaology\effects\resurrect.dm" #include "code\modules\xenoarcheaology\effects\resurrect.dm"
#include "code\modules\xenoarcheaology\effects\roboheal.dm" #include "code\modules\xenoarcheaology\effects\roboheal.dm"
#include "code\modules\xenoarcheaology\effects\robohurt.dm" #include "code\modules\xenoarcheaology\effects\robohurt.dm"
#include "code\modules\xenoarcheaology\effects\sleepy.dm" #include "code\modules\xenoarcheaology\effects\sleepy.dm"
#include "code\modules\xenoarcheaology\effects\sprinting.dm"
#include "code\modules\xenoarcheaology\effects\stun.dm" #include "code\modules\xenoarcheaology\effects\stun.dm"
#include "code\modules\xenoarcheaology\effects\sweating_reagents.dm"
#include "code\modules\xenoarcheaology\effects\teleport.dm" #include "code\modules\xenoarcheaology\effects\teleport.dm"
#include "code\modules\xenoarcheaology\effects\tesla.dm"
#include "code\modules\xenoarcheaology\effects\vampire.dm" #include "code\modules\xenoarcheaology\effects\vampire.dm"
#include "code\modules\xenoarcheaology\finds\eguns.dm" #include "code\modules\xenoarcheaology\finds\eguns.dm"
#include "code\modules\xenoarcheaology\finds\find_spawning.dm" #include "code\modules\xenoarcheaology\finds\find_spawning.dm"