mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-20 03:25:49 +01:00
[PTBF] Adds blob hallucinations in dark areas (#27722)
* [PTBF] Adds blob hallucinations in dark areas This hallucination looks for dark, unobstructed tiles within view of the hallucinating target, and gradually expands a blob from one of those tiles. It also spawns a blob zombie nearby. If the blob zombie knocks the target down, the target will hallucinate becoming a blob zombie. * Blob hallucination icon fix/change, add vomit sfx Blob zombies now appropriately spawn their heads, and as requested in PR review, the first blob spawned will have a core icon, and will be accompanied by a vomit sound effect, like actual blobs. Additionally, the blob zombie will no longer attack the target after already once knocking them down. * Apply suggestions from code review Remove unnecessary nulls Change return signature of blob_zombie#think to match convention Set blob_zombie's name in typedef instead of initializer Declare source_turf in loop body in blob#expand Add nullchecks and safety check for deleted targets in blob#Destroy Format blob hallucination colors list Return qdel hint in blob#Initialize instead of qdeling self Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> Signed-off-by: asciodev <81930475+asciodev@users.noreply.github.com> * Prevent blob zombie hallucination name from being overwritten when created Signed-off-by: asciodev <81930475+asciodev@users.noreply.github.com> * DM doesn't like parentheses on their own lines apparently * Enable dynamic blob hallucination expansion count Co-authored-by: Drsmail <60036448+Drsmail@users.noreply.github.com> --------- Signed-off-by: asciodev <81930475+asciodev@users.noreply.github.com> Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> Co-authored-by: Drsmail <60036448+Drsmail@users.noreply.github.com>
This commit is contained in:
@@ -329,3 +329,150 @@
|
||||
target.visible_message("<span class='warning'>[target] recoils as if hit by something, before suddenly collapsing!</span>",
|
||||
"<span class='userdanger'>[name] has [attack_verb] [target]!</span>")
|
||||
QDEL_IN(src, 3 SECONDS)
|
||||
|
||||
/obj/effect/hallucination/blob
|
||||
duration = 30 SECONDS
|
||||
/// The blob zombie hallucination.
|
||||
var/obj/effect/hallucination/chaser/attacker/blob_zombie/zombie
|
||||
/// The self delusion blob zombie hallucination, triggers on knockdown.
|
||||
var/obj/effect/hallucination/blob_zombify/player_zombie
|
||||
/// List of turfs that need expanding from.
|
||||
var/list/turf/expand_queue = list()
|
||||
/// Associative list of turfs that have already been processed.
|
||||
var/list/turf/processed = list()
|
||||
/// The image for the chaser zombie's blob head
|
||||
var/image/chaser_blob_head
|
||||
/// The image for the player zombie's blob head
|
||||
var/image/target_blob_head
|
||||
/// The delay at which the blob expands in deciseconds. Shouldn't be too low to prevent lag.
|
||||
var/expand_delay
|
||||
/// The amount of time in deciseconds the hallucination should continue after final expansion.
|
||||
var/conclude_delay = 2 SECONDS
|
||||
/// Expand timer handle.
|
||||
var/expand_timer
|
||||
|
||||
/obj/effect/hallucination/blob/Initialize(mapload, mob/living/carbon/target, expansions = 4)
|
||||
. = ..()
|
||||
expand_delay = (duration - conclude_delay) / max(1, expansions)
|
||||
var/list/locs = list()
|
||||
for(var/turf/T in oview(world.view / 2, target))
|
||||
var/light_amount = T.get_lumcount()
|
||||
if(!is_blocked_turf(T) && light_amount <= 0.5)
|
||||
locs += T
|
||||
if(!length(locs))
|
||||
return INITIALIZE_HINT_QDEL
|
||||
var/turf/T = get_turf(pick(locs))
|
||||
color = pick(COLOR_BLACK,
|
||||
COLOR_RIPPING_TENDRILS,
|
||||
COLOR_BOILING_OIL,
|
||||
COLOR_ENVENOMED_FILAMENTS,
|
||||
COLOR_LEXORIN_JELLY,
|
||||
COLOR_KINETIC_GELATIN,
|
||||
COLOR_CRYOGENIC_LIQUID,
|
||||
COLOR_SORIUM,
|
||||
COLOR_TESLIUM_PASTE)
|
||||
create_blob(T, core = TRUE)
|
||||
target.playsound_local(T, 'sound/effects/splat.ogg', 50, 1)
|
||||
create_zombie(T)
|
||||
expand_queue += T
|
||||
processed[T] = TRUE
|
||||
expand_timer = addtimer(CALLBACK(src, PROC_REF(expand)), expand_delay, TIMER_LOOP | TIMER_STOPPABLE)
|
||||
|
||||
/obj/effect/hallucination/blob/Destroy()
|
||||
deltimer(expand_timer)
|
||||
expand_queue.Cut()
|
||||
processed.Cut()
|
||||
QDEL_NULL(zombie)
|
||||
QDEL_NULL(player_zombie)
|
||||
if(!QDELETED(target))
|
||||
target.client?.images -= chaser_blob_head
|
||||
target.client?.images -= target_blob_head
|
||||
chaser_blob_head = null
|
||||
target_blob_head = null
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Called regularly in a timer to process the blob expanding.
|
||||
*/
|
||||
/obj/effect/hallucination/blob/proc/expand()
|
||||
// Brace for potentially expensive proc
|
||||
for(var/turf/source_turf as anything in expand_queue)
|
||||
expand_queue -= source_turf
|
||||
//Expand to each dir
|
||||
for(var/direction in GLOB.cardinal)
|
||||
var/turf/target_turf = get_step(source_turf, direction)
|
||||
if(processed[target_turf] || !source_turf.CanAtmosPass(direction) || !target_turf.CanAtmosPass(turn(direction, 180)))
|
||||
continue
|
||||
create_blob(target_turf)
|
||||
expand_queue += target_turf
|
||||
processed[target_turf] = TRUE
|
||||
|
||||
/**
|
||||
* Creates a fake blob overlay on the given turf.
|
||||
*
|
||||
* Arguments:
|
||||
* * T - The turf to create a fake blob overlay on.
|
||||
*/
|
||||
/obj/effect/hallucination/blob/proc/create_blob(turf/T, core = FALSE)
|
||||
var/blob_icon_state = "blob"
|
||||
if(core)
|
||||
blob_icon_state = "blob_core"
|
||||
var/image/I = image('icons/mob/blob.dmi', T, blob_icon_state, layer = FLY_LAYER)
|
||||
I.plane = GAME_PLANE
|
||||
I.color = color
|
||||
add_icon(I)
|
||||
|
||||
/obj/effect/hallucination/blob/proc/create_zombie(turf/T)
|
||||
zombie = new(T, target, src)
|
||||
|
||||
/obj/effect/hallucination/blob/proc/zombify(turf/T)
|
||||
player_zombie = new(T, target, src)
|
||||
|
||||
/obj/effect/hallucination/chaser/attacker/blob_zombie
|
||||
name = "blob zombie"
|
||||
hallucination_icon = 'icons/mob/human.dmi'
|
||||
hallucination_icon_state = "zombie2_s"
|
||||
duration = 45 SECONDS
|
||||
damage = 25
|
||||
/// The hallucination that spawned us.
|
||||
var/obj/effect/hallucination/blob/owning_hallucination = null
|
||||
/// Whether or not the target has been zombified already.
|
||||
var/has_zombified = FALSE
|
||||
|
||||
/obj/effect/hallucination/chaser/attacker/blob_zombie/Initialize(mapload, mob/living/carbon/target, obj/effect/hallucination/blob/blob)
|
||||
. = ..()
|
||||
name = "blob zombie"
|
||||
var/image/I = image('icons/mob/blob.dmi', src, "blob_head")
|
||||
I.color = blob.color
|
||||
target.client.images += I
|
||||
owning_hallucination = blob
|
||||
blob.chaser_blob_head = I
|
||||
|
||||
/obj/effect/hallucination/chaser/attacker/blob_zombie/attack_effects()
|
||||
do_attack_animation(target)
|
||||
target.playsound_local(get_turf(src), 'sound/weapons/genhit1.ogg', 50, TRUE)
|
||||
to_chat(target, "<span class='userdanger'>[name] has hit [target]!</span>")
|
||||
|
||||
/obj/effect/hallucination/chaser/attacker/blob_zombie/on_knockdown()
|
||||
if(!QDELETED(owning_hallucination))
|
||||
target.visible_message("<span class='warning'>[target] recoils as if hit by something, before suddenly collapsing!</span>",
|
||||
"<span class='warning'>The corpse of [target.name] suddenly rises!</span>")
|
||||
owning_hallucination.zombify(target)
|
||||
has_zombified = TRUE
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/hallucination/chaser/attacker/blob_zombie/think()
|
||||
if(has_zombified)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/effect/hallucination/blob_zombify
|
||||
duration = 20 SECONDS
|
||||
|
||||
/obj/effect/hallucination/blob_zombify/Initialize(mapload, mob/living/carbon/target, obj/effect/hallucination/blob/blob)
|
||||
. = ..()
|
||||
var/image/I = image('icons/mob/blob.dmi', target, icon_state = "blob_head")
|
||||
I.color = blob.color
|
||||
target.client.images += I
|
||||
blob.target_blob_head = I
|
||||
|
||||
@@ -32,6 +32,7 @@ GLOBAL_LIST_INIT(hallucinations, list(
|
||||
/obj/effect/hallucination/fake_grenade/spawner = 10,
|
||||
/obj/effect/hallucination/terror_infestation = 10,
|
||||
/obj/effect/hallucination/loose_energy_ball = 10,
|
||||
/obj/effect/hallucination/blob = 10,
|
||||
/datum/hallucination_manager/xeno_pounce = 10
|
||||
)
|
||||
))
|
||||
|
||||
Reference in New Issue
Block a user