Files
Bubberstation/code/modules/hallucination/body.dm
Funce 60bfb76832 [MIRROR] Dynamic Human Icon Generation For Simple/Basic Mobs (& Cardboard Cutouts) [MDB IGNORE] (#18884)
* Dynamic Human Icon Generation For Simple/Basic Mobs (& Cardboard Cutouts) (#72517)

revive of #68760
this time a proc, not an element
this time supports cardboard cutouts
this time supports mob corpses

![image](https://user-images.githubusercontent.com/23585223/211064291-81070650-189f-4afa-8116-81b687e3ea35.png)

prevents these icons ever being outdated, they'll always look what they
are supposed to, saves spriting work

🆑 Fikou, a hood by Viro
refactor: humanoid mobs and cardboard cutouts automatically generate
their sprites, they no longer will be outdated
/🆑

Co-authored-by: Time-Green <timkoster1@hotmail.com>

* Modular!

* Fix signal override merge skew (#72882)

Caused by https://github.com/tgstation/tgstation/pull/72517, with
https://github.com/tgstation/tgstation/pull/72561 raising an error that
was being hidden before

This changes equip logic somewhat so that set_wearer was being called
twice.

I don't think this should be being run in visualsOnly at all, as it does
a ton of stuff like registering signals, updating UI, etc etc etc. Don't
have time to investigate further.

---------

Co-authored-by: Fikou <23585223+Fikou@users.noreply.github.com>
Co-authored-by: Time-Green <timkoster1@hotmail.com>
Co-authored-by: GoldenAlpharex <jerego1234@hotmail.com>
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
2023-01-27 13:56:00 -05:00

194 lines
6.2 KiB
Plaintext

/// 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.
var/body_image_file
/// The icon state to make the body image form.
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
var/spawn_under_hallucinator = FALSE
/datum/hallucination/body/start()
// This hallucination is purely visual, so we don't need to bother for clientless mobs
if(!hallucinator.client)
return FALSE
var/list/possible_points = list()
if(spawn_under_hallucinator)
possible_points += get_turf(hallucinator)
else
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
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()
/datum/hallucination/body/proc/queue_cleanup()
QDEL_IN(src, rand(3 SECONDS, 5 SECONDS)) //Only seen for a brief moment.
return TRUE
/datum/hallucination/body/Destroy()
hallucinator.client?.images -= shown_body
shown_body = null
return ..()
/// Makes the image of the body to show at the location passed.
/datum/hallucination/body/proc/make_body_image(turf/location)
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 = 8
body_image_file = 'icons/mob/species/human/human.dmi'
body_image_state = "husk"
/datum/hallucination/body/husk/sideways
random_hallucination_weight = 4
/datum/hallucination/body/husk/sideways/make_body_image(turf/location)
var/image/body = ..()
var/matrix/turn_matrix = matrix()
turn_matrix.Turn(90)
body.transform = turn_matrix
return body
/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_REF(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/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/traders.dmi'
body_image_state = "faceless"
/datum/hallucination/body/weird/bones
body_image_file = 'icons/mob/simple/traders.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/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))
body.alpha = 245
SET_PLANE_EXPLICIT(body, ABOVE_HUD_PLANE, location)
return body
/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_REF(freeze_player)), 1 SECONDS) // You barely have a moment to react before you're frozen
addtimer(CALLBACK(src, PROC_REF(freeze_intimidate)), 11.8 SECONDS)
hallucinator.cause_hallucination(/datum/hallucination/fake_sound/weird/radio_static, "freezer hallucination")
return TRUE
/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/weird/freezer/proc/freeze_intimidate()
if(QDELETED(src))
return
// Spook 'em before we delete
shown_body.pixel_x = (shown_body.pixel_x / 2)
shown_body.pixel_y = (shown_body.pixel_y / 2)