mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-29 18:40:42 +00:00
* 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  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>
194 lines
6.2 KiB
Plaintext
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)
|