mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-26 14:39:58 +01:00
Adds a few (very) basic hallucinations, to keep people on their toes (#70251)
Spoiler alert!
Adds a few extra "weird" fake body hallucinations.
These just pop up a weird sprite somewhere in the view of the player.
Another fun thing: Body hallucinations will appear to be floating if they spawn in nograv areas.
Adds a "watcher" hallucination, a strange static figure that sticks on your screen until either a few minutes elapse. If you step out of view of it, then return, it will disappear.
Adds a variant of the "fake death" hallucination which appears as if you were dusted.
Adds two delusion - One that makes everyone appear to be ghosts, and one that makes everyone appear to be syndicates.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/// Makes a random body appear and disappear quickly.
|
||||
/// Makes a random body appear and disappear quickly in view of the hallucinator.
|
||||
/datum/hallucination/body
|
||||
abstract_hallucination_parent = /datum/hallucination/body
|
||||
/// The file to make the body image from.
|
||||
@@ -7,6 +7,8 @@
|
||||
var/body_image_state
|
||||
/// The actual image we made and showed show.
|
||||
var/image/shown_body
|
||||
/// Whether we apply the floating anim to the body
|
||||
var/body_floats = FALSE
|
||||
/// The layer this body will be drawn on, in case we want to bypass lighting
|
||||
var/body_layer = TURF_LAYER
|
||||
/// if TRUE, spawns the body under the hallucinator instead of somewhere in view
|
||||
@@ -21,13 +23,19 @@
|
||||
if(spawn_under_hallucinator)
|
||||
possible_points += get_turf(hallucinator)
|
||||
else
|
||||
for(var/turf/open/floor/open_floor in view(hallucinator))
|
||||
possible_points += open_floor
|
||||
for(var/turf/open/open_turf in view(hallucinator))
|
||||
if(open_turf.is_blocked_turf())
|
||||
continue
|
||||
possible_points += open_turf
|
||||
|
||||
if(!length(possible_points))
|
||||
return FALSE
|
||||
|
||||
shown_body = make_body_image(pick(possible_points))
|
||||
var/turf/picked = pick(possible_points)
|
||||
if(isspaceturf(picked) || !picked.has_gravity())
|
||||
body_floats = TRUE
|
||||
|
||||
shown_body = make_body_image(picked)
|
||||
|
||||
hallucinator.client?.images |= shown_body
|
||||
return queue_cleanup()
|
||||
@@ -43,15 +51,18 @@
|
||||
|
||||
/// Makes the image of the body to show at the location passed.
|
||||
/datum/hallucination/body/proc/make_body_image(turf/location)
|
||||
return image(body_image_file, location, body_image_state, body_layer)
|
||||
var/image/created_image = image(body_image_file, location, body_image_state, body_layer)
|
||||
if(body_floats)
|
||||
DO_FLOATING_ANIM(created_image)
|
||||
return created_image
|
||||
|
||||
/datum/hallucination/body/husk
|
||||
random_hallucination_weight = 4
|
||||
random_hallucination_weight = 8
|
||||
body_image_file = 'icons/mob/species/human/human.dmi'
|
||||
body_image_state = "husk"
|
||||
|
||||
/datum/hallucination/body/husk/sideways
|
||||
random_hallucination_weight = 2
|
||||
random_hallucination_weight = 4
|
||||
|
||||
/datum/hallucination/body/husk/sideways/make_body_image(turf/location)
|
||||
var/image/body = ..()
|
||||
@@ -60,19 +71,101 @@
|
||||
body.transform = turn_matrix
|
||||
return body
|
||||
|
||||
/datum/hallucination/body/alien
|
||||
/datum/hallucination/body/ghost
|
||||
random_hallucination_weight = 2
|
||||
body_image_file = 'icons/mob/simple/mob.dmi'
|
||||
body_image_state = "ghost"
|
||||
body_floats = TRUE
|
||||
|
||||
/datum/hallucination/body/hole
|
||||
random_hallucination_weight = 1
|
||||
body_image_file = 'icons/effects/effects.dmi'
|
||||
body_image_state = "blank"
|
||||
|
||||
/datum/hallucination/body/staticguy
|
||||
random_hallucination_weight = 1
|
||||
body_image_file = 'icons/effects/effects.dmi'
|
||||
body_image_state = "static"
|
||||
/// Our QDEL_IN timer id, so we can cancel it
|
||||
var/del_timerid
|
||||
|
||||
/datum/hallucination/body/staticguy/Destroy()
|
||||
if(!QDELETED(hallucinator))
|
||||
UnregisterSignal(hallucinator, COMSIG_MOVABLE_MOVED)
|
||||
if(del_timerid)
|
||||
deltimer(del_timerid)
|
||||
del_timerid = null
|
||||
return ..()
|
||||
|
||||
/datum/hallucination/body/staticguy/queue_cleanup()
|
||||
RegisterSignal(hallucinator, COMSIG_MOVABLE_MOVED, .proc/on_move)
|
||||
del_timerid = QDEL_IN(src, rand(2 MINUTES, 3 MINUTES))
|
||||
return TRUE
|
||||
|
||||
/// Signal proc for [COMSIG_MOVABLE_MOVED] - if we move out of view of the hallucination, it disappears, how spooky
|
||||
/datum/hallucination/body/staticguy/proc/on_move(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
// Entering its turf will cause it to fade out then delete
|
||||
if(shown_body.loc == hallucinator.loc)
|
||||
animate(shown_body, alpha = 0, time = 0.5 SECONDS)
|
||||
deltimer(del_timerid)
|
||||
del_timerid = QDEL_IN(src, 0.6 SECONDS)
|
||||
return
|
||||
|
||||
// Staying in view will do nothing
|
||||
if(shown_body.loc in view(hallucinator))
|
||||
return
|
||||
|
||||
// Leaving view will delete it immediately
|
||||
deltimer(del_timerid)
|
||||
del_timerid = null
|
||||
qdel(src)
|
||||
|
||||
/datum/hallucination/body/weird
|
||||
random_hallucination_weight = 0.1 // These are very uncommon
|
||||
abstract_hallucination_parent = /datum/hallucination/body/weird
|
||||
|
||||
/datum/hallucination/body/weird/alien
|
||||
body_image_file = 'icons/mob/nonhuman-player/alien.dmi'
|
||||
body_image_state = "alienother"
|
||||
body_floats = TRUE
|
||||
|
||||
/datum/hallucination/body/freezer
|
||||
random_hallucination_weight = 1
|
||||
/datum/hallucination/body/weird/mini_bubblegum
|
||||
body_image_file = 'icons/mob/simple/mob.dmi'
|
||||
body_image_state = "horror"
|
||||
|
||||
/datum/hallucination/body/weird/chrono
|
||||
body_image_file = 'icons/mob/simple/mob.dmi'
|
||||
body_image_state = "chronostuck"
|
||||
body_floats = TRUE
|
||||
|
||||
/datum/hallucination/body/weird/god
|
||||
body_image_file = 'icons/mob/simple/mob.dmi'
|
||||
body_image_state = "god"
|
||||
body_floats = TRUE
|
||||
|
||||
/datum/hallucination/body/weird/sling
|
||||
body_image_file = 'icons/mob/simple/mob.dmi'
|
||||
body_image_state = "shadowling_ascended"
|
||||
body_floats = TRUE
|
||||
|
||||
/datum/hallucination/body/weird/faceless
|
||||
body_image_file = 'icons/mob/simple/simple_human.dmi'
|
||||
body_image_state = "faceless"
|
||||
|
||||
/datum/hallucination/body/weird/bones
|
||||
body_image_file = 'icons/mob/simple/simple_human.dmi'
|
||||
body_image_state = "mrbones"
|
||||
|
||||
/datum/hallucination/body/weird/freezer
|
||||
random_hallucination_weight = 0.3 // Slightly more common since it's cool (heh)
|
||||
body_image_file = 'icons/effects/effects.dmi'
|
||||
body_image_state = "the_freezer"
|
||||
body_layer = ABOVE_ALL_MOB_LAYER
|
||||
spawn_under_hallucinator = TRUE
|
||||
|
||||
/datum/hallucination/body/freezer/make_body_image(turf/location)
|
||||
/datum/hallucination/body/weird/freezer/make_body_image(turf/location)
|
||||
var/image/body = ..()
|
||||
body.pixel_x = pick(rand(-208,-48), rand(48, 208))
|
||||
body.pixel_y = pick(rand(-208,-48), rand(48, 208))
|
||||
@@ -80,20 +173,19 @@
|
||||
SET_PLANE_EXPLICIT(body, ABOVE_HUD_PLANE, location)
|
||||
return body
|
||||
|
||||
/datum/hallucination/body/freezer/queue_cleanup()
|
||||
/datum/hallucination/body/weird/freezer/queue_cleanup()
|
||||
QDEL_IN(src, 12 SECONDS) //The freezer stays on screen while you're frozen
|
||||
addtimer(CALLBACK(src, .proc/freeze_player), 1 SECONDS) // You barely have a moment to react before you're frozen
|
||||
addtimer(CALLBACK(src, .proc/freeze_intimidate), 11.8 SECONDS)
|
||||
hallucinator.cause_hallucination(/datum/hallucination/fake_sound/weird/radio_static, "freezer hallucination")
|
||||
return TRUE
|
||||
|
||||
/datum/hallucination/body/freezer/proc/freeze_player()
|
||||
/datum/hallucination/body/weird/freezer/proc/freeze_player()
|
||||
if(QDELETED(src))
|
||||
return
|
||||
hallucinator.cause_hallucination(/datum/hallucination/ice, "freezer hallucination", duration = 11 SECONDS, play_freeze_sound = FALSE)
|
||||
|
||||
|
||||
/datum/hallucination/body/freezer/proc/freeze_intimidate()
|
||||
/datum/hallucination/body/weird/freezer/proc/freeze_intimidate()
|
||||
if(QDELETED(src))
|
||||
return
|
||||
// Spook 'em before we delete
|
||||
|
||||
@@ -26,24 +26,30 @@
|
||||
|
||||
/datum/hallucination/delusion/New(
|
||||
mob/living/hallucinator,
|
||||
duration = 30 SECONDS,
|
||||
affects_us = TRUE,
|
||||
affects_others = FALSE,
|
||||
skip_nearby = TRUE,
|
||||
play_wabbajack = FALSE,
|
||||
duration,
|
||||
affects_us,
|
||||
affects_others,
|
||||
skip_nearby,
|
||||
play_wabbajack,
|
||||
)
|
||||
|
||||
src.duration = duration
|
||||
src.affects_us = affects_us
|
||||
src.affects_others = affects_others
|
||||
src.skip_nearby = skip_nearby
|
||||
src.play_wabbajack = play_wabbajack
|
||||
if(isnum(duration))
|
||||
src.duration = duration
|
||||
if(!isnull(affects_us))
|
||||
src.affects_us = affects_us
|
||||
if(!isnull(affects_others))
|
||||
src.affects_others = affects_others
|
||||
if(!isnull(skip_nearby))
|
||||
src.skip_nearby = skip_nearby
|
||||
if(!isnull(play_wabbajack))
|
||||
src.play_wabbajack = play_wabbajack
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/hallucination/delusion/Destroy()
|
||||
if(!QDELETED(hallucinator))
|
||||
for(var/image/to_remove as anything in delusions)
|
||||
hallucinator.client?.images -= to_remove
|
||||
if(!QDELETED(hallucinator) && LAZYLEN(delusions))
|
||||
hallucinator.client?.images -= delusions
|
||||
LAZYNULL(delusions)
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -99,11 +105,11 @@
|
||||
|
||||
/datum/hallucination/delusion/custom/New(
|
||||
mob/living/hallucinator,
|
||||
duration = 30 SECONDS,
|
||||
affects_us = TRUE,
|
||||
affects_others = FALSE,
|
||||
skip_nearby = FALSE,
|
||||
play_wabbajack = FALSE,
|
||||
duration,
|
||||
affects_us,
|
||||
affects_others,
|
||||
skip_nearby,
|
||||
play_wabbajack,
|
||||
custom_icon_file,
|
||||
custom_icon_state,
|
||||
custom_name,
|
||||
@@ -167,11 +173,50 @@
|
||||
delusion_name = "demon"
|
||||
|
||||
/datum/hallucination/delusion/preset/cyborg
|
||||
play_wabbajack = TRUE
|
||||
delusion_icon_file = 'icons/mob/silicon/robots.dmi'
|
||||
delusion_icon_state = "robot"
|
||||
delusion_name = "cyborg"
|
||||
play_wabbajack = TRUE
|
||||
|
||||
/datum/hallucination/delusion/preset/cyborg/make_delusion_image(mob/over_who)
|
||||
. = ..()
|
||||
hallucinator.playsound_local(get_turf(over_who), 'sound/voice/liveagain.ogg', 75, TRUE)
|
||||
|
||||
/datum/hallucination/delusion/preset/ghost
|
||||
delusion_icon_file = 'icons/mob/simple/mob.dmi'
|
||||
delusion_icon_state = "ghost"
|
||||
delusion_name = "ghost"
|
||||
affects_others = TRUE
|
||||
|
||||
/datum/hallucination/delusion/preset/ghost/make_delusion_image(mob/over_who)
|
||||
var/image/funny_image = ..()
|
||||
funny_image.name = over_who.name
|
||||
DO_FLOATING_ANIM(funny_image)
|
||||
return funny_image
|
||||
|
||||
/datum/hallucination/delusion/preset/syndies
|
||||
random_hallucination_weight = 1
|
||||
delusion_icon_file = 'icons/mob/simple/simple_human.dmi'
|
||||
delusion_icon_state = "syndicate_space"
|
||||
delusion_name = "Syndicate"
|
||||
affects_others = TRUE
|
||||
affects_us = FALSE
|
||||
|
||||
/datum/hallucination/delusion/preset/syndies/make_delusion_image(mob/over_who)
|
||||
var/static/list/syndicate_icon_states
|
||||
|
||||
if(!syndicate_icon_states)
|
||||
syndicate_icon_states = list()
|
||||
for(var/state in icon_states(delusion_icon_file))
|
||||
if(!findtext(state, "syndicate"))
|
||||
continue
|
||||
|
||||
syndicate_icon_states += state
|
||||
|
||||
if(length(syndicate_icon_states) > 0)
|
||||
delusion_name = over_who.name
|
||||
delusion_icon_state = pick(syndicate_icon_states)
|
||||
else
|
||||
stack_trace("Hey! The hallucination [type] couldn't find a single icon state to use, it'll be invisible. Correct this.")
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// This hallucinations makes us suddenly think we died, stopping us / changing our hud / sending a fake deadchat message.
|
||||
/datum/hallucination/death
|
||||
random_hallucination_weight = 1
|
||||
|
||||
@@ -80,3 +81,55 @@
|
||||
|
||||
if(!QDELETED(src))
|
||||
qdel(src)
|
||||
|
||||
// A subtype of death which plays a dusted animation.
|
||||
/datum/hallucination/death/dust
|
||||
/// List of all images we created to convey the effect to the hallucinator (so we can remove them after)
|
||||
var/list/image/created_images
|
||||
|
||||
/datum/hallucination/death/dust/Destroy()
|
||||
if(!QDELETED(hallucinator) && LAZYLEN(created_images))
|
||||
hallucinator.client?.images -= created_images
|
||||
LAZYNULL(created_images)
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/hallucination/death/dust/start()
|
||||
|
||||
if(!ishuman(hallucinator))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/human/hallucinating_human = hallucinator
|
||||
var/dust_icon_state = hallucinating_human.dna?.species?.dust_anim
|
||||
if(!dust_icon_state)
|
||||
return FALSE
|
||||
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
created_images = list()
|
||||
var/turf/below_hallucinating = get_turf(hallucinator)
|
||||
|
||||
// Apply a blank / empty image to make them look invisible to themselves
|
||||
var/image/make_them_invisible = image(loc = hallucinator)
|
||||
make_them_invisible.override = TRUE
|
||||
created_images += make_them_invisible
|
||||
|
||||
// Grab the typepath of the dust animation visual so we can steal its icon (for consistency and futureproofing)
|
||||
var/obj/effect/temp_visual/dust_animation/dust_source = /obj/effect/temp_visual/dust_animation
|
||||
var/image/fake_dust_animation = image(initial(dust_source.icon), below_hallucinating, dust_icon_state, layer = ABOVE_MOB_LAYER)
|
||||
created_images += fake_dust_animation
|
||||
|
||||
// Grab the typepath of remains so we can steal its icon and state (futureproofing)
|
||||
var/obj/effect/decal/remains/human/remains_source = /obj/effect/decal/remains/human
|
||||
var/image/fake_remains_image = image(initial(remains_source.icon), below_hallucinating, initial(remains_source.icon_state))
|
||||
created_images += fake_remains_image
|
||||
|
||||
// Grab the typepath of an observer so we can steal its icon and state (futureproofing)
|
||||
var/mob/dead/observer/observer_source = /mob/dead/observer
|
||||
var/image/fake_ghost = image(initial(observer_source.icon), below_hallucinating, initial(observer_source.icon_state))
|
||||
DO_FLOATING_ANIM(fake_ghost)
|
||||
created_images += fake_ghost
|
||||
|
||||
hallucinator.client?.images |= created_images
|
||||
|
||||
Reference in New Issue
Block a user