mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-08-25 06:06:34 +01:00
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:
@@ -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
|
||||
|
||||
@@ -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>")
|
||||
@@ -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)
|
||||
|
||||
@@ -72,18 +72,5 @@
|
||||
return TRUE
|
||||
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
|
||||
hit_zones = list("mass")
|
||||
hit_zones = list("mass")
|
||||
|
||||
@@ -26,7 +26,9 @@
|
||||
/mob/living/simple_mob/animal/space/alien,
|
||||
/mob/living/simple_mob/animal/space/bear,
|
||||
/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
|
||||
spawn_type = pick(\
|
||||
/mob/living/simple_mob/animal/passive/cat,
|
||||
|
||||
@@ -68,29 +68,31 @@
|
||||
/datum/artifact_effect/proc/ToggleActivate(reveal_toggle = TRUE)
|
||||
set waitfor = FALSE
|
||||
var/atom/target = get_master_holder()
|
||||
if (world.time - last_activation > 1 SECOND)
|
||||
last_activation = world.time
|
||||
if (world.time - last_activation < 1 SECOND)
|
||||
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)
|
||||
activated = 0
|
||||
display_msg = pick("momentarily glows brightly!","distorts slightly for a moment!","flickers slightly!","vibrates!","shimmers slightly for a moment!")
|
||||
else
|
||||
activated = 1
|
||||
if (reveal_toggle && target)
|
||||
if (!isliving(target))
|
||||
target.update_icon()
|
||||
var/display_msg
|
||||
display_msg = pick("grows dull!","fades in intensity!","suddenly becomes very still!","suddenly becomes very quiet!")
|
||||
if (active_effect)
|
||||
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
|
||||
display_msg = pick("grows dull!","fades in intensity!","suddenly becomes very still!","suddenly becomes very quiet!")
|
||||
if (active_effect)
|
||||
if (activated)
|
||||
target.underlays.Add(active_effect)
|
||||
else
|
||||
target.underlays.Remove(active_effect)
|
||||
var/atom/toplevelholder = target
|
||||
while (!istype(toplevelholder.loc, /turf))
|
||||
toplevelholder = toplevelholder.loc
|
||||
toplevelholder.visible_message("<font color='red'>[bicon(toplevelholder)] [toplevelholder] [display_msg]</font>")
|
||||
target.underlays.Remove(active_effect)
|
||||
var/atom/toplevelholder = target
|
||||
while (!istype(toplevelholder.loc, /turf))
|
||||
toplevelholder = toplevelholder.loc
|
||||
toplevelholder.visible_message("<font color='red'>[bicon(toplevelholder)] [toplevelholder] [display_msg]</font>")
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/artifact_effect/proc/DoEffectTouch(mob/living/user)
|
||||
@@ -105,10 +107,13 @@
|
||||
return
|
||||
|
||||
|
||||
/datum/artifact_effect/proc/UpdateMove()
|
||||
/datum/artifact_effect/proc/UpdateMove(var/turf/old_loc)
|
||||
return
|
||||
|
||||
|
||||
/datum/artifact_effect/proc/attackby(mob/living/user, obj/item/I)
|
||||
return FALSE
|
||||
|
||||
/datum/artifact_effect/proc/getDescription()
|
||||
. = "<b>"
|
||||
switch (effect_type)
|
||||
|
||||
@@ -294,37 +294,39 @@
|
||||
|
||||
|
||||
/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)
|
||||
|
||||
if (istype(W, /obj/item/reagent_containers))
|
||||
if(W.reagents.has_reagent("hydrogen", 1) || W.reagents.has_reagent("water", 1))
|
||||
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))
|
||||
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))
|
||||
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))
|
||||
if(my_effect.trigger == TRIGGER_TOXIN)
|
||||
my_effect.ToggleActivate()
|
||||
return my_effect.ToggleActivate()
|
||||
else if(istype(W,/obj/item/melee/baton) && W:status ||\
|
||||
istype(W,/obj/item/melee/energy) ||\
|
||||
istype(W,/obj/item/melee/cultblade) ||\
|
||||
istype(W,/obj/item/card/emag) ||\
|
||||
istype(W,/obj/item/multitool))
|
||||
if (my_effect.trigger == TRIGGER_ENERGY)
|
||||
my_effect.ToggleActivate()
|
||||
return my_effect.ToggleActivate()
|
||||
|
||||
else if (istype(W,/obj/item/flame) && W:lit ||\
|
||||
istype(W,/obj/item/weldingtool) && W:welding)
|
||||
if(my_effect.trigger == TRIGGER_HEAT)
|
||||
my_effect.ToggleActivate()
|
||||
return my_effect.ToggleActivate()
|
||||
else
|
||||
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()
|
||||
var/datum/reagent/Touching = args[2]
|
||||
@@ -348,10 +350,13 @@
|
||||
if(my_effect.trigger == TRIGGER_TOXIN)
|
||||
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)
|
||||
if(my_effect)
|
||||
my_effect.UpdateMove()
|
||||
my_effect.UpdateMove(old_loc)
|
||||
|
||||
/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.
|
||||
@@ -369,10 +374,6 @@
|
||||
if(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
|
||||
var/trigger_cold = 0
|
||||
var/trigger_hot = 0
|
||||
@@ -426,4 +427,3 @@
|
||||
//NITROGEN GAS ACTIVATION
|
||||
if(my_effect.trigger == TRIGGER_NITRO && (trigger_nitro ^ my_effect.activated))
|
||||
my_effect.ToggleActivate()
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
|
||||
/datum/artifact_effect/common/animate_anomaly/ToggleActivate(reveal_toggle = TRUE)
|
||||
..()
|
||||
. = ..()
|
||||
find_target()
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -19,6 +19,9 @@
|
||||
if (env)
|
||||
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()
|
||||
var/atom/holder = get_master_holder()
|
||||
@@ -26,3 +29,6 @@
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if (env && env.temperature > target_temp)
|
||||
env.temperature -= pick(0, 0, 1)
|
||||
var/turf/simulated/T = get_turf(holder)
|
||||
if(istype(T))
|
||||
T.freeze_floor()
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
/datum/artifact_effect/uncommon/forcefield/ToggleActivate()
|
||||
var/atom/holder = get_master_holder()
|
||||
..()
|
||||
. = ..()
|
||||
if (created_field.len)
|
||||
for (var/obj/effect/energy_field/F in created_field)
|
||||
created_field.Remove(F)
|
||||
@@ -29,7 +29,6 @@
|
||||
E.invisibility = 0
|
||||
spawn(10)
|
||||
UpdateMove()
|
||||
return 1
|
||||
|
||||
|
||||
/datum/artifact_effect/uncommon/forcefield/process()
|
||||
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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()
|
||||
Reference in New Issue
Block a user