Merge remote-tracking branch 'upstream/master' into job_refactor_tg

This commit is contained in:
Tigercat2000
2017-02-25 05:42:47 -08:00
195 changed files with 4145 additions and 3442 deletions
+14 -2
View File
@@ -169,7 +169,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
else
var/response
var/alertmsg = "Are you -sure- you want to ghost?\n([warningmsg]. If you ghost now, you probably won't be able to rejoin the round! You can't change your mind, so choose wisely!)"
response = alert(src, alertmsg,"Are you sure you want to ghost?","Ghost","Stay in body")
response = alert(src, alertmsg,"Are you sure you want to ghost?","Stay in body","Ghost")
if(response != "Ghost")
return //didn't want to ghost after-all
resting = 1
@@ -641,10 +641,22 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
client.images -= ghostimage //remove ourself
/mob/proc/can_admin_interact()
return 0
return FALSE
/mob/proc/can_advanced_admin_interact()
return FALSE
/mob/dead/observer/can_admin_interact()
return check_rights(R_ADMIN, 0, src)
/mob/dead/observer/can_advanced_admin_interact()
if(!can_admin_interact())
return FALSE
if(client && client.advanced_admin_interaction)
return TRUE
return FALSE
//this is a mob verb instead of atom for performance reasons
//see /mob/verb/examinate() in mob.dm for more info
+9
View File
@@ -37,3 +37,12 @@
return
. = src.emote_dead(message)
/mob/dead/observer/handle_track(var/message, var/verb = "says", var/datum/language/language, var/mob/speaker = null, var/speaker_name, var/atom/follow_target, var/hard_to_hear)
return "[speaker_name] ([ghost_follow_link(follow_target, ghost=src)])"
/mob/dead/observer/handle_speaker_name(var/mob/speaker = null, var/vname, var/hard_to_hear)
var/speaker_name = ..()
if(speaker && (speaker_name != speaker.real_name) && !isAI(speaker)) //Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs.
speaker_name = "[speaker.real_name] ([speaker_name])"
return speaker_name
+18 -59
View File
@@ -117,65 +117,8 @@
if(hard_to_hear)
message = stars(message)
var/speaker_name = "unknown"
if(speaker)
speaker_name = speaker.name
if(vname)
speaker_name = vname
if(hard_to_hear)
speaker_name = "unknown"
var/changed_voice
if(isAI(src) && !hard_to_hear)
var/jobname // the mob's "job"
var/mob/living/carbon/human/impersonating //The crewmember being impersonated, if any.
if(ishuman(speaker))
var/mob/living/carbon/human/H = speaker
var/obj/item/weapon/card/id/id = H.wear_id
if((istype(id) && id.is_untrackable()) && H.HasVoiceChanger())
changed_voice = 1
var/mob/living/carbon/human/I = locate(speaker_name)
if(I)
impersonating = I
jobname = impersonating.get_assignment()
else
jobname = "Unknown"
else
jobname = H.get_assignment()
else if(iscarbon(speaker)) // Nonhuman carbon mob
jobname = "No ID"
else if(isAI(speaker))
jobname = "AI"
else if(isrobot(speaker))
jobname = "Cyborg"
else if(ispAI(speaker))
jobname = "Personal AI"
else if(isAutoAnnouncer(speaker))
var/mob/living/automatedannouncer/AA = speaker
jobname = AA.role
else
jobname = "Unknown"
if(changed_voice)
if(impersonating)
track = "<a href='byond://?src=[UID()];track=\ref[impersonating]'>[speaker_name] ([jobname])</a>"
else
track = "[speaker_name] ([jobname])"
else
if(istype(follow_target, /mob/living/simple_animal/bot))
track = "<a href='byond://?src=[UID()];trackbot=\ref[follow_target]'>[speaker_name] ([jobname])</a>"
else
track = "<a href='byond://?src=[UID()];track=\ref[speaker]'>[speaker_name] ([jobname])</a>"
if(isobserver(src))
if(speaker && (speaker_name != speaker.real_name) && !isAI(speaker)) //Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs.
speaker_name = "[speaker.real_name] ([speaker_name])"
track = "[speaker_name] ([ghost_follow_link(follow_target, ghost=src)])"
var/speaker_name = handle_speaker_name(speaker, vname, hard_to_hear)
track = handle_track(message, verb, language, speaker, speaker_name, follow_target, hard_to_hear)
var/formatted
if(language)
@@ -190,6 +133,22 @@
else
to_chat(src, "[part_a][speaker_name][part_b][formatted]</span></span>")
/mob/proc/handle_speaker_name(var/mob/speaker = null, var/vname, var/hard_to_hear)
var/speaker_name = "unknown"
if(speaker)
speaker_name = speaker.name
if(vname)
speaker_name = vname
if(hard_to_hear)
speaker_name = "unknown"
return speaker_name
/mob/proc/handle_track(var/message, var/verb = "says", var/datum/language/language, var/mob/speaker = null, var/speaker_name, var/atom/follow_target, var/hard_to_hear)
return
/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null)
if(!client)
return
@@ -82,6 +82,17 @@ I'm using this for Stat to give it a more nifty interface to work with
/mob/living/carbon/brain/proc/has_synthetic_assistance()
return (container && istype(container, /obj/item/device/mmi)) || in_contents_of(/obj/mecha)
/mob/living/carbon/brain/proc/get_race()
if(container)
var/obj/item/device/mmi/M = container
if(istype(M) && M.held_brain)
return M.held_brain.dna.get_species_name()
else
return "Artificial Life"
if(istype(loc, /obj/item/organ/internal/brain))
var/obj/item/organ/internal/brain/B = loc
return B.dna.get_species_name()
/mob/living/carbon/brain/Stat()
..()
if(has_synthetic_assistance())
@@ -494,7 +494,8 @@
msg += "<span class = 'deptradio'>Medical records:</span> <a href='?src=[UID()];medrecord=`'>\[View\]</a> <a href='?src=[UID()];medrecordadd=`'>\[Add comment\]</a>\n"
if(print_flavor_text()) msg += "[print_flavor_text()]\n"
if(print_flavor_text() && !skipface)
msg += "[print_flavor_text()]\n"
msg += "*---------*</span>"
if(pose)
+11 -15
View File
@@ -1049,12 +1049,11 @@
if(R.fields["id"] == E.fields["id"])
if(hasHUD(usr,"medical"))
read = 1
var/counter = 1
while(R.fields[text("com_[]", counter)])
to_chat(usr, text("[]", R.fields[text("com_[]", counter)]))
counter++
if(counter == 1)
to_chat(usr, "No comment found")
if(length(R.fields["comments"]))
for(var/c in R.fields["comments"])
to_chat(usr, c)
else
to_chat(usr, "<span class='warning'>No comment found</span>")
to_chat(usr, "<a href='?src=[UID()];medrecordadd=`'>\[Add comment\]</a>")
if(!read)
@@ -1076,18 +1075,15 @@
for(var/datum/data/record/R in data_core.medical)
if(R.fields["id"] == E.fields["id"])
if(hasHUD(usr,"medical"))
var/t1 = sanitize(copytext(input("Add Comment:", "Med. records", null, null) as message,1,MAX_MESSAGE_LEN))
if( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"medical")) )
var/t1 = copytext(trim(sanitize(input("Add Comment:", "Med. records", null, null) as message)), 1, MAX_MESSAGE_LEN)
if(!t1 || usr.stat || usr.restrained() || !hasHUD(usr, "medical"))
return
var/counter = 1
while(R.fields[text("com_[]", counter)])
counter++
if(istype(usr,/mob/living/carbon/human))
if(ishuman(usr))
var/mob/living/carbon/human/U = usr
R.fields[text("com_[counter]")] = text("Made by [U.get_authentification_name()] ([U.get_assignment()]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]<BR>[t1]")
if(istype(usr,/mob/living/silicon/robot))
R.fields["comments"] += "Made by [U.get_authentification_name()] ([U.get_assignment()]) on [current_date_string] [worldtime2text()]<BR>[t1]"
if(isrobot(usr))
var/mob/living/silicon/robot/U = usr
R.fields[text("com_[counter]")] = text("Made by [U.name] ([U.modtype] [U.braintype]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]<BR>[t1]")
R.fields["comments"] += "Made by [U.name] ([U.modtype] [U.braintype]) on [current_date_string] [worldtime2text()]<BR>[t1]"
if(href_list["lookitem"])
var/obj/item/I = locate(href_list["lookitem"])
+4 -2
View File
@@ -105,7 +105,9 @@
/mob/living/carbon/human/handle_speech_problems(var/message, var/verb)
var/list/returns[3]
var/speech_problem_flag = 0
var/span = mind.speech_span
var/span = ""
if(mind)
span = mind.speech_span
if(silent || (disabilities & MUTE))
message = ""
@@ -228,4 +230,4 @@
if(istype(r_ear, /obj/item/device/radio/headset))
R = r_ear
if(R.translate_binary)
. = TRUE
. = TRUE
@@ -298,6 +298,10 @@
scream_verb = "shrieks"
male_scream_sound = 'sound/voice/shriek1.ogg'
female_scream_sound = 'sound/voice/shriek1.ogg'
male_cough_sounds = list('sound/voice/shriekcough.ogg')
female_cough_sounds = list('sound/voice/shriekcough.ogg')
male_sneeze_sound = 'sound/voice/shrieksneeze.ogg'
female_sneeze_sound = 'sound/voice/shrieksneeze.ogg'
icon_skin_tones = list(
1 = "Default Green",
+2 -1
View File
@@ -6,7 +6,8 @@
/mob/living/ghostize(can_reenter_corpse = 1)
var/prev_client = client
if(..())
. = ..()
if(.)
if(ranged_ability && prev_client)
ranged_ability.remove_mousepointer(prev_client)
+38 -49
View File
@@ -618,9 +618,10 @@ var/list/ai_verbs_default = list(
sleep(40)
continue
return
return
else if(href_list["open"])
var/mob/target = locate(href_list["open"]) in mob_list
if(target)
open_nearest_door(target)
/mob/living/silicon/ai/bullet_act(var/obj/item/projectile/Proj)
..(Proj)
@@ -1092,52 +1093,6 @@ var/list/ai_verbs_default = list(
aiRadio.interact(src)
/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target)
if(!istype(target))
return
spawn(0)
if(ishuman(target))
var/mob/living/carbon/human/H = target
var/obj/item/weapon/card/id/id = H.wear_id
if(istype(id) && id.is_untrackable())
to_chat(src, "Unable to locate an airlock")
return
if(H.digitalcamo)
to_chat(src, "Unable to locate an airlock")
return
if(!near_camera(target))
to_chat(src, "Target is not near any active cameras.")
return
var/obj/machinery/door/airlock/tobeopened
var/dist = -1
for(var/obj/machinery/door/airlock/D in range(3,target))
if(!D.density)
continue
if(dist < 0)
dist = get_dist(D, target)
// to_chat(world, dist)
tobeopened = D
else
if(dist > get_dist(D, target))
dist = get_dist(D, target)
// to_chat(world, dist)
tobeopened = D
// to_chat(world, "found [tobeopened.name] closer")
else
// to_chat(world, "[D.name] not close enough | [get_dist(D, target)] | [dist]")
if(tobeopened)
switch(alert(src, "Do you want to open \the [tobeopened] for [target]?","Doorknob_v2a.exe","Yes","No"))
if("Yes")
var/nhref = "src=[tobeopened.UID()];aiEnable=7"
tobeopened.Topic(nhref, params2list(nhref), tobeopened, 1)
to_chat(src, "\blue You've opened \the [tobeopened] for [target].")
if("No")
to_chat(src, "\red You deny the request.")
else
to_chat(src, "\red You've failed to open an airlock for [target]")
return
/mob/living/silicon/ai/proc/check_unable(flags = 0)
if(stat == DEAD)
to_chat(usr, "<span class='warning'>You are dead!</span>")
@@ -1234,3 +1189,37 @@ var/list/ai_verbs_default = list(
view_core() //A BYOND bug requires you to be viewing your core before your verbs update
verbs += /mob/living/silicon/ai/proc/choose_modules
malf_picker = new /datum/module_picker
/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target)
if(!istype(target))
return
if(target && target.can_track())
var/obj/machinery/door/airlock/A = null
var/dist = -1
for(var/obj/machinery/door/airlock/D in range(3, target))
if(!D.density)
continue
var/curr_dist = get_dist(D, target)
if(dist < 0)
dist = curr_dist
A = D
else if(dist > curr_dist)
dist = curr_dist
A = D
if(istype(A))
switch(alert(src, "Do you want to open \the [A] for [target]?", "Doorknob_v2a.exe", "Yes", "No"))
if("Yes")
A.AIShiftClick()
to_chat(src, "<span class='notice'>You open \the [A] for [target].</span>")
else
to_chat(src, "<span class='warning'>You deny the request.</span>")
else
to_chat(src, "<span class='warning'>Unable to locate an airlock near [target].</span>")
else
to_chat(src, "<span class='warning'>Target is not on or near any active cameras on the station.</span>")
+67
View File
@@ -1,3 +1,70 @@
/*
* AI Saycode
*/
/mob/living/silicon/ai/handle_track(var/message, var/verb = "says", var/datum/language/language, var/mob/speaker = null, var/speaker_name, var/atom/follow_target, var/hard_to_hear)
if(hard_to_hear)
return
var/jobname // the mob's "job"
var/mob/living/carbon/human/impersonating //The crewmember being impersonated, if any.
var/changed_voice
if(ishuman(speaker))
var/mob/living/carbon/human/H = speaker
var/obj/item/weapon/card/id/id = H.wear_id
if((istype(id) && id.is_untrackable()) && H.HasVoiceChanger())
changed_voice = 1
var/mob/living/carbon/human/I = locate(speaker_name)
if(I)
impersonating = I
jobname = impersonating.get_assignment()
else
jobname = "Unknown"
else
jobname = H.get_assignment()
else if(iscarbon(speaker)) // Nonhuman carbon mob
jobname = "No ID"
else if(isAI(speaker))
jobname = "AI"
else if(isrobot(speaker))
jobname = "Cyborg"
else if(ispAI(speaker))
jobname = "Personal AI"
else if(isAutoAnnouncer(speaker))
var/mob/living/automatedannouncer/AA = speaker
jobname = AA.role
else
jobname = "Unknown"
var/track = ""
var/mob/mob_to_track = null
if(changed_voice)
if(impersonating)
mob_to_track = impersonating
else
track = "[speaker_name] ([jobname])"
else
if(istype(follow_target, /mob/living/simple_animal/bot))
track = "<a href='byond://?src=[UID()];trackbot=\ref[follow_target]'>[speaker_name] ([jobname])</a>"
else
mob_to_track = speaker
if(mob_to_track)
track = "<a href='byond://?src=[UID()];track=\ref[mob_to_track]'>[speaker_name] ([jobname])</a>"
track += "<a href='byond://?src=[UID()];open=\ref[mob_to_track]'>\[OPEN\]</a>"
return track
/*
* AI VOX Announcements
*/
var/announcing_vox = 0 // Stores the time of the last announcement
var/const/VOX_CHANNEL = 200
var/const/VOX_DELAY = 100
@@ -263,6 +263,9 @@
interact(H)
else
return ..()
/mob/living/simple_animal/bot/attack_ghost(mob/M)
interact(M)
/mob/living/simple_animal/bot/attack_ai(mob/user)
if(!topic_denied(user))
@@ -818,7 +821,7 @@ Pass a positive integer as an argument to override a bot's default speed.
return 1
add_fingerprint(usr)
if((href_list["power"]) && (bot_core.allowed(usr) || !locked))
if((href_list["power"]) && (bot_core.allowed(usr) || !locked || usr.can_admin_interact()))
if(on)
turn_off()
else
@@ -838,6 +841,7 @@ Pass a positive integer as an argument to override a bot's default speed.
to_chat(usr, "<span class='warning'>[text_hack]</span>")
show_laws()
bot_reset()
add_logs(usr, src, "hacked")
else if(!hacked)
to_chat(usr, "<span class='userdanger'>[text_dehack_fail]</span>")
else
@@ -846,8 +850,9 @@ Pass a positive integer as an argument to override a bot's default speed.
to_chat(usr, "<span class='notice'>[text_dehack]</span>")
show_laws()
bot_reset()
add_logs(usr, src, "dehacked")
if("ejectpai")
if(paicard && (!locked || issilicon(usr) || check_rights(R_ADMIN, 0, usr)))
if(paicard && (!locked || issilicon(usr) || usr.can_admin_interact()))
to_chat(usr, "<span class='notice'>You eject [paicard] from [bot_name]</span>")
ejectpai(usr)
update_controls()
@@ -867,19 +872,21 @@ Pass a positive integer as an argument to override a bot's default speed.
qdel(src)
/mob/living/simple_animal/bot/proc/topic_denied(mob/user) //Access check proc for bot topics! Remember to place in a bot's individual Topic if desired.
if(user.can_admin_interact())
return 0
if(user.incapacitated() || !(issilicon(user) || in_range(src, user)))
return 1
// 0 for access, 1 for denied.
if(emagged == 2) //An emagged bot cannot be controlled by humans, silicons can if one hacked it.
if(!hacked) //Manually emagged by a human - access denied to all.
return 1
else if(!issilicon(user) && !check_rights(R_ADMIN, 0, user)) //Bot is hacked, so only silicons and admins are allowed access.
else if(!issilicon(user)) //Bot is hacked, so only silicons are allowed access.
return 1
return 0
/mob/living/simple_animal/bot/proc/hack(mob/user)
var/hack
if(issilicon(user) || check_rights(R_ADMIN, 0, user)) //Allows silicons or admins to toggle the emag status of a bot.
if(issilicon(user) || user.can_admin_interact()) //Allows silicons or admins to toggle the emag status of a bot.
hack += "[emagged == 2 ? "Software compromised! Unit may exhibit dangerous or erratic behavior." : "Unit operating normally. Release safety lock?"]<BR>"
hack += "Harm Prevention Safety System: <A href='?src=[UID()];operation=hack'>[emagged ? "<span class='bad'>DANGER</span>" : "Engaged"]</A><BR>"
else if(!locked) //Humans with access can use this option to hide a bot from the AI's remote control panel and PDA control.
@@ -888,7 +895,7 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/proc/showpai(mob/user)
var/eject = ""
if(!locked || issilicon(usr) || check_rights(R_ADMIN, 0, user))
if(!locked || issilicon(usr) || user.can_admin_interact())
if(paicard || allow_pai)
eject += "Personality card status: "
if(paicard)
@@ -204,7 +204,7 @@ Status: []<BR>
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
Maintenance panel panel is [open ? "opened" : "closed"]"},
text("<A href='?src=[UID()];power=1'>[on ? "On" : "Off"]</A>"))
if(!locked || issilicon(user) || check_rights(R_ADMIN, 0, user))
if(!locked || issilicon(user) || user.can_admin_interact())
dat += text({"<BR>Cleans Blood: []<BR>"}, text("<A href='?src=[UID()];operation=blood'>[blood ? "Yes" : "No"]</A>"))
dat += text({"<BR>Patrol station: []<BR>"}, text("<A href='?src=[UID()];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A>"))
return dat
@@ -106,7 +106,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]<BR>"},
"<A href='?src=[UID()];power=1'>[on ? "On" : "Off"]</A>" )
if(!locked || issilicon(user) || check_rights(R_ADMIN, 0, user))
if(!locked || issilicon(user) || user.can_admin_interact())
if(!lasercolor)
dat += text({"<BR>
Arrest Unidentifiable Persons: []<BR>
@@ -69,7 +69,7 @@
dat += "Maintenance panel panel is [open ? "opened" : "closed"]<BR>"
dat += "Tiles left: [amount]<BR>"
dat += "Behvaiour controls are [locked ? "locked" : "unlocked"]<BR>"
if(!locked || issilicon(user) || check_rights(R_ADMIN, 0, user))
if(!locked || issilicon(user) || user.can_admin_interact())
dat += "Add tiles to new hull plating: <A href='?src=[UID()];operation=autotile'>[autotile ? "Yes" : "No"]</A><BR>"
dat += "Replace floor tiles: <A href='?src=[UID()];operation=replace'>[replacetiles ? "Yes" : "No"]</A><BR>"
dat += "Finds tiles: <A href='?src=[UID()];operation=tiles'>[eattiles ? "Yes" : "No"]</A><BR>"
@@ -149,7 +149,7 @@
else
dat += "None Loaded"
dat += "<br>Behaviour controls are [locked ? "locked" : "unlocked"]<hr>"
if(!locked || issilicon(user) || check_rights(R_ADMIN, 0, user))
if(!locked || issilicon(user) || user.can_admin_interact())
dat += "<TT>Healing Threshold: "
dat += "<a href='?src=[UID()];adj_threshold=-10'>--</a> "
dat += "<a href='?src=[UID()];adj_threshold=-5'>-</a> "
@@ -284,7 +284,7 @@
dat += "<b>Destination:</b> [!destination ? "<i>none</i>" : destination]<BR>"
dat += "<b>Power level:</b> [cell ? cell.percent() : 0]%"
if(locked && !ai && !check_rights(R_ADMIN, 0, user))
if(locked && !ai && !user.can_admin_interact())
dat += "&nbsp;<br /><div class='notice'>Controls are locked</div><A href='?src=[UID()];op=unlock'>Unlock Controls</A>"
else
dat += "&nbsp;<br /><div class='notice'>Controls are unlocked</div><A href='?src=[UID()];op=lock'>Lock Controls</A><BR><BR>"
@@ -119,7 +119,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
"<A href='?src=[UID()];power=1'>[on ? "On" : "Off"]</A>" )
if(!locked || issilicon(user) || check_rights(R_ADMIN, 0, user))
if(!locked || issilicon(user) || user.can_admin_interact())
dat += text({"<BR>
Arrest Unidentifiable Persons: []<BR>
Arrest for Unauthorized Weapons: []<BR>
@@ -161,8 +161,8 @@
/mob/living/simple_animal/hostile/poison/bees/worker/Found(atom/A)
if(istype(A, /obj/machinery/hydroponics))
var/obj/machinery/hydroponics/Hydro = A
if(Hydro.myseed && !Hydro.dead && !Hydro.recent_bee_visit)
wanted_objects |= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted
if(Hydro.myseed && !Hydro.dead && !Hydro.recent_bee_visit && !Hydro.lid_state)
wanted_objects |= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted and uncovered
return 1
..()
@@ -188,12 +188,12 @@
..()
/mob/living/simple_animal/hostile/poison/bees/worker/proc/pollinate(obj/machinery/hydroponics/Hydro)
if(!istype(Hydro) || !Hydro.myseed || Hydro.dead || Hydro.recent_bee_visit)
if(!istype(Hydro) || !Hydro.myseed || Hydro.dead || Hydro.recent_bee_visit || Hydro.lid_state)
target = null
return
target = null //so we pick a new hydro tray next FindTarget(), instead of loving the same plant for eternity
wanted_objects -= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted
wanted_objects -= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted and uncovered
Hydro.recent_bee_visit = TRUE
spawn(BEE_TRAY_RECENT_VISIT)
if(Hydro)
@@ -470,7 +470,7 @@
if(CHEF)
clothes_s = new /icon(uniform_dmi, "chef_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/head.dmi', "chefhat"), ICON_OVERLAY)
clothes_s.Blend(new /icon('icons/mob/head.dmi', "chef"), ICON_OVERLAY)
if(prob(1))
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "apronchef"), ICON_OVERLAY)
switch(backbag)