mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 09:42:29 +00:00
## About The Pull Request This has the potential to create a lot of needless mob updates which is not great. Now should only update a mob's clothing if it was actually washed. This PR 1) ensures that all wash() procs return a bitflag. 2) ensures that `wash()` proccalls which result in expensive operations like icon updates only do so when it is necessary ## Why It's Good For The Game Updating mob sprites is expensive, and doing it when nothing has been changed is bad. ## Changelog Nothing really player facing
148 lines
4.6 KiB
Plaintext
148 lines
4.6 KiB
Plaintext
|
|
/**
|
|
* Face decal component
|
|
*
|
|
* For when you have some dirt on your face
|
|
*/
|
|
|
|
/datum/component/face_decal
|
|
dupe_mode = COMPONENT_DUPE_HIGHLANDER
|
|
/// Overlay we use for non-carbon mobs
|
|
var/mutable_appearance/normal_overlay
|
|
/// Bodypart overlay we use for carbon mobs
|
|
var/datum/bodypart_overlay/simple/bodypart_overlay
|
|
/// Cached head for carbons, to ensure proper removal of our overlay
|
|
var/obj/item/bodypart/my_head
|
|
/// Base icon state we use for the effect
|
|
var/icon_state
|
|
/// Layers for the bodypart_overlay to draw on
|
|
var/layers
|
|
/// Color that the overlay is modified by
|
|
var/color
|
|
|
|
/datum/component/face_decal/Initialize(icon_state, layers, color)
|
|
src.icon_state = icon_state
|
|
src.layers = layers
|
|
src.color = color
|
|
|
|
/datum/component/face_decal/Destroy(force)
|
|
. = ..()
|
|
normal_overlay = null
|
|
my_head = null
|
|
QDEL_NULL(bodypart_overlay)
|
|
|
|
/datum/component/face_decal/RegisterWithParent()
|
|
if(iscarbon(parent))
|
|
var/mob/living/carbon/human/carbon_parent = parent
|
|
my_head = carbon_parent.get_bodypart(BODY_ZONE_HEAD)
|
|
if(!my_head) //just to be sure
|
|
qdel(src)
|
|
return
|
|
bodypart_overlay = new()
|
|
bodypart_overlay.layers = layers
|
|
if(carbon_parent.bodyshape & BODYSHAPE_SNOUTED) //stupid, but external organ bodytypes are not stored on the limb
|
|
bodypart_overlay.icon_state = "[icon_state]_lizard"
|
|
else if(my_head.bodyshape & BODYSHAPE_MONKEY)
|
|
bodypart_overlay.icon_state = "[icon_state]_monkey"
|
|
else
|
|
bodypart_overlay.icon_state = "[icon_state]_human"
|
|
if (!isnull(color))
|
|
bodypart_overlay.draw_color = color
|
|
my_head.add_bodypart_overlay(bodypart_overlay)
|
|
RegisterSignals(my_head, list(COMSIG_BODYPART_REMOVED, COMSIG_QDELETING), PROC_REF(lost_head))
|
|
else
|
|
normal_overlay = get_normal_overlay()
|
|
normal_overlay.color = color
|
|
|
|
|
|
RegisterSignals(parent, list(
|
|
COMSIG_COMPONENT_CLEAN_ACT,
|
|
COMSIG_COMPONENT_CLEAN_FACE_ACT),
|
|
PROC_REF(clean_up)
|
|
)
|
|
|
|
if (!isnull(normal_overlay))
|
|
if (!isnull(color))
|
|
normal_overlay.color = color
|
|
var/atom/atom_parent = parent
|
|
RegisterSignal(atom_parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(update_overlays))
|
|
atom_parent.update_appearance()
|
|
|
|
/datum/component/face_decal/proc/get_normal_overlay()
|
|
return
|
|
|
|
/datum/component/face_decal/UnregisterFromParent()
|
|
UnregisterSignal(parent, list(
|
|
COMSIG_COMPONENT_CLEAN_ACT,
|
|
COMSIG_COMPONENT_CLEAN_FACE_ACT))
|
|
if(my_head)
|
|
if(bodypart_overlay)
|
|
my_head.remove_bodypart_overlay(bodypart_overlay)
|
|
QDEL_NULL(bodypart_overlay)
|
|
UnregisterSignal(my_head, list(COMSIG_BODYPART_REMOVED, COMSIG_QDELETING))
|
|
my_head = null
|
|
if(normal_overlay)
|
|
var/atom/atom_parent = parent
|
|
UnregisterSignal(atom_parent, COMSIG_ATOM_UPDATE_OVERLAYS)
|
|
atom_parent.update_appearance()
|
|
normal_overlay = null
|
|
|
|
///Callback to remove our decal
|
|
/datum/component/face_decal/proc/clean_up(datum/source, clean_types)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!(clean_types & CLEAN_TYPE_BLOOD))
|
|
return NONE
|
|
|
|
qdel(src)
|
|
return COMPONENT_CLEANED|COMPONENT_CLEANED_GAIN_XP
|
|
|
|
/// Ensures normal_overlay overlay in case the mob is not a carbon
|
|
/datum/component/face_decal/proc/update_overlays(atom/parent_atom, list/overlays)
|
|
SIGNAL_HANDLER
|
|
|
|
if(normal_overlay)
|
|
overlays += normal_overlay
|
|
|
|
/// Removes the decal when the head gets dismembered
|
|
/datum/component/face_decal/proc/lost_head(obj/item/bodypart/source, mob/living/carbon/owner, dismembered)
|
|
SIGNAL_HANDLER
|
|
qdel(src)
|
|
|
|
/// splat subtype, handling signals and mood logic
|
|
|
|
GLOBAL_LIST_INIT(splattable, zebra_typecacheof(list(
|
|
/mob/living/carbon/human = "human",
|
|
/mob/living/basic/pet/dog/corgi = "corgi",
|
|
/mob/living/silicon/ai = "ai",
|
|
)))
|
|
|
|
/datum/component/face_decal/splat
|
|
///The mood_event that we add
|
|
var/mood_event_type
|
|
|
|
/datum/component/face_decal/splat/Initialize(icon_state, layers, color, memory_type = /datum/memory/witnessed_creampie, mood_event_type = /datum/mood_event/creampie)
|
|
if(!is_type_in_typecache(parent, GLOB.splattable))
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
. = ..()
|
|
|
|
SEND_SIGNAL(parent, COMSIG_MOB_HIT_BY_SPLAT, src)
|
|
add_memory_in_range(parent, 7, memory_type, protagonist = parent)
|
|
src.mood_event_type = mood_event_type
|
|
|
|
/datum/component/face_decal/splat/get_normal_overlay()
|
|
return mutable_appearance('icons/mob/effects/face_decal.dmi', "[icon_state]_[is_type_in_list(parent, GLOB.splattable, zebra = TRUE)]")
|
|
|
|
/datum/component/face_decal/splat/RegisterWithParent()
|
|
. = ..()
|
|
if(iscarbon(parent))
|
|
var/mob/living/carbon/human/carbon_parent = parent
|
|
carbon_parent.add_mood_event("splat", mood_event_type)
|
|
|
|
/datum/component/face_decal/splat/UnregisterFromParent()
|
|
. = ..()
|
|
if(iscarbon(parent))
|
|
var/mob/living/carbon/carbon_parent = parent
|
|
carbon_parent.clear_mood_event("splat")
|