You can draw faces on bots (#95258)

## About The Pull Request

Adds the ability to use a pen or crayon or spraycan to draw a face or
eyes onto certain bots
This allows people who miss the pareidolia of the old medkit sprite to
fix it themselves
You can clean it off again using most cleaning products, if you disagree

<img width="649" height="220" alt="image"
src="https://github.com/user-attachments/assets/de4869b8-9ac1-4c79-8890-bd95fd4fcaa1"
/>

I think from looking at this screenshot apparently I haven't enabled
pixel perfect 2x on my laptop for which i should be executed, sorry

I didn't add any for ones not pictured here because I couldn't think of
a good way to draw them but it's simple enough to expand.
The face will be coloured with whatever ink you used to draw it, I was
just lazy and only used a regular pen in this picture
How are all of the non-white drawing implements adding that white
circle? Don't worry about it

This comes in the form of a component so if you want to make other
things easily graffitable then you can do that
I ironically called it the defaceable component even though it's used to
add faces

## Why It's Good For The Game

It seems like something people have been wanting and it seemed like a
cute idea

## Changelog

🆑
add: You can draw faces onto some bots using a pen, crayon, or spraycan
/🆑
This commit is contained in:
Jacquerel
2026-03-04 23:55:05 +00:00
committed by GitHub
parent f315a0dea2
commit a5c9662caa
10 changed files with 154 additions and 7 deletions
@@ -108,6 +108,8 @@ GLOBAL_LIST_INIT(command_strings, list(
var/list/original_allies
/// If true we will offer this
COOLDOWN_DECLARE(offer_ghosts_cooldown)
/// List of overlays to add to the bot if someone has drawn on it, index to a boolean of whether it should ignore paint colour
var/list/facepaint_overlays
/mob/living/basic/bot/Initialize(mapload)
. = ..()
@@ -149,6 +151,13 @@ GLOBAL_LIST_INIT(command_strings, list(
if(mapload && is_station_level(z) && (bot_mode_flags & BOT_MODE_CAN_BE_SAPIENT) && (bot_mode_flags & BOT_MODE_ROUNDSTART_POSSESSION))
enable_possession(mapload = mapload)
if (length(facepaint_overlays))
AddComponent(/datum/component/defaceable, \
icon = 'icons/mob/silicon/aibot_faces.dmi', \
icon_states = facepaint_overlays, \
drawing_of = "a face", \
)
pa_system = (isnull(announcement_type)) ? new(src, automated_announcements = generate_speak_list()) : new announcement_type(src, automated_announcements = generate_speak_list())
pa_system.Grant(src)
ai_controller.set_blackboard_key(BB_ANNOUNCE_ABILITY, pa_system)
@@ -19,6 +19,7 @@
possessed_message = "You are a cleanbot! Clean the station to the best of your ability!"
ai_controller = /datum/ai_controller/basic_controller/bot/cleanbot
path_image_color = "#993299"
facepaint_overlays = list("cleanbot" = FALSE, "cleanbot_highlight" = TRUE)
///the bucket used to build us.
var/obj/item/reagent_containers/cup/bucket/build_bucket
///Flags indicating what kind of cleanables we should scan for to set as our target to clean.
@@ -28,6 +28,9 @@
announcement_type = /datum/action/cooldown/bot_announcement/medbot
path_image_color = "#d9d9f4"
///Because of our animation we need to handle drawn-on overlays ourself
var/painted_face_colour
///anouncements when we find a target to heal
var/static/list/wait_announcements = list(
MEDIBOT_VOICED_HOLD_ON = 'sound/mobs/non-humanoids/medbot/coming.ogg',
@@ -140,6 +143,11 @@
post_tipped_callback = CALLBACK(src, PROC_REF(after_tip_over)), \
post_untipped_callback = CALLBACK(src, PROC_REF(after_righted)))
AddComponent(/datum/component/defaceable, \
drawing_of = "eyes", \
on_defaced = CALLBACK(src, PROC_REF(on_defaced)), \
)
var/static/list/hat_offsets = list(4,-9)
var/static/list/remove_hat = list(SIGNAL_ADDTRAIT(TRAIT_MOB_TIPPED))
var/static/list/prevent_checks = list(TRAIT_MOB_TIPPED)
@@ -193,13 +201,24 @@
if(!(medical_mode_flags & MEDBOT_STATIONARY_MODE))
. += mutable_appearance(icon, "[base_icon_state]_overlay_wheels")
if(HAS_TRAIT(src, TRAIT_INCAPACITATED))
. += mutable_appearance(icon, "[base_icon_state]_overlay_incapacitated")
. += emissive_appearance(icon, "[base_icon_state]_overlay_incapacitated", src, alpha = src.alpha)
else if(bot_mode_flags & BOT_MODE_ON)
var/mode_suffix = mode == BOT_HEALING ? "active" : "idle"
. += mutable_appearance(icon, "[base_icon_state]_overlay_on_[mode_suffix]")
. += emissive_appearance(icon, "[base_icon_state]_overlay_on_[mode_suffix]", src, alpha = src.alpha)
var/mode_suffix = mode == BOT_HEALING ? "active" : "idle"
if (HAS_TRAIT(src, TRAIT_DEFACED))
var/mutable_appearance/face = mutable_appearance('icons/mob/silicon/aibot_faces.dmi', "medbot_[mode_suffix]")
face.color = painted_face_colour
. += face
. += mutable_appearance('icons/mob/silicon/aibot_faces.dmi', "medbot_highlight_[mode_suffix]")
else
if(HAS_TRAIT(src, TRAIT_INCAPACITATED))
. += mutable_appearance(icon, "[base_icon_state]_overlay_incapacitated")
. += emissive_appearance(icon, "[base_icon_state]_overlay_incapacitated", src, alpha = src.alpha)
else if(bot_mode_flags & BOT_MODE_ON)
. += mutable_appearance(icon, "[base_icon_state]_overlay_on_[mode_suffix]")
. += emissive_appearance(icon, "[base_icon_state]_overlay_on_[mode_suffix]", src, alpha = src.alpha)
/// Set our drawn-on ink colour
/mob/living/basic/bot/medbot/proc/on_defaced(ink_colour)
SIGNAL_HANDLER
painted_face_colour = ink_colour
//this is sin
/mob/living/basic/bot/medbot/generate_speak_list()