"
dat += "Name: "
dat += "[real_name]"
dat += "(Randomize)"
- dat += "(Always Randomize) "
+ dat += "(Always Randomize) "
dat += " | "
dat += ""
dat += "Slot [default_slot][saved ? "" : " (empty)"] "
@@ -748,13 +749,13 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
var/list/html = list()
html += ""
if(!length(SSjobs.occupations))
- html += "The Jobs subsystem is not yet finished creating jobs, please try again later"
- html += "Done " // Easier to press up here.
+ html += "Подсистема вакансий ещё не успела создать вакансии, пожалуйста, повторите попытку позже"
+ html += "Принять " // Easier to press up here.
else
html += ""
- html += "Choose occupation chances Unavailable occupations are crossed out.
"
- html += "Save " // Easier to press up here.
- html += "Left-click to raise an occupation preference, right-click to lower it.
"
+ html += "Выберите предпочитаемые должности Определите приоритет на получение желаемой работы.
"
+ html += "Сохранить " // Easier to press up here.
+ html += "Левый клик - для повышения предпочтения профессии, правый - для понижения.
"
html += ""
html += "" // Table within a table for alignment, also allows you to easily add more colomns.
html += ""
@@ -788,95 +789,96 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
html += " | "
index = 0
+ var/color
+ color = "dark"
+ if(job.admin_only)
+ color = "light"
html += ""
var/rank
if(job.alt_titles)
rank = "[GetPlayerAltTitle(job)]"
else
rank = job.title
+ if((job_support_low & JOB_CIVILIAN) && (job.title != "Civilian"))
+ rank = "[GetPlayerAltTitle(job)]"
lastJob = job
if(!is_job_whitelisted(user, job.title))
- html += "[rank] | \[КАРМА] | "
+ html += "[rank] \[КАРМА] | "
continue
if(jobban_isbanned(user, job.title))
- html += "[rank] \[ЗАБАНЕНО] | "
+ html += "[rank] \[ЗАБАНЕНО] | "
continue
var/available_in_playtime = job.available_in_playtime(user.client)
if(available_in_playtime)
- html += "[rank] \[" + get_exp_format(available_in_playtime) + " за " + job.get_exp_req_type() + "\] | "
+ html += "[rank] \[" + get_exp_format(available_in_playtime) + " за " + job.get_exp_req_type() + "\] | "
continue
if(job.barred_by_disability(user.client))
- html += "[rank] \[ИНВАЛИДНОСТЬ\] | "
+ html += "[rank] \[ИНВАЛИДНОСТЬ\] | "
continue
if(!job.player_old_enough(user.client))
var/available_in_days = job.available_in_days(user.client)
- html += "[rank] \[ЧЕРЕЗ [(available_in_days)] ДНЕЙ] | "
+ html += "[rank] \[ЧЕРЕЗ [(available_in_days)] ДНЕЙ] | "
continue
if(!job.character_old_enough(user.client))
- html += "[rank] \[ВОЗРАСТ ОТ [(job.min_age_allowed)]] | "
- continue
- if((job_support_low & JOB_CIVILIAN) && (job.title != "Civilian"))
- html += "[rank] | "
+ html += "[rank] \[ВОЗРАСТ ОТ [(job.min_age_allowed)]] | "
continue
if((job.title in GLOB.command_positions) || (job.title == "AI"))//Bold head jobs
- html += "[rank]"
+ html += "[rank]"
else
- html += "[rank]"
+ html += "[rank]"
+ if((job_support_low & JOB_CIVILIAN) && (job.title != "Civilian"))
+ html += " | "
+ continue
html += ""
- var/prefLevelLabel = "ERROR"
- var/prefLevelColor = "pink"
+ var/prefLevelLabel = "ОШИБКА"
+ var/prefLevelColor = "bg-danger"
var/prefUpperLevel = -1 // level to assign on left click
var/prefLowerLevel = -1 // level to assign on right click
if(GetJobDepartment(job, 1) & job.flag)
- prefLevelLabel = "High"
- prefLevelColor = "slateblue"
+ prefLevelLabel = "Высокий"
+ prefLevelColor = "btn-primary text-light"
prefUpperLevel = 4
prefLowerLevel = 2
else if(GetJobDepartment(job, 2) & job.flag)
- prefLevelLabel = "Medium"
- prefLevelColor = "green"
+ prefLevelLabel = "Средний"
+ prefLevelColor = "btn-success text-light"
prefUpperLevel = 1
prefLowerLevel = 3
else if(GetJobDepartment(job, 3) & job.flag)
- prefLevelLabel = "Low"
- prefLevelColor = "orange"
+ prefLevelLabel = "Низкий"
+ prefLevelColor = "btn-warning text-dark"
prefUpperLevel = 2
prefLowerLevel = 4
else
- prefLevelLabel = "NEVER"
- prefLevelColor = "red"
+ prefLevelLabel = "НИКОГДА"
+ prefLevelColor = "btn-outline-secondary"
prefUpperLevel = 3
prefLowerLevel = 1
- html += ""
-
- // HTML += ""
+ html += ""
if(job.title == "Civilian")//Civilian is special
if(job_support_low & JOB_CIVILIAN)
- html += " Yes"
+ html += " Да"
else
- html += " No"
+ html += " Нет"
html += " | "
+ index += 1
+ html += "  |   | "
continue
- /*
- if(GetJobDepartment(job, 1) & job.flag)
- HTML += " \[High]"
- else if(GetJobDepartment(job, 2) & job.flag)
- HTML += " \[Medium]"
- else if(GetJobDepartment(job, 3) & job.flag)
- HTML += " \[Low]"
+
+ if(prefLowerLevel>1)
+ html += "[prefLevelLabel]"
else
- HTML += " \[NEVER]"
- */
- html += "[prefLevelLabel]"
+ html += "[prefLevelLabel]"
html += ""
+ index += 1
for(var/i in 1 to limit - index) // Finish the column so it is even
html += "  |   | "
@@ -885,22 +887,23 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
switch(alternate_option)
if(GET_RANDOM_JOB)
- html += " Get random job if preferences unavailable "
+ html += " Получить случайную работу, если предпочитаемая работа недоступна "
if(BE_ASSISTANT)
- html += " Be a civilian if preferences unavailable "
+ html += " Стать гражданским, если предпочитаемая работа недоступна "
if(RETURN_TO_LOBBY)
- html += " Return to lobby if preferences unavailable "
+ html += " Вернуться в лобби, если предпочитаемая работа недоступна "
- html += "Reset"
- html += " Learn About Job Selection"
+ html += "Сброс"
+ html += " Узнать о \"Выборе должности\""
html += ""
user << browse(null, "window=preferences")
// user << browse(HTML, "window=mob_occupation;size=[width]x[height]")
- var/datum/browser/popup = new(user, "mob_occupation", "Occupation Preferences ", width, height)
+ var/datum/browser/popup = new(user, "mob_occupation", "Предпочитаемые должности ", width, height)
popup.set_window_options("can_close=0")
var/html_string = html.Join()
popup.set_content(html_string)
+ popup.add_stylesheet("bootstrap.min.css", 'html/browser/bootstrap.min.css')
popup.open(0)
return
@@ -921,6 +924,15 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
parent?.update_active_keybindings()
return keybindings
+/datum/preferences/proc/null_longtextfix(raw)
+ var/text
+ if(raw)
+ try
+ text = raw
+ catch
+ text = ""
+ return text
+
/datum/preferences/proc/capture_keybinding(mob/user, datum/keybinding/KB, old)
var/HTML = {"
Keybinding: [KB.name]
Press any key to change Press ESC to clear
@@ -1104,11 +1116,18 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
HTML += " Security Records "
if(length(sec_record) <= 40)
- HTML += "[sec_record] "
+ HTML += "[sec_record]"
else
- HTML += "[copytext_char(sec_record, 1, 37)]... "
+ HTML += "[copytext_char(sec_record, 1, 37)]..."
+
+ HTML += " Exploitable Records "
- HTML += "\[Done\]"
+ if(length(exploit_record) <= 40)
+ HTML += "[exploit_record]"
+ else
+ HTML += "[copytext_char(exploit_record, 1, 37)]..."
+
+ HTML += "
\[Done\]"
HTML += ""
var/datum/browser/popup = new(user, "records", "Character Records ", 350, 300)
@@ -1365,6 +1384,15 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
gen_record = genmsg
SetRecords(user)
+ if(href_list["task"] == "exploit_record")
+ var/expmsg = input(usr,"Set your exploitable notes here. This info is available to traitors only.","Exploitable Records",html_decode(exploit_record)) as message
+
+ if(expmsg != null)
+ expmsg = copytext(expmsg, 1, MAX_PAPER_MESSAGE_LEN)
+ expmsg = html_encode(expmsg)
+
+ exploit_record = expmsg
+ SetRecords(user)
if(href_list["preference"] == "gear")
if(href_list["toggle_gear"])
@@ -1518,6 +1546,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
species = tgui_input_list(user, "Please select a species", "Character Generation", sortTim(new_species, cmp = /proc/cmp_text_asc))
if(!species)
+ species = prev_species
return
var/datum/species/NS = GLOB.all_species[species]
if(!istype(NS)) //The species was invalid. Notify the user and fail out.
@@ -1585,7 +1614,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
alt_head = "None" //No alt heads on species that don't have them.
speciesprefs = 0 //My Vox tank shouldn't change how my future Grey talks.
-
+ language = LANGUAGE_NONE
body_accessory = null //no vulptail on humans damnit
body_accessory = random_body_accessory(NS.name, NS.optional_body_accessory)
@@ -1612,14 +1641,18 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
alert(user, "There are not currently any available secondary languages.")
else
*/
- for(var/L in GLOB.all_languages)
- var/datum/language/lang = GLOB.all_languages[L]
- if(!(lang.flags & RESTRICTED))
- new_languages += lang.name
-
- language = tgui_input_list(user, "Please select a secondary language", "Character Generation", sortTim(new_languages, cmp = /proc/cmp_text_asc))
- if(!language)
+ for(var/language_name in GLOB.all_languages)
+ var/datum/language/lang = GLOB.all_languages[language_name]
+ if(lang.flags & UNIQUE)
+ if(language_name in S.secondary_langs)
+ new_languages += language_name
+ else if(!(lang.flags & RESTRICTED))
+ new_languages += language_name
+
+ var/new_language = tgui_input_list(user, "Please select a secondary language", "Character Generation", sortTim(new_languages, cmp = /proc/cmp_text_asc))
+ if(!new_language)
return
+ language = new_language
if("autohiss_mode")
if(S.autohiss_basic_map)
@@ -2200,14 +2233,14 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
if("clientfps")
var/version_message
- if(user.client && user.client.byond_version < 511)
- version_message = "\nYou need to be using byond version 511 or later to take advantage of this feature, your version of [user.client.byond_version] is too low"
- if(world.byond_version < 511)
+ if(user.client && user.client.byond_version < MINIMUM_FPS_VERSION)
+ version_message = "\nYou need to be using byond version [MINIMUM_FPS_VERSION] or later to take advantage of this feature, your version of [user.client.byond_version] is too low"
+ if(world.byond_version < MINIMUM_FPS_VERSION)
version_message += "\nThis server does not currently support client side fps. You can set now for when it does."
var/desiredfps = input(user, "Выберите желаемый FPS.[version_message]\n 0 = значение по умолчанию ([CONFIG_GET(number/clientfps)]) < РЕКОМЕНДОВАНО\n -1 = синхронизировано с сервером ([world.fps])\n30 = Может помочь при проблемах с плавностью.", "Настройка персонажа", clientfps) as null|num
if(!isnull(desiredfps))
clientfps = desiredfps
- if(world.byond_version >= 511 && user.client && user.client.byond_version >= 511)
+ if(world.byond_version >= MINIMUM_FPS_VERSION && user.client && user.client.byond_version >= MINIMUM_FPS_VERSION)
if(clientfps)
parent.fps = clientfps
else
@@ -2585,6 +2618,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
else if(firstspace == name_length)
real_name += "[character.gender==FEMALE ? pick(GLOB.last_names_female) : pick(GLOB.last_names)]"
+
character.add_language(language)
@@ -2596,6 +2630,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
character.med_record = med_record
character.sec_record = sec_record
character.gen_record = gen_record
+ character.exploit_record = exploit_record
character.change_gender(gender)
character.age = age
diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm
index b71da792be3..27ed97fce51 100644
--- a/code/modules/client/preference/preferences_mysql.dm
+++ b/code/modules/client/preference/preferences_mysql.dm
@@ -20,7 +20,8 @@
discord_id,
discord_name,
keybindings,
- viewrange
+ viewrange,
+ ghost_darkness_level
FROM [format_table_name("player")]
WHERE ckey=:ckey"}, list(
"ckey" = C.ckey
@@ -53,6 +54,7 @@
discord_name = query.item[18]
keybindings = init_keybindings(raw = query.item[19])
viewrange = query.item[20]
+ ghost_darkness_level = query.item[21]
qdel(query)
@@ -105,7 +107,8 @@
clientfps=:clientfps,
parallax=:parallax,
keybindings=:keybindings,
- viewrange=:viewrange
+ viewrange=:viewrange,
+ ghost_darkness_level=:ghost_darkness_level
WHERE ckey=:ckey"}, list(
// OH GOD THE PARAMETERS
"ooccolour" = ooccolor,
@@ -125,7 +128,8 @@
"parallax" = parallax,
"keybindings" = json_encode(keybindings_overrides),
"viewrange" = viewrange,
- "ckey" = C.ckey
+ "ghost_darkness_level" = ghost_darkness_level,
+ "ckey" = C.ckey,
)
)
@@ -202,6 +206,7 @@
med_record,
sec_record,
gen_record,
+ exploit_record,
disabilities,
player_alt_titles,
organ_data,
@@ -279,6 +284,7 @@
med_record = query.item[42]
sec_record = query.item[43]
gen_record = query.item[44]
+ exploit_record = null_longtextfix(query.item[45])
// Apparently, the preceding vars weren't always encoded properly...
if(findtext(flavor_text, "<")) // ... so let's clumsily check for tags!
flavor_text = html_encode(flavor_text)
@@ -288,31 +294,33 @@
sec_record = html_encode(sec_record)
if(findtext(gen_record, "<"))
gen_record = html_encode(gen_record)
- disabilities = text2num(query.item[45])
- player_alt_titles = params2list(query.item[46])
- organ_data = params2list(query.item[47])
- rlimb_data = params2list(query.item[48])
- nanotrasen_relation = query.item[49]
- speciesprefs = text2num(query.item[50])
+ if(findtext(exploit_record, "<"))
+ exploit_record = html_encode(exploit_record)
+ disabilities = text2num(query.item[46])
+ player_alt_titles = params2list(query.item[47])
+ organ_data = params2list(query.item[48])
+ rlimb_data = params2list(query.item[49])
+ nanotrasen_relation = query.item[50]
+ speciesprefs = text2num(query.item[51])
//socks
- socks = query.item[51]
- body_accessory = query.item[52]
- loadout_gear = params2list(query.item[53])
- autohiss_mode = text2num(query.item[54])
- uplink_pref = query.item[55]
+ socks = query.item[52]
+ body_accessory = query.item[53]
+ loadout_gear = params2list(query.item[54])
+ autohiss_mode = text2num(query.item[55])
+ uplink_pref = query.item[56]
// TTS
- tts_seed = query.item[56]
+ tts_seed = query.item[57]
//Emotes
- custom_emotes_tmp = query.item[57]
+ custom_emotes_tmp = query.item[58]
// Gradient
- h_grad_style = query.item[58]
- h_grad_offset_x = query.item[59] // parsed down below
- h_grad_colour = query.item[60]
- h_grad_alpha = query.item[61]
+ h_grad_style = query.item[59]
+ h_grad_offset_x = query.item[60] // parsed down below
+ h_grad_colour = query.item[61]
+ h_grad_alpha = query.item[62]
saved = TRUE
@@ -472,6 +480,7 @@
med_record=:med_record,
sec_record=:sec_record,
gen_record=:gen_record,
+ exploit_record=:exploit_record,
player_alt_titles=:playertitlelist,
disabilities=:disabilities,
organ_data=:organlist,
@@ -536,6 +545,7 @@
"med_record" = med_record,
"sec_record" = sec_record,
"gen_record" = gen_record,
+ "exploit_record" = exploit_record,
"playertitlelist" = (playertitlelist ? playertitlelist : ""), // This it intentnional. It wont work without it!
"disabilities" = disabilities,
"organlist" = (organlist ? organlist : ""),
@@ -592,6 +602,7 @@
med_record,
sec_record,
gen_record,
+ exploit_record,
player_alt_titles,
disabilities, organ_data, rlimb_data, nanotrasen_relation, speciesprefs,
socks, body_accessory, gear, autohiss, hair_gradient, hair_gradient_offset, hair_gradient_colour, hair_gradient_alpha, uplink_pref, tts_seed, custom_emotes)
@@ -620,6 +631,7 @@
:med_record,
:sec_record,
:gen_record,
+ :exploit_record,
:playertitlelist,
:disabilities, :organlist, :rlimblist, :nanotrasen_relation, :speciesprefs,
:socks, :body_accessory, :gearlist, :autohiss_mode, :h_grad_style, :h_grad_offset, :h_grad_colour, :h_grad_alpha, :uplink_pref, :tts_seed, :custom_emotes)
@@ -672,6 +684,7 @@
"med_record" = med_record,
"sec_record" = sec_record,
"gen_record" = gen_record,
+ "exploit_record" = exploit_record,
"playertitlelist" = (playertitlelist ? playertitlelist : ""), // This it intentnional. It wont work without it!
"disabilities" = disabilities,
"organlist" = (organlist ? organlist : ""),
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index a0022fb206b..6c4bdf0aa11 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -22,19 +22,22 @@
var/alt_desc = null
var/flash_protect = 0 //What level of bright light protection item has. 1 = Flashers, Flashes, & Flashbangs | 2 = Welding | -1 = OH GOD WELDING BURNT OUT MY RETINAS
var/tint = 0 //Sets the item's level of visual impairment tint, normally set to the same as flash_protect
- var/up = 0 //but seperated to allow items to protect but not impair vision, like space helmets
-
- var/visor_flags = 0 //flags that are added/removed when an item is adjusted up/down
- var/visor_flags_inv = 0 //same as visor_flags, but for flags_inv
- var/visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT | VISOR_VISIONFLAGS | VISOR_DARKNESSVIEW | VISOR_INVISVIEW //what to toggle when toggled with weldingvisortoggle()
-
- var/toggle_message = null
- var/alt_toggle_message = null
- var/active_sound = null
- var/toggle_sound = null
- var/toggle_cooldown = null
+ var/tint_up = 0 // tint when its up
+ var/up = FALSE //but seperated to allow items to protect but not impair vision, like space helmets
+
+ var/visor_flags = NONE //flags that are added/removed when an item is adjusted up/down
+ var/visor_flags_inv = NONE //same as visor_flags, but for flags_inv
+ var/visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT | VISOR_VISIONFLAGS | VISOR_DARKNESSVIEW | VISOR_INVISVIEW | VISOR_FULL_HUD
+ //what to toggle when toggled with weldingvisortoggle()
+
+ var/can_toggle = FALSE
+ var/toggle_on_message
+ var/toggle_off_message
+ var/active_sound
+ var/toggle_sound
+ var/toggle_cooldown = 0
var/cooldown = 0
- var/species_disguise = null
+ var/species_disguise
var/magical = FALSE
var/dyeable = FALSE
var/heal_bodypart = null //If a bodypart or an organ is specified here, it will slowly regenerate while the clothes are worn. Currently only implemented for eyes, though.
@@ -42,44 +45,49 @@
w_class = WEIGHT_CLASS_SMALL
-/obj/item/clothing/proc/weldingvisortoggle(mob/user) //proc to toggle welding visors on helmets, masks, goggles, etc.
- if(!can_use(user))
+/obj/item/clothing/update_icon_state()
+ if(!can_toggle)
return FALSE
+ // Done as such to not break chameleon gear since you can't rely on initial states
+ icon_state = "[replacetext("[icon_state]", "_up", "")][up ? "_up" : ""]"
+ return TRUE
- visor_toggling()
- to_chat(user, "You adjust \the [src] [up ? "up" : "down"].")
+/obj/item/clothing/proc/weldingvisortoggle(mob/user) //proc to toggle welding visors on helmets, masks, goggles, etc.
+ if(!can_use(user))
+ return FALSE
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- H.update_head(src, forced = TRUE)
- if(H.wear_mask == src)
- H.wear_mask_update(src, FALSE)
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
+ visor_toggling(user)
+ to_chat(user, span_notice("You adjust [src] [up ? "up" : "down"]."))
+ update_equipped_item()
return TRUE
+
/obj/item/clothing/proc/visor_toggling() //handles all the actual toggling of flags
+ if(!can_toggle)
+ return FALSE
+
+ . = TRUE
up = !up
flags ^= visor_flags
flags_inv ^= visor_flags_inv
flags_cover ^= initial(flags_cover)
- icon_state = "[initial(icon_state)][up ? "up" : ""]"
if(visor_vars_to_toggle & VISOR_FLASHPROTECT)
flash_protect ^= initial(flash_protect)
if(visor_vars_to_toggle & VISOR_TINT)
- tint ^= initial(tint)
+ tint = up ? tint_up : initial(tint)
+ update_icon(UPDATE_ICON_STATE)
+
// Aurora forensics port.
/obj/item/clothing/clean_blood()
. = ..()
gunshot_residue = null
+
/obj/item/clothing/proc/can_use(mob/user)
- if(user && ismob(user))
- if(!user.incapacitated())
- return TRUE
+ if(isliving(user) && !user.incapacitated())
+ return TRUE
return FALSE
@@ -95,7 +103,7 @@
return FALSE
-/obj/item/clothing/proc/refit_for_species(var/target_species)
+/obj/item/clothing/proc/refit_for_species(target_species)
//Set species_restricted list
switch(target_species)
if("Human", "Skrell") //humanoid bodytypes
@@ -158,6 +166,7 @@
var/list/color_view = null//overrides client.color while worn
var/prescription = FALSE
var/prescription_upgradable = FALSE
+ var/over_hat = FALSE
var/over_mask = FALSE //Whether or not the eyewear is rendered above the mask. Purely cosmetic.
strip_delay = 20 // but seperated to allow items to protect but not impair vision, like space helmets
put_on_delay = 25
@@ -180,6 +189,12 @@ SEE_PIXELS// if an object is located on an unlit area, but some of its pixels ar
BLIND // can't see anything
*/
+
+/obj/item/clothing/glasses/update_icon_state()
+ if(..())
+ item_state = "[replacetext("[item_state]", "_up", "")][up ? "_up" : ""]"
+
+
/obj/item/clothing/glasses/verb/adjust_eyewear() //Adjust eyewear to be worn above or below the mask.
set name = "Adjust Eyewear"
set category = "Object"
@@ -230,20 +245,29 @@ BLIND // can't see anything
return 0 // return 1 to cancel attack_hand()
/obj/item/clothing/gloves/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/wirecutters))
+ if(W.tool_behaviour == TOOL_WIRECUTTER)
if(!clipped)
playsound(src.loc, W.usesound, 100, 1)
user.visible_message("[user] snips the fingertips off [src].","You snip the fingertips off [src].")
- clipped = 1
- name = "mangled [name]"
- desc = "[desc] They have had the fingertips cut off of them."
- update_icon()
+ clipped = TRUE
+ update_appearance()
else
to_chat(user, "[src] have already been clipped!")
return
else
return ..()
+
+/obj/item/clothing/gloves/update_name(updates = ALL)
+ . = ..()
+ name = clipped ? "mangled [initial(name)]" : initial(name)
+
+
+/obj/item/clothing/gloves/update_desc(updates = ALL)
+ . = ..()
+ desc = clipped ? "[initial(desc)] They have had the fingertips cut off of them." : initial(desc)
+
+
/obj/item/clothing/under/proc/set_sensors(mob/living/user)
if(user.stat || user.restrained())
return
@@ -333,8 +357,6 @@ BLIND // can't see anything
var/see_in_dark = 0
var/lighting_alpha
- var/can_toggle = null
-
sprite_sheets = list(
"Monkey" = 'icons/mob/clothing/species/monkey/head.dmi',
"Farwa" = 'icons/mob/clothing/species/monkey/head.dmi',
@@ -343,10 +365,51 @@ BLIND // can't see anything
"Stok" = 'icons/mob/clothing/species/monkey/head.dmi'
)
-///obj/item/clothing/head/equipped(var/mob/living/carbon/human/lesser/monkey/user, var/slot) //Смещаем шапки у обезьян
-// ..()
-// if(!issmall(user))
-// return
+
+/obj/item/clothing/head/update_icon_state()
+ if(..())
+ item_state = "[replacetext("[item_state]", "_up", "")][up ? "_up" : ""]"
+
+
+/obj/item/clothing/head/attack_self(mob/user)
+ adjust_headgear(user)
+
+
+/obj/item/clothing/head/proc/adjust_headgear(mob/living/carbon/human/user)
+ if(!can_toggle || user.incapacitated() || world.time < cooldown + toggle_cooldown)
+ return FALSE
+
+ . = TRUE
+
+ cooldown = world.time
+ up = !up
+ update_icon(UPDATE_ICON_STATE)
+ if(user.head == src)
+ user.update_head(src, forced = TRUE)
+ for(var/datum/action/action as anything in actions)
+ action.UpdateButtonIcon()
+ else
+ update_equipped_item()
+
+ if(up && toggle_on_message)
+ to_chat(user, span_notice("[toggle_on_message] [src]"))
+ else if(!up && toggle_off_message)
+ to_chat(user, span_notice("[toggle_off_message] [src]"))
+
+ if(active_sound)
+ INVOKE_ASYNC(src, PROC_REF(headgear_loop_sound))
+
+ if(toggle_sound)
+ playsound(loc, toggle_sound, 100, FALSE, 4)
+
+
+/obj/item/clothing/head/proc/headgear_loop_sound()
+ set waitfor = FALSE
+
+ while(up)
+ playsound(loc, active_sound, 100, FALSE, 4)
+ sleep(1.5 SECONDS)
+
//Mask
/obj/item/clothing/mask
@@ -354,7 +417,6 @@ BLIND // can't see anything
icon = 'icons/obj/clothing/masks.dmi'
body_parts_covered = HEAD
slot_flags = SLOT_MASK
- var/mask_adjusted = 0
var/adjusted_flags = null
strip_delay = 40
put_on_delay = 40
@@ -368,16 +430,22 @@ BLIND // can't see anything
)
//Proc that moves gas/breath masks out of the way
-/obj/item/clothing/mask/proc/adjustmask(var/mob/user)
+/obj/item/clothing/mask/proc/adjustmask(mob/user)
var/mob/living/carbon/human/H = usr //Used to check if the mask is on the head, to check if the hands are full, and to turn off internals if they were on when the mask was pushed out of the way.
- if(user.incapacitated()) //This check allows you to adjust your masks while you're buckled into chairs or beds.
- return
- if(mask_adjusted)
- icon_state = initial(icon_state)
+ if(!can_toggle || user.incapacitated()) //This check allows you to adjust your masks while you're buckled into chairs or beds.
+ return FALSE
+ if(is_obscured_for_unEquip(H))
+ return FALSE
+
+ . = TRUE
+
+ up = !up
+ update_icon(UPDATE_ICON_STATE)
+
+ if(!up)
gas_transfer_coefficient = initial(gas_transfer_coefficient)
permeability_coefficient = initial(permeability_coefficient)
- to_chat(user, "You push \the [src] back into place.")
- mask_adjusted = 0
+ to_chat(user, span_notice("You push \the [src] back into place."))
slot_flags = initial(slot_flags)
if(flags_inv != initial(flags_inv))
if(initial(flags_inv) & HIDENAME) //If the mask is one that hides the face and can be adjusted yet lost that trait when it was adjusted, make it hide the face again.
@@ -388,18 +456,11 @@ BLIND // can't see anything
if(flags_cover != initial(flags_cover))
if(initial(flags_cover) & MASKCOVERSMOUTH) //If the mask covers the mouth when it's down and can be adjusted yet lost that trait when it was adjusted, make it cover the mouth again.
flags_cover |= MASKCOVERSMOUTH
- if(H.head == src && flags_inv == HIDENAME) //Means that only things like bandanas and balaclavas will be affected since they obscure the identity of the wearer.
- if(H.l_hand && H.r_hand) //If both hands are occupied, drop the object on the ground.
- user.drop_item_ground(src)
- else //Otherwise, put it in an available hand, the active one preferentially.
- user.drop_item_ground(src)
- user.put_in_hands(src)
+
else
- icon_state += "_up"
- to_chat(user, "You push \the [src] out of the way.")
+ to_chat(user, span_notice("You push \the [src] out of the way."))
gas_transfer_coefficient = null
permeability_coefficient = null
- mask_adjusted = 1
if(adjusted_flags)
slot_flags = adjusted_flags
if(ishuman(user) && H.internal && !H.get_organ_slot(INTERNAL_ORGAN_BREATHING_TUBE) && user.wear_mask == src) /*If the user was wearing the mask providing internals on their face at the time it was adjusted, turn off internals.
@@ -413,18 +474,13 @@ BLIND // can't see anything
flags_cover &= ~MASKCOVERSMOUTH
if(flags & AIRTIGHT) //If the mask was airtight, it won't be anymore since you just pushed it off your face.
flags &= ~AIRTIGHT
- if(user.wear_mask == src && initial(flags_inv) == HIDENAME) //Means that you won't have to take off and put back on simple things like breath masks which, realistically, can just be pulled down off your face.
- if(H.l_hand && H.r_hand) //If both hands are occupied, drop the object on the ground.
- user.drop_item_ground(src)
- else //Otherwise, put it in an available hand, the active one preferentially.
- user.drop_item_ground(src)
- user.put_in_hands(src)
- H.wear_mask_update(src, toggle_off = mask_adjusted)
- usr.update_inv_wear_mask()
- usr.update_inv_head()
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
+
+ if(H?.wear_mask == src)
+ H.wear_mask_update(src, toggle_off = up)
+ for(var/datum/action/action as anything in actions)
+ action.UpdateButtonIcon()
+ else
+ update_equipped_item()
// Changes the speech verb when wearing a mask if a value is returned
/obj/item/clothing/mask/proc/change_speech_verb()
@@ -436,9 +492,9 @@ BLIND // can't see anything
icon = 'icons/obj/clothing/shoes.dmi'
desc = "Comfortable-looking shoes."
gender = PLURAL //Carn: for grammatically correct text-parsing
- var/chained = 0
- var/can_cut_open = 0
- var/cut_open = 0
+ //var/chained = 0
+ var/can_cut_open = FALSE
+ var/cut_open = FALSE
body_parts_covered = FEET
slot_flags = SLOT_FEET
pickup_sound = 'sound/items/handling/shoes_pickup.ogg'
@@ -476,29 +532,44 @@ BLIND // can't see anything
M.dropped()
return
- if(istype(I, /obj/item/wirecutters))
+ if(I.tool_behaviour == TOOL_WIRECUTTER)
if(can_cut_open)
if(!cut_open)
playsound(src.loc, I.usesound, 100, 1)
user.visible_message("[user] cuts open the toes of [src].","You cut open the toes of [src].")
- cut_open = 1
- icon_state = "[icon_state]_opentoe"
- item_state = "[item_state]_opentoe"
- name = "mangled [name]"
- desc = "[desc] They have had their toes opened up."
- update_icon()
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- if(H.shoes == src)
- user.update_inv_shoes()
+ cut_open = TRUE
+ update_appearance(UPDATE_NAME|UPDATE_DESC|UPDATE_ICON_STATE)
else
to_chat(user, "[src] have already had [p_their()] toes cut open!")
return
else
return ..()
+
+/obj/item/clothing/shoes/update_name()
+ . = ..()
+ if(!cut_open)
+ return
+ name = "mangled [initial(name)]"
+
+
+/obj/item/clothing/shoes/update_desc()
+ . = ..()
+ if(!cut_open)
+ return
+ desc = "[initial(desc)] They have had their toes opened up."
+
+
+/obj/item/clothing/shoes/update_icon_state()
+ if(!cut_open)
+ return
+ icon_state = "[icon_state]_opentoe"
+ item_state = "[item_state]_opentoe"
+ update_equipped_item()
+
+
/obj/item/proc/negates_gravity()
- return 0
+ return
//Suit
/obj/item/clothing/suit
@@ -511,9 +582,8 @@ BLIND // can't see anything
pickup_sound = 'sound/items/handling/cloth_pickup.ogg'
slot_flags = SLOT_OCLOTHING
var/blood_overlay_type = "suit"
- var/suittoggled = FALSE
- var/suit_adjusted = 0
- var/ignore_suitadjust = 1
+ var/suit_adjusted = FALSE
+ var/ignore_suitadjust = TRUE
var/adjust_flavour = null
var/list/hide_tail_by_species = null
max_integrity = 400
@@ -524,58 +594,59 @@ BLIND // can't see anything
"Farwa" = 'icons/mob/clothing/species/monkey/suit.dmi',
"Wolpin" = 'icons/mob/clothing/species/monkey/suit.dmi',
"Neara" = 'icons/mob/clothing/species/monkey/suit.dmi',
- "Plasmaman" = 'icons/mob/clothing/species/plasmaman/suit.dmi'
- //"Stok" = 'icons/mob/clothing/species/monkey/suit.dmi'
+ "Plasmaman" = 'icons/mob/clothing/species/plasmaman/suit.dmi',
+ "Stok" = 'icons/mob/clothing/species/monkey/suit.dmi'
)
//Proc that opens and closes jackets.
-/obj/item/clothing/suit/proc/adjustsuit(var/mob/user)
- if(!ignore_suitadjust)
- if(!user.incapacitated())
- if(!(HULK in user.mutations))
- if(suit_adjusted)
- var/flavour = "close"
- icon_state = copytext(icon_state, 1, findtext(icon_state, "_open")) /*Trims the '_open' off the end of the icon state, thus avoiding a case where jackets that start open will
- end up with a suffix of _open_open if adjusted twice, since their initial state is _open. */
- item_state = copytext(item_state, 1, findtext(item_state, "_open"))
- if(adjust_flavour)
- flavour = "[copytext(adjust_flavour, 3, length(adjust_flavour) + 1)] up" //Trims off the 'un' at the beginning of the word. unzip -> zip, unbutton->button.
- to_chat(user, "You [flavour] \the [src].")
- suit_adjusted = 0 //Suit is no longer adjusted.
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
- else
- var/flavour = "open"
- icon_state += "_open"
- item_state += "_open"
- if(adjust_flavour)
- flavour = "[adjust_flavour]"
- to_chat(user, "You [flavour] \the [src].")
- suit_adjusted = 1 //Suit's adjusted.
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
- else
- if(user.can_unEquip(src)) //Checks to see if the item can be unequipped. If so, lets shred. Otherwise, struggle and fail.
- if(contents) //If the suit's got any storage capability...
- for(var/obj/item/O in contents) //AVOIDING ITEM LOSS. Check through everything that's stored in the jacket and see if one of the items is a pocket.
- if(istype(O, /obj/item/storage/internal)) //If it's a pocket...
- if(O.contents) //Check to see if the pocket's got anything in it.
- for(var/obj/item/I in O.contents) //Dump the pocket out onto the floor below the user.
- user.drop_item_ground(I, force = TRUE)
-
- user.visible_message("[user] bellows, [pick("shredding", "ripping open", "tearing off")] [user.p_their()] jacket in a fit of rage!","You accidentally [pick("shred", "rend", "tear apart")] [src] with your [pick("excessive", "extreme", "insane", "monstrous", "ridiculous", "unreal", "stupendous")] [pick("power", "strength")]!")
- user.temporarily_remove_item_from_inventory(src)
- qdel(src) //Now that the pockets have been emptied, we can safely destroy the jacket.
- user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!"))
- else
- to_chat(user, "You yank and pull at \the [src] with your [pick("excessive", "extreme", "insane", "monstrous", "ridiculous", "unreal", "stupendous")] [pick("power", "strength")], however you are unable to change its state!")//Yep, that's all they get. Avoids having to snowflake in a cooldown.
-
- return
- user.update_inv_wear_suit()
+/obj/item/clothing/suit/proc/adjustsuit(mob/user)
+ if(ignore_suitadjust)
+ to_chat(user, span_notice("You attempt to button up the velcro on [src], before promptly realising how foolish you are."))
+ return
+ if(user.incapacitated())
+ return
+
+ if((HULK in user.mutations))
+ if(user.can_unEquip(src)) //Checks to see if the item can be unequipped. If so, lets shred. Otherwise, struggle and fail.
+ for(var/obj/item/thing in src) //AVOIDING ITEM LOSS. Check through everything that's stored in the jacket and see if one of the items is a pocket.
+ if(istype(thing, /obj/item/storage/internal)) //If it's a pocket...
+ for(var/obj/item/pocket_thing in thing) //Dump the pocket out onto the floor below the user.
+ user.drop_item_ground(pocket_thing, force = TRUE)
+
+ user.visible_message("[user] bellows, [pick("shredding", "ripping open", "tearing off")] [user.p_their()] jacket in a fit of rage!","You accidentally [pick("shred", "rend", "tear apart")] [src] with your [pick("excessive", "extreme", "insane", "monstrous", "ridiculous", "unreal", "stupendous")] [pick("power", "strength")]!")
+ user.temporarily_remove_item_from_inventory(src)
+ qdel(src) //Now that the pockets have been emptied, we can safely destroy the jacket.
+ user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!"))
+ else
+ to_chat(user, "You yank and pull at \the [src] with your [pick("excessive", "extreme", "insane", "monstrous", "ridiculous", "unreal", "stupendous")] [pick("power", "strength")], however you are unable to change its state!")//Yep, that's all they get. Avoids having to snowflake in a cooldown.
+ return
+
+ update_icon(UPDATE_ICON_STATE)
+ update_equipped_item()
+
+ if(suit_adjusted)
+ var/flavour = "close"
+ if(adjust_flavour)
+ flavour = "[copytext(adjust_flavour, 3, length(adjust_flavour) + 1)] up" //Trims off the 'un' at the beginning of the word. unzip -> zip, unbutton->button.
+ to_chat(user, "You [flavour] [src].")
else
- to_chat(user, "You attempt to button up the velcro on \the [src], before promptly realising how foolish you are.")
+ var/flavour = "open"
+ if(adjust_flavour)
+ flavour = "[adjust_flavour]"
+ to_chat(user, "You [flavour] [src].")
+
+ suit_adjusted = !suit_adjusted
+
+
+/obj/item/clothing/suit/update_icon_state()
+ // Trims the '_open' off the end of the icon state, thus avoiding a case where jackets that start open will
+ // end up with a suffix of _open_open if adjusted twice, since their initial state is _open
+ var/base_icon_state = copytext(icon_state, 1, findtext(icon_state, "_open"))
+ var/base_item_state = copytext(item_state, 1, findtext(item_state, "_open"))
+
+ icon_state = suit_adjusted ? base_icon_state : "[base_icon_state]_open"
+ item_state = suit_adjusted ? base_item_state : "[base_item_state]_open"
+
// Proc used to check if suit storage is limited by item weight
// Allows any suit to have their own weight limit for items that can be equipped into suit storage
@@ -657,10 +728,10 @@ BLIND // can't see anything
var/obj/item/tank/jetpack/suit/jetpack = null
-/obj/item/clothing/suit/space/New()
+/obj/item/clothing/suit/space/Initialize(mapload)
+ . = ..()
if(jetpack && ispath(jetpack))
jetpack = new jetpack(src)
- ..()
/obj/item/clothing/suit/space/screwdriver_act(mob/user, obj/item/I)
@@ -679,22 +750,18 @@ BLIND // can't see anything
to_chat(user, span_notice("You successfully remove the jetpack from [src]."))
-/obj/item/clothing/suit/space/equipped(mob/user, slot, initial)
+/obj/item/clothing/suit/space/equipped(mob/user, slot, initial = FALSE)
. = ..()
-
- if(jetpack)
- if(slot == slot_wear_suit)
- for(var/X in jetpack.actions)
- var/datum/action/A = X
- A.Grant(user)
+ if(jetpack && slot == slot_wear_suit)
+ for(var/datum/action/action as anything in jetpack.actions)
+ action.Grant(user)
/obj/item/clothing/suit/space/dropped(mob/user, silent = FALSE)
- ..()
+ . = ..()
if(jetpack)
- for(var/X in jetpack.actions)
- var/datum/action/A = X
- A.Remove(user)
+ for(var/datum/action/action as anything in jetpack.actions)
+ action.Remove(user)
/obj/item/clothing/suit/space/attackby(obj/item/I, mob/user, params)
@@ -736,8 +803,8 @@ BLIND // can't see anything
"Monkey" = 'icons/mob/clothing/species/monkey/uniform.dmi',
"Farwa" = 'icons/mob/clothing/species/monkey/uniform.dmi',
"Wolpin" = 'icons/mob/clothing/species/monkey/uniform.dmi',
- "Neara" = 'icons/mob/clothing/species/monkey/uniform.dmi'
- //"Stok" = 'icons/mob/clothing/species/monkey/uniform.dmi' - стоки слишком жирные для маленькой одежды
+ "Neara" = 'icons/mob/clothing/species/monkey/uniform.dmi',
+ "Stok" = 'icons/mob/clothing/species/monkey/uniform.dmi'
)
var/has_sensor = TRUE//For the crew computer 2 = unable to change mode
@@ -755,10 +822,12 @@ BLIND // can't see anything
var/list/accessories = list()
var/basecolor
-/obj/item/clothing/under/rank/New()
+
+/obj/item/clothing/under/rank/Initialize(mapload)
+ . = ..()
if(random_sensor)
sensor_mode = pick(SENSOR_OFF, SENSOR_LIVING, SENSOR_VITALS, SENSOR_COORDS)
- ..()
+
/obj/item/clothing/under/Destroy()
QDEL_LIST(accessories)
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index 9a44815a53e..8f602caf51c 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -1,40 +1,78 @@
-/obj/item/clothing/glasses/New()
+/obj/item/clothing/glasses/Initialize(mapload)
. = ..()
if(prescription_upgradable && prescription)
// Pre-upgraded upgradable glasses
- name = "prescription [name]"
+ upgrade_prescription()
-/obj/item/clothing/glasses/attackby(obj/item/O, mob/user)
- if(user.stat || user.restrained() || !ishuman(user))
+
+/obj/item/clothing/glasses/attackby(obj/item/I, mob/living/carbon/human/user, params)
+ if(!prescription_upgradable || user.incapacitated() || !ishuman(user))
return ..()
- var/mob/living/carbon/human/H = user
- if(prescription_upgradable)
- if(istype(O, /obj/item/clothing/glasses/regular))
- if(prescription)
- to_chat(H, "You can't possibly imagine how adding more lenses would improve \the [name].")
- return
- H.drop_transfer_item_to_loc(O, src) // Store the glasses for later removal
- to_chat(H, "You fit \the [name] with lenses from \the [O].")
- prescription = TRUE
- name = "prescription [name]"
- if(H.glasses == src)
- H.update_nearsighted_effects()
- return
- if(prescription && istype(O, /obj/item/screwdriver))
- var/obj/item/clothing/glasses/regular/G = locate() in src
- if(!G)
- G = new(get_turf(H))
- to_chat(H, "You salvage the prescription lenses from \the [name].")
- prescription = FALSE
- name = initial(name)
- H.put_in_hands(G)
- if(H.glasses == src)
- H.update_nearsighted_effects()
- return
- return ..()
+
+
+ if(!istype(I, /obj/item/clothing/glasses/regular))
+ return ..()
+
+ if(prescription)
+ to_chat(user, span_warning("You can't possibly imagine how adding more lenses would improve [src]."))
+ return
+
+ if(!user.drop_transfer_item_to_loc(I, src)) // Store the glasses for later removal
+ return
+
+ upgrade_prescription(I, user)
+
+
+/obj/item/clothing/glasses/update_name(updates = ALL)
+ . = ..()
+ name = prescription ? "prescription [initial(name)]" : initial(name)
+
+
+/obj/item/clothing/glasses/proc/upgrade_prescription(obj/item/I, mob/living/carbon/human/user)
+ if(!I)
+ new /obj/item/clothing/glasses/regular(src)
+ else if(I.loc != src)
+ I.forceMove(src)
+ prescription = TRUE
+ update_appearance(UPDATE_NAME)
+ if(user)
+ to_chat(user, span_notice("You fit [src] with lenses from [I]."))
+ if(user.glasses == src)
+ user.update_nearsighted_effects()
+
+
+/obj/item/clothing/glasses/proc/remove_prescription(mob/living/carbon/human/user)
+ var/obj/item/clothing/glasses/regular/prescription_glasses = locate() in src
+
+ if(!prescription_glasses)
+ return
+
+ prescription = FALSE
+ update_appearance(UPDATE_NAME)
+
+ prescription_glasses.forceMove(drop_location())
+
+ if(user)
+ to_chat(user, span_notice("You salvage the prescription lenses from [src]."))
+ user.put_in_hands(prescription_glasses, ignore_anim = FALSE)
+ if(user.glasses == src)
+ user.update_nearsighted_effects()
+
+
+/obj/item/clothing/glasses/screwdriver_act(mob/living/user, obj/item/I)
+ if(!prescription)
+ to_chat(user, span_notice("There are no prescription lenses in [src]."))
+ return FALSE
+ if(!I.use_tool(src, user, 0, volume = I.tool_volume))
+ return TRUE
+ remove_prescription(user)
+ return TRUE
+
/obj/item/clothing/glasses/visor_toggling()
- ..()
+ . = ..()
+ if(!.)
+ return .
if(visor_vars_to_toggle & VISOR_VISIONFLAGS)
vision_flags ^= initial(vision_flags)
if(visor_vars_to_toggle & VISOR_DARKNESSVIEW)
@@ -42,15 +80,6 @@
if(visor_vars_to_toggle & VISOR_INVISVIEW)
invis_view ^= initial(invis_view)
-/obj/item/clothing/glasses/weldingvisortoggle(mob/user)
- . = ..()
- if(. && user)
- if(ishuman(user))
- var/mob/living/carbon/human/human = user
- human.wear_glasses_update(src)
- else
- user.update_sight()
- user.update_inv_glasses()
/obj/item/clothing/glasses/meson
name = "Optical Meson Scanner"
@@ -440,6 +469,7 @@
actions_types = list(/datum/action/item_action/toggle)
flash_protect = 2
tint = 2
+ can_toggle = TRUE
visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT
sprite_sheets = list(
"Vox" = 'icons/mob/clothing/species/vox/eyes.dmi',
@@ -449,8 +479,8 @@
"Farwa" = 'icons/mob/clothing/species/monkey/eyes.dmi',
"Wolpin" = 'icons/mob/clothing/species/monkey/eyes.dmi',
"Neara" = 'icons/mob/clothing/species/monkey/eyes.dmi',
- "Stok" = 'icons/mob/clothing/species/monkey/eyes.dmi'
- )
+ "Stok" = 'icons/mob/clothing/species/monkey/eyes.dmi',
+ )
/obj/item/clothing/glasses/welding/attack_self(mob/user)
weldingvisortoggle(user)
@@ -559,6 +589,7 @@
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
resistance_flags = LAVA_PROOF | FIRE_PROOF
HUDType = DATA_HUD_MEDICAL_ADVANCED
+ var/double_eye = FALSE
sprite_sheets = list(
"Vox" = 'icons/mob/clothing/species/vox/eyes.dmi',
"Grey" = 'icons/mob/clothing/species/grey/eyes.dmi',
@@ -570,20 +601,34 @@
"Stok" = 'icons/mob/clothing/species/monkey/eyes.dmi'
)
+
+/obj/item/clothing/glasses/hud/godeye/update_icon_state()
+ icon_state = "[double_eye ? "double" : ""]godeye"
+ item_state = "[double_eye ? "double" : ""]godeye"
+
+
+/obj/item/clothing/glasses/hud/godeye/update_desc(updates = ALL)
+ . = ..()
+ if(!double_eye)
+ desc = initial(desc)
+ return
+ desc = "A pair of strange eyes, said to have been torn from an omniscient creature that used to roam the wastes. There's no real reason to have two, but that isn't stopping you."
+
+
/obj/item/clothing/glasses/hud/godeye/attackby(obj/item/W, mob/user, params)
- if(istype(W, src) && W != src && W.loc == user)
- if(W.icon_state == "godeye")
- W.icon_state = "doublegodeye"
- W.item_state = "doublegodeye"
- W.desc = "A pair of strange eyes, said to have been torn from an omniscient creature that used to roam the wastes. There's no real reason to have two, but that isn't stopping you."
- if(iscarbon(user))
- var/mob/living/carbon/C = user
- C.update_inv_wear_mask()
- else
+ if(istype(W, type) && W != src && W.loc == user && !double_eye)
+ if(double_eye)
to_chat(user, span_notice("The eye winks at you and vanishes into the abyss, you feel really unlucky."))
- qdel(src)
+ qdel(src)
+ return
+
+ double_eye = TRUE
+ update_appearance(UPDATE_ICON_STATE|UPDATE_NAME)
+ user.wear_glasses_update(src)
+ return
..()
+
/obj/item/clothing/glasses/tajblind
name = "embroidered veil"
desc = "An Ahdominian made veil that allows the user to see while obscuring their eyes."
@@ -591,6 +636,7 @@
item_state = "tajblind"
flags_cover = GLASSESCOVERSEYES
actions_types = list(/datum/action/item_action/toggle)
+ tint = 3
sprite_sheets = list(
"Vox" = 'icons/mob/clothing/species/vox/eyes.dmi',
@@ -610,26 +656,20 @@
item_state = "tajblind_engi"
vision_flags = SEE_TURFS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
+ flash_protect = 2
+ var/flash_protect_up = 0
+
/obj/item/clothing/glasses/tajblind/eng/sunglasses
- flash_protect = 1
- tint = 1
+ flash_protect_up = 1
+ tint_up = 1
+
/obj/item/clothing/glasses/tajblind/eng/toggle_veil(mob/user)
- if(user.canmove && !user.incapacitated())
- if(up)
- up = !up
- tint = initial(tint)
- flash_protect = initial(flash_protect)
- to_chat(user, "You activate [src], allowing you to see.")
- else
- up = !up
- tint = 3
- flash_protect = 2
- to_chat(user, "You deactivate [src], obscuring your vision.")
- var/mob/living/carbon/user1 = user
- user1.update_tint()
- user1.update_inv_glasses()
+ . = ..()
+ if(.)
+ flash_protect = up ? flash_protect_up : initial(flash_protect)
+
/obj/item/clothing/glasses/tajblind/sci
name = "hi-tech veil"
@@ -641,7 +681,7 @@
/obj/item/clothing/glasses/tajblind/sci/sunglasses
flash_protect = 1
- tint = 1
+ tint_up = 1
/obj/item/clothing/glasses/tajblind/cargo
name = "khaki veil"
@@ -654,24 +694,23 @@
/obj/item/clothing/glasses/tajblind/cargo/sunglasses
flash_protect = 1
- tint = 1
+ tint_up = 1
+
/obj/item/clothing/glasses/tajblind/attack_self(mob/user)
toggle_veil(user)
-/obj/item/clothing/glasses/proc/toggle_veil(mob/user)
- if(user.canmove && !user.incapacitated())
- if(up)
- up = !up
- tint = initial(tint)
- to_chat(user, "You activate [src], allowing you to see.")
- else
- up = !up
- tint = 3
- to_chat(user, "You deactivate [src], obscuring your vision.")
- var/mob/living/carbon/user1 = user
- user1.update_tint()
- user1.update_inv_glasses()
+
+/obj/item/clothing/glasses/proc/toggle_veil(mob/living/carbon/human/user)
+ if(user.incapacitated())
+ return FALSE
+ . = TRUE
+ up = !up
+ tint = up ? tint_up : initial(tint)
+ if(user.glasses == src)
+ to_chat(user, span_notice("[up ? "You deactivate [src], obscuring your vision." : "You activate [src], allowing you to see."]"))
+ user.wear_glasses_update(src)
+
/obj/item/clothing/glasses/sunglasses/blindfold/cucumbermask
desc = "A simple pair of two cucumber slices. Medically proven to be able to heal your eyes over time."
@@ -679,3 +718,4 @@
heal_bodypart = INTERNAL_ORGAN_EYES
icon_state = "cucumbermask"
item_state = "cucumbermask"
+
diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm
index fb5b7dbc8d7..803f76fa03a 100644
--- a/code/modules/clothing/glasses/hud.dm
+++ b/code/modules/clothing/glasses/hud.dm
@@ -7,7 +7,7 @@
/// The visual icons granted by wearing these glasses.
var/HUDType = null
/// List of things added to examine text, like security or medical records.
- var/list/examine_extensions = null
+ var/examine_extensions = 0
/obj/item/clothing/glasses/hud/equipped(mob/living/carbon/human/user, slot, initial)
@@ -31,6 +31,24 @@
emagged = TRUE
desc = desc + " The display flickers slightly."
+/obj/item/clothing/glasses/hud/visor_toggling(mob/living/carbon/human/user)
+ . = ..()
+ if(!.)
+ return
+ if(visor_vars_to_toggle & VISOR_EXAM_EXTENTIONS)
+ examine_extensions ^= initial(examine_extensions)
+
+ if(visor_vars_to_toggle & VISOR_HUDTYPE)
+ HUDType ^= initial(HUDType)
+
+ var/datum/atom_hud/H = GLOB.huds[initial(HUDType)]
+ if(istype(user) && src == user.glasses)
+ if(HUDType)
+ H.add_hud_to(user)
+
+ else
+ H.remove_hud_from(user)
+
/*
MEDICAL
*/
@@ -41,7 +59,7 @@ MEDICAL
icon_state = "healthhud"
origin_tech = "magnets=3;biotech=2"
HUDType = DATA_HUD_MEDICAL_ADVANCED
- examine_extensions = list(EXAMINE_HUD_MEDICAL)
+ examine_extensions = EXAMINE_HUD_MEDICAL
sprite_sheets = list(
"Vox" = 'icons/mob/clothing/species/vox/eyes.dmi',
@@ -78,6 +96,7 @@ MEDICAL
icon_state = "tajblind_med"
item_state = "tajblind_med"
flags_cover = GLASSESCOVERSEYES
+ tint = 3
actions_types = list(/datum/action/item_action/toggle)
sprite_sheets = list(
@@ -94,7 +113,7 @@ MEDICAL
/obj/item/clothing/glasses/hud/health/tajblind/sunglasses
see_in_dark = 1
flash_protect = 1
- tint = 1
+ tint_up = 1
/obj/item/clothing/glasses/hud/health/tajblind/attack_self(mob/user)
toggle_veil(user)
@@ -152,12 +171,13 @@ DIAGNOSTIC
icon_state = "tajblind_diagnostic"
item_state = "tajblind_diagnostic"
flags_cover = GLASSESCOVERSEYES
+ tint = 3
actions_types = list(/datum/action/item_action/toggle)
/obj/item/clothing/glasses/hud/diagnostic/tajblind/sunglasses
see_in_dark = 1
flash_protect = 1
- tint = 1
+ tint_up = 1
/obj/item/clothing/glasses/hud/diagnostic/tajblind/attack_self(mob/user)
toggle_veil(user)
@@ -173,7 +193,7 @@ SECURITY
origin_tech = "magnets=3;combat=2"
var/global/list/jobs[0]
HUDType = DATA_HUD_SECURITY_ADVANCED
- examine_extensions = list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE)
+ examine_extensions = EXAMINE_HUD_SECURITY_READ | EXAMINE_HUD_SECURITY_WRITE
sprite_sheets = list(
"Vox" = 'icons/mob/clothing/species/vox/eyes.dmi',
@@ -187,7 +207,7 @@ SECURITY
)
/obj/item/clothing/glasses/hud/security/read_only
- examine_extensions = list(EXAMINE_HUD_SECURITY_READ)
+ examine_extensions = EXAMINE_HUD_SECURITY_READ
/obj/item/clothing/glasses/hud/security/night
name = "\improper Night Vision Security HUD"
@@ -218,8 +238,33 @@ SECURITY
"Stok" = 'icons/mob/clothing/species/monkey/eyes.dmi'
)
+/obj/item/clothing/glasses/hud/security/sunglasses/tacticool
+ name = "security tactical glasses"
+ desc = "Ballistic glasses with a security HUD. Gives you tacticool protection and selfish increase. The elastic band allows it to be worn over a helmet."
+ icon_state = "secgoggles-g"
+ item_state = "secgoggles-g"
+ over_mask = TRUE
+ over_hat = TRUE
+ can_toggle = TRUE
+ visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT | VISOR_DARKNESSVIEW | VISOR_FULL_HUD
+ actions_types = list(/datum/action/item_action/toggle)
+
+ sprite_sheets = list(
+ "Vox" = 'icons/mob/clothing/species/vox/eyes.dmi',
+ "Drask" = 'icons/mob/clothing/species/drask/eyes.dmi',
+ "Grey" = 'icons/mob/clothing/species/grey/eyes.dmi',
+ "Monkey" = 'icons/mob/clothing/species/monkey/eyes.dmi',
+ "Farwa" = 'icons/mob/clothing/species/monkey/eyes.dmi',
+ "Wolpin" = 'icons/mob/clothing/species/monkey/eyes.dmi',
+ "Neara" = 'icons/mob/clothing/species/monkey/eyes.dmi',
+ "Stok" = 'icons/mob/clothing/species/monkey/eyes.dmi'
+ )
+
+/obj/item/clothing/glasses/hud/security/sunglasses/tacticool/attack_self(mob/user)
+ weldingvisortoggle(user)
+
/obj/item/clothing/glasses/hud/security/sunglasses/read_only
- examine_extensions = list(EXAMINE_HUD_SECURITY_READ)
+ examine_extensions = EXAMINE_HUD_SECURITY_READ
/obj/item/clothing/glasses/hud/security/sunglasses/prescription
prescription = TRUE
@@ -243,6 +288,8 @@ SECURITY
icon_state = "tajblind_sec"
item_state = "tajblind_sec"
flags_cover = GLASSESCOVERSEYES
+ tint_up = 1
+ tint = 3
actions_types = list(/datum/action/item_action/toggle)
sprite_sheets = list(
@@ -258,7 +305,7 @@ SECURITY
toggle_veil(user)
/obj/item/clothing/glasses/hud/security/sunglasses/tajblind/read_only
- examine_extensions = list(EXAMINE_HUD_SECURITY_READ)
+ examine_extensions = EXAMINE_HUD_SECURITY_READ
/*
HYDROPONIC
@@ -269,7 +316,7 @@ HYDROPONIC
desc = "A heads-up display capable of analyzing the health and status of plants growing in hydro trays and soil."
icon_state = "hydroponichud"
HUDType = DATA_HUD_HYDROPONIC
- examine_extensions = list(DATA_HUD_HYDROPONIC)
+ examine_extensions = EXAMINE_HUD_BOTANY
sprite_sheets = list(
"Vox" = 'icons/mob/clothing/species/vox/eyes.dmi',
"Drask" = 'icons/mob/clothing/species/drask/eyes.dmi',
@@ -304,12 +351,13 @@ HYDROPONIC
desc = "An Ahdominian made veil that allows the user to see while obscuring their eyes. There is botanical hud in it."
icon_state = "tajblind_bot"
item_state = "tajblind_bot"
+ tint = 3
actions_types = list(/datum/action/item_action/toggle)
/obj/item/clothing/glasses/hud/hydroponic/tajblind/sunglasses
see_in_dark = 1
flash_protect = 1
- tint = 1
+ tint_up = 1
/obj/item/clothing/glasses/hud/hydroponic/tajblind/attack_self(mob/user)
toggle_veil(user)
@@ -324,7 +372,7 @@ SKILLS
icon_state = "skill"
item_state = "glasses"
HUDType = DATA_HUD_SECURITY_BASIC
- examine_extensions = list(EXAMINE_HUD_SKILLS)
+ examine_extensions = EXAMINE_HUD_SKILLS
sprite_sheets = list(
"Drask" = 'icons/mob/clothing/species/drask/eyes.dmi',
"Grey" = 'icons/mob/clothing/species/grey/eyes.dmi',
@@ -361,12 +409,13 @@ SKILLS
icon_state = "tajblind_skill"
item_state = "tajblind_skill"
flags_cover = GLASSESCOVERSEYES
+ tint = 3
actions_types = list(/datum/action/item_action/toggle)
/obj/item/clothing/glasses/hud/skills/tajblind/sunglasses
see_in_dark = 1
flash_protect = 1
- tint = 1
+ tint_up = 1
/obj/item/clothing/glasses/hud/skills/tajblind/attack_self(mob/user)
toggle_veil(user)
diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm
index a8525be2633..25f78c6eddb 100644
--- a/code/modules/clothing/gloves/color.dm
+++ b/code/modules/clothing/gloves/color.dm
@@ -102,8 +102,8 @@
/obj/item/clothing/gloves/color/black/thief
pickpocket = 1
-/obj/item/clothing/gloves/color/black/attackby(obj/item/W as obj, mob/user as mob, params)
- if(istype(W, /obj/item/wirecutters))
+/obj/item/clothing/gloves/color/black/attackby(obj/item/W, mob/user, params)
+ if(W.tool_behaviour == TOOL_WIRECUTTER)
if(can_be_cut && icon_state == initial(icon_state))//only if not dyed
var/confirm = alert("Do you want to cut off the gloves fingertips? Warning: It might destroy their functionality.","Cut tips?","Yes","No")
if(get_dist(user, src) > 1)
diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm
index 98b76d8646a..85220c7a610 100644
--- a/code/modules/clothing/gloves/miscellaneous.dm
+++ b/code/modules/clothing/gloves/miscellaneous.dm
@@ -99,9 +99,9 @@
/obj/item/clothing/gloves/color/yellow/stun/get_cell()
return cell
-/obj/item/clothing/gloves/color/yellow/stun/New()
- ..()
- update_icon()
+/obj/item/clothing/gloves/color/yellow/stun/Initialize(mapload)
+ . = ..()
+ update_icon(UPDATE_OVERLAYS)
/obj/item/clothing/gloves/color/yellow/stun/Destroy()
QDEL_NULL(cell)
@@ -132,12 +132,13 @@
return TRUE
return FALSE
-/obj/item/clothing/gloves/color/yellow/stun/update_icon()
- ..()
- overlays.Cut()
- overlays += "gloves_wire"
+
+/obj/item/clothing/gloves/color/yellow/stun/update_overlays()
+ . = ..()
+ . += "gloves_wire"
if(cell)
- overlays += "gloves_cell"
+ . += "gloves_cell"
+
/obj/item/clothing/gloves/color/yellow/stun/attackby(obj/item/W, mob/living/user, params)
if(istype(W, /obj/item/stock_parts/cell))
@@ -147,7 +148,7 @@
return
cell = W
to_chat(user, "You attach [W] to [src].")
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
else
to_chat(user, "[src] already has a cell.")
else
@@ -161,7 +162,7 @@
to_chat(user, "You cut [cell] away from [src].")
cell.forceMove(get_turf(loc))
cell = null
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
/obj/item/clothing/gloves/color/yellow/stun/emp_act()
if(!ishuman(loc))
diff --git a/code/modules/clothing/gloves/rings.dm b/code/modules/clothing/gloves/rings.dm
index 3b9e4eadab8..f5bcbbd698e 100644
--- a/code/modules/clothing/gloves/rings.dm
+++ b/code/modules/clothing/gloves/rings.dm
@@ -14,11 +14,11 @@
var/stud = 0
var/ring_color = "iron"
-/obj/item/clothing/gloves/ring/New()
- ..()
- update_icon()
+/obj/item/clothing/gloves/ring/Initialize(mapload)
+ . = ..()
+ update_icon(UPDATE_ICON_STATE)
-/obj/item/clothing/gloves/ring/update_icon()
+/obj/item/clothing/gloves/ring/update_icon_state()
icon_state = "[stud ? "d_" : ""][ring_color]ring"
/obj/item/clothing/gloves/ring/examine(mob/user)
@@ -28,7 +28,7 @@
if(stud)
. += "It is adorned with a single gem."
-/obj/item/clothing/gloves/ring/attackby(obj/item/I as obj, mob/user as mob, params)
+/obj/item/clothing/gloves/ring/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/stack/sheet/mineral/diamond))
var/obj/item/stack/sheet/mineral/diamond/D = I
if(stud)
@@ -76,10 +76,10 @@
icon_state = "redring"
ring_color = "red"
-/obj/item/clothing/gloves/ring/plastic/random/New()
+/obj/item/clothing/gloves/ring/plastic/random/Initialize(mapload)
ring_color = pick("white","blue","red")
name = "[ring_color] plastic ring"
- ..()
+ . = ..()
// weird
/obj/item/clothing/gloves/ring/glass
diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm
index 45d0984d685..99db59689fe 100644
--- a/code/modules/clothing/head/hardhat.dm
+++ b/code/modules/clothing/head/hardhat.dm
@@ -24,24 +24,21 @@
/obj/item/clothing/head/hardhat/attack_self()
toggle_helmet_light()
+
/obj/item/clothing/head/hardhat/proc/toggle_helmet_light()
on = !on
if(on)
turn_on()
else
turn_off()
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
+
-/obj/item/clothing/head/hardhat/update_icon()
+/obj/item/clothing/head/hardhat/update_icon_state()
icon_state = "hardhat[on]_[item_color]"
item_state = "hardhat[on]_[item_color]"
- if(ishuman(loc))
- var/mob/living/carbon/human/H = loc
- H.update_inv_head()
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
- ..()
+ update_equipped_item()
+
/obj/item/clothing/head/hardhat/proc/turn_on()
set_light(brightness_on)
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index 298a86c5c38..5323bc59fbf 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -28,25 +28,12 @@
"Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/helmet.dmi'
)
-/obj/item/clothing/head/helmet/attack_self(mob/user)
- if(can_toggle && !user.incapacitated())
- if(world.time > cooldown + toggle_cooldown)
- cooldown = world.time
- up = !up
- flags ^= visor_flags
- flags_inv ^= visor_flags_inv
- icon_state = "[initial(icon_state)][up ? "up" : ""]"
- to_chat(user, "[up ? alt_toggle_message : toggle_message] \the [src]")
-
- user.update_inv_head()
-
- if(active_sound)
- while(up)
- playsound(src.loc, "[active_sound]", 100, 0, 4)
- sleep(15)
- if(toggle_sound)
- playsound(src.loc, "[toggle_sound]", 100, 0, 4)
+/obj/item/clothing/head/helmet/adjust_headgear(mob/user)
+ . = ..()
+ if(.)
+ flags ^= visor_flags
+ flags_inv ^= visor_flags_inv
/obj/item/clothing/head/helmet/visor
name = "visor helmet"
@@ -122,10 +109,10 @@
name = "helmet of justice"
desc = "WEEEEOOO. WEEEEEOOO. WEEEEOOOO."
icon_state = "justice"
- toggle_message = "You turn off the lights on"
- alt_toggle_message = "You turn on the lights on"
+ toggle_on_message = "You turn off the lights on"
+ toggle_off_message = "You turn on the lights on"
actions_types = list(/datum/action/item_action/toggle_helmet_light)
- can_toggle = 1
+ can_toggle = TRUE
toggle_cooldown = 20
active_sound = 'sound/items/weeoo1.ogg'
dog_fashion = null
@@ -134,8 +121,8 @@
name = "alarm helmet"
desc = "WEEEEOOO. WEEEEEOOO. STOP THAT MONKEY. WEEEOOOO."
icon_state = "justice2"
- toggle_message = "You turn off the light on"
- alt_toggle_message = "You turn on the light on"
+ toggle_on_message = "You turn off the light on"
+ toggle_off_message = "You turn on the light on"
/obj/item/clothing/head/helmet/swat
@@ -214,10 +201,10 @@
flags = BLOCKHAIR
item_state = "gladiator"
flags_inv = HIDEMASK|HIDEHEADSETS|HIDEGLASSES
- toggle_message = "You attach the face shield to the"
- alt_toggle_message = "You remove the face shield from the"
+ toggle_on_message = "You attach the face shield to the"
+ toggle_off_message = "You remove the face shield from the"
actions_types = list(/datum/action/item_action/toggle_helmet_mode)
- can_toggle = 1
+ can_toggle = TRUE
toggle_cooldown = 20
toggle_sound = 'sound/items/zippoclose.ogg'
dog_fashion = null
@@ -421,3 +408,24 @@
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
species_restricted = list("Human", "Slime People", "Skeleton", "Nucleation", "Machine")
+
+/obj/item/clothing/head/helmet/lightweighthelmet
+ name = "lightweight helmet"
+ desc = "Standard Security gear. Protects the head from impacts."
+ icon_state = "lightweighthelmet"
+ item_state = "lightweighthelmet"
+ flags_inv = HIDEHEADSETS
+ strip_delay = 60
+ flags = BLOCKHEADHAIR
+ flags_cover = null
+ dog_fashion = null
+ sprite_sheets = list(
+ "Vox" = 'icons/mob/clothing/species/vox/helmet.dmi',
+ "Drask" = 'icons/mob/clothing/species/drask/helmet.dmi',
+ "Grey" = 'icons/mob/clothing/species/grey/helmet.dmi',
+ "Monkey" = 'icons/mob/clothing/species/monkey/head.dmi',
+ "Farwa" = 'icons/mob/clothing/species/monkey/head.dmi',
+ "Wolpin" = 'icons/mob/clothing/species/monkey/head.dmi',
+ "Neara" = 'icons/mob/clothing/species/monkey/head.dmi',
+ "Stok" = 'icons/mob/clothing/species/monkey/head.dmi'
+ )
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index f875c19e718..e87a1509def 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -21,6 +21,7 @@
materials = list(MAT_METAL=1750, MAT_GLASS=400)
flash_protect = 2
tint = 2
+ can_toggle = TRUE
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 60)
flags_inv = HIDEMASK|HIDEHEADSETS|HIDEGLASSES|HIDENAME
actions_types = list(/datum/action/item_action/toggle)
@@ -44,9 +45,6 @@
"Stok" = 'icons/mob/clothing/species/monkey/head.dmi'
)
-/obj/item/clothing/head/welding/attack_self(mob/user)
- weldingvisortoggle(user)
-
/obj/item/clothing/head/welding/flamedecal
name = "flame decal welding helmet"
desc = "A welding helmet adorned with flame decals, and several cryptic slogans of varying degrees of legibility."
@@ -62,8 +60,8 @@
desc = "A white welding helmet with a character written across it."
icon_state = "welding_white"
-/obj/item/clothing/head/welding/attack_self()
- toggle()
+/obj/item/clothing/head/welding/attack_self(mob/user)
+ weldingvisortoggle(user)
/obj/item/clothing/head/welding/attackby(obj/item/I, mob/living/user)
if(istype(I, /obj/item/toy/crayon/spraycan))
@@ -98,40 +96,6 @@
return ..()
-/obj/item/clothing/head/welding/proc/toggle()
- if(up)
- up = !up
- flags_cover |= (HEADCOVERSEYES | HEADCOVERSMOUTH)
- flags_inv |= (HIDEMASK|HIDEHEADSETS|HIDEGLASSES|HIDENAME)
- if(paint)
- icon_state = paint
- else
- icon_state = initial(icon_state)
- to_chat(usr, "You flip the [src] down to protect your eyes.")
- flash_protect = 2
- tint = 2
- else
- up = !up
- flags_cover &= ~(HEADCOVERSEYES | HEADCOVERSMOUTH)
- flags_inv &= ~(HIDEMASK|HIDEHEADSETS|HIDEGLASSES|HIDENAME)
- if(paint)
- icon_state = "[paint]up"
- else
- icon_state = "[initial(icon_state)]up"
- to_chat(usr, "You push the [src] up out of your face.")
- flash_protect = 0
- tint = 0
- var/mob/living/carbon/user = usr
- user.update_tint()
- user.update_inv_head() //so our mob-overlays update
- user.update_inv_wear_mask()
-
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
-
-
-
/*
* Cakehat
*/
@@ -139,40 +103,55 @@
name = "cake-hat"
desc = "It's tasty looking!"
icon_state = "cake0"
+ base_icon_state = "cake"
flags_cover = HEADCOVERSEYES
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
- var/onfire = 0.0
- var/status = 0
- var/fire_resist = T0C+1300 //this is the max temp it can stand before you start to cook. although it might not burn away, you take damage
- var/processing = 0 //I dont think this is used anywhere.
+ var/on_fire = FALSE
+
/obj/item/clothing/head/cakehat/process()
- if(!onfire)
- STOP_PROCESSING(SSobj, src)
- return
+ if(!on_fire)
+ return PROCESS_KILL
+
+ var/turf/cake_turf = loc
+ if(is_equipped(include_pockets = TRUE, include_hands = TRUE))
+ cake_turf = loc.loc
+
+ if(isturf(cake_turf))
+ cake_turf.hotspot_expose(700, 1)
+
+
+/obj/item/clothing/head/cakehat/attack_self(mob/user)
+ toggle_cake_light(user)
- var/turf/location = src.loc
- if(istype(location, /mob/))
- var/mob/living/carbon/human/M = location
- if(M.l_hand == src || M.r_hand == src || M.head == src)
- location = M.loc
-
- if(istype(location, /turf))
- location.hotspot_expose(700, 1)
-
-/obj/item/clothing/head/cakehat/attack_self(mob/user as mob)
- if(status > 1) return
- src.onfire = !( src.onfire )
- if(src.onfire)
- src.force = 3
- src.damtype = "fire"
- src.icon_state = "cake1"
+
+/obj/item/clothing/head/cakehat/proc/toggle_cake_light(mob/user)
+ on_fire = !on_fire
+ update_icon(UPDATE_ICON_STATE)
+ user?.visible_message(
+ span_notice("[user] [on_fire ? "lights up" : "extinguishes"] [src]."),
+ span_notice("You [on_fire ? "lighted up" : "extinguished"] [src]."),
+ )
+ if(on_fire)
+ set_light(1.5, 1, LIGHT_COLOR_YELLOW)
+ force = 3
+ damtype = BURN
START_PROCESSING(SSobj, src)
else
- src.force = null
- src.damtype = "brute"
- src.icon_state = "cake0"
- return
+ set_light(0)
+ force = 0
+ damtype = BRUTE
+ STOP_PROCESSING(SSobj, src)
+
+
+/obj/item/clothing/head/cakehat/update_icon_state()
+ icon_state = "[base_icon_state][on_fire]"
+
+
+/obj/item/clothing/head/cakehat/extinguish_light(force = FALSE)
+ if(!force || !on_fire)
+ return
+ toggle_cake_light()
/*
@@ -181,12 +160,16 @@
/obj/item/clothing/head/ushanka
name = "ushanka"
desc = "Perfect for winter in Siberia, da?"
- icon_state = "ushankadown"
- item_state = "ushankadown"
+ icon_state = "ushanka"
+ item_state = "ushanka"
flags_inv = HIDEHEADSETS
cold_protection = HEAD
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
dog_fashion = /datum/dog_fashion/head/ushanka
+ actions_types = list(/datum/action/item_action/toggle_helmet_mode)
+ can_toggle = TRUE
+ toggle_on_message = "You raise the ear flaps on"
+ toggle_off_message = "You lower the ear flaps on"
sprite_sheets = list(
"Grey" = 'icons/mob/clothing/species/grey/head.dmi',
"Monkey" = 'icons/mob/clothing/species/monkey/head.dmi',
@@ -196,16 +179,6 @@
"Stok" = 'icons/mob/clothing/species/monkey/head.dmi'
)
-/obj/item/clothing/head/ushanka/attack_self(mob/user as mob)
- if(src.icon_state == "ushankadown")
- src.icon_state = "ushankaup"
- src.item_state = "ushankaup"
- to_chat(user, "You raise the ear flaps on the ushanka.")
- else
- src.icon_state = "ushankadown"
- src.item_state = "ushankadown"
- to_chat(user, "You lower the ear flaps on the ushanka.")
-
/obj/item/clothing/head/sovietsidecap
name = "\improper Soviet side cap"
desc = "A simple military cap with a Soviet star on the front. What it lacks in protection it makes up for in revolutionary spirit."
@@ -280,43 +253,42 @@
name = "kitty ears"
desc = "A pair of kitty ears. Meow!"
icon_state = "kitty"
- var/icon/mob
dog_fashion = /datum/dog_fashion/head/kitty
+ var/mob/living/carbon/human/previous_owner
+ var/outer_state = "kitty"
+ var/inner_state = "kittyinner"
-/obj/item/clothing/head/kitty/update_icon(var/mob/living/carbon/human/user)
- if(!istype(user)) return
- var/obj/item/organ/external/head/head_organ = user.get_organ(BODY_ZONE_HEAD)
- mob = new/icon("icon" = 'icons/mob/clothing/head.dmi', "icon_state" = "kitty")
- mob.Blend(head_organ.hair_colour, ICON_ADD)
+/obj/item/clothing/head/kitty/mouse
+ name = "mouse ears"
+ desc = "A pair of mouse ears. Squeak!"
+ icon_state = "mousey"
+ outer_state = "mousey"
+ inner_state = "mouseyinner"
- var/icon/earbit = new/icon("icon" = 'icons/mob/clothing/head.dmi', "icon_state" = "kittyinner")
- mob.Blend(earbit, ICON_OVERLAY)
- icon_override = mob
+/obj/item/clothing/head/kitty/Destroy()
+ previous_owner = null
+ return ..()
-/obj/item/clothing/head/kitty/equipped(mob/M, slot, initial)
- . = ..()
-
- if(ishuman(M) && slot == slot_head)
- update_icon(M)
+/obj/item/clothing/head/kitty/equipped(mob/user, slot, initial)
+ . = ..()
+ if(. && slot == slot_head)
+ update_look(user)
-/obj/item/clothing/head/kitty/mouse
- name = "mouse ears"
- desc = "A pair of mouse ears. Squeak!"
- icon_state = "mousey"
-/obj/item/clothing/head/kitty/mouse/update_icon(var/mob/living/carbon/human/user)
- if(!istype(user)) return
+/obj/item/clothing/head/kitty/proc/update_look(mob/living/carbon/human/user)
+ if(!ishuman(user) || user == previous_owner)
+ return
+ previous_owner = user
var/obj/item/organ/external/head/head_organ = user.get_organ(BODY_ZONE_HEAD)
- mob = new/icon("icon" = 'icons/mob/clothing/head.dmi', "icon_state" = "mousey")
- mob.Blend(head_organ.hair_colour, ICON_ADD)
-
- var/icon/earbit = new/icon("icon" = 'icons/mob/clothing/head.dmi', "icon_state" = "mouseyinner")
- mob.Blend(earbit, ICON_OVERLAY)
+ var/icon/new_look = icon('icons/mob/clothing/head.dmi', outer_state)
+ new_look.Blend(head_organ.hair_colour, ICON_ADD)
+ new_look.Blend(icon('icons/mob/clothing/head.dmi', inner_state), ICON_OVERLAY)
+ icon_override = new_look
+ user.update_inv_head()
- icon_override = mob
/obj/item/clothing/head/cardborg
name = "cardborg helmet"
@@ -338,19 +310,18 @@
)
-/obj/item/clothing/head/cardborg/equipped(mob/living/user, slot, initial)
+/obj/item/clothing/head/cardborg/equipped(mob/living/carbon/human/user, slot, initial)
. = ..()
+ if(ishuman(user) && slot == slot_head && istype(user.wear_suit, /obj/item/clothing/suit/cardborg))
+ var/obj/item/clothing/suit/cardborg/user_suit = user.wear_suit
+ user_suit.disguise(user, src)
- if(ishuman(user) && slot == slot_head)
- var/mob/living/carbon/human/H = user
- if(istype(H.wear_suit, /obj/item/clothing/suit/cardborg))
- var/obj/item/clothing/suit/cardborg/CB = H.wear_suit
- CB.disguise(user, src)
/obj/item/clothing/head/cardborg/dropped(mob/living/user, silent = FALSE)
- ..()
+ . = ..()
user.remove_alt_appearance("standard_borg_disguise")
+
/*
* Head Mirror
*/
diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm
index 34e2b64ec12..2cf395d7c33 100644
--- a/code/modules/clothing/head/soft_caps.dm
+++ b/code/modules/clothing/head/soft_caps.dm
@@ -4,7 +4,7 @@
icon_state = "cargosoft"
item_state = "helmet"
item_color = "cargo"
- var/flipped = 0
+ var/flipped = FALSE
actions_types = list(/datum/action/item_action/flip_cap)
dog_fashion = /datum/dog_fashion/head/cargo_tech
sprite_sheets = list(
@@ -17,27 +17,30 @@
)
dyeable = TRUE
+
+/obj/item/clothing/head/soft/update_icon_state()
+ icon_state = flipped ? "[item_color]soft_flipped" : "[item_color]soft"
+ update_equipped_item()
+
+
/obj/item/clothing/head/soft/dropped(mob/user, silent = FALSE)
- icon_state = "[item_color]soft"
- flipped = 0
- ..()
+ . = ..()
+ if(flipped)
+ flipped = FALSE
+ update_icon(UPDATE_ICON_STATE)
+
/obj/item/clothing/head/soft/attack_self(mob/user)
flip(user)
+
/obj/item/clothing/head/soft/proc/flip(mob/user)
flipped = !flipped
+ update_icon(UPDATE_ICON_STATE)
if(flipped)
- icon_state = "[item_color]soft_flipped"
- to_chat(usr, "You flip the hat backwards.")
+ to_chat(user, span_notice("You flip the hat backwards."))
else
- icon_state = "[item_color]soft"
- to_chat(user, "You flip the hat back in normal position.")
- user.update_inv_head() //so our mob-overlays update
-
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
+ to_chat(user, span_notice("You flip the hat back in normal position."))
/obj/item/clothing/head/soft/red
name = "red cap"
diff --git a/code/modules/clothing/masks/boxing.dm b/code/modules/clothing/masks/boxing.dm
index cac4042c6e9..6295c77592a 100644
--- a/code/modules/clothing/masks/boxing.dm
+++ b/code/modules/clothing/masks/boxing.dm
@@ -6,6 +6,7 @@
flags = BLOCKHAIR
flags_inv = HIDENAME
w_class = WEIGHT_CLASS_SMALL
+ can_toggle = TRUE
actions_types = list(/datum/action/item_action/adjust)
adjusted_flags = SLOT_HEAD
@@ -26,12 +27,24 @@
"Stok" = 'icons/mob/clothing/species/monkey/mask.dmi'
)
-/obj/item/clothing/mask/balaclava/attack_self(var/mob/user)
+/obj/item/clothing/mask/balaclava/attack_self(mob/user)
adjustmask(user)
-/obj/item/clothing/mask/balaclava/adjustmask(user)
- ..()
- flags = mask_adjusted ? null : initial(flags)
+/obj/item/clothing/mask/balaclava/adjustmask(mob/user)
+ . = ..()
+ if(!.)
+ return
+ var/mob/living/carbon/human/H = usr
+ if(H.l_hand && H.r_hand)
+ user.drop_item_ground(src)
+ else
+ user.drop_item_ground(src)
+ user.put_in_hands(src)
+
+ if(!up)
+ flags |= BLOCKHAIR
+ else
+ flags &= ~BLOCKHAIR
/obj/item/clothing/mask/luchador
name = "Luchador Mask"
diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm
index 7603c354d17..9712a8cdc10 100644
--- a/code/modules/clothing/masks/breath.dm
+++ b/code/modules/clothing/masks/breath.dm
@@ -10,6 +10,7 @@
permeability_coefficient = 0.50
actions_types = list(/datum/action/item_action/adjust)
resistance_flags = NONE
+ can_toggle = TRUE
sprite_sheets = list(
"Vox" = 'icons/mob/clothing/species/vox/mask.dmi',
"Vox Armalis" = 'icons/mob/clothing/species/armalis/mask.dmi',
@@ -29,7 +30,7 @@
"Stok" = 'icons/mob/clothing/species/monkey/mask.dmi'
)
-/obj/item/clothing/mask/breath/attack_self(var/mob/user)
+/obj/item/clothing/mask/breath/attack_self(mob/user)
adjustmask(user)
/obj/item/clothing/mask/breath/AltClick(mob/living/user)
@@ -57,7 +58,7 @@
species_restricted = list("Vox", "Vox Armalis") //These should fit the "Mega Vox" just fine.
actions_types = null
-/obj/item/clothing/mask/breath/vox/attack_self(var/mob/user)
+/obj/item/clothing/mask/breath/vox/attack_self(mob/user)
return
/obj/item/clothing/mask/breath/vox/AltClick(mob/user)
diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm
index ecd69b85e3f..f36c1724294 100644
--- a/code/modules/clothing/masks/gasmask.dm
+++ b/code/modules/clothing/masks/gasmask.dm
@@ -38,6 +38,7 @@
materials = list(MAT_METAL=4000, MAT_GLASS=2000)
flash_protect = 2
tint = 2
+ can_toggle = TRUE
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 55)
origin_tech = "materials=2;engineering=3"
actions_types = list(/datum/action/item_action/toggle)
@@ -46,9 +47,15 @@
visor_flags_inv = HIDEGLASSES
resistance_flags = FIRE_PROOF
+
/obj/item/clothing/mask/gas/welding/attack_self(mob/user)
weldingvisortoggle(user)
+
+/obj/item/clothing/mask/gas/welding/adjustmask(mob/user)
+ return
+
+
/obj/item/clothing/mask/gas/explorer
name = "explorer gas mask"
desc = "A military-grade gas mask that can be connected to an air supply."
@@ -56,6 +63,7 @@
actions_types = list(/datum/action/item_action/adjust)
armor = list("melee" = 10, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 20, "acid" = 40)
resistance_flags = FIRE_PROOF
+ can_toggle = TRUE
sprite_sheets = list(
"Vox" = 'icons/mob/clothing/species/vox/mask.dmi',
@@ -74,16 +82,32 @@
"Stok" = 'icons/mob/clothing/species/monkey/mask.dmi'
)
+
/obj/item/clothing/mask/gas/explorer/attack_self(mob/user)
adjustmask(user)
-/obj/item/clothing/mask/gas/explorer/adjustmask(user)
- ..()
- w_class = mask_adjusted ? WEIGHT_CLASS_SMALL : WEIGHT_CLASS_NORMAL
-/obj/item/clothing/mask/gas/explorer/folded/Initialize()
+/obj/item/clothing/mask/gas/explorer/adjustmask(mob/user)
. = ..()
- adjustmask()
+ if(.)
+ w_class = up ? WEIGHT_CLASS_SMALL : WEIGHT_CLASS_NORMAL
+
+
+/obj/item/clothing/mask/gas/explorer/folded/Initialize(mapload)
+ . = ..()
+ force_adjust_mask()
+
+
+/obj/item/clothing/mask/gas/explorer/folded/proc/force_adjust_mask()
+ up = !up
+ update_icon(UPDATE_ICON_STATE)
+ gas_transfer_coefficient = null
+ permeability_coefficient = null
+ flags_cover &= ~MASKCOVERSMOUTH
+ flags_inv &= ~HIDENAME
+ flags &= ~AIRTIGHT
+ w_class = WEIGHT_CLASS_SMALL
+
//Bane gas mask
/obj/item/clothing/mask/banemask
@@ -288,9 +312,12 @@
desc = "A standard issue Security gas mask with integrated 'Compli-o-nator 3000' device, plays over a dozen pre-recorded compliance phrases designed to get scumbags to stand still whilst you taze them. Do not tamper with the device."
icon_state = "sechailer"
item_state = "sechailer"
+ flags_inv = HIDENAME
+ flags_cover = MASKCOVERSMOUTH
var/phrase = 1
var/aggressiveness = 1
var/safety = 1
+ can_toggle = TRUE
actions_types = list(/datum/action/item_action/halt, /datum/action/item_action/adjust, /datum/action/item_action/selectphrase)
var/phrase_list = list(
@@ -329,6 +356,7 @@
icon_state = "hosmask"
aggressiveness = 3
phrase = 12
+ can_toggle = FALSE
actions_types = list(/datum/action/item_action/halt, /datum/action/item_action/selectphrase)
/obj/item/clothing/mask/gas/sechailer/warden
@@ -337,6 +365,7 @@
icon_state = "wardenmask"
aggressiveness = 3
phrase = 12
+ can_toggle = FALSE
actions_types = list(/datum/action/item_action/halt, /datum/action/item_action/selectphrase)
@@ -346,6 +375,7 @@
icon_state = "officermask"
aggressiveness = 3
phrase = 12
+ can_toggle = FALSE
actions_types = list(/datum/action/item_action/halt, /datum/action/item_action/selectphrase)
/obj/item/clothing/mask/gas/sechailer/blue
@@ -355,6 +385,7 @@
item_state = "blue_sechailer"
aggressiveness = 3
phrase = 12
+ can_toggle = FALSE
actions_types = list(/datum/action/item_action/halt, /datum/action/item_action/selectphrase)
/obj/item/clothing/mask/gas/sechailer/cyborg
@@ -362,6 +393,7 @@
desc = "A set of recognizable pre-recorded messages for cyborgs to use when apprehending criminals."
icon = 'icons/obj/device.dmi'
icon_state = "taperecorder_idle"
+ can_toggle = FALSE
actions_types = list(/datum/action/item_action/halt, /datum/action/item_action/selectphrase)
/obj/item/clothing/mask/gas/sechailer/ui_action_click(mob/user, actiontype)
@@ -401,8 +433,14 @@
else
to_chat(user, "It's broken.")
+ var/datum/action/item_action/halt/halt_action = locate() in actions
+ if(halt_action)
+ halt_action.name = "[uppertext(key)]!"
+ halt_action.UpdateButtonIcon()
+
+
/obj/item/clothing/mask/gas/sechailer/attackby(obj/item/W as obj, mob/user as mob, params)
- if(istype(W, /obj/item/screwdriver))
+ if(W.tool_behaviour == TOOL_SCREWDRIVER)
switch(aggressiveness)
if(1)
to_chat(user, "You set the aggressiveness restrictor to the second position.")
@@ -422,7 +460,7 @@
phrase = 1
if(5)
to_chat(user, "You adjust the restrictor but nothing happens, probably because its broken.")
- else if(istype(W, /obj/item/wirecutters))
+ else if(W.tool_behaviour == TOOL_WIRECUTTER)
if(aggressiveness != 5)
to_chat(user, "You broke it!")
aggressiveness = 5
diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm
index 3ad5c475930..eb9b12ed201 100644
--- a/code/modules/clothing/masks/miscellaneous.dm
+++ b/code/modules/clothing/masks/miscellaneous.dm
@@ -23,7 +23,7 @@
)
// Clumsy folks can't take the mask off themselves.
-/obj/item/clothing/mask/muzzle/attack_hand(mob/user as mob)
+/obj/item/clothing/mask/muzzle/attack_hand(mob/user)
if(user.wear_mask == src && !user.IsAdvancedToolUser())
return 0
else if(security_lock && locked)
@@ -207,7 +207,7 @@
return loc
return FALSE
-/obj/item/clothing/mask/muzzle/safety/shock/proc/process_activation(var/obj/D, var/normal = 1, var/special = 1)
+/obj/item/clothing/mask/muzzle/safety/shock/proc/process_activation(obj/D, normal = 1, special = 1)
visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*")
var/mob/living/L = can_shock(loc)
if(!L)
@@ -224,11 +224,11 @@
trigger.HasProximity(AM)
-/obj/item/clothing/mask/muzzle/safety/shock/hear_talk(mob/living/M as mob, list/message_pieces)
+/obj/item/clothing/mask/muzzle/safety/shock/hear_talk(mob/living/M, list/message_pieces)
if(trigger)
trigger.hear_talk(M, message_pieces)
-/obj/item/clothing/mask/muzzle/safety/shock/hear_message(mob/living/M as mob, msg)
+/obj/item/clothing/mask/muzzle/safety/shock/hear_message(mob/living/M, msg)
if(trigger)
trigger.hear_message(M, msg)
@@ -243,6 +243,7 @@
flags_cover = MASKCOVERSMOUTH
gas_transfer_coefficient = 0.90
permeability_coefficient = 0.01
+ can_toggle = TRUE
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 25, "rad" = 0, "fire" = 0, "acid" = 0)
actions_types = list(/datum/action/item_action/adjust)
@@ -264,7 +265,7 @@
)
-/obj/item/clothing/mask/surgical/attack_self(var/mob/user)
+/obj/item/clothing/mask/surgical/attack_self(mob/user)
adjustmask(user)
/obj/item/clothing/mask/fakemoustache
@@ -332,19 +333,6 @@
w_class = WEIGHT_CLASS_SMALL
gas_transfer_coefficient = 0.90
-/* --------------------------------
- * Хрен знает зачем у нас тут шарф у которого даже спрайта нет. И который ещё и маска...
- * Я пожалуй оставлю, но закоменчу этот код.
-/obj/item/clothing/mask/ninjascarf
- name = "ninja scarf"
- desc = "A stealthy, dark scarf."
- icon_state = "ninja_scarf"
- item_state = "ninja_scarf"
- flags_cover = MASKCOVERSMOUTH
- w_class = WEIGHT_CLASS_SMALL
- gas_transfer_coefficient = 0.90
-*/
-
/obj/item/clothing/mask/pig
name = "pig mask"
desc = "A rubber pig mask."
@@ -534,7 +522,7 @@
adjusted_flags = SLOT_HEAD
icon_state = "bandbotany"
dyeable = TRUE
-
+ can_toggle = TRUE
sprite_sheets = list(
"Vox" = 'icons/mob/clothing/species/vox/mask.dmi',
"Unathi" = 'icons/mob/clothing/species/unathi/mask.dmi',
@@ -553,9 +541,18 @@
)
actions_types = list(/datum/action/item_action/adjust)
-/obj/item/clothing/mask/bandana/attack_self(var/mob/user)
+/obj/item/clothing/mask/bandana/attack_self(mob/user)
adjustmask(user)
+/obj/item/clothing/mask/bandana/adjustmask(mob/user)
+ ..()
+ var/mob/living/carbon/human/H = usr
+ if(H.l_hand && H.r_hand)
+ user.drop_item_ground(src)
+ else
+ user.drop_item_ground(src)
+ user.put_in_hands(src)
+
/obj/item/clothing/mask/bandana/red
name = "red bandana"
icon_state = "bandred"
@@ -663,3 +660,39 @@
/obj/item/clothing/mask/gas/voice_modulator/change_speech_verb()
if(voice_modulator.active)
return pick("modulates", "drones", "hums", "buzzes")
+
+//sec scarf
+
+/obj/item/clothing/mask/secscarf
+ name = "security scarf"
+ desc = "Bleck security snood. Excellent replacement for a balaclava."
+ icon_state = "secscarf"
+ item_state = "secscarf"
+ icon = 'icons/obj/clothing/masks.dmi'
+ flags_inv = HIDENAME
+ flags = BLOCKFACIALHAIR
+ flags_cover = MASKCOVERSMOUTH
+ can_toggle = TRUE
+ strip_delay = 20
+ put_on_delay = 20
+ armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
+ gas_transfer_coefficient = 0.90
+ permeability_coefficient = 0.90
+ actions_types = list(/datum/action/item_action/adjust)
+
+ sprite_sheets = list(
+ "Vox" = 'icons/mob/clothing/species/vox/mask.dmi',
+ "Drask" = 'icons/mob/clothing/species/drask/mask.dmi',
+ "Grey" = 'icons/mob/clothing/species/grey/mask.dmi',
+ "Unathi" = 'icons/mob/clothing/species/unathi/mask.dmi',
+ "Tajaran" = 'icons/mob/clothing/species/tajaran/mask.dmi',
+ "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/mask.dmi',
+ "Monkey" = 'icons/mob/clothing/species/monkey/mask.dmi',
+ "Farwa" = 'icons/mob/clothing/species/monkey/mask.dmi',
+ "Wolpin" = 'icons/mob/clothing/species/monkey/mask.dmi',
+ "Neara" = 'icons/mob/clothing/species/monkey/mask.dmi',
+ "Stok" = 'icons/mob/clothing/species/monkey/mask.dmi'
+ )
+
+/obj/item/clothing/mask/secscarf/attack_self(mob/user)
+ adjustmask(user)
diff --git a/code/modules/clothing/neck/cloaks.dm b/code/modules/clothing/neck/cloaks.dm
index efd54786445..a64160f61d7 100644
--- a/code/modules/clothing/neck/cloaks.dm
+++ b/code/modules/clothing/neck/cloaks.dm
@@ -10,8 +10,8 @@
/obj/item/clothing/neck/cloak/Initialize(mapload)
. = ..()
+ AddComponent(/datum/component/spraycan_paintable)
add_atom_colour(colour, FIXED_COLOUR_PRIORITY)
- update_icon()
/obj/item/clothing/neck/cloak/grey
colour = "#535353"
@@ -121,20 +121,3 @@
icon_state = "syndadmiral"
item_state = "syndadmiral"
-/obj/item/clothing/neck/toggle/attack_self(mob/user)
- if(icon_state == initial(icon_state))
- icon_state = icon_state + "_t"
- item_state = icon_state + "_t"
- else
- icon_state = initial(icon_state)
- item_state = initial(item_state)
- user.update_inv_neck()
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
-
-/obj/item/clothing/neck/cloak/New()
- ..()
- AddComponent(/datum/component/spraycan_paintable)
- START_PROCESSING(SSobj, src)
- update_icon()
diff --git a/code/modules/clothing/neck/mantles.dm b/code/modules/clothing/neck/mantles.dm
index a5c9a82195a..32285d87202 100644
--- a/code/modules/clothing/neck/mantles.dm
+++ b/code/modules/clothing/neck/mantles.dm
@@ -82,8 +82,7 @@
desc = "A tweed mantle, worn by the Research Director. Smells like science."
icon_state = "rdmantle"
-/obj/item/clothing/neck/mantle/New()
- ..()
+/obj/item/clothing/neck/mantle/Initialize(mapload)
+ . = ..()
AddComponent(/datum/component/spraycan_paintable)
- START_PROCESSING(SSobj, src)
- update_icon()
+
diff --git a/code/modules/clothing/neck/ponchos.dm b/code/modules/clothing/neck/ponchos.dm
index 59002150fae..be819ebe42a 100644
--- a/code/modules/clothing/neck/ponchos.dm
+++ b/code/modules/clothing/neck/ponchos.dm
@@ -25,12 +25,8 @@
"Wryn" = 'icons/mob/clothing/species/wryn/neck.dmi'
)
-/obj/item/clothing/neck/poncho/update_icon()
- . = ..()
- if(flipped)
- icon_state = "[item_color]poncho_flip"
- else
- icon_state = "[item_color]poncho"
+/obj/item/clothing/neck/poncho/update_icon_state()
+ icon_state = "[item_color]poncho[flipped ? "_flip" : ""]"
/obj/item/clothing/neck/poncho/AltClick(mob/living/carbon/human/user)
if(!iscarbon(user))
@@ -57,7 +53,7 @@
..()
if(flipped)
flipped = FALSE
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
/obj/item/clothing/neck/poncho/equipped(mob/user, slot, initial)
. = ..()
@@ -65,18 +61,17 @@
var/mob/living/carbon/human/human = user
if((slot != human.neck) && flipped)
flipped = FALSE
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
/obj/item/clothing/neck/poncho/proc/flip(mob/user)
if(user.incapacitated())
to_chat(user, span_warning("You can't do that right now!"))
return
flipped = !flipped
+ update_icon(UPDATE_ICON_STATE)
if(flipped)
- update_icon()
to_chat(user, "You flip [src] behind your back.")
else
- update_icon()
to_chat(user, "You flip [src] to its normal position.")
user.update_inv_neck()
diff --git a/code/modules/clothing/shoes/colour.dm b/code/modules/clothing/shoes/colour.dm
index 13a72265047..40d8a31f0dc 100644
--- a/code/modules/clothing/shoes/colour.dm
+++ b/code/modules/clothing/shoes/colour.dm
@@ -99,18 +99,24 @@
QDEL_NULL(shackles)
return ..()
+
/obj/item/clothing/shoes/orange/attack_self(mob/user)
if(shackles)
user.put_in_hands(shackles)
shackles = null
slowdown = SHOES_SLOWDOWN
- icon_state = "orange"
+ update_icon(UPDATE_ICON_STATE)
+
+
+/obj/item/clothing/shoes/orange/update_icon_state()
+ icon_state = "orange[shackles ? "1" : ""]"
+
/obj/item/clothing/shoes/orange/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/restraints/handcuffs) && !shackles)
- if(user.drop_transfer_item_to_loc(I, src))
- shackles = I
- slowdown = 15
- icon_state = "orange1"
- return
+ if(istype(I, /obj/item/restraints/handcuffs) && !shackles && user.drop_transfer_item_to_loc(I, src))
+ shackles = I
+ slowdown = 15
+ update_icon(UPDATE_ICON_STATE)
+ return
return ..()
+
diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm
index 5124a5c2a73..affd6bb1c19 100644
--- a/code/modules/clothing/shoes/magboots.dm
+++ b/code/modules/clothing/shoes/magboots.dm
@@ -4,7 +4,7 @@
icon_state = "magboots0"
origin_tech = "materials=3;magnets=4;engineering=4"
var/magboot_state = "magboots"
- var/magpulse = 0
+ var/magpulse = FALSE
var/slowdown_active = 2
var/slowdown_passive = SHOES_SLOWDOWN
var/magpulse_name = "mag-pulse traction system"
@@ -40,21 +40,31 @@
magpulse_name = "anchoring spikes"
slowdown_active = 2
-/obj/item/clothing/shoes/magboots/attack_self(mob/user)
+
+/obj/item/clothing/shoes/magboots/update_icon_state()
+ icon_state = "[magboot_state][magpulse]"
+
+
+/obj/item/clothing/shoes/magboots/attack_self(mob/user, forced = FALSE)
+ toggle_magpulse(user, forced)
+
+
+/obj/item/clothing/shoes/magboots/proc/toggle_magpulse(mob/user, forced)
if(magpulse)
+ START_PROCESSING(SSobj, src) //Gravboots
flags &= ~NOSLIP
slowdown = slowdown_passive
else
+ STOP_PROCESSING(SSobj, src)
flags |= NOSLIP
slowdown = slowdown_active
magpulse = !magpulse
- icon_state = "[magboot_state][magpulse]"
- to_chat(user, "You [magpulse ? "enable" : "disable"] the [magpulse_name].")
- user.update_inv_shoes() //so our mob-overlays update
+ update_icon(UPDATE_ICON_STATE)
+ if(!forced)
+ to_chat(user, "You [magpulse ? "enable" : "disable"] the [magpulse_name].")
user.update_gravity(user.mob_has_gravity())
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
+ update_equipped_item()
+
/obj/item/clothing/shoes/magboots/negates_gravity()
return flags & NOSLIP
@@ -161,7 +171,7 @@
slowdown_active = 0
magboot_state = "gravboots"
magpulse_name = "micro gravitational traction system"
- var/datum/martial_art/grav_stomp/style = new //Only works with core and cell installed.
+ var/datum/martial_art/grav_stomp/style
var/jumpdistance = 5
var/jumpspeed = 3
var/recharging_rate = 6 SECONDS
@@ -171,6 +181,12 @@
var/obj/item/assembly/signaler/anomaly/grav/core = null
var/obj/item/stock_parts/cell/cell = null
+
+/obj/item/clothing/shoes/magboots/gravity/Initialize()
+ . = ..()
+ style = new()
+
+
/obj/item/clothing/shoes/magboots/gravity/Destroy()
QDEL_NULL(style)
QDEL_NULL(cell)
@@ -189,7 +205,8 @@
else
. += "It is missing a gravitational anomaly core and a power cell."
-/obj/item/clothing/shoes/magboots/gravity/attack_self(mob/user)
+
+/obj/item/clothing/shoes/magboots/gravity/toggle_magpulse(mob/user, forced)
if(!cell)
to_chat(user, "Your boots do not have a power cell!")
return
@@ -199,8 +216,8 @@
if(!core)
to_chat(user, "There's no core installed!")
return
+ return ..()
- ..()
/obj/item/clothing/shoes/magboots/gravity/process()
if(!cell) //There should be a cell here, but safety first
@@ -209,7 +226,7 @@
if(ishuman(loc))
var/mob/living/carbon/human/user = loc
to_chat(user, "[src] has ran out of charge, and turned off!")
- attack_self(user)
+ attack_self(user, TRUE)
else
cell.use(power_consumption_rate)
@@ -272,7 +289,7 @@
style.remove(H)
if(magpulse)
to_chat(user, "As [src] are removed, they deactivate.")
- attack_self(user)
+ attack_self(user, TRUE)
/obj/item/clothing/shoes/magboots/gravity/item_action_slot_check(slot)
if(slot == slot_shoes)
diff --git a/code/modules/clothing/spacesuits/alien.dm b/code/modules/clothing/spacesuits/alien.dm
index b1eb9def064..9eef7a999aa 100644
--- a/code/modules/clothing/spacesuits/alien.dm
+++ b/code/modules/clothing/spacesuits/alien.dm
@@ -207,36 +207,44 @@
"Vox Armalis" = 'icons/mob/clothing/species/armalis/feet.dmi'
)
-/obj/item/clothing/shoes/magboots/vox/attack_self(mob/user)
+
+/obj/item/clothing/shoes/magboots/vox/update_icon_state()
+ return
+
+
+/obj/item/clothing/shoes/magboots/vox/attack_self(mob/user, forced = FALSE)
+ toggle_magpulse(user, forced)
+
+
+/obj/item/clothing/shoes/magboots/vox/toggle_magpulse(mob/living/user, forced)
if(magpulse)
flags &= ~NOSLIP
- magpulse = 0
- flags |= NODROP
- to_chat(user, "You relax your deathgrip on the flooring.")
+ flags &= ~NODROP
+ slowdown = slowdown_passive
+ if(!forced)
+ to_chat(user, "You relax your deathgrip on the flooring.")
else
- //make sure these can only be used when equipped.
- if(!ishuman(user))
- return
- var/mob/living/carbon/human/H = user
- if(H.shoes != src)
- to_chat(user, "You will have to put on the [src] before you can do that.")
- return
+ flags |= NOSLIP
+ flags |= NODROP //kinda hard to take off magclaws when you are gripping them tightly.
+ slowdown = slowdown_active
+ if(!forced)
+ to_chat(user, "You dig your claws deeply into the flooring, bracing yourself.")
+ magpulse = !magpulse
+ user.update_gravity(user.mob_has_gravity())
- flags |= NOSLIP
- magpulse = 1
- flags &= ~NODROP //kinda hard to take off magclaws when you are gripping them tightly.
- to_chat(user, "You dig your claws deeply into the flooring, bracing yourself.")
- to_chat(user, "It would be hard to take off the [src] without relaxing your grip first.")
+/obj/item/clothing/shoes/magboots/vox/item_action_slot_check(slot)
+ if(slot == slot_shoes)
+ return TRUE
+
//In case they somehow come off while enabled.
/obj/item/clothing/shoes/magboots/vox/dropped(mob/user, silent = FALSE)
- ..()
- if(src.magpulse)
+ . = ..()
+ if(magpulse)
user.visible_message("The [src] go limp as they are removed from [usr]'s feet.", "The [src] go limp as they are removed from your feet.")
- flags &= ~NOSLIP
- magpulse = 0
- flags &= ~NODROP
+ toggle_magpulse(user, forced = TRUE)
+
/obj/item/clothing/shoes/magboots/vox/examine(mob/user)
. = ..()
diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm
index b79da33d5bf..7a62cff2630 100644
--- a/code/modules/clothing/spacesuits/chronosuit.dm
+++ b/code/modules/clothing/spacesuits/chronosuit.dm
@@ -180,7 +180,7 @@
/obj/effect/chronos_cam
name = "Chronosuit View"
density = 0
- anchored = 1
+ anchored = TRUE
invisibility = INVISIBILITY_ABSTRACT
opacity = 0
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
diff --git a/code/modules/clothing/spacesuits/ert.dm b/code/modules/clothing/spacesuits/ert.dm
index 2a9bccbb70f..47c0e306c85 100644
--- a/code/modules/clothing/spacesuits/ert.dm
+++ b/code/modules/clothing/spacesuits/ert.dm
@@ -238,11 +238,11 @@
"Vox" = 'icons/mob/clothing/species/vox/suit.dmi',
"Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/suit.dmi'
)
- allowed = list(/obj/item/nullrod/claymore, /obj/item/storage/belt/claymore)
+ allowed = list(/obj/item/nullrod/claymore, /obj/item/storage/belt/claymore, /obj/item/gun/energy,/obj/item/reagent_containers/spray/pepper,/obj/item/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/flashlight/seclite,/obj/item/melee/classic_baton/telescopic,/obj/item/kitchen/knife/combat)
hide_tail_by_species = list("Unathi, Ash Walker, Ash Walker Shaman, Draconid, Tajaran, Vox, Vulpkanin")
-/obj/item/clothing/suit/space/hardsuit/ert/paranormal/New()
- ..()
+/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize(mapload)
+ . = ..()
new /obj/item/nullrod(src)
/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor
@@ -314,6 +314,11 @@
"Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/helmet.dmi'
)
+
+/obj/item/clothing/head/helmet/space/hardsuit/deathsquad/update_icon_state()
+ return
+
+
/obj/item/clothing/suit/space/hardsuit/deathsquad
name = "deathsquad suit"
desc = "A heavily armored, advanced space suit that protects against most forms of damage."
@@ -338,6 +343,12 @@
"Stok" = 'icons/mob/clothing/species/monkey/suit.dmi',
"Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/suit.dmi'
)
+
+
+/obj/item/clothing/suit/space/hardsuit/deathsquad/update_icon_state()
+ return
+
+
/obj/item/clothing/suit/space/ert_eva_amber
name = "ERT Amber Spacesuit"
icon_state = "ert_eva_amber"
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index 252092a5966..3d852b311a1 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -7,14 +7,11 @@
item_state = "eng_helm"
armor = list("melee" = 10, "bullet" = 5, "laser" = 10, "energy" = 15, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 50, "acid" = 75)
item_color = "engineering" //Determines used sprites: hardsuit[on]-[color] and hardsuit[on]-[color]2 (lying down sprite)
- //heat_protection =
- //max_heat_protection_temperature =
- //resistance_flags =
max_integrity = 300
var/basestate = "hardsuit"
allowed = list(/obj/item/flashlight)
var/brightness_on = 4 //luminosity when on
- var/on = FALSE
+ var/light_on = FALSE
var/obj/item/clothing/suit/space/hardsuit/suit
actions_types = list(/datum/action/item_action/toggle_helmet_light)
@@ -40,57 +37,78 @@
"Vulpkanin" = 'icons/obj/clothing/species/vulpkanin/hats.dmi'
)
-/obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user)
- toggle_light(user)
-/obj/item/clothing/head/helmet/space/hardsuit/proc/toggle_light(mob/user)
- on = !on
- icon_state = "[basestate][on]-[item_color]"
+/obj/item/clothing/head/helmet/space/hardsuit/Destroy()
+ suit = null
+ return ..()
- if(istype(user,/mob/living/carbon/human))
- var/mob/living/carbon/human/H = user
- H.update_inv_head()
- if(on)
- set_light(brightness_on)
- else
- set_light(0)
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
+/obj/item/clothing/head/helmet/space/hardsuit/update_icon_state()
+ icon_state = "[basestate][light_on]-[item_color]"
+
+
+/obj/item/clothing/head/helmet/space/hardsuit/equipped(mob/user, slot, initial = FALSE)
+ . = ..()
+ if(slot != slot_head)
+ if(suit)
+ suit.RemoveHelmet()
+ else
+ qdel(src)
-/obj/item/clothing/head/helmet/space/hardsuit/extinguish_light(force = FALSE)
- if(on)
- toggle_light()
- visible_message(span_danger("[src]'s light fades and turns off."))
/obj/item/clothing/head/helmet/space/hardsuit/dropped(mob/user, silent = FALSE)
- ..()
+ . = ..()
+ if(suit && loc != suit)
+ forceMove(suit)
+ else
+ qdel(src)
+
+
+/obj/item/clothing/head/helmet/space/hardsuit/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
if(suit)
suit.RemoveHelmet()
+ else
+ qdel(src)
+
+
+/obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user)
+ light_on = !light_on
+ toggle_light(light_on)
+
+
+/obj/item/clothing/head/helmet/space/hardsuit/proc/toggle_light(enable = TRUE, update_buttons = TRUE)
+ light_on = enable
+ update_icon(UPDATE_ICON_STATE)
+ update_equipped_item(update_buttons)
+
+ if(light_on)
+ set_light(brightness_on)
+ else
+ set_light(0)
+
/obj/item/clothing/head/helmet/space/hardsuit/item_action_slot_check(slot)
if(slot == slot_head)
- return 1
-
-/obj/item/clothing/head/helmet/space/hardsuit/equipped(mob/user, slot, initial)
- . = ..()
+ return TRUE
- if(slot != slot_head)
- if(suit)
- suit.RemoveHelmet()
- else
- qdel(src)
-/obj/item/clothing/head/helmet/space/hardsuit/proc/display_visor_message(var/msg)
+/obj/item/clothing/head/helmet/space/hardsuit/proc/display_visor_message(msg)
var/mob/wearer = loc
if(msg && ishuman(wearer))
- wearer.show_message("[msg]", 1)
+ wearer.show_message(span_robot("[msg]"), 1)
+
/obj/item/clothing/head/helmet/space/hardsuit/emp_act(severity)
..()
display_visor_message("[severity > 1 ? "Light" : "Strong"] electromagnetic pulse detected!")
+
+/obj/item/clothing/head/helmet/space/hardsuit/extinguish_light(force = FALSE)
+ if(light_on)
+ toggle_light(enable = FALSE)
+ visible_message(span_danger("[src]'s light fades and turns off."))
+
+
/obj/item/clothing/suit/space/hardsuit
name = "hardsuit"
desc = "A special space suit for environments that might pose hazards beyond just the vacuum of space. Provides more protection than a standard space suit."
@@ -126,15 +144,116 @@
)
-/obj/item/clothing/suit/space/hardsuit/attack_self(mob/user)
- user.changeNext_move(CLICK_CD_MELEE)
- ..()
+/obj/item/clothing/suit/space/hardsuit/Initialize(mapload)
+ . = ..()
+ MakeHelmet()
+
+
+/obj/item/clothing/suit/space/hardsuit/Destroy()
+ if(helmet)
+ QDEL_NULL(helmet)
+ QDEL_NULL(jetpack)
+ return ..()
+
+
+/obj/item/clothing/suit/space/hardsuit/proc/MakeHelmet()
+ if(!helmettype || helmet)
+ return
+
+ var/obj/item/clothing/head/helmet/space/hardsuit/new_helmet = new helmettype(src)
+ new_helmet.suit = src
+ helmet = new_helmet
+ helmet.update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC)
+
+
+/obj/item/clothing/suit/space/hardsuit/equipped(mob/user, slot, initial)
+ . = ..()
+ if(suit_adjusted)
+ RemoveHelmet()
+
+
+/obj/item/clothing/suit/space/hardsuit/dropped(mob/user, silent = FALSE)
+ . = ..()
+ if(suit_adjusted)
+ RemoveHelmet()
+
+
+/obj/item/clothing/suit/space/hardsuit/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
+ if(suit_adjusted)
+ RemoveHelmet()
+ return ..()
+
+
+/obj/item/clothing/suit/space/hardsuit/ui_action_click(mob/user)
+ ToggleHelmet()
/obj/item/clothing/suit/space/hardsuit/item_action_slot_check(slot)
if(slot == slot_wear_suit) //we only give the mob the ability to toggle the helmet if he's wearing the hardsuit.
return TRUE
+
+/obj/item/clothing/suit/space/hardsuit/attack_self(mob/user)
+ user.changeNext_move(CLICK_CD_MELEE)
+ ..()
+
+
+/obj/item/clothing/suit/space/hardsuit/proc/ToggleHelmet()
+ var/mob/living/carbon/human/user = loc
+ if(!ishuman(user) || !helmet)
+ return
+ if(taser_proof && taser_proof.ert_mindshield_locked)
+ if(isertmindshielded(user))
+ to_chat(user, span_notice("Access granted, identity verified..."))
+ else
+ to_chat(user, span_warning("Access denied. The user is not identified!"))
+ return
+ if(suit_adjusted)
+ RemoveHelmet()
+ return
+ if(user.wear_suit != src)
+ to_chat(user, span_warning("You must be wearing [src] to engage the helmet!"))
+ return
+ EngageHelmet()
+
+
+/obj/item/clothing/suit/space/hardsuit/proc/EngageHelmet()
+ if(!helmet)
+ return FALSE
+ var/mob/living/carbon/human/user = loc
+ if(!ishuman(user))
+ return FALSE
+ if(user.head)
+ to_chat(usr, span_warning("You're already wearing something on your head!"))
+ return FALSE
+ if(!user.equip_to_slot(helmet, slot_head))
+ return FALSE
+ . = TRUE
+ suit_adjusted = TRUE
+ to_chat(user, span_notice("You engage the helmet on the hardsuit."))
+ user.update_head(helmet, TRUE)
+ user.update_inv_wear_suit()
+ playsound(user, 'sound/items/rig_deploy.ogg', 110, TRUE)
+
+
+/obj/item/clothing/suit/space/hardsuit/proc/RemoveHelmet()
+ if(!helmet)
+ return FALSE
+ . = TRUE
+ suit_adjusted = FALSE
+ var/mob/living/carbon/human/user = loc
+ if(helmet.light_on)
+ helmet.toggle_light(enable = FALSE)
+ if(ishuman(user))
+ user.temporarily_remove_item_from_inventory(helmet, force = TRUE)
+ user.update_inv_wear_suit()
+ to_chat(user, span_notice("The helmet on the hardsuit disengages."))
+ helmet.forceMove(src)
+ playsound(user, 'sound/items/rig_retract.ogg', 110, TRUE)
+ for(var/datum/action/action as anything in actions)
+ action.UpdateButtonIcon()
+
+
//Engineering hardsuit
/obj/item/clothing/head/helmet/space/hardsuit/engine
name = "engineering hardsuit helmet"
@@ -230,103 +349,137 @@
name = "blood-red hardsuit helmet"
desc = "A dual-mode advanced helmet designed for work in special operations. It is in travel mode. Property of Gorlex Marauders."
alt_desc = "A dual-mode advanced helmet designed for work in special operations. It is in combat mode. Property of Gorlex Marauders."
- icon_state = "hardsuit1-syndi"
+ icon_state = "hardsuit0-syndi"
item_state = "syndie_helm"
armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 30, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90)
item_color = "syndi"
- on = 1
+ var/on = FALSE
var/obj/item/clothing/suit/space/hardsuit/syndi/linkedsuit = null
actions_types = list(/datum/action/item_action/toggle_helmet_mode)
visor_flags_inv = HIDEMASK|HIDEGLASSES|HIDENAME|HIDETAIL
visor_flags = STOPSPRESSUREDMAGE
var/combat_rad = 50
-/obj/item/clothing/head/helmet/space/hardsuit/syndi/update_icon()
+
+/obj/item/clothing/head/helmet/space/hardsuit/syndi/Destroy()
+ linkedsuit = null
+ return ..()
+
+
+/obj/item/clothing/head/helmet/space/hardsuit/syndi/update_icon_state()
icon_state = "hardsuit[on]-[item_color]"
-/obj/item/clothing/head/helmet/space/hardsuit/syndi/New()
- ..()
- if(istype(loc, /obj/item/clothing/suit/space/hardsuit/syndi))
- linkedsuit = loc
-/obj/item/clothing/head/helmet/space/hardsuit/syndi/attack_self(mob/user) //Toggle Helmet
- if(!isturf(user.loc))
- to_chat(user, "You cannot toggle your helmet while in this [user.loc]!" )
+/obj/item/clothing/head/helmet/space/hardsuit/syndi/update_name(updates = ALL)
+ . = ..()
+ name = "[initial(name)][on ? "" : " (combat)"]"
+
+
+/obj/item/clothing/head/helmet/space/hardsuit/syndi/update_desc(updates = ALL)
+ . = ..()
+ desc = "[initial(desc)][on ? "" : alt_desc]"
+
+
+/obj/item/clothing/head/helmet/space/hardsuit/syndi/attack_self(mob/user)
+ adjust_headgear(user)
+
+
+/obj/item/clothing/head/helmet/space/hardsuit/syndi/adjust_headgear(mob/living/carbon/human/user, toggle = TRUE)
+ if(user && !isturf(user.loc))
+ to_chat(user, span_warning("You cannot toggle your helmet while in [user.loc]!" ))
return
- on = !on
+ if(toggle)
+ on = !on
+ toggle_light(enable = on, update_buttons = FALSE)
+ if(user)
+ to_chat(user, span_notice("You switch your hardsuit to [on ? "EVA mode, sacrificing speed for space protection." : "combat mode and can now run at full speed."]"))
+ playsound(loc, 'sound/items/rig_deploy.ogg', 110, TRUE)
if(on)
- to_chat(user, "You switch your hardsuit to EVA mode, sacrificing speed for space protection.")
- name = initial(name)
- desc = initial(desc)
- set_light(brightness_on)
flags |= visor_flags
- flags_cover |= HEADCOVERSEYES | HEADCOVERSMOUTH
+ flags_cover |= (HEADCOVERSEYES|HEADCOVERSMOUTH)
flags_inv |= visor_flags_inv
cold_protection |= HEAD
armor.rad = 100
else
- to_chat(user, "You switch your hardsuit to combat mode and can now run at full speed.")
- name += " (combat)"
- desc = alt_desc
- set_light(0)
flags &= ~visor_flags
- flags_cover &= ~(HEADCOVERSEYES | HEADCOVERSMOUTH)
+ flags_cover &= ~(HEADCOVERSEYES|HEADCOVERSMOUTH)
flags_inv &= ~visor_flags_inv
cold_protection &= ~HEAD
armor.rad = combat_rad
- update_icon()
- playsound(src.loc, 'sound/items/rig_deploy.ogg', 110, 1)
- toggle_hardsuit_mode(user)
- user.update_inv_head()
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- H.update_head(src, forced = TRUE)
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
-
-/obj/item/clothing/head/helmet/space/hardsuit/syndi/proc/toggle_hardsuit_mode(mob/user) //Helmet Toggles Suit Mode
- if(linkedsuit)
- if(on)
- linkedsuit.name = initial(linkedsuit.name)
- linkedsuit.desc = initial(linkedsuit.desc)
- linkedsuit.slowdown = 1
- linkedsuit.flags |= STOPSPRESSUREDMAGE
- linkedsuit.cold_protection |= UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS | TAIL
- linkedsuit.on = TRUE
- linkedsuit.armor.rad = 100
- else
- linkedsuit.name += " (combat)"
- linkedsuit.desc = linkedsuit.alt_desc
- linkedsuit.slowdown = 0
- linkedsuit.flags &= ~STOPSPRESSUREDMAGE
- linkedsuit.cold_protection &= ~(UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS | TAIL)
- linkedsuit.on = FALSE
- linkedsuit.armor.rad = combat_rad
-
- linkedsuit.update_icon()
- user.update_inv_wear_suit()
- user.update_inv_w_uniform()
+ update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC)
+ user?.update_head(src)
+ for(var/datum/action/action as anything in actions)
+ action.UpdateButtonIcon()
+ update_linked_hardsuit(user, toggle)
+
+
+/obj/item/clothing/head/helmet/space/hardsuit/syndi/proc/update_linked_hardsuit(mob/user, toggle = TRUE)
+ if(!linkedsuit)
+ return
+
+ if(toggle)
+ linkedsuit.on = !linkedsuit.on
+
+ if(linkedsuit.on)
+ linkedsuit.slowdown = 1
+ linkedsuit.flags |= STOPSPRESSUREDMAGE
+ linkedsuit.cold_protection |= (UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS|TAIL)
+ linkedsuit.armor.rad = 100
+ else
+ linkedsuit.slowdown = 0
+ linkedsuit.flags &= ~STOPSPRESSUREDMAGE
+ linkedsuit.cold_protection &= ~(UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS|TAIL)
+ linkedsuit.armor.rad = combat_rad
+
+ linkedsuit.update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC)
+ user?.update_inv_wear_suit()
+ user?.update_inv_w_uniform()
+
/obj/item/clothing/suit/space/hardsuit/syndi
name = "blood-red hardsuit"
desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in travel mode. Property of Gorlex Marauders."
alt_desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in combat mode. Property of Gorlex Marauders."
- icon_state = "hardsuit1-syndi"
+ icon_state = "hardsuit0-syndi"
item_state = "syndie_hardsuit"
armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 30, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90)
item_color = "syndi"
w_class = WEIGHT_CLASS_NORMAL
- var/on = 1
+ var/on = FALSE
actions_types = list(/datum/action/item_action/toggle_hardsuit_mode)
allowed = list(/obj/item/gun, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/energy/sword, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi
jetpack = /obj/item/tank/jetpack/suit
-/obj/item/clothing/suit/space/hardsuit/syndi/update_icon()
+
+/obj/item/clothing/suit/space/hardsuit/syndi/Initialize(mapload)
+ . = ..()
+ var/obj/item/clothing/head/helmet/space/hardsuit/syndi/our_helmet = helmet
+ our_helmet?.linkedsuit = src
+ our_helmet?.adjust_headgear(toggle = FALSE)
+
+
+/obj/item/clothing/suit/space/hardsuit/syndi/update_icon_state()
icon_state = "hardsuit[on]-[item_color]"
+
+/obj/item/clothing/suit/space/hardsuit/syndi/update_name(updates = ALL)
+ . = ..()
+ name = "[initial(name)][on ? "" : " (combat)"]"
+
+
+/obj/item/clothing/suit/space/hardsuit/syndi/update_desc(updates = ALL)
+ . = ..()
+ desc = "[initial(desc)][on ? "" : alt_desc]"
+
+
+/obj/item/clothing/suit/space/hardsuit/syndi/EngageHelmet()
+ . = ..()
+ if(. && on)
+ helmet?.toggle_light(enable = TRUE, update_buttons = FALSE)
+
+
//Elite Syndie suit
/obj/item/clothing/head/helmet/space/hardsuit/syndi/elite
name = "elite syndicate hardsuit helmet"
@@ -365,14 +518,14 @@
/obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/med
name = "Elite medical syndicate hardsuit helmet"
desc = "An elite version of the syndicate helmet. This one is made special for medics."
- icon_state = "hardsuit1-smedelite"
+ icon_state = "hardsuit0-smedelite"
item_state = "hardsuit0-smedelite"
item_color = "smedelite"
/obj/item/clothing/suit/space/hardsuit/syndi/elite/med
name = "Elite medical syndicate hardsuit helmet"
desc = "An elite version of the syndicate hardsuit. This one is made special for medics."
- icon_state = "hardsuit1-smedelite"
+ icon_state = "hardsuit0-smedelite"
item_state = "hardsuit0-smedelite"
item_color = "smedelite"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/med
@@ -398,7 +551,7 @@
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom
sprite_sheets = null
-/obj/item/clothing/suit/space/hardsuit/syndi/freedom/update_icon()
+/obj/item/clothing/suit/space/hardsuit/syndi/freedom/update_icon_state()
return
/obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom
@@ -408,7 +561,7 @@
item_state = "griffinhat"
sprite_sheets = null
-/obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom/update_icon()
+/obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom/update_icon_state()
return
//Soviet hardsuit
@@ -562,25 +715,21 @@
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80)
item_color = "rd"
scan_reagents = TRUE
- var/hud_active = TRUE
var/explosion_detection_dist = 40
-/obj/item/clothing/head/helmet/space/hardsuit/rd/equipped(mob/user, slot, initial)
- . = ..()
+/obj/item/clothing/head/helmet/space/hardsuit/rd/equipped(mob/living/carbon/human/user, slot, initial)
+ . = ..()
if(slot == slot_head)
GLOB.doppler_arrays += src //Needed to sense the kabooms
- if(ishuman(user))
- var/mob/living/carbon/human/U = user
- if(istype(U.glasses, /obj/item/clothing/glasses/hud/diagnostic)) // If they are for some reason wearing a diagnostic hud when they put the helmet on
- return // already have a hud
- hud_active = TRUE
+
/obj/item/clothing/head/helmet/space/hardsuit/rd/dropped(mob/living/carbon/human/user, silent = FALSE)
- ..()
- if((user.head == src) && hud_active)
+ . = ..()
+ if(!user || user.head != src)
GLOB.doppler_arrays -= src
+
/obj/item/clothing/head/helmet/space/hardsuit/rd/proc/sense_explosion(x0, y0, z0, devastation_range, heavy_impact_range,
light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range)
var/turf/T = get_turf(src)
diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm
index ae4c772c0ea..d6612af62e4 100644
--- a/code/modules/clothing/spacesuits/plasmamen.dm
+++ b/code/modules/clothing/spacesuits/plasmamen.dm
@@ -8,7 +8,7 @@
flash_protect = 2
tint = 2
HUDType = 0
- var/list/examine_extensions = null
+ var/examine_extensions = 0
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75)
resistance_flags = FIRE_PROOF
var/brightness_on = 4 //luminosity when the light is on
@@ -27,25 +27,27 @@
sprite_sheets = list("Plasmaman" = 'icons/mob/clothing/species/plasmaman/helmet.dmi')
var/upgradable = FALSE
-/obj/item/clothing/head/helmet/space/plasmaman/New()
- ..()
+
+/obj/item/clothing/head/helmet/space/plasmaman/Initialize(mapload)
+ . = ..()
visor_toggling()
update_icon()
- cut_overlays()
+
/obj/item/clothing/head/helmet/space/plasmaman/AltClick(mob/user)
if(!user.incapacitated() && Adjacent(user))
toggle_welding_screen(user)
+
/obj/item/clothing/head/helmet/space/plasmaman/visor_toggling() //handles all the actual toggling of flags
up = !up
flags ^= visor_flags
flags_inv ^= visor_flags_inv
- icon_state = "[initial(icon_state)]"
if(visor_vars_to_toggle & VISOR_FLASHPROTECT)
flash_protect ^= initial(flash_protect)
if(visor_vars_to_toggle & VISOR_TINT)
- tint ^= initial(tint)
+ tint = up ? tint_up : initial(tint)
+
/obj/item/clothing/head/helmet/space/plasmaman/proc/toggle_welding_screen(mob/living/user)
if(weldingvisortoggle(user))
@@ -53,73 +55,72 @@
to_chat(user, "Your helmet's torch can't pass through your welding visor!")
on = FALSE
playsound(src, 'sound/mecha/mechmove03.ogg', 50, 1) //Visors don't just come from nothing
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
+ actions_types = list(/datum/action/item_action/toggle_helmet_light)
else
playsound(src, 'sound/mecha/mechmove03.ogg', 50, 1) //Visors don't just come from nothing
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
-/obj/item/clothing/head/helmet/space/plasmaman/update_icon()
- cut_overlays()
- add_overlay(visor_icon)
- ..()
- actions_types = list(/datum/action/item_action/toggle_helmet_light)
-/obj/item/clothing/head/helmet/space/plasmaman/attack_self(mob/user)
+/obj/item/clothing/head/helmet/space/plasmaman/update_icon_state()
+ if(!upgradable)
+ icon_state = "[initial(icon_state)][on ? "-light":""]"
+ item_state = icon_state
+ return
+
+ switch(armor.getRating(MELEE))
+ if(30)
+ icon_state = "[initial(icon_state)][on ? "-light":""]"
+ item_state = icon_state
+ if(40,50)
+ icon_state = "[initial(icon_state)]_reinf[on ? "-light":""]"
+ item_state = icon_state
+ if(60)
+ icon_state = "[initial(icon_state)]_reinf_full[on ? "-light":""]"
+ item_state = icon_state
+
+
+/obj/item/clothing/head/helmet/space/plasmaman/attack_self(mob/living/carbon/human/user)
toggle_light(user)
+
/obj/item/clothing/head/helmet/space/plasmaman/proc/toggle_light(mob/user)
on = !on
- if(upgradable)
- switch(armor.getRating("melee"))
- if(30)
- icon_state = "[initial(icon_state)][on ? "-light":""]"
- item_state = icon_state
- if(40,50)
- icon_state = "[initial(icon_state)]_reinf[on ? "-light":""]"
- item_state = icon_state
- if(60)
- icon_state = "[initial(icon_state)]_reinf_full[on ? "-light":""]"
- item_state = icon_state
- else
- icon_state = "[initial(icon_state)][on ? "-light":""]"
- item_state = icon_state
-
- var/mob/living/carbon/human/H = user
- if(istype(H))
- H.update_inv_head()
+ update_icon(UPDATE_ICON_STATE)
if(on)
if(!up)
- if(istype(H))
- to_chat(user, "Your helmet's torch can't pass through your welding visor!")
+ if(user)
+ to_chat(user, span_notice("Your helmet's torch can't pass through your welding visor!"))
set_light(0)
else
set_light(brightness_on)
else
set_light(0)
- for(var/X in actions)
- var/datum/action/A=X
- A.UpdateButtonIcon()
+ update_equipped_item()
+
/obj/item/clothing/head/helmet/space/plasmaman/extinguish_light(force = FALSE)
if(on)
toggle_light()
update_equipped_item()
+
/obj/item/clothing/head/helmet/space/plasmaman/equipped(mob/living/carbon/human/user, slot, initial)
. = ..()
-
if(HUDType && slot == slot_head)
var/datum/atom_hud/H = GLOB.huds[HUDType]
H.add_hud_to(user)
+
/obj/item/clothing/head/helmet/space/plasmaman/dropped(mob/living/carbon/human/user, silent = FALSE)
- ..()
+ . = ..()
if(HUDType && istype(user) && user.head == src)
var/datum/atom_hud/H = GLOB.huds[HUDType]
H.remove_hud_from(user)
+
/obj/item/clothing/head/helmet/space/plasmaman/security
name = "security plasma envirosuit helmet"
desc = "A plasmaman containment helmet designed for security officers, protecting them from being flashed and burning alive, alongside other undesirables."
@@ -127,7 +128,7 @@
item_state = "security_envirohelm"
armor = list("melee" = 35, "bullet" = 30, "laser" = 30,"energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 50)
HUDType = DATA_HUD_SECURITY_ADVANCED
- examine_extensions = list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE)
+ examine_extensions = EXAMINE_HUD_SECURITY_READ | EXAMINE_HUD_SECURITY_WRITE
/obj/item/clothing/head/helmet/space/plasmaman/security/dec
name = "detective plasma envirosuit helmet"
@@ -136,7 +137,7 @@
armor = list("melee" = 25, "bullet" = 5, "laser" = 25, "energy" = 10, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 50)
scan_reagents = 1
HUDType = DATA_HUD_SECURITY_ADVANCED
- examine_extensions = list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE)
+ examine_extensions = EXAMINE_HUD_SECURITY_READ | EXAMINE_HUD_SECURITY_WRITE
/obj/item/clothing/head/helmet/space/plasmaman/security/warden
name = "warden's plasma envirosuit helmet"
@@ -156,7 +157,7 @@
icon_state = "doctor_envirohelm"
item_state = "doctor_envirohelm"
HUDType = DATA_HUD_MEDICAL_ADVANCED
- examine_extensions = list(EXAMINE_HUD_MEDICAL)
+ examine_extensions = EXAMINE_HUD_MEDICAL
/obj/item/clothing/head/helmet/space/plasmaman/cmo
name = "chief medical officer's plasma envirosuit helmet"
@@ -166,7 +167,7 @@
gas_transfer_coefficient = 0.01
permeability_coefficient = 0.01
HUDType = DATA_HUD_MEDICAL_ADVANCED
- examine_extensions = list(EXAMINE_HUD_MEDICAL)
+ examine_extensions = EXAMINE_HUD_MEDICAL
scan_reagents = 1
/obj/item/clothing/head/helmet/space/plasmaman/genetics
@@ -304,7 +305,7 @@
icon_state = "white_envirohelm"
item_state = "white_envirohelm"
HUDType = DATA_HUD_SECURITY_ADVANCED
- examine_extensions = list(EXAMINE_HUD_SECURITY_READ)
+ examine_extensions = EXAMINE_HUD_SECURITY_READ
/obj/item/clothing/head/helmet/space/plasmaman/nt_rep
name = "nanotrasen representative envirosuit helmet"
@@ -312,7 +313,7 @@
icon_state = "ntrep_envirohelm"
item_state = "ntrep_envirohelm"
HUDType = DATA_HUD_SECURITY_BASIC
- examine_extensions = list(EXAMINE_HUD_SKILLS)
+ examine_extensions = EXAMINE_HUD_SKILLS
/obj/item/clothing/head/helmet/space/plasmaman/chef
name = "chef plasma envirosuit helmet"
@@ -335,7 +336,7 @@
item_state = "botany_envirohelm"
flags = THICKMATERIAL
HUDType = DATA_HUD_HYDROPONIC
- examine_extensions = list(DATA_HUD_HYDROPONIC)
+ examine_extensions = EXAMINE_HUD_BOTANY
/obj/item/clothing/head/helmet/space/plasmaman/janitor
name = "janitor's plasma envirosuit helmet"
@@ -364,7 +365,7 @@
item_state = "hop_envirohelm"
armor = list("melee" = 25, "bullet" = 15, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 50)
HUDType = DATA_HUD_SECURITY_BASIC
- examine_extensions = list(EXAMINE_HUD_SKILLS)
+ examine_extensions = EXAMINE_HUD_SKILLS
/obj/item/clothing/head/helmet/space/plasmaman/captain
name = "captain envirosuit helmet"
@@ -373,7 +374,7 @@
item_state = "cap_envirohelm"
armor = list("melee" = 25, "bullet" = 15, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 50)
HUDType = DATA_HUD_SECURITY_BASIC
- examine_extensions = list(EXAMINE_HUD_SKILLS)
+ examine_extensions = EXAMINE_HUD_SKILLS
/obj/item/clothing/head/helmet/space/plasmaman/blueshield
name = "blueshield envirosuit helmet"
@@ -382,7 +383,7 @@
item_state = "bs_envirohelm"
armor = list("melee" = 35, "bullet" = 30, "laser" = 30,"energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 50)
HUDType = DATA_HUD_MEDICAL_ADVANCED
- examine_extensions = list(EXAMINE_HUD_MEDICAL)
+ examine_extensions = EXAMINE_HUD_MEDICAL
/obj/item/clothing/head/helmet/space/plasmaman/wizard
name = "wizard plasma envirosuit helmet"
@@ -410,4 +411,4 @@
icon_state = "centcomm_envirohelm"
item_state = "centcomm_envirohelm"
HUDType = DATA_HUD_SECURITY_BASIC
- examine_extensions = list(EXAMINE_HUD_SKILLS)
+ examine_extensions = EXAMINE_HUD_SKILLS
diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm
index 41e92a995e7..24cb0a4b6b1 100644
--- a/code/modules/clothing/suits/armor.dm
+++ b/code/modules/clothing/suits/armor.dm
@@ -59,38 +59,47 @@
item_state = "armor"
var/obj/item/clothing/accessory/holobadge/attached_badge
+
+/obj/item/clothing/suit/armor/vest/security/update_icon_state()
+ icon_state = "armor[attached_badge ? "sec" : ""]"
+
+
+/obj/item/clothing/suit/armor/vest/security/update_desc(updates = ALL)
+ . = ..()
+ if(attached_badge)
+ desc = "An armored vest that protects against some damage. This one has [attached_badge] attached to it."
+ else
+ desc = initial(desc)
+
+
/obj/item/clothing/suit/armor/vest/security/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/clothing/accessory/holobadge) && !attached_badge)
- if(user.drop_transfer_item_to_loc(I, src))
- add_fingerprint(user)
- attached_badge = I
- var/datum/action/A = new /datum/action/item_action/remove_badge(src)
- A.Grant(user)
- icon_state = "armorsec"
- user.update_inv_wear_suit()
- desc = "An armored vest that protects against some damage. This one has [attached_badge] attached to it."
- to_chat(user, "You attach [attached_badge] to [src].")
+ if(istype(I, /obj/item/clothing/accessory/holobadge) && !attached_badge && user.drop_transfer_item_to_loc(I, src))
+ add_fingerprint(user)
+ attached_badge = I
+ var/datum/action/item_action/remove_badge/holoaction = new(src)
+ holoaction.Grant(user)
+ update_appearance(UPDATE_ICON_STATE|UPDATE_DESC)
+ update_equipped_item()
+ to_chat(user, span_notice("You attach [attached_badge] to [src]."))
return
..()
+
/obj/item/clothing/suit/armor/vest/security/attack_self(mob/user)
if(attached_badge)
add_fingerprint(user)
user.put_in_hands(attached_badge)
-
for(var/datum/action/item_action/remove_badge/action in actions)
LAZYREMOVE(actions, action)
action.Remove(user)
-
- icon_state = "armor"
- user.update_inv_wear_suit()
- desc = "An armored vest that protects against some damage. This one has a clip for a holobadge."
- to_chat(user, "You remove [attached_badge] from [src].")
attached_badge = null
-
+ update_appearance(UPDATE_ICON_STATE|UPDATE_DESC)
+ update_equipped_item()
+ to_chat(user, span_notice("You remove [attached_badge] from [src]."))
return
..()
+
/obj/item/clothing/suit/armor/vest/blueshield
name = "blueshield security armor"
desc = "An armored vest with the badge of a Blueshield Lieutenant."
@@ -321,38 +330,45 @@
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
hit_reaction_chance = 50
+
+/obj/item/clothing/suit/armor/reactive/update_icon_state()
+ icon_state = "reactive[active ? "" : "off"]"
+ item_state = "reactive[active ? "" : "off"]"
+
+
/obj/item/clothing/suit/armor/reactive/attack_self(mob/user)
- active = !(active)
if(emp_d)
- to_chat(user, "[src] is disabled from an electromagnetic pulse!")
+ to_chat(user, span_warning("[src] is disabled from an electromagnetic pulse!"))
return
+ active = !active
+ update_icon(UPDATE_ICON_STATE)
+ add_fingerprint(user)
if(active)
- to_chat(user, "[src] is now active.")
- icon_state = "reactive"
- item_state = "reactive"
+ to_chat(user, span_notice("[src] is now active."))
else
- to_chat(user, "[src] is now inactive.")
- icon_state = "reactiveoff"
- item_state = "reactiveoff"
- add_fingerprint(user)
- user.update_inv_wear_suit()
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
+ to_chat(user, span_notice("[src] is now inactive."))
+ update_equipped_item()
+
/obj/item/clothing/suit/armor/reactive/emp_act(severity)
active = FALSE
emp_d = TRUE
- icon_state = "reactiveoff"
- item_state = "reactiveoff"
- if(istype(loc, /mob/living/carbon/human))
- var/mob/living/carbon/human/C = loc
- C.update_inv_wear_suit()
- addtimer(CALLBACK(src, PROC_REF(reboot)), 100 / severity)
+ update_icon(UPDATE_ICON_STATE)
+ addtimer(CALLBACK(src, PROC_REF(reboot)), 100 / severity)
+ if(ishuman(loc))
+ var/mob/living/carbon/human/user = loc
+ to_chat(user, span_warning("[src] starts malfunctioning!"))
+ update_equipped_item()
..()
+
/obj/item/clothing/suit/armor/reactive/proc/reboot()
emp_d = FALSE
+ if(ishuman(loc))
+ var/mob/living/carbon/human/user = loc
+ update_equipped_item()
+ to_chat(user, span_notice("Looks like [src] returns its functionality."))
+
//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!)
/obj/item/clothing/suit/armor/reactive/teleport
@@ -526,7 +542,7 @@
icon_state = "knight_templar"
item_state = "knight_templar"
hide_tail_by_species = list("Vox", "Vulpkanin")
- allowed = list(/obj/item/nullrod/claymore, /obj/item/storage/belt/claymore)
+ allowed = list(/obj/item/nullrod/claymore, /obj/item/storage/belt/claymore, /obj/item/gun/energy,/obj/item/reagent_containers/spray/pepper,/obj/item/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/flashlight/seclite,/obj/item/melee/classic_baton/telescopic,/obj/item/kitchen/knife/combat)
sprite_sheets = list(
"Plasmaman" = 'icons/mob/clothing/species/plasmaman/suit.dmi',
"Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/suit.dmi'
@@ -616,6 +632,30 @@
flags = BLOCKHAIR
flags_cover = HEADCOVERSEYES
+/obj/item/clothing/suit/hooded/goliath/wizard
+ armor = list("melee" = 60, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 60)
+ hoodtype = /obj/item/clothing/head/hooded/goliath/wizard
+ magical = TRUE
+
+/obj/item/clothing/head/hooded/goliath/wizard
+ name = "shaman skull"
+ icon_state = "shamskull"
+ item_state = "shamskull"
+ desc = "The skull of a long dead animal bolted to the front of a repurposed pan."
+ armor = list("melee" = 60, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 60)
+ magical = TRUE
+
+//mob_size using for crusher mark
+/obj/item/clothing/suit/hooded/goliath/wizard/equipped(mob/living/user, slot, initial)
+ . = ..()
+ if(istype(user))
+ user.mob_size = MOB_SIZE_LARGE
+
+/obj/item/clothing/suit/hooded/goliath/wizard/dropped(mob/living/user, silent)
+ . = ..()
+ if(istype(user))
+ user.mob_size = MOB_SIZE_HUMAN
+
/obj/item/clothing/suit/armor/bone
name = "bone armor"
desc = "A tribal armor plate, crafted from animal bone."
diff --git a/code/modules/clothing/suits/hood.dm b/code/modules/clothing/suits/hood.dm
index 2b2e54d9306..ebdd618eae4 100644
--- a/code/modules/clothing/suits/hood.dm
+++ b/code/modules/clothing/suits/hood.dm
@@ -5,90 +5,138 @@
var/obj/item/clothing/head/hooded/hood
var/hoodtype = /obj/item/clothing/head/hooded/winterhood //so the chaplain hoodie or other hoodies can override this
+
/obj/item/clothing/suit/hooded/Initialize(mapload)
. = ..()
MakeHood()
+
/obj/item/clothing/suit/hooded/Destroy()
QDEL_NULL(hood)
. = ..()
+
/obj/item/clothing/suit/hooded/proc/MakeHood()
item_color = initial(icon_state)
if(!hood)
- var/obj/item/clothing/head/hooded/W = new hoodtype(src)
- W.suit = src
- hood = W
+ var/obj/item/clothing/head/hooded/new_hood = new hoodtype(src)
+ new_hood.suit = src
+ hood = new_hood
+
+
+/obj/item/clothing/suit/hooded/attack_self(mob/user)
+ user.changeNext_move(CLICK_CD_MELEE)
+ ..()
+
+
+/obj/item/clothing/suit/hooded/update_icon_state()
+ icon_state = "[item_color][suit_adjusted ? "_hood" : ""]"
+
/obj/item/clothing/suit/hooded/ui_action_click()
ToggleHood()
+
/obj/item/clothing/suit/hooded/item_action_slot_check(slot, mob/user)
if(slot == slot_wear_suit)
- return 1
+ return TRUE
-/obj/item/clothing/suit/hooded/equipped(mob/user, slot, initial)
- . = ..()
- if(slot != slot_wear_suit)
+/obj/item/clothing/suit/hooded/equipped(mob/user, slot, initial = FALSE)
+ . = ..()
+ if(suit_adjusted)
RemoveHood()
-/obj/item/clothing/suit/hooded/proc/RemoveHood()
- if(isnull(hood))
- return
- icon_state = item_color
- suit_adjusted = 0
- if(ishuman(hood.loc))
- var/mob/living/carbon/H = hood.loc
- H.transfer_item_to_loc(hood, src, TRUE)
- H.update_inv_wear_suit()
- else
- hood.forceMove(src)
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
/obj/item/clothing/suit/hooded/dropped(mob/user, silent = FALSE)
- ..()
- RemoveHood()
+ . = ..()
+ if(suit_adjusted)
+ RemoveHood()
+
+
+/obj/item/clothing/suit/hooded/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
+ if(suit_adjusted)
+ RemoveHood()
+ return ..()
+
/obj/item/clothing/suit/hooded/proc/ToggleHood()
- if(!suit_adjusted)
- if(ishuman(loc))
- var/mob/living/carbon/human/H = loc
- if(H.wear_suit != src)
- to_chat(H,"You must be wearing [src] to put up the hood!")
- return
- if(H.head)
- to_chat(H,"You're already wearing something on your head!")
- return
- else if(H.equip_to_slot_if_possible(hood, slot_head))
- suit_adjusted = 1
- icon_state = "[item_color]_hood"
- H.update_inv_wear_suit()
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
- else
+ var/mob/living/carbon/human/user = loc
+ if(!ishuman(user) || !hood)
+ return
+ if(suit_adjusted)
RemoveHood()
+ return
+ if(user.wear_suit != src)
+ to_chat(user, span_warning("You must be wearing [src] to put up the hood!"))
+ return
+ EngageHood()
+
+
+/obj/item/clothing/suit/hooded/proc/EngageHood()
+ if(!hood)
+ return FALSE
+ var/mob/living/carbon/human/user = loc
+ if(!ishuman(user))
+ return FALSE
+ if(user.head)
+ to_chat(user, span_warning("You're already wearing something on your head!"))
+ return
+ if(!user.equip_to_slot(hood, slot_head))
+ return FALSE
+ . = TRUE
+ suit_adjusted = TRUE
+ update_icon(UPDATE_ICON_STATE)
+ to_chat(user, span_notice("You adjust the hood on [src]."))
+ user.update_head(hood, TRUE)
+ user.update_inv_wear_suit()
+
+
+/obj/item/clothing/suit/hooded/proc/RemoveHood()
+ if(!hood)
+ return FALSE
+ . = TRUE
+ suit_adjusted = FALSE
+ update_icon(UPDATE_ICON_STATE)
+ var/mob/living/carbon/human/user = loc
+ if(ishuman(user))
+ user.temporarily_remove_item_from_inventory(hood, force = TRUE)
+ user.update_inv_wear_suit()
+ to_chat(user, span_notice("The hood fells off from [src]."))
+ hood.forceMove(src)
+ for(var/datum/action/action as anything in actions)
+ action.UpdateButtonIcon()
+
/obj/item/clothing/head/hooded
var/obj/item/clothing/suit/hooded/suit
+
/obj/item/clothing/head/hooded/Destroy()
suit = null
return ..()
-/obj/item/clothing/head/hooded/dropped(mob/user, silent = FALSE)
- ..()
- if(suit)
- suit.RemoveHood()
-/obj/item/clothing/head/hooded/equipped(mob/user, slot, initial)
+/obj/item/clothing/head/hooded/equipped(mob/user, slot, initial = FALSE)
. = ..()
-
if(slot != slot_head)
if(suit)
suit.RemoveHood()
else
qdel(src)
+
+
+/obj/item/clothing/head/hooded/dropped(mob/user, silent = FALSE)
+ . = ..()
+ if(suit && loc != suit)
+ forceMove(suit)
+ else
+ qdel(src)
+
+
+/obj/item/clothing/head/hooded/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params)
+ if(suit)
+ suit.RemoveHood()
+ else
+ qdel(src)
+
diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm
index e8c3abe6ef8..9797d891a1f 100644
--- a/code/modules/clothing/suits/jobs.dm
+++ b/code/modules/clothing/suits/jobs.dm
@@ -505,11 +505,13 @@
"Grey" = 'icons/mob/clothing/species/grey/suit.dmi'
)
+
/obj/item/clothing/suit/suspenders/Initialize(mapload)
. = ..()
if(!color && paintable)
color = "#a30e22"
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
+
/obj/item/clothing/suit/suspenders/attackby(obj/D, mob/user, params)
. = ..()
@@ -519,6 +521,7 @@
color = can.colour
update_icon(UPDATE_OVERLAYS)
+
/obj/item/clothing/suit/suspenders/update_overlays()
. = ..()
if(color)
@@ -527,7 +530,6 @@
var/mutable_appearance/suspenders_clips = mutable_appearance(icon='icons/obj/clothing/belts.dmi', icon_state = "suspenders_clips", appearance_flags = RESET_COLOR)
. += suspenders_clips
-
/obj/item/clothing/suit/suspenders/nodrop
flags = NODROP
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index baeb4b05493..8bf89f6ecbb 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -225,8 +225,8 @@
name = "\improper super-hero E-N suit"
icon_state = "ensuit"
-/obj/item/clothing/suit/corgisuit/super_hero/en/New()
- ..()
+/obj/item/clothing/suit/corgisuit/super_hero/en/Initialize(mapload)
+ . = ..()
START_PROCESSING(SSobj, src)
/obj/item/clothing/suit/corgisuit/super_hero/en/Destroy()
@@ -235,14 +235,15 @@
/obj/item/clothing/suit/corgisuit/super_hero/en/process()
if(prob(2))
- for(var/obj/M in orange(2,src))
- if(!M.anchored && (M.flags & CONDUCT))
- step_towards(M,src)
- for(var/mob/living/silicon/S in orange(2,src))
- if(istype(S, /mob/living/silicon/ai)) continue
- step_towards(S,src)
- for(var/mob/living/carbon/human/machine/M in orange(2,src))
- step_towards(M,src)
+ for(var/obj/object in orange(2, src))
+ if(!object.anchored && (object.flags & CONDUCT))
+ step_towards(object, src)
+ for(var/mob/living/silicon/robot in orange(2,src))
+ if(isAI(robot))
+ continue
+ step_towards(robot, src)
+ for(var/mob/living/carbon/human/machine/IPC in orange(2,src))
+ step_towards(IPC, src)
/obj/item/clothing/suit/monkeysuit
name = "monkey suit"
@@ -1148,7 +1149,6 @@
if(!istype(H) || slot != slot_wear_suit)
STOP_PROCESSING(SSobj, src)
- return
else
START_PROCESSING(SSobj, src)
diff --git a/code/modules/clothing/suits/storage.dm b/code/modules/clothing/suits/storage.dm
index d834e1579eb..e1537044931 100644
--- a/code/modules/clothing/suits/storage.dm
+++ b/code/modules/clothing/suits/storage.dm
@@ -2,8 +2,8 @@
var/obj/item/storage/internal/pockets
w_class = WEIGHT_CLASS_NORMAL //we don't want these to be able to fit in their own pockets.
-/obj/item/clothing/suit/storage/New()
- ..()
+/obj/item/clothing/suit/storage/Initialize(mapload)
+ . = ..()
pockets = new/obj/item/storage/internal(src)
pockets.storage_slots = 2 //two slots
pockets.max_w_class = WEIGHT_CLASS_SMALL //fit only pocket sized items
@@ -13,15 +13,18 @@
QDEL_NULL(pockets)
return ..()
-/obj/item/clothing/suit/storage/attack_hand(mob/user as mob)
- if(pockets.handle_attack_hand(user))
- ..(user)
-/obj/item/clothing/suit/storage/MouseDrop(obj/over_object as obj)
- if(pockets.handle_mousedrop(usr, over_object))
- ..(over_object)
+/obj/item/clothing/suit/storage/attack_hand(mob/user)
+ if(!pockets || !pockets.handle_attack_hand(user))
+ return ..()
+
+
+/obj/item/clothing/suit/storage/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
+ if(!pockets || !pockets.handle_mousedrop(usr, over_object))
+ return ..()
+
-/obj/item/clothing/suit/storage/attackby(obj/item/W as obj, mob/user as mob, params)
+/obj/item/clothing/suit/storage/attackby(obj/item/W, mob/user, params)
. = ..()
if(istype(W, /obj/item/radio/spy_spider))
return
@@ -35,7 +38,7 @@
pockets.hear_talk(M, message_pieces)
..()
-/obj/item/clothing/suit/storage/hear_message(mob/M, var/msg)
+/obj/item/clothing/suit/storage/hear_message(mob/M, msg)
pockets.hear_message(M, msg)
..()
diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm
deleted file mode 100644
index 2617619b6c7..00000000000
--- a/code/modules/clothing/suits/toggles.dm
+++ /dev/null
@@ -1,88 +0,0 @@
-//Hardsuit toggle code
-/obj/item/clothing/suit/space/hardsuit/New()
- MakeHelmet()
- ..()
-
-/obj/item/clothing/suit/space/hardsuit/Destroy()
- if(helmet)
- helmet.suit = null
- QDEL_NULL(helmet)
- QDEL_NULL(jetpack)
- return ..()
-
-/obj/item/clothing/head/helmet/space/hardsuit/Destroy()
- if(suit)
- suit.helmet = null
- return ..()
-
-/obj/item/clothing/suit/space/hardsuit/proc/MakeHelmet()
- if(!helmettype)
- return
- if(!helmet)
- var/obj/item/clothing/head/helmet/space/hardsuit/W = new helmettype(src)
- W.suit = src
- helmet = W
-
-/obj/item/clothing/suit/space/hardsuit/ui_action_click()
- ..()
- ToggleHelmet()
-
-/obj/item/clothing/suit/space/hardsuit/equipped(mob/user, slot, initial)
- . = ..()
-
- if(!helmettype)
- return
- if(slot != slot_wear_suit)
- RemoveHelmet()
-
-/obj/item/clothing/suit/space/hardsuit/proc/RemoveHelmet()
- if(!helmet)
- return
- suittoggled = FALSE
- if(ishuman(helmet.loc))
- var/mob/living/carbon/H = helmet.loc
- if(helmet.on)
- helmet.attack_self(H)
- H.transfer_item_to_loc(helmet, src, TRUE)
- H.update_inv_wear_suit()
- to_chat(H, "The helmet on the hardsuit disengages.")
- playsound(src.loc, 'sound/items/rig_retract.ogg', 110, 1)
- else
- helmet.forceMove(src)
-
-/obj/item/clothing/suit/space/hardsuit/dropped(mob/user, silent = FALSE)
- ..()
- RemoveHelmet()
-
-/obj/item/clothing/suit/space/hardsuit/proc/EngageHelmet()
- var/mob/living/carbon/human/H = src.loc
- if(H.equip_to_slot_if_possible(helmet, slot_head))
- to_chat(H, "You engage the helmet on the hardsuit.")
- suittoggled = TRUE
- H.update_inv_wear_suit()
- playsound(src.loc, 'sound/items/rig_deploy.ogg', 110, 1)
-
-/obj/item/clothing/suit/space/hardsuit/proc/ToggleHelmet()
- if(ishuman(loc))
- var/mob/living/carbon/human/H = loc
- if(taser_proof && taser_proof.ert_mindshield_locked)
- if(isertmindshielded(H))
- to_chat(H, "Access granted, identity verified...")
- else
- to_chat(H, "Access denied. The user is not identified!")
- return
- if(!helmettype)
- return
- if(!helmet)
- return
- if(!suittoggled)
- if(H.wear_suit != src)
- to_chat(H, "You must be wearing [src] to engage the helmet!")
- return
- if(H.head)
- to_chat(H, "You're already wearing something on your head!")
- return
- else
- EngageHelmet()
- else
- RemoveHelmet()
diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm
index b53d4b13383..4dd553949b8 100644
--- a/code/modules/clothing/suits/wiz_robe.dm
+++ b/code/modules/clothing/suits/wiz_robe.dm
@@ -78,6 +78,68 @@
dog_fashion = null
flags_cover = HEADCOVERSMOUTH|HEADCOVERSEYES
+/obj/item/clothing/head/wizard/magusdefender
+ name = "Magus Helm"
+ desc = "A mysterious helmet that hums with an unearthly power"
+ icon_state = "magusdefender"
+ item_state = "magusdefender"
+ dog_fashion = null
+ flags_cover = HEADCOVERSMOUTH|HEADCOVERSEYES
+ sprite_sheets = list(
+ "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/head.dmi',
+ "Vox" = 'icons/mob/clothing/species/vox/head.dmi',
+ "Drask" = 'icons/mob/clothing/species/drask/head.dmi',
+ "Unathi" = 'icons/mob/clothing/species/unathi/head.dmi',
+ "Tajaran" = 'icons/mob/clothing/species/tajaran/head.dmi'
+ )
+
+/obj/item/clothing/head/wizard/necromage
+ name = "Necronat Mask"
+ desc = "A mysterious mask made from the skull of the previous owner."
+ icon_state = "necromage"
+ item_state = "necromage"
+ dog_fashion = null
+ flags_cover = HEADCOVERSMOUTH|HEADCOVERSEYES
+ sprite_sheets = list(
+ "Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/head.dmi',
+ "Vox" = 'icons/mob/clothing/species/vox/head.dmi',
+ "Drask" = 'icons/mob/clothing/species/drask/head.dmi',
+ "Unathi" = 'icons/mob/clothing/species/unathi/head.dmi',
+ "Tajaran" = 'icons/mob/clothing/species/tajaran/head.dmi'
+ )
+
+/obj/item/clothing/head/wizard/artmage
+ name = "Wizard Sculptor's Beret"
+ desc = "The classic beret of the followers of the school of sculpture allows you to look like a real artist."
+ icon_state = "artmage"
+ item_state = "artmage"
+ dog_fashion = null
+ sprite_sheets = list(
+ "Vox" = 'icons/mob/clothing/species/vox/head.dmi',
+ "Drask" = 'icons/mob/clothing/species/drask/head.dmi'
+ )
+
+/obj/item/clothing/head/wizard/visionmage
+ name = "Golden tiara"
+ desc = "Golden tiara with a third eye, don't look directly into it."
+ icon_state = "visionmage"
+ item_state = "visionmage"
+ dog_fashion = null
+ sprite_sheets = list(
+ "Vox" = 'icons/mob/clothing/species/vox/head.dmi',
+ "Drask" = 'icons/mob/clothing/species/drask/head.dmi'
+ )
+
+/obj/item/clothing/head/wizard/healmage
+ name = "Healer's Hat"
+ desc = "The magical hat of a healer's robe that protects against leprosy."
+ icon_state = "healmage"
+ item_state = "healmage"
+ dog_fashion = null
+ sprite_sheets = list(
+ "Drask" = 'icons/mob/clothing/species/drask/head.dmi'
+ )
+
/obj/item/clothing/head/wizard/amp
name = "psychic amplifier"
desc = "A crown-of-thorns psychic amplifier. Kind of looks like a tiara having sex with an industrial robot."
@@ -167,6 +229,57 @@
"Unathi" = 'icons/mob/clothing/species/unathi/suit.dmi'
)
+/obj/item/clothing/suit/wizrobe/magusdefender
+ name = "Magus Robe"
+ desc = "A set of armoured robes that seem to radiate a dark power."
+ icon_state = "magusdefender"
+ item_state = "magusdefender"
+ sprite_sheets = list(
+ "Vox" = 'icons/mob/clothing/species/vox/suit.dmi',
+ "Drask" = 'icons/mob/clothing/species/drask/suit.dmi'
+ )
+
+/obj/item/clothing/suit/wizrobe/necromage
+ name = "Necronat Robe"
+ desc = "Black and toxic green robes that seem to radiate a dark power and scent of death."
+ icon_state = "necromage"
+ item_state = "necromage"
+ sprite_sheets = list(
+ "Vox" = 'icons/mob/clothing/species/vox/suit.dmi',
+ "Drask" = 'icons/mob/clothing/species/drask/suit.dmi'
+ )
+
+/obj/item/clothing/suit/wizrobe/artmage
+ name = "Wizard Sculptor's Apron"
+ desc = "A classic apron of followers of the school of sculpture, it protects well from flying clay."
+ icon_state = "artmage"
+ item_state = "artmage"
+ sprite_sheets = list(
+ "Vox" = 'icons/mob/clothing/species/vox/suit.dmi',
+ "Drask" = 'icons/mob/clothing/species/drask/suit.dmi'
+ )
+
+/obj/item/clothing/suit/wizrobe/visionmage
+ name = "Dark robe"
+ desc = "A dark seer's robe woven from otherworldly threads. Emits dark energy."
+ icon_state = "visionmage"
+ item_state = "visionmage"
+ sprite_sheets = list(
+ "Vox" = 'icons/mob/clothing/species/vox/suit.dmi',
+ "Drask" = 'icons/mob/clothing/species/drask/suit.dmi'
+ )
+
+/obj/item/clothing/suit/wizrobe/healmage
+ name = "Healer's Robe"
+ desc = "Magical robe of a healing servant that protects against leprosy."
+ icon_state = "healmage"
+ item_state = "healmage"
+ sprite_sheets = list(
+ "Vox" = 'icons/mob/clothing/species/vox/suit.dmi',
+ "Unathi" = 'icons/mob/clothing/species/unathi/suit.dmi',
+ "Drask" = 'icons/mob/clothing/species/drask/suit.dmi'
+ )
+
/obj/item/clothing/suit/wizrobe/psypurple
name = "purple robes"
desc = "Heavy, royal purple robes threaded with psychic amplifiers and weird, bulbous lenses. Do not machine wash."
diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm
index 138f7662f69..1beecc71651 100644
--- a/code/modules/clothing/under/accessories/accessory.dm
+++ b/code/modules/clothing/under/accessories/accessory.dm
@@ -14,8 +14,8 @@
var/image/inv_overlay = null //overlay used when attached to clothing.
var/allow_duplicates = TRUE // Allow accessories of the same type.
-/obj/item/clothing/accessory/New()
- ..()
+/obj/item/clothing/accessory/Initialize(mapload)
+ . = ..()
inv_overlay = image("icon" = 'icons/obj/clothing/ties_overlay.dmi', "icon_state" = "[item_color? "[item_color]" : "[icon_state]"]")
/obj/item/clothing/accessory/Destroy()
diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm
index e1521241bf8..085070e0069 100644
--- a/code/modules/clothing/under/accessories/holster.dm
+++ b/code/modules/clothing/under/accessories/holster.dm
@@ -188,5 +188,5 @@
/obj/item/clothing/accessory/holster/knives/can_holster(obj/item/I)
return is_type_in_list(I, holster_allow, FALSE)
-/obj/item/clothing/accessory/holster/attached_examine(mob/user)
+/obj/item/clothing/accessory/holster/knives/attached_examine(mob/user)
return span_notice("\A [src] with [holstered.len] knives attached to it.")
diff --git a/code/modules/clothing/under/accessories/storage.dm b/code/modules/clothing/under/accessories/storage.dm
index 6b54e23425c..4b201f7d857 100644
--- a/code/modules/clothing/under/accessories/storage.dm
+++ b/code/modules/clothing/under/accessories/storage.dm
@@ -12,8 +12,8 @@
actions_types = list(/datum/action/item_action/accessory/storage)
w_class = WEIGHT_CLASS_NORMAL // so it doesn't fit in pockets
-/obj/item/clothing/accessory/storage/New()
- ..()
+/obj/item/clothing/accessory/storage/Initialize(mapload)
+ . = ..()
hold = new/obj/item/storage/internal(src)
hold.storage_slots = slots
@@ -21,22 +21,25 @@
QDEL_NULL(hold)
return ..()
-/obj/item/clothing/accessory/storage/attack_hand(mob/user as mob)
+
+/obj/item/clothing/accessory/storage/attack_hand(mob/user)
if(has_suit) //if we are part of a suit
- hold.open(user)
+ hold?.open(user)
return
- if(hold.handle_attack_hand(user)) //otherwise interact as a regular storage item
- ..(user)
+ if(!hold || !hold.handle_attack_hand(user)) //otherwise interact as a regular storage item
+ return ..()
+
-/obj/item/clothing/accessory/storage/MouseDrop(obj/over_object as obj)
+/obj/item/clothing/accessory/storage/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
if(has_suit)
- return
+ return has_suit.MouseDrop(over_object, src_location, over_location, src_control, over_control, params)
+
+ if(!hold || !hold.handle_mousedrop(usr, over_object))
+ return ..()
- if(hold.handle_mousedrop(usr, over_object))
- ..(over_object)
-/obj/item/clothing/accessory/storage/attackby(obj/item/W as obj, mob/user as mob, params)
+/obj/item/clothing/accessory/storage/attackby(obj/item/W, mob/user, params)
return hold.attackby(W, user, params)
/obj/item/clothing/accessory/storage/emp_act(severity)
@@ -47,7 +50,7 @@
hold.hear_talk(M, message_pieces, verb)
..()
-/obj/item/clothing/accessory/storage/hear_message(mob/M, var/msg, verb, datum/language/speaking)
+/obj/item/clothing/accessory/storage/hear_message(mob/M, msg, verb, datum/language/speaking)
hold.hear_message(M, msg)
..()
@@ -65,7 +68,7 @@
L += G.gift:return_inv()
return L
-/obj/item/clothing/accessory/storage/attack_self(mob/user as mob)
+/obj/item/clothing/accessory/storage/attack_self(mob/user)
if(has_suit) //if we are part of a suit
hold.open(user)
else
@@ -112,8 +115,8 @@
item_color = "unathiharness2"
slots = 2
-/obj/item/clothing/accessory/storage/knifeharness/New()
- ..()
+/obj/item/clothing/accessory/storage/knifeharness/Initialize(mapload)
+ . = ..()
hold.max_combined_w_class = 4
hold.can_hold = list(/obj/item/hatchet/unathiknife, /obj/item/kitchen/knife)
diff --git a/code/modules/clothing/under/color.dm b/code/modules/clothing/under/color.dm
index 0ae953fd089..1db6254a7ea 100644
--- a/code/modules/clothing/under/color.dm
+++ b/code/modules/clothing/under/color.dm
@@ -3,14 +3,25 @@
dyeable = TRUE
-/obj/item/clothing/under/color/random/New()
- ..()
- var/list/excluded = list(/obj/item/clothing/under/color/random, /obj/item/clothing/under/color/blackf, /obj/item/clothing/under/color/blue/dodgeball, /obj/item/clothing/under/color/orange/prison, /obj/item/clothing/under/color/red/dodgeball, /obj/item/clothing/under/color/red/jersey, /obj/item/clothing/under/color/blue/jersey)
- var/obj/item/clothing/under/color/C = pick(subtypesof(/obj/item/clothing/under/color) - excluded)
- name = initial(C.name)
- icon_state = initial(C.icon_state)
- item_state = initial(C.item_state)
- item_color = initial(C.item_color)
+/obj/item/clothing/under/color/random/Initialize(mapload)
+ . = ..()
+
+ var/static/list/excluded = list(
+ /obj/item/clothing/under/color/random,
+ /obj/item/clothing/under/color/blackf,
+ /obj/item/clothing/under/color/blue/dodgeball,
+ /obj/item/clothing/under/color/orange/prison,
+ /obj/item/clothing/under/color/red/dodgeball,
+ /obj/item/clothing/under/color/red/jersey,
+ /obj/item/clothing/under/color/blue/jersey,
+ )
+ var/static/list/allowed_colors = subtypesof(/obj/item/clothing/under/color) - excluded
+ var/obj/item/clothing/under/color/new_color = pick(allowed_colors)
+ name = initial(new_color.name)
+ icon_state = initial(new_color.icon_state)
+ item_state = initial(new_color.item_state)
+ item_color = initial(new_color.item_color)
+
/obj/item/clothing/under/color/black
name = "black jumpsuit"
diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm
index 9ba82ef12e0..d3a5683cb02 100644
--- a/code/modules/clothing/under/miscellaneous.dm
+++ b/code/modules/clothing/under/miscellaneous.dm
@@ -1077,3 +1077,36 @@
AddComponent(/datum/component/spraycan_paintable)
START_PROCESSING(SSobj, src)
update_icon()
+
+
+/obj/item/clothing/under/ussptracksuit_red
+ name = "red track suit"
+ desc = "A classic track suit. There is a small tag on the clothes that says \"Made in the USSP\"."
+ icon_state = "ussptracksuit_red"
+ item_state = "ussptracksuit_red"
+ item_color = "ussptracksuit_red"
+
+
+/obj/item/clothing/under/ussptracksuit_blue
+ name = "blue track suit"
+ desc = "A classic track suit. There is a small tag on the clothes that says \"Made in the USSP\"."
+ icon_state = "ussptracksuit_blue"
+ item_state = "ussptracksuit_blue"
+ item_color = "ussptracksuit_blue"
+
+
+/obj/item/clothing/under/ussptracksuit_black
+ name = "black track suit"
+ desc = "A classic track suit. There is a small tag on the clothes that says \"Made in the USSP\"."
+ icon_state = "ussptracksuit_black"
+ item_state = "ussptracksuit_black"
+ item_color = "ussptracksuit_black"
+
+
+/obj/item/clothing/under/ussptracksuit_white
+ name = "white track suit"
+ desc = "A classic track suit. There is a small tag on the clothes that says \"Made in the USSP\"."
+ icon_state = "ussptracksuit_white"
+ item_state = "ussptracksuit_white"
+ item_color = "ussptracksuit_white"
+
diff --git a/code/modules/clothing/upgrade_modules/hardsuit_shield_module/hardsuit.dm b/code/modules/clothing/upgrade_modules/hardsuit_shield_module/hardsuit.dm
index f31c73b380c..6b303697e3d 100644
--- a/code/modules/clothing/upgrade_modules/hardsuit_shield_module/hardsuit.dm
+++ b/code/modules/clothing/upgrade_modules/hardsuit_shield_module/hardsuit.dm
@@ -1,7 +1,7 @@
/obj/item/clothing/suit/space/hardsuit
var/obj/item/hardsuit_shield/shield = null
-/obj/item/clothing/suit/space/hardsuit/New()
+/obj/item/clothing/suit/space/hardsuit/Initialize(mapload)
. = ..()
if(shield && ispath(shield))
shield = new shield(src)
@@ -21,7 +21,7 @@
shield = new_shield
shield.hardsuit = src
to_chat(user, "You successfully install the shield upgrade into [src].")
- return
+
/obj/item/clothing/suit/space/hardsuit/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(shield)
diff --git a/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit.dm b/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit.dm
index 73981f53808..bcb488973bc 100644
--- a/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit.dm
+++ b/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit.dm
@@ -1,7 +1,7 @@
/obj/item/clothing/suit/space/hardsuit
var/obj/item/hardsuit_taser_proof/taser_proof = null
-/obj/item/clothing/suit/space/hardsuit/New()
+/obj/item/clothing/suit/space/hardsuit/Initialize(mapload)
. = ..()
if(taser_proof && ispath(taser_proof))
taser_proof = new taser_proof(src)
diff --git a/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit_taser_proof.dm b/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit_taser_proof.dm
index 50f481c7c1e..8c977b313e0 100644
--- a/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit_taser_proof.dm
+++ b/code/modules/clothing/upgrade_modules/hardsuit_taser_proof_module/hardsuit_taser_proof.dm
@@ -34,7 +34,7 @@
/obj/item/hardsuit_taser_proof/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!hardsuit)
return FALSE
- if(!hardsuit.suittoggled)
+ if(!hardsuit.suit_adjusted)
return FALSE
var/obj/item/projectile/P = hitby
if(P.shockbull)
diff --git a/code/modules/crafting/guncrafting.dm b/code/modules/crafting/guncrafting.dm
index 7c0ea71d05f..39d481238f5 100644
--- a/code/modules/crafting/guncrafting.dm
+++ b/code/modules/crafting/guncrafting.dm
@@ -15,10 +15,25 @@
icon = 'icons/obj/improvised.dmi'
icon_state = "riflestock"
+/obj/item/weaponcrafting/revolverbarrel
+ name = "improvised revolver barrel"
+ desc = "A roughly made revolver barrel."
+ icon = 'icons/obj/improvised.dmi'
+ icon_state = "rev_barrel"
+ w_class = WEIGHT_CLASS_SMALL
+ var/new_fire_sound = 'sound/weapons/gunshots/1rev257.ogg'
+
+/obj/item/weaponcrafting/revolverbarrel/steel
+ name = "steel revolver barrel"
+ desc = "High quality heavy steel gun barrel to increase stability."
+ icon = 'icons/obj/improvised.dmi'
+ icon_state = "s_rev_barrel"
+ new_fire_sound = 'sound/weapons/gunshots/1rev257S.ogg'
+
// CRAFTING //
-/obj/item/weaponcrafting/receiver/attackby(obj/item/W as obj, mob/user as mob, params)
+/obj/item/weaponcrafting/receiver/attackby(obj/item/W, mob/user, params)
if(istype(W,/obj/item/pipe))
to_chat(user, "You attach the shotgun barrel to the receiver. The pins seem loose.")
var/obj/item/weaponcrafting/ishotgunconstruction/I = new(drop_location())
@@ -36,13 +51,13 @@
icon = 'icons/obj/improvised.dmi'
icon_state = "ishotgunstep1"
-/obj/item/weaponcrafting/ishotgunconstruction/attackby(var/obj/item/I, mob/user as mob, params)
+/obj/item/weaponcrafting/ishotgunconstruction/attackby(obj/item/I, mob/user, params)
..()
- if(istype(I, /obj/item/screwdriver))
+ if(I.tool_behaviour == TOOL_SCREWDRIVER)
var/obj/item/weaponcrafting/ishotgunconstruction2/C = new(drop_location())
user.temporarily_remove_item_from_inventory(src)
user.put_in_hands(C, ignore_anim = FALSE)
- to_chat(user, "You screw the pins into place, securing the pipe to the receiver.")
+ to_chat(user, span_notice("You screw the pins into place, securing the pipe to the receiver."))
qdel(src)
/obj/item/weaponcrafting/ishotgunconstruction2
@@ -51,7 +66,7 @@
icon = 'icons/obj/improvised.dmi'
icon_state = "ishotgunstep1"
-/obj/item/weaponcrafting/ishotgunconstruction2/attackby(obj/item/W as obj, mob/user as mob, params)
+/obj/item/weaponcrafting/ishotgunconstruction2/attackby(obj/item/W, mob/user, params)
if(istype(W,/obj/item/weaponcrafting/stock))
to_chat(user, "You attach the stock to the receiver-barrel assembly.")
var/obj/item/weaponcrafting/ishotgunconstruction3/I = new(drop_location())
@@ -67,7 +82,7 @@
icon = 'icons/obj/improvised.dmi'
icon_state = "ishotgunstep2"
-/obj/item/weaponcrafting/ishotgunconstruction3/attackby(var/obj/item/I, mob/user as mob, params)
+/obj/item/weaponcrafting/ishotgunconstruction3/attackby(obj/item/I, mob/user, params)
..()
if(istype(I, /obj/item/stack/packageWrap))
var/obj/item/stack/packageWrap/C = I
@@ -76,9 +91,8 @@
investigate_log("[key_name_log(user)] crafted [W]", INVESTIGATE_CRAFTING)
user.temporarily_remove_item_from_inventory(src)
user.put_in_hands(W, ignore_anim = FALSE)
- to_chat(user, "You tie the wrapping paper around the stock and the barrel to secure it.")
+ to_chat(user, span_notice("You tie the wrapping paper around the stock and the barrel to secure it."))
qdel(src)
else
- to_chat(user, "You need at least five feet of wrapping paper to secure the stock.")
+ to_chat(user, span_warning("You need at least five feet of wrapping paper to secure the stock."))
return
-
diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm
index f26a7f733a3..9ec15f9a8ab 100644
--- a/code/modules/crafting/recipes.dm
+++ b/code/modules/crafting/recipes.dm
@@ -200,6 +200,29 @@
subcategory = CAT_WEAPON
alert_admins_on_craft = TRUE
+/datum/crafting_recipe/revolver_ibullet
+ name = "Improvised Revolver Shell"
+ result = /obj/item/ammo_casing/revolver/improvised
+ reqs = list(/obj/item/stack/sheet/metal = 1,
+ /obj/item/stack/cable_coil = 1,
+ /datum/reagent/fuel = 5,)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 2
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/revolver_pbullet
+ name = "Phosphorous Revolver Bullet"
+ result = /obj/item/ammo_casing/revolver/improvised/phosphorus
+ reqs = list(/obj/item/stack/sheet/metal = 1,
+ /obj/item/stack/cable_coil = 1,
+ /datum/reagent/phosphorus = 5,
+ /datum/reagent/fuel = 5,)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 2
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
/datum/crafting_recipe/pulseslug
name = "Pulse Slug Shell"
result = /obj/item/ammo_casing/shotgun/pulseslug
@@ -255,18 +278,6 @@
category = CAT_WEAPONRY
subcategory = CAT_AMMO
-/datum/crafting_recipe/improvisedbullet
- name = "Improvised Revolver Shell"
- result = /obj/item/ammo_casing/revolver/improvised
- reqs = list(/obj/item/stack/sheet/metal = 1,
- /obj/item/stack/cable_coil = 1,
- /datum/reagent/fuel = 5)
- tools = list(TOOL_SCREWDRIVER)
- time = 2
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-
/datum/crafting_recipe/improvisedslugoverload
name = "Overload Improvised Shell"
result = /obj/item/ammo_casing/shotgun/improvised/overload
@@ -302,8 +313,8 @@
subcategory = CAT_WEAPON
/datum/crafting_recipe/irevolver
- name = "Improvised revolver"
- result = /obj/item/gun/projectile/revolver/improvisedrevolver
+ name = "Improvised Revolver"
+ result = /obj/item/gun/projectile/revolver/improvised
reqs = list(/obj/item/weaponcrafting/receiver = 1,
/obj/item/stack/sheet/wood = 2,
/obj/item/stack/sheet/metal = 3,
@@ -1339,6 +1350,14 @@
/obj/item/toy/crayon/spraycan = 1)
category = CAT_MISC
+/datum/crafting_recipe/ntlockerpaint
+ name = "NT Special Mech Paintkit"
+ result = /obj/item/paintkit/lockermech_nt
+ time = 35
+ reqs = list(/obj/item/stack/sheet/cardboard = 5,
+ /obj/item/toy/crayon/spraycan = 1)
+ category = CAT_MISC
+
/datum/crafting_recipe/stacklifter
name = "The weight stacklifter"
result = /obj/structure/weightmachine/stacklifter
@@ -1390,7 +1409,7 @@
/datum/crafting_recipe/makeshift_speedloader
name = "Makeshift Speedloader"
- result = /obj/item/ammo_box/speedloader/improvisedrevolver
+ result = /obj/item/ammo_box/speedloader/improvised
time = 5 SECONDS
reqs = list(/obj/item/c_tube = 4,
/obj/item/stack/packageWrap = 10,
diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm
index 023bb48b9ac..ddc42aa3ae2 100644
--- a/code/modules/customitems/item_defines.dm
+++ b/code/modules/customitems/item_defines.dm
@@ -76,21 +76,20 @@
playsound(src.loc, usesound, 20, 1)
used = 1
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
-/obj/item/fluff/tattoo_gun/update_icon()
- ..()
- overlays.Cut()
+/obj/item/fluff/tattoo_gun/update_overlays()
+ . = ..()
if(!used)
var/image/ink = image(src.icon, src, "ink_overlay")
ink.icon += rgb(tattoo_r, tattoo_g, tattoo_b, 190)
- overlays += ink
+ . += ink
/obj/item/fluff/tattoo_gun/New()
..()
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
/obj/item/fluff/tattoo_gun/elliot_cybernetic_tat
desc = "A cheap plastic tattoo application pen. This one seems heavily used."
@@ -314,17 +313,18 @@
var/obj/item/clothing/suit/armor/jacket = target
jacket.icon_state = "desolate_coat_open"
jacket.icon = 'icons/obj/custom_items.dmi'
- jacket.ignore_suitadjust = 0
- jacket.suit_adjusted = 1
+ jacket.ignore_suitadjust = FALSE
+ jacket.suit_adjusted = TRUE
+ jacket.update_icon(UPDATE_ICON_STATE)
+ jacket.update_equipped_item(update_buttons = FALSE)
var/has_action = FALSE
- for(var/datum/action/A in jacket.actions)
- if(istype(A, /datum/action/item_action/openclose))
- has_action = TRUE
+ for(var/datum/action/item_action/openclose/action in jacket.actions)
+ action.UpdateButtonIcon()
+ has_action = TRUE
if(!has_action)
new /datum/action/item_action/openclose(jacket)//this actually works
jacket.adjust_flavour = "unbutton"
jacket.sprite_sheets = null
- user.update_inv_wear_suit()
qdel(src)
/obj/item/fluff/fei_gasmask_kit //Fei Hazelwood: Tariq Yon-Dale
@@ -953,29 +953,27 @@
"Neara" = 'icons/mob/clothing/species/monkey/suit.dmi',
"Stok" = 'icons/mob/clothing/species/monkey/suit.dmi'
)
- ignore_suitadjust = 0
actions_types = list(/datum/action/item_action/toggle)
- suit_adjusted = 0
+ suit_adjusted = FALSE
+
+
+/obj/item/clothing/suit/storage/fluff/k3_webbing/update_icon_state()
+ var/base_icon_state = copytext(icon_state, 1, findtext(icon_state, "_on"))
+ var/base_item_state = copytext(item_state, 1, findtext(item_state, "_on"))
+
+ icon_state = suit_adjusted ? base_icon_state : "[base_icon_state]_on"
+ item_state = suit_adjusted ? base_item_state : "[base_item_state]_on"
+
+
+/obj/item/clothing/suit/storage/fluff/k3_webbing/adjustsuit(mob/user)
+ if(user.incapacitated())
+ return
+
+ update_icon(UPDATE_ICON_STATE)
+ update_equipped_item()
+ to_chat(user, "You turn the [src]'s lighting system [suit_adjusted ? "off" : "on"].")
+ suit_adjusted = !suit_adjusted
-/obj/item/clothing/suit/storage/fluff/k3_webbing/adjustsuit(var/mob/user)
- if(!user.incapacitated())
- var/flavour
- if(suit_adjusted)
- flavour = "off"
- icon_state = copytext(icon_state, 1, findtext(icon_state, "_on"))
- item_state = copytext(item_state, 1, findtext(item_state, "_on"))
- suit_adjusted = 0 //Lights Off
- else
- flavour = "on"
- icon_state += "_on"
- item_state += "_on"
- suit_adjusted = 1 //Lights On
-
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
- to_chat(user, "You turn the [src]'s lighting system [flavour].")
- user.update_inv_wear_suit()
/obj/item/clothing/suit/hooded/hoodie/fluff/xantholne // Xantholne: Meex Zwichsnicrur
name = "stripped winter coat"
@@ -1326,26 +1324,24 @@
flags = BLOCKHAIR
flags_cover = HEADCOVERSEYES
actions_types = list(/datum/action/item_action/toggle)
- var/adjusted = 0
+ var/adjusted = FALSE
+
/obj/item/clothing/head/fluff/chronx/ui_action_click()
adjust()
+
+/obj/item/clothing/head/fluff/chronx/update_icon_state()
+ icon_state = adjusted ? initial(icon_state) : "[initial(icon_state)][adjusted ? "" : "_open"]"
+ item_state = adjusted ? initial(item_state) : "[initial(item_state)][adjusted ? "" : "_open"]"
+
+
/obj/item/clothing/head/fluff/chronx/proc/adjust()
- if(adjusted)
- icon_state = initial(icon_state)
- item_state = initial(item_state)
- to_chat(usr, "You untransform \the [src].")
- adjusted = 0
- else
- icon_state += "_open"
- item_state += "_open"
- to_chat(usr, "You transform \the [src].")
- adjusted = 1
- usr.update_inv_head()
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
+ update_icon(UPDATE_ICON_STATE)
+ update_equipped_item()
+ to_chat(usr, "You untransform [src].")
+ adjusted = !adjusted
+
/obj/item/clothing/suit/chaplain_hoodie/fluff/chronx //chronx100: Hughe O'Splash
name = "Cthulhu's Robes"
@@ -1420,6 +1416,12 @@
icon = 'icons/obj/custom_items.dmi'
icon_state = "classic_witch"
item_state = "classic_witch"
+ var/current_state
+
+
+/obj/item/clothing/head/wizard/fluff/dreamy/update_icon_state()
+ icon_state = current_state ? current_state : initial(icon_state)
+
/obj/item/clothing/head/wizard/fluff/dreamy/attack_self(mob/user)
var/list/options = list()
@@ -1439,7 +1441,8 @@
var/choice = tgui_input_list(user, "To what form do you wish to Shapeshift this hat?", "Shapeshift Hat", options)
if(choice && !user.stat && in_range(user, src))
- icon_state = options[choice]
+ current_state = options[choice]
+ update_icon(UPDATE_ICON_STATE)
to_chat(user, "Your strange witch hat has now shapeshifted into it's [choice] form!")
return 1
..()
@@ -1647,21 +1650,19 @@
species_restricted = list("Vox")
-
/obj/item/clothing/gloves/ring/fluff
name = "fluff ring"
desc = "Someone forgot to set this fluff item's description, notify a coder!"
icon = 'icons/obj/custom_items.dmi'
fluff_material = TRUE
-/obj/item/clothing/gloves/ring/fluff/update_icon()
+/obj/item/clothing/gloves/ring/fluff/update_icon_state()
return
-/obj/item/clothing/gloves/ring/fluff/attackby(obj/item/I as obj, mob/user as mob, params)
+/obj/item/clothing/gloves/ring/fluff/attackby(obj/item/I, mob/user, params)
return
-
/obj/item/clothing/gloves/ring/fluff/benjaminfallout //Benjaminfallout: Pretzel Brassheart
name = "Pretzel's Ring"
desc = "A small platinum ring with a large light blue diamond. Engraved inside the band are the words: 'To my lovely Pristine Princess. Forever yours, Savinien.'"
diff --git a/code/modules/detective_work/footprints_and_rag.dm b/code/modules/detective_work/footprints_and_rag.dm
index fe9b50547c1..06a7527061b 100644
--- a/code/modules/detective_work/footprints_and_rag.dm
+++ b/code/modules/detective_work/footprints_and_rag.dm
@@ -21,6 +21,7 @@
flags = NOBLUDGEON
container_type = OPENCONTAINER
has_lid = FALSE
+ blocks_emissive = EMISSIVE_BLOCK_GENERIC
var/wipespeed = 30
/obj/item/reagent_containers/glass/rag/attack(atom/target as obj|turf|area, mob/user as mob , flag)
diff --git a/code/modules/detectivework/microscope/dnascanner.dm b/code/modules/detectivework/microscope/dnascanner.dm
index 11c84e1a87e..575c5a0e36b 100644
--- a/code/modules/detectivework/microscope/dnascanner.dm
+++ b/code/modules/detectivework/microscope/dnascanner.dm
@@ -5,7 +5,7 @@
icon = 'icons/obj/forensics.dmi'
icon_state = "dnaopen"
layer = BELOW_OBJ_LAYER
- anchored = 1
+ anchored = TRUE
density = 1
var/obj/item/forensics/swab = null
@@ -31,7 +31,7 @@
to_chat(user, "Вы вставляете \the [W] в ДНК анализатор.")
user.drop_transfer_item_to_loc(W, src)
swab = W
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
return
..()
@@ -41,21 +41,21 @@
to_chat(user, "Сканер пуст!")
return
add_fingerprint(user)
- scanning = 1
- update_icon()
+ scanning = TRUE
+ update_icon(UPDATE_ICON_STATE)
to_chat(user, "Сканер начинает с жужением анализировать содержимое пробирки \the [swab].")
if(!do_after(user, 25, src) || !swab)
to_chat(user, "Вы перестали анализировать \the [swab].")
- scanning = 0
- update_icon()
+ scanning = FALSE
+ update_icon(UPDATE_ICON_STATE)
return
to_chat(user, "Печать отчета...")
var/obj/item/paper/report = new(get_turf(src))
report.stamped = list(/obj/item/stamp)
- report.overlays = list("paper_stamped")
+ LAZYADD(report.stamp_overlays, "paper_stamped")
report_num++
if(swab)
@@ -73,8 +73,8 @@
report.info += "\nАнализируемый объект: [bloodswab.name] [bloodswab.desc]
" + data
report.forceMove(src.loc)
report.update_icon()
- scanning = 0
- update_icon()
+ scanning = FALSE
+ update_icon(UPDATE_ICON_STATE)
return
/obj/machinery/dnaforensics/proc/remove_sample(mob/living/remover)
@@ -87,18 +87,18 @@
swab.forceMove_turf()
remover.put_in_hands(swab, ignore_anim = FALSE)
swab = null
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
/obj/machinery/dnaforensics/AltClick()
remove_sample(usr)
-/obj/machinery/dnaforensics/MouseDrop(atom/other)
- if(usr == other)
+/obj/machinery/dnaforensics/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
+ if(usr == over_object)
remove_sample(usr)
- else
- return ..()
+ return FALSE
+ return ..()
-/obj/machinery/dnaforensics/update_icon()
+/obj/machinery/dnaforensics/update_icon_state()
icon_state = "dnaopen"
if(swab)
icon_state = "dnaclosed"
diff --git a/code/modules/detectivework/microscope/microscope.dm b/code/modules/detectivework/microscope/microscope.dm
index 20b9dd4638f..14df5adc50f 100644
--- a/code/modules/detectivework/microscope/microscope.dm
+++ b/code/modules/detectivework/microscope/microscope.dm
@@ -7,7 +7,7 @@
desc = "Высокотехнологичный микроскоп, способный увеличивать изображение до 3000 раз."
icon = 'icons/obj/forensics.dmi'
icon_state = "microscope"
- anchored = 1
+ anchored = TRUE
density = 1
var/obj/item/sample = null
@@ -32,7 +32,7 @@
to_chat(user, "Вы вставили \the [W] в микроскоп.")
user.drop_transfer_item_to_loc(W, src)
sample = W
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
return
..()
@@ -53,7 +53,7 @@
to_chat(user, "Печать отчета...")
var/obj/item/paper/report = new(get_turf(src))
report.stamped = list(/obj/item/stamp)
- report.overlays = list("paper_stamped")
+ LAZYADD(report.stamp_overlays, "paper_stamped")
report_num++
if(istype(sample, /obj/item/forensics/swab))
@@ -109,7 +109,7 @@
sample.forceMove_turf()
remover.put_in_hands(sample, ignore_anim = FALSE)
sample = null
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
/obj/machinery/microscope/proc/is_complete_print(print)
return stringpercent(print) <= fingerprint_complete
@@ -117,13 +117,13 @@
/obj/machinery/microscope/AltClick()
remove_sample(usr)
-/obj/machinery/microscope/MouseDrop(atom/other)
- if(usr == other)
+/obj/machinery/microscope/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
+ if(usr == over_object)
remove_sample(usr)
- else
- return ..()
+ return FALSE
+ return ..()
-/obj/machinery/microscope/update_icon()
+/obj/machinery/microscope/update_icon_state()
icon_state = "microscope"
if(sample)
icon_state += "slide"
diff --git a/code/modules/detectivework/tools/sample_kits.dm b/code/modules/detectivework/tools/sample_kits.dm
index fc97702a6c3..fe9ddba2c85 100644
--- a/code/modules/detectivework/tools/sample_kits.dm
+++ b/code/modules/detectivework/tools/sample_kits.dm
@@ -157,19 +157,19 @@
. = ..()
-/obj/item/forensics/sample_kit/MouseDrop(atom/over)
+/obj/item/forensics/sample_kit/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
. = ..()
if(!.)
return FALSE
var/mob/user = usr
- if(istype(over, /obj/screen))
+ if(istype(over_object, /obj/screen))
return FALSE
if(loc != user || user.incapacitated() || !ishuman(user))
return FALSE
- afterattack(over, user, TRUE)
+ afterattack(over_object, user, TRUE)
return TRUE
diff --git a/code/modules/economy/ATM.dm b/code/modules/economy/ATM.dm
index 90d9aea64b4..91d8ed728ab 100644
--- a/code/modules/economy/ATM.dm
+++ b/code/modules/economy/ATM.dm
@@ -42,6 +42,7 @@ log transactions
/obj/machinery/atm/Initialize()
..()
reconnect_database()
+ update_icon()
/obj/machinery/atm/process()
if(stat & NOPOWER)
@@ -80,6 +81,35 @@ log transactions
linked_db = DB
break
+
+/obj/machinery/atm/update_icon_state()
+ . = ..()
+ if(stat & NOPOWER)
+ icon_state = "atm_off"
+ else
+ icon_state = "atm"
+
+
+/obj/machinery/atm/power_change(forced = FALSE)
+ if(!..())
+ return
+ if(stat & NOPOWER)
+ set_light(0)
+ else
+ set_light(1, LIGHTING_MINIMUM_POWER)
+ update_icon()
+
+
+/obj/machinery/atm/update_overlays()
+ . = ..()
+ underlays.Cut()
+
+ if(stat & NOPOWER)
+ return
+
+ underlays += emissive_appearance(icon, "atm_lightmask")
+
+
/obj/machinery/atm/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/card))
if(!powered())
@@ -280,7 +310,7 @@ log transactions
if(!R.stamped)
R.stamped = new()
R.stamped += /obj/item/stamp
- R.overlays += stampoverlay
+ LAZYADD(R.stamp_overlays, stampoverlay)
R.stamps += " This paper has been stamped by the Automatic Teller Machine."
playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 50, TRUE)
diff --git a/code/modules/economy/Accounts.dm b/code/modules/economy/Accounts.dm
index 0d0b1d317e6..ff59caf8aa7 100644
--- a/code/modules/economy/Accounts.dm
+++ b/code/modules/economy/Accounts.dm
@@ -105,7 +105,7 @@ GLOBAL_LIST_EMPTY(all_money_accounts)
if(!R.stamped)
R.stamped = new
R.stamped += /obj/item/stamp
- R.overlays += stampoverlay
+ LAZYADD(R.stamp_overlays, stampoverlay)
R.stamps += " This paper has been stamped by the Accounts Database."
//add the account
diff --git a/code/modules/economy/EFTPOS.dm b/code/modules/economy/EFTPOS.dm
index 2555ad08253..0f7aaa0a90b 100644
--- a/code/modules/economy/EFTPOS.dm
+++ b/code/modules/economy/EFTPOS.dm
@@ -39,7 +39,7 @@
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "paper_eftpos"
-/obj/item/paper/check/update_icon()
+/obj/item/paper/check/update_icon_state()
return
/obj/item/paper/check/AltClick(mob/user, obj/item/I)
diff --git a/code/modules/economy/quests/_base_quests.dm b/code/modules/economy/quests/_base_quests.dm
index 7022f3a0dd6..419d9b715a2 100644
--- a/code/modules/economy/quests/_base_quests.dm
+++ b/code/modules/economy/quests/_base_quests.dm
@@ -64,7 +64,7 @@
if(!quest_type)
var/list/possible_types = list()
if((length(GLOB.clients) < MIN_PLAYERS_FOR_MIX) && (length(current_quests) == 2))
- for(var/datum/cargo_quest/quest in current_quests)
+ for(var/datum/cargo_quest/quest as anything in current_quests)
possible_types += quest.type
else
for(var/path in subtypesof(/datum/cargo_quest) - /datum/cargo_quest/thing)
@@ -75,10 +75,10 @@
possible_types.Remove(customer.cant_order)
quest_type = pick(possible_types)
- for(var/datum/cargo_quest/quest in current_quests)
+ for(var/datum/cargo_quest/quest as anything in current_quests)
if(quest.type != quest_type)
continue
- quest.generate_goal(difficultly = quest_difficulty.diff_flag)
+ quest.add_goal(difficultly = quest_difficulty.diff_flag)
quest.update_interface_icon()
return
@@ -140,10 +140,12 @@
var/datum/cargo_quests_storage/q_storage
/// Quest desc, using in interface.
var/list/desc = list()
- /// Quest interface icons, using in interface.
- var/list/interface_icons = list()
- /// Quest interface icon states, using in interface.
- var/list/interface_icon_states = list()
+ /// Quest base icon, using in interface.
+ var/interface_icon
+ /// Quest base icon state, using in interface.
+ var/interface_icon_state
+ /// Quest interface images, using in interface.
+ var/list/interface_images = list()
/// Requested order's item types, unless otherwise specified.
var/list/req_items = list()
///possible difficultly
@@ -152,18 +154,21 @@
/datum/cargo_quest/New(storage)
q_storage = storage
- generate_goal(difficultly = q_storage.quest_difficulty.diff_flag)
+ add_goal(difficultly = q_storage.quest_difficulty.diff_flag)
update_interface_icon()
-/datum/cargo_quest/proc/generate_goal(difficultly)
+/datum/cargo_quest/proc/generate_goal_list(difficultly)
return
-/datum/cargo_quest/proc/length_quest()
+/datum/cargo_quest/proc/add_goal(difficultly)
return
-/datum/cargo_quest/proc/update_interface_icon()
+/datum/cargo_quest/proc/length_quest()
return
+/datum/cargo_quest/proc/update_interface_icon()
+ if(interface_icon && interface_icon_state)
+ interface_images += icon2base64(icon(interface_icon, interface_icon_state, SOUTH, 1))
/datum/cargo_quest/proc/check_required_item(atom/movable/check_item)
return
diff --git a/code/modules/economy/quests/quest_console.dm b/code/modules/economy/quests/quest_console.dm
index 17e213989c6..5627a9942e8 100644
--- a/code/modules/economy/quests/quest_console.dm
+++ b/code/modules/economy/quests/quest_console.dm
@@ -9,7 +9,7 @@
desc = "Essential for supply requests. Your bread and butter."
icon_keyboard = "cargo_quest_key"
icon_screen = "cargo_quest"
- req_access = list(ACCESS_QM)
+ req_access = list(ACCESS_CARGO)
circuit = /obj/item/circuitboard/supplyquest
/// If TRUE you can see only active quests
var/for_active_quests = FALSE
@@ -71,17 +71,16 @@
/obj/machinery/computer/supplyquest/ui_data(mob/user)
var/list/data = list()
var/list/quest_storages = list()
- for(var/datum/cargo_quests_storage/quest_storage in SScargo_quests.quest_storages)
+ for(var/datum/cargo_quests_storage/quest_storage as anything in SScargo_quests.quest_storages)
if(for_active_quests && !quest_storage.active)
continue
var/timeleft_sec = round((quest_storage.time_start + quest_storage.quest_time - world.time) / 10)
var/list/quests_items = list()
for(var/datum/cargo_quest/cargo_quest as anything in quest_storage.current_quests)
- var/image_index = rand(1, length(cargo_quest.interface_icons))
quests_items.Add(list(list(
"quest_type_name" = cargo_quest.quest_type_name,
"desc" = cargo_quest.desc.Join(""),
- "image" = "[icon2base64(icon(cargo_quest.interface_icons[image_index], cargo_quest.interface_icon_states[image_index], SOUTH, 1))]",
+ "image" = "[cargo_quest.interface_images[rand(1, length(cargo_quest.interface_images))]]",
)))
quest_storages.Add(list(list(
@@ -236,7 +235,6 @@
for_active_quests = TRUE
circuit = /obj/item/circuitboard/questcons
density = FALSE
- req_access = list(ACCESS_CARGO)
/obj/machinery/computer/supplyquest/workers/Initialize(mapload)
@@ -306,10 +304,10 @@
playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, 1)
print_animation()
+
/obj/machinery/computer/supplyquest/workers/proc/print_animation()
- add_overlay(image(icon, icon_state = "print_quest_overlay", layer = overlay_layer))
- spawn(4 SECONDS) // Should change this after merging update_overlays for computers
- update_icon()
+ flick_overlay_view(image(icon, src, "print_quest_overlay", layer + 0.1), 4 SECONDS)
+
/obj/item/qm_quest_tablet
name = "Quartermaster Tablet"
diff --git a/code/modules/economy/quests/reagents_quests.dm b/code/modules/economy/quests/reagents_quests.dm
index e1b4df1405f..2e6ca37bfdb 100644
--- a/code/modules/economy/quests/reagents_quests.dm
+++ b/code/modules/economy/quests/reagents_quests.dm
@@ -1,8 +1,8 @@
/datum/cargo_quest/reagents
quest_type_name = "Chemical"
req_items = list(/obj/item/reagent_containers)
- interface_icons = list('icons/obj/chemical.dmi')
- interface_icon_states = list("beakerlarge")
+ interface_icon = 'icons/obj/chemical.dmi'
+ interface_icon_state = "beakerlarge"
difficultly_flags = (QUEST_DIFFICULTY_EASY)
@@ -34,7 +34,7 @@
"growthserum" = list("volume" = 15, "reward" = 55)
)
-/datum/cargo_quest/reagents/generate_goal(difficultly)
+/datum/cargo_quest/reagents/add_goal(difficultly)
var/list/possible_reagents_list = repeated_reagents.Copy() + unique_reagents.Copy()
var/our_reagent = pick(possible_reagents_list)
required_reagents[our_reagent] += possible_reagents_list[our_reagent]
@@ -65,9 +65,6 @@
/datum/cargo_quest/reagents/drinks
quest_type_name = "Drink"
- interface_icons = list()
- interface_icon_states = list()
-
repeated_reagents = list(
"b52" = list("volume" = 30,"reward" = 60),
"bacchus_blessing" = list("volume" = 30,"reward" = 100),
@@ -101,22 +98,15 @@
"gibbfloats" = list("volume" = 30,"reward" = 40),
"nuka_cola" = list("volume" = 30,"reward" = 60),
"pumpkin_latte" = list("volume" = 30,"reward" = 40),
+ "zazafizzy" = list("volume" = 30, "reward" = 20)
)
unique_reagents = list()
/datum/cargo_quest/reagents/drinks/update_interface_icon()
- var/list/new_interface_icons = list()
- var/list/new_interface_icon_states = list()
-
for(var/reagent_id in required_reagents)
var/datum/reagent/reagent = GLOB.chemical_reagents_list[reagent_id]
if(reagent.drink_icon)
- new_interface_icons += 'icons/obj/drinks.dmi'
- new_interface_icon_states += reagent.drink_icon
+ interface_images += icon2base64(icon('icons/obj/drinks.dmi', reagent.drink_icon, SOUTH, 1))
else
- new_interface_icons += 'icons/obj/chemical.dmi'
- new_interface_icon_states += "beakerlarge"
-
- interface_icons = new_interface_icons
- interface_icon_states = new_interface_icon_states
+ interface_images += icon2base64(icon('icons/obj/chemical.dmi', "beakerlarge", SOUTH, 1))
diff --git a/code/modules/economy/quests/thing_quests.dm b/code/modules/economy/quests/thing_quests.dm
index 99ff36ef3b2..03a34d37c82 100644
--- a/code/modules/economy/quests/thing_quests.dm
+++ b/code/modules/economy/quests/thing_quests.dm
@@ -8,11 +8,7 @@
var/unique_things = TRUE
var/list/current_list
-/datum/cargo_quest/thing/generate_goal(difficultly, request_obj, target_reward)
- if(request_obj)
- req_items += request_obj
- q_storage.reward += target_reward
- return
+/datum/cargo_quest/thing/generate_goal_list(difficultly)
var/list/difficult_list
switch(difficultly)
@@ -28,10 +24,16 @@
if(QUEST_DIFFICULTY_VERY_HARD)
difficult_list = very_hard_items
+ return difficult_list
+
+/datum/cargo_quest/thing/add_goal(difficultly)
+ var/list/difficult_list = generate_goal_list(difficultly)
var/obj/generated_item = pick(difficult_list)
+
q_storage.reward += difficult_list[generated_item]
if(unique_things)
difficult_list.Remove(generated_item)
+
req_items += generated_item
current_list = req_items.Copy()
@@ -39,20 +41,15 @@
/datum/cargo_quest/thing/update_interface_icon()
- var/list/new_interface_icons = list()
- var/list/new_interface_icon_states = list()
-
+ if(interface_icon && interface_icon_state)
+ interface_images += icon2base64(icon(interface_icon, interface_icon_state, SOUTH, 1))
+ return
for(var/our_item in req_items)
var/obj/obj = our_item
if(initial(obj.icon) && initial(obj.icon_state))
- new_interface_icons += initial(obj.icon)
- new_interface_icon_states += initial(obj.icon_state)
+ interface_images += icon2base64(icon(initial(obj.icon), initial(obj.icon_state), SOUTH, 1))
else
- new_interface_icons += 'icons/obj/storage.dmi'
- new_interface_icon_states += "box"
-
- interface_icons = new_interface_icons
- interface_icon_states = new_interface_icon_states
+ interface_images += icon2base64(icon('icons/obj/storage.dmi', "box", SOUTH, 1))
/datum/cargo_quest/thing/length_quest()
return length(req_items)
@@ -124,13 +121,14 @@
/obj/item/organ/internal/heart/cursed = 550,
/obj/item/organ/internal/xenos/plasmavessel/hunter = 550,
/obj/item/organ/internal/xenos/plasmavessel/drone = 550,
- /obj/item/organ/internal/xenos/neurotoxin = 650,
+ /obj/item/organ/internal/xenos/neurotoxin/sentinel = 650,
/obj/item/organ/internal/wryn/glands = 700,
/obj/item/organ/internal/xenos/hivenode = 700,
/obj/item/organ/internal/heart/plasmaman = 750,
/obj/item/organ/internal/xenos/acidgland/sentinel = 750,
/obj/item/organ/internal/xenos/acidgland/praetorian = 750,
/obj/item/organ/internal/xenos/resinspinner = 750,
+ /obj/item/organ/internal/xenos/neurotoxin = 850,
/obj/item/organ/internal/xenos/acidgland/queen = 900,
/obj/item/organ/internal/xenos/plasmavessel/queen = 900
)
@@ -148,6 +146,7 @@
/obj/item/reagent_containers/food/snacks/amanitajelly = 50,
/obj/item/reagent_containers/food/snacks/donut/chaos = 50,
/obj/item/reagent_containers/food/snacks/sliceable/noel = 50,
+ /obj/item/reagent_containers/food/snacks/candy/jellybean/purple = 50,
/obj/item/reagent_containers/food/snacks/monstermeat/bearmeat = 50,
/obj/item/reagent_containers/food/snacks/sashimi = 60,
/obj/item/reagent_containers/food/snacks/fishburger = 60,
@@ -160,10 +159,27 @@
/obj/item/reagent_containers/food/snacks/monkeysdelight = 60,
/obj/item/reagent_containers/food/snacks/aesirsalad = 60,
/obj/item/reagent_containers/food/snacks/rofflewaffles = 60,
+ /obj/item/reagent_containers/food/snacks/muffin = 60,
+ /obj/item/reagent_containers/food/snacks/pancake/choc_chip_pancake = 60,
+ /obj/item/reagent_containers/food/snacks/meatsteak/vulpkanin = 60,
+ /obj/item/reagent_containers/food/snacks/meatsteak/human = 60,
+ /obj/item/reagent_containers/food/snacks/meatsteak/slime = 60,
+ /obj/item/reagent_containers/food/snacks/meatsteak/skrell = 60,
+ /obj/item/reagent_containers/food/snacks/meatsteak/tajaran = 60,
+ /obj/item/reagent_containers/food/snacks/meatsteak/unathi = 60,
)
normal_items = list(
+ /obj/item/reagent_containers/food/snacks/meatsteak/vox = 70,
+ /obj/item/reagent_containers/food/snacks/meatsteak/wryn = 70,
+ /obj/item/reagent_containers/food/snacks/meatsteak/kidan = 70,
+ /obj/item/reagent_containers/food/snacks/meatsteak/diona = 70,
+ /obj/item/reagent_containers/food/snacks/meatsteak/nian = 70,
+ /obj/item/reagent_containers/food/snacks/meatsteak/drask = 70,
+ /obj/item/reagent_containers/food/snacks/meatsteak/grey = 70,
/obj/item/reagent_containers/food/snacks/candy/jawbreaker = 70,
+ /obj/item/reagent_containers/food/snacks/telebacon = 70,
+ /obj/item/reagent_containers/food/snacks/plov = 70,
/obj/item/reagent_containers/food/snacks/weirdoliviersalad = 70,
/obj/item/reagent_containers/food/snacks/doner_mushroom = 70,
/obj/item/reagent_containers/food/snacks/doner_vegan = 70,
@@ -249,19 +265,10 @@
difficultly_flags = (QUEST_DIFFICULTY_EASY|QUEST_DIFFICULTY_NORMAL|QUEST_DIFFICULTY_HARD)
-/datum/cargo_quest/thing/minerals/generate_goal(difficultly, request_obj, target_reward)
- var/list/difficult_list
- switch(difficultly)
- if(QUEST_DIFFICULTY_EASY)
- difficult_list = easy_items
-
- if(QUEST_DIFFICULTY_NORMAL)
- difficult_list = normal_items
-
- if(QUEST_DIFFICULTY_HARD)
- difficult_list = hard_items
-
+/datum/cargo_quest/thing/minerals/add_goal(difficultly)
+ var/list/difficult_list = generate_goal_list(difficultly)
var/obj/item/generated_mineral = pick(difficult_list)
+
q_storage.reward += difficult_list[generated_mineral]["reward"]
if(!required_minerals[generated_mineral])
required_minerals += generated_mineral
@@ -298,16 +305,10 @@
current_list = required_minerals.Copy()
/datum/cargo_quest/thing/minerals/update_interface_icon()
- var/list/new_interface_icons = list()
- var/list/new_interface_icon_states = list()
for(var/mineral in required_minerals)
var/obj/obj = mineral
- new_interface_icons += initial(obj.icon)
- new_interface_icon_states += initial(obj.icon_state)
-
- interface_icons = new_interface_icons
- interface_icon_states = new_interface_icon_states
+ interface_images += icon2base64(icon(initial(obj.icon), initial(obj.icon_state), SOUTH, 1))
/datum/cargo_quest/thing/minerals/length_quest()
var/stack_length
@@ -396,8 +397,8 @@
/datum/cargo_quest/thing/botanygenes
quest_type_name = "Botany Genes on Disks"
- interface_icons = list('icons/obj/module.dmi')
- interface_icon_states = list("datadisk_hydro")
+ interface_icon = 'icons/obj/module.dmi'
+ interface_icon_state = "datadisk_hydro"
req_items = list(/obj/item/disk/plantgene)
var/list/required_genes = list()
easy_items = list(
@@ -426,17 +427,9 @@
)
difficultly_flags = (QUEST_DIFFICULTY_EASY|QUEST_DIFFICULTY_NORMAL|QUEST_DIFFICULTY_HARD)
-/datum/cargo_quest/thing/botanygenes/generate_goal(difficultly, request_obj, target_reward)
-
- var/list/difficult_list
- switch(difficultly)
- if(QUEST_DIFFICULTY_EASY)
- difficult_list = easy_items
- if(QUEST_DIFFICULTY_NORMAL)
- difficult_list = normal_items
- if(QUEST_DIFFICULTY_HARD)
- difficult_list = hard_items
+/datum/cargo_quest/thing/botanygenes/add_goal(difficultly)
+ var/list/difficult_list = generate_goal_list(difficultly)
var/datum/plant_gene/generated_gene = pick(difficult_list)
q_storage.reward += difficult_list[generated_gene]
@@ -448,9 +441,6 @@
desc += "[capitalize(format_text(initial(generated_gene.name)))] "
-/datum/cargo_quest/thing/botanygenes/update_interface_icon()
- return
-
/datum/cargo_quest/thing/botanygenes/length_quest()
return length(required_genes)
@@ -473,8 +463,8 @@
/datum/cargo_quest/thing/genes
quest_type_name = "DNA Genes"
- interface_icons = list('icons/obj/hypo.dmi')
- interface_icon_states = list("dnainjector")
+ interface_icon = 'icons/obj/hypo.dmi'
+ interface_icon_state = "dnainjector"
req_items = list(/obj/item/dnainjector)
var/list/required_blocks = list()
@@ -528,22 +518,12 @@
)
difficultly_flags = (QUEST_DIFFICULTY_NORMAL|QUEST_DIFFICULTY_HARD)
-/datum/cargo_quest/thing/genes/update_interface_icon()
- return
-
/datum/cargo_quest/thing/genes/length_quest()
return length(required_blocks)
-/datum/cargo_quest/thing/genes/generate_goal(difficultly, request_obj, target_reward)
+/datum/cargo_quest/thing/genes/add_goal(difficultly)
- var/list/difficult_list
- switch(difficultly)
- if(QUEST_DIFFICULTY_EASY)
- difficult_list = easy_items
- if(QUEST_DIFFICULTY_NORMAL)
- difficult_list = normal_items
- if(QUEST_DIFFICULTY_HARD)
- difficult_list = hard_items
+ var/list/difficult_list = generate_goal_list(difficultly)
var/generated_gene = pick(difficult_list)
q_storage.reward += difficult_list[generated_gene]
@@ -585,8 +565,8 @@
#define REQUIRED_BLOOD_AMOUNT 10
/datum/cargo_quest/thing/virus
quest_type_name = "Viruses symptoms in vials (10u minimum)"
- interface_icons = list('icons/obj/chemical.dmi')
- interface_icon_states = list("vial")
+ interface_icon = 'icons/obj/chemical.dmi'
+ interface_icon_state = "vial"
req_items = list(/obj/item/reagent_containers/glass/beaker/vial)
var/list/required_symptoms = list()
@@ -638,26 +618,11 @@
)
difficultly_flags = (QUEST_DIFFICULTY_EASY|QUEST_DIFFICULTY_NORMAL|QUEST_DIFFICULTY_HARD)
-/datum/cargo_quest/thing/virus/update_interface_icon()
- return
-
/datum/cargo_quest/thing/virus/length_quest()
return length(required_symptoms)
-/datum/cargo_quest/thing/virus/generate_goal(difficultly, request_obj, target_reward)
- var/list/difficult_list
- switch(difficultly)
- if(QUEST_DIFFICULTY_EASY)
- difficult_list = easy_items
-
- if(QUEST_DIFFICULTY_NORMAL)
- difficult_list = normal_items
-
- if(QUEST_DIFFICULTY_HARD)
- difficult_list = hard_items
-
- if(QUEST_DIFFICULTY_VERY_HARD)
- difficult_list = very_hard_items
+/datum/cargo_quest/thing/virus/add_goal(difficultly)
+ var/list/difficult_list = generate_goal_list(difficultly)
var/datum/symptom/generated_symptom = pick(difficult_list)
q_storage.reward += difficult_list[generated_symptom]
@@ -705,8 +670,8 @@
/datum/cargo_quest/thing/capsule
quest_type_name = "Mob in lazarus capsule"
- interface_icons = list('icons/obj/mobcap.dmi')
- interface_icon_states = list("mobcap3")
+ interface_icon = 'icons/obj/mobcap.dmi'
+ interface_icon_state = "mobcap3"
req_items = list(/obj/item/mobcapsule)
var/list/required_mobs = list()
@@ -726,27 +691,11 @@
)
difficultly_flags = (QUEST_DIFFICULTY_NORMAL|QUEST_DIFFICULTY_HARD)
-/datum/cargo_quest/thing/capsule/update_interface_icon()
- return
-
/datum/cargo_quest/thing/capsule/length_quest()
return length(required_mobs)
-/datum/cargo_quest/thing/capsule/generate_goal(difficultly, request_obj, target_reward)
- var/list/difficult_list
- switch(difficultly)
- if(QUEST_DIFFICULTY_EASY)
- difficult_list = easy_items
-
- if(QUEST_DIFFICULTY_NORMAL)
- difficult_list = normal_items
-
- if(QUEST_DIFFICULTY_HARD)
- difficult_list = hard_items
-
- if(QUEST_DIFFICULTY_VERY_HARD)
- difficult_list = very_hard_items
-
+/datum/cargo_quest/thing/capsule/add_goal(difficultly)
+ var/list/difficult_list = generate_goal_list(difficultly)
var/mob/generated_mob = pick(difficult_list)
q_storage.reward += difficult_list[generated_mob]
if(unique_things)
diff --git a/code/modules/events/door_runtime.dm b/code/modules/events/door_runtime.dm
index 3e44bf90de9..ea8de1ebf8c 100644
--- a/code/modules/events/door_runtime.dm
+++ b/code/modules/events/door_runtime.dm
@@ -10,7 +10,7 @@
INVOKE_ASYNC(D, TYPE_PROC_REF(/obj/machinery/door, hostile_lockdown))
addtimer(CALLBACK(D, TYPE_PROC_REF(/obj/machinery/door, disable_lockdown)), 90 SECONDS)
addtimer(CALLBACK(src, PROC_REF(reboot)), 90 SECONDS)
- post_status("alert", "lockdown")
+ post_status(STATUS_DISPLAY_ALERT, "lockdown")
/datum/event/door_runtime/proc/reboot()
GLOB.minor_announcement.Announce("Автоматическая перезагрузка системы завершена. Хорошего вам дня.","ПЕРЕЗАГРУЗКА СЕТИ:")
diff --git a/code/modules/events/dust.dm b/code/modules/events/dust.dm
index 89cacffb1f4..af5ef381c1b 100644
--- a/code/modules/events/dust.dm
+++ b/code/modules/events/dust.dm
@@ -14,7 +14,7 @@
icon = 'icons/obj/meteor.dmi'
icon_state = "space_dust"
density = 1
- anchored = 1
+ anchored = TRUE
var/strength = 2 //ex_act severity number
var/life = 2 //how many things we hit before qdel(src)
var/atom/goal = null
diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm
index e6dce3240bb..a0ab1c3bc12 100644
--- a/code/modules/events/event_container.dm
+++ b/code/modules/events/event_container.dm
@@ -222,7 +222,7 @@ GLOBAL_LIST_EMPTY(event_last_fired)
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ревенант", /datum/event/revenant, 150),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Спавн свармеров", /datum/event/spawn_swarmer, 0, is_one_shot = TRUE),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Спавн морфа", /datum/event/spawn_morph, 40, list(ASSIGNMENT_SECURITY = 10), is_one_shot = TRUE),
- new /datum/event_meta(EVENT_LEVEL_MODERATE, "Pulse Demon Infiltration", /datum/event/spawn_pulsedemon, 150, list(ASSIGNMENT_ENGINEER = 10), is_one_shot = TRUE),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Pulse Demon Infiltration", /datum/event/spawn_pulsedemon, 0),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Вспышка болезни", /datum/event/disease_outbreak, 0, list(ASSIGNMENT_MEDICAL = 150), TRUE),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Хедкрабы", /datum/event/headcrabs, 0, list(ASSIGNMENT_SECURITY = 20)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Сбой работы дверей", /datum/event/door_runtime, 50, list(ASSIGNMENT_ENGINEER = 25, ASSIGNMENT_AI = 150), TRUE),
diff --git a/code/modules/events/immovable_rod.dm b/code/modules/events/immovable_rod.dm
index 35cf4c70b4c..96047820537 100644
--- a/code/modules/events/immovable_rod.dm
+++ b/code/modules/events/immovable_rod.dm
@@ -27,7 +27,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
icon_state = "immrod"
throwforce = 100
density = 1
- anchored = 1
+ anchored = TRUE
var/z_original = 0
var/destination
var/notify = TRUE
diff --git a/code/modules/events/tear.dm b/code/modules/events/tear.dm
index 93c498e37bd..3ea7f0aadf0 100644
--- a/code/modules/events/tear.dm
+++ b/code/modules/events/tear.dm
@@ -25,7 +25,7 @@
icon='icons/effects/tear.dmi'
icon_state="tear"
density = 0
- anchored = 1
+ anchored = TRUE
light_range = 3
/obj/effect/tear/Initialize(mapload)
diff --git a/code/modules/fish/fish_items.dm b/code/modules/fish/fish_items.dm
index e47c5a98942..59d2caab707 100644
--- a/code/modules/fish/fish_items.dm
+++ b/code/modules/fish/fish_items.dm
@@ -131,7 +131,7 @@
force = 3
/obj/item/fish/shark/attackby(var/obj/item/O, var/mob/user as mob)
- if(istype(O, /obj/item/wirecutters))
+ if(O.tool_behaviour == TOOL_WIRECUTTER)
to_chat(user, "You rip out the teeth of \the [src.name]!")
new /obj/item/fish/toothless_shark(get_turf(src))
new /obj/item/shard/shark_teeth(get_turf(src))
diff --git a/code/modules/fish/fish_types.dm b/code/modules/fish/fish_types.dm
index 86b87373422..f7c2e6659cc 100644
--- a/code/modules/fish/fish_types.dm
+++ b/code/modules/fish/fish_types.dm
@@ -63,7 +63,7 @@
/datum/fish/feederfish/special_interact(obj/machinery/fishtank/my_tank)
if(!my_tank || !istype(my_tank))
return
- if(my_tank.fish_count < 2)
+ if(my_tank.get_num_fish() < 2)
return
if(my_tank.food_level <= 5 && prob(25))
my_tank.adjust_food_level(1)
diff --git a/code/modules/fish/fishtank.dm b/code/modules/fish/fishtank.dm
index 3b2fca703bf..2c743a77285 100644
--- a/code/modules/fish/fishtank.dm
+++ b/code/modules/fish/fishtank.dm
@@ -3,7 +3,6 @@
// Fish Tanks //
//////////////////////////////
-
/obj/machinery/fishtank
name = "placeholder tank"
desc = "So generic, it might as well have no description at all."
@@ -16,12 +15,11 @@
var/tank_type = "" // Type of aquarium, used for icon updating
var/water_capacity = 0 // Number of units the tank holds (varies with tank type)
var/water_level = 0 // Number of units currently in the tank (new tanks start empty)
- var/light_switch = 0 // 0 = off, 1 = on (off by default)
+ var/light_switch = FALSE
var/filth_level = 0 // How dirty the tank is (max 10)
- var/lid_switch = 0 // 0 = open, 1 = closed (open by default)
+ var/lid_switch = FALSE
var/max_fish = 0 // How many fish the tank can support (varies with tank type, 1 fish per 50 units sounds reasonable)
var/food_level = 0 // Amount of fishfood floating in the tank (max 10)
- var/fish_count = 0 // Number of fish in the tank
var/list/fish_list = list() // Tracks the current types of fish in the tank
var/egg_count = 0 // How many fish eggs can be harvested from the tank (capped at the max_fish value)
var/list/egg_list = list() // Tracks the current types of harvestable eggs in the tank
@@ -30,6 +28,7 @@
var/leaking = FALSE // 0 if not leaking, 1 if minor leak, 2 if major leak (not leaking by default)
var/shard_count = 0 // Number of glass shards to salvage when broken (1 less than the number of sheets to build the tank)
+
/obj/machinery/fishtank/bowl
name = "fish bowl"
desc = "A small bowl capable of housing a single fish, commonly found on desks. This one has a tiny treasure chest in it!"
@@ -46,6 +45,7 @@
max_integrity = 15 // Not very sturdy
shard_count = 0 // No salvageable shards
+
/obj/machinery/fishtank/tank
name = "fish tank"
desc = "A large glass tank designed to house aquatic creatures. Contains an integrated water circulation system."
@@ -85,68 +85,87 @@
// VERBS & PROCS //
//////////////////////////////
+/obj/machinery/fishtank/AltClick(mob/user)
+ if(!Adjacent(user))
+ return ..()
+ toggle_lid(user)
+
+
+/obj/machinery/fishtank/AltShiftClick(mob/user)
+ if(!Adjacent(user))
+ return ..()
+ toggle_light(user)
+
+
/obj/machinery/fishtank/verb/toggle_lid_verb()
set name = "Toggle Tank Lid"
set category = "Object"
set src in view(1)
+ toggle_lid(usr)
- toggle_lid()
-
-/obj/machinery/fishtank/proc/toggle_lid()
- lid_switch = !lid_switch
- update_icon()
/obj/machinery/fishtank/verb/toggle_light_verb()
set name = "Toggle Tank Light"
set category = "Object"
set src in view(1)
+ toggle_light(usr)
- toggle_light()
-/obj/machinery/fishtank/proc/toggle_light()
+/obj/machinery/fishtank/proc/toggle_lid(mob/user)
+ if(user.incapacitated() || user.restrained())
+ return
+ lid_switch = !lid_switch
+ update_icon(UPDATE_OVERLAYS)
+
+
+/obj/machinery/fishtank/proc/toggle_light(mob/user)
+ if(user.incapacitated() || user.restrained())
+ return
light_switch = !light_switch
if(light_switch)
set_light(2, 2, "#a0a080")
else
adjust_tank_light()
+
//////////////////////////////
-// NEW() PROCS //
+// Initialize() PROCS //
//////////////////////////////
-/obj/machinery/fishtank/New()
- ..()
- if(!has_lid) //Tank doesn't have a lid/light, remove the verbs for then
+/obj/machinery/fishtank/Initialize(mapload)
+ . = ..()
+ if(!has_lid) //Tank doesn't have a lid/light, remove the verbs for then
verbs -= /obj/machinery/fishtank/verb/toggle_lid_verb
verbs -= /obj/machinery/fishtank/verb/toggle_light_verb
-/obj/machinery/fishtank/tank/New()
- ..()
- if(prob(5)) //5% chance to get the castle decoration
+
+/obj/machinery/fishtank/tank/Initialize(mapload)
+ . = ..()
+ if(prob(5)) //5% chance to get the castle decoration
icon_state = "tank2"
+
//////////////////////////////
// ICON PROCS //
//////////////////////////////
-/obj/machinery/fishtank/update_icon()
- cut_overlays()
-
+/obj/machinery/fishtank/update_overlays()
+ . = ..()
//Update Alert Lights
if(has_lid) //Skip the alert lights for aquariums that don't have lids (fishbowls)
if(egg_count > 0) //There is at least 1 egg to harvest
- add_overlay("over_egg")
- if(lid_switch == 1) //Lid is closed, lid status light is red
- add_overlay("over_lid_1")
+ . += "over_egg"
+ if(lid_switch) //Lid is closed, lid status light is red
+ . += "over_lid_1"
else //Lid is open, lid status light is green
- add_overlay("over_lid_0")
+ . += "over_lid_0"
if(food_level > 5) //Food_level is high and isn't a concern yet
- add_overlay("over_food_0")
+ . += "over_food_0"
else if(food_level > 2) //Food_level is starting to get low, but still above the breeding threshold
- add_overlay("over_food_1")
+ . += "over_food_1"
else //Food_level is below breeding threshold, or fully consumed, feed the fish!
- add_overlay("over_food_2")
- add_overlay("over_leak_[leaking]") //Green if we aren't leaking, light blue and slow blink if minor link, dark blue and rapid flashing for major leak
+ . += "over_food_2"
+ . += "over_leak_[leaking]" //Green if we aren't leaking, light blue and slow blink if minor link, dark blue and rapid flashing for major leak
//Update water overlay
if(!water_level)
@@ -154,23 +173,25 @@
var/water_type = "_clean" //Default to clean water
if(filth_level > 5) water_type = "_dirty" //Show dirty water above filth_level 5 (breeding threshold)
if(water_level > (water_capacity * 0.85)) //Show full if the water_level is over 85% of water_capacity
- add_overlay("over_[tank_type]_full[water_type]")
+ . += "over_[tank_type]_full[water_type]"
else if(water_level > (water_capacity * 0.35)) //Show half-full if the water_level is over 35% of water_capacity
- add_overlay("over_[tank_type]_half[water_type]")
+ . += "over_[tank_type]_half[water_type]"
-/obj/machinery/fishtank/wall/update_icon()
- ..()
+
+/obj/machinery/fishtank/wall/update_overlays()
+ . = ..()
// Update fish overlay for wall tanks
var/num_fish = length(fish_list)
if(!num_fish)
return
switch(num_fish)
if(1 to 3)
- add_overlay("over_tank_fish_33")
+ . += "over_tank_fish_33"
if(4 to 7)
- add_overlay("over_tank_fish_66")
+ . += "over_tank_fish_66"
if(7 to INFINITY)
- add_overlay("over_tank_fish_100")
+ . += "over_tank_fish_100"
+
//////////////////////////////
// PROCESS PROC //
@@ -180,23 +201,23 @@
/obj/machinery/fishtank/wall/CanAtmosPass(turf/T)
return FALSE
+
/obj/machinery/fishtank/process()
//Start by counting fish in the tank
- fish_count = 0
- var/ate_food = 0
- for(var/fish in fish_list)
- if(fish)
- fish_count++
+ var/fish_count = get_num_fish()
+ var/ate_food = FALSE
//Check if the water level can support the current number of fish
if((fish_count * 50) > water_level)
if(prob(50)) //Not enough water for all the fish, chance to kill one
+ fish_count--
kill_fish() //Chance passed, kill a random fish
adjust_filth_level(2) //Dead fish raise the filth level quite a bit, reflect this
//Check filth_level
if(filth_level == 10 && fish_count > 0) //This tank is nasty and possibly unsuitable for fish if any are in it
if(prob(30)) //Chance for a fish to die each cycle while the tank is this nasty
+ fish_count--
kill_fish() //Kill a random fish, don't raise filth level since we're at cap already
//Check breeding conditions
@@ -205,7 +226,7 @@
if(prob(((fish_count - 2) * 5)+10)) //Chances increase with each additional fish, 10% base + 5% per additional fish
breed_fish()
adjust_food_level(-0.1) //Remove extra food for the breeding process
- ate_food = 1
+ ate_food = TRUE
//Handle standard food and filth adjustments
if(food_level > 0 && prob(50)) //Chance for the fish to eat some food
@@ -213,7 +234,7 @@
adjust_food_level(fish_count * -0.05)
else //Use up the last of the food
adjust_food_level(-food_level)
- ate_food = 1
+ ate_food = TRUE
if(water_level > 0) //Don't dirty the tank if it has no water
if(fish_count == 0) //If the tank has no fish, algae growth can occur
@@ -234,17 +255,23 @@
adjust_water_level(-10)
else if(leaking == 1) //At or below 50% health, the tank will lose 1 water_level per cycle (minor leak)
adjust_water_level(-1)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
+
//////////////////////////////
// SUPPORT PROCS //
//////////////////////////////
+/obj/machinery/fishtank/proc/get_num_fish()
+ return length(fish_list)
+
+
/obj/machinery/fishtank/proc/handle_special_interactions()
for(var/datum/fish/fish in fish_list)
fish.special_interact(src)
adjust_tank_light()
+
/obj/machinery/fishtank/proc/adjust_tank_light()
if(!light_switch) //tank light overrides fish lights
var/glo_light = 0
@@ -256,16 +283,20 @@
else
set_light(0, 0)
+
/obj/machinery/fishtank/proc/adjust_water_level(amount = 0)
water_level = min(water_capacity, max(0, water_level + amount))
update_icon()
+
/obj/machinery/fishtank/proc/adjust_filth_level(amount = 0)
filth_level = min(10, max(0, filth_level + amount))
+
/obj/machinery/fishtank/proc/adjust_food_level(amount = 0)
food_level = min(10, max(0, food_level + amount))
+
/obj/machinery/fishtank/proc/check_health()
//Leaking status check
if(obj_integrity <= (max_integrity * 0.25)) //Major leak at or below 25% health (-10 water/cycle)
@@ -275,30 +306,31 @@
else //Not leaking above 50% health
leaking = 0
+
/obj/machinery/fishtank/proc/kill_fish(datum/fish/fish_type = null)
//Check if we were passed a fish to kill, otherwise kill a random one
if(!fish_type)
fish_type = pick(fish_list)
fish_list.Remove(fish_type) //Kill a fish of the specified type
- fish_count -- //Lower fish_count to reflect the death of a fish, so the everything else works fine
if(istype(fish_type, /datum/fish/glofish))
adjust_tank_light()
qdel(fish_type)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
+
/obj/machinery/fishtank/proc/add_fish(datum/fish/fish_type = null)
//Check if we were passed a fish type
if(fish_type)
fish_type = new fish_type
fish_list.Add(fish_type) //Add a fish of the specified type
- fish_count++ //Increase fish_count to reflect the introduction of a fish, so the everything else works fine
//Announce the new fish
visible_message("A new [fish_type.fish_name] has hatched in [src]!")
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
//Null type fish are dud eggs, give a message to inform the player
else
to_chat(usr, "The eggs disolve in the water. They were duds!")
+
/obj/machinery/fishtank/proc/harvest_eggs(mob/user, obj/item/storage/bag/fish/fish_bag)
if(!egg_count) //Can't harvest non-existant eggs
return
@@ -320,42 +352,57 @@
egg_list.Cut() //Destroy any excess eggs, clearing the egg_list
if(duds)
- to_chat(user, "[duds] egg\s [duds == 1 ? "was a dud" : "were duds"]!")
+ to_chat(user, span_notice("[duds] egg\s [duds == 1 ? "was a dud" : "were duds"]!"))
+
/obj/machinery/fishtank/proc/harvest_fish(mob/user)
- if(fish_count <= 0) //Can't catch non-existant fish!
- to_chat(user, "There are no fish in [src] to catch!")
+ if(!get_num_fish()) //Can't catch non-existant fish!
+ to_chat(user, span_warning("There are no fish in [src] to catch!"))
return
- var/list/fish_types = list()
- var/list/fish_types_input = list()
+ var/list/fish_types = list() // fish sorted by type. Key is type of fish, value is a list of fish of that type
+ var/list/fish_types_input = list() // The choices given to the player, and the types of fish those choices are for. Key is string shown to player, value is type of fish
for(var/datum/fish/F in fish_list) // Group up the fish first
fish_types[F.type] += list(F)
for(var/key in fish_types) // Then populate the list
var/datum/fish/fish_type = key
var/count = length(fish_types[key])
- fish_types_input += list("[initial(fish_type.fish_name)][count > 1 ? " (x[count])" : ""]" = fish_types[key])
+ var/fish_description = "[initial(fish_type.fish_name)][count > 1 ? " (x[count])" : ""]"
+ fish_types_input[fish_description] = fish_type
var/caught_fish = tgui_input_list(user, "Select a fish to catch.", "Fishing", fish_types_input) //Select a fish from the tank
- if(fish_count <= 0)
- to_chat(user, "There are no fish in [src] to catch!")
+ if(!caught_fish)
+ return
+ if(!Adjacent(user))
+ to_chat(user, span_warning("You are no longer next to [src], so you can't catch fish!"))
return
- else if(caught_fish)
- var/list/fishes_of_type = fish_types_input[caught_fish]
- var/datum/fish/fish_to_scoop = pick(fishes_of_type)
- // Is the user holding a fish bag?
- var/obj/item/storage/bag/fish_bag
- if(istype(user.r_hand, /obj/item/storage/bag/fish))
- fish_bag = user.r_hand
- else if(istype(user.l_hand, /obj/item/storage/bag/fish))
- fish_bag = user.l_hand
- var/fish_name = fish_to_scoop.fish_name
- // Move the fish in
- var/fish_item = fish_to_scoop.fish_item
- if(fish_item)
- var/obj/item/I = new fish_item(get_turf(user))
- if(fish_bag?.can_be_inserted(I))
- fish_bag.handle_item_insertion(I)
- user.visible_message("[user.name] scoops \a [fish_name] from [src].", "You scoop \a [fish_name] out of [src].")
- kill_fish(fish_to_scoop) //Kill the caught fish from the tank
+ if(!get_num_fish())
+ to_chat(user, span_warning("There are no fish in [src] to catch!"))
+ return
+ var/fish_type_caught = fish_types_input[caught_fish]
+ var/list/fishes_of_type = list()
+ for(var/datum/fish/F in fish_list)
+ if(F.type == fish_type_caught)
+ fishes_of_type += list(F)
+ if(!length(fishes_of_type))
+ var/datum/fish/fish_type = fish_type_caught
+ to_chat(user, span_warning("There are no [fish_type.fish_name] in [src] to catch!"))
+ return
+ var/datum/fish/fish_to_scoop = pick(fishes_of_type)
+ // Is the user holding a fish bag?
+ var/obj/item/storage/bag/fish_bag
+ if(istype(user.r_hand, /obj/item/storage/bag/fish))
+ fish_bag = user.r_hand
+ else if(istype(user.l_hand, /obj/item/storage/bag/fish))
+ fish_bag = user.l_hand
+ var/fish_name = fish_to_scoop.fish_name
+ // Move the fish in
+ var/fish_item = fish_to_scoop.fish_item
+ if(fish_item)
+ var/obj/item/I = new fish_item(get_turf(user))
+ if(fish_bag?.can_be_inserted(I))
+ fish_bag.handle_item_insertion(I)
+ user.visible_message("[user.name] scoops \a [fish_name] from [src].", "You scoop \a [fish_name] out of [src].")
+ kill_fish(fish_to_scoop) //Kill the caught fish from the tank
+
/obj/machinery/fishtank/proc/spill_water()
var/turf/simulated/T = get_turf(src)
@@ -366,20 +413,21 @@
if("tank") //Fishtank: Wets it's own tile and the 4 adjacent tiles (cardinal directions)
if(istype(T))
T.MakeSlippery()
- for(var/turf/simulated/ST in T.CardinalTurfs())
+ for(var/turf/simulated/ST in T.AdjacentTurfs(open_only = TRUE, cardinal_only = TRUE))
ST.MakeSlippery()
if("wall") //Wall-tank: Wets it's own tile and the surrounding 8 tiles (3x3 square)
for(var/turf/simulated/ST in spiral_range_turfs(1, loc))
ST.MakeSlippery()
+
/obj/machinery/fishtank/proc/breed_fish()
var/list/breed_candidates = fish_list.Copy()
var/datum/fish/parent1 = pick_n_take(breed_candidates)
if(!parent1.crossbreeder) //fish with crossbreed = 0 will only breed with their own species, and only leave duds if they can't breed
- var/match_found = 0
+ var/match_found = FALSE
for(var/datum/fish/possible in breed_candidates)
if(parent1.type == possible.type)
- match_found = 1
+ match_found = TRUE
break
if(match_found)
egg_list.Add(parent1.egg_item)
@@ -404,12 +452,14 @@
egg_list.Add(parent2.egg_item)
egg_count++
+
/obj/machinery/fishtank/welder_act(mob/user, obj/item/I)
. = TRUE
if(!I.tool_use_check(user, 0))
return
default_welder_repair(user, I)
+
////////////////////////////// Note from FalseIncarnate:
// EXAMINE PROC // This proc is massive, messy, and probably could be handled better.
////////////////////////////// Feel free to try cleaning it up if you think of a better way to do it.
@@ -417,6 +467,7 @@
/obj/machinery/fishtank/examine(mob/user)
. = ..()
var/examine_message = ""
+ var/fish_count = get_num_fish()
//Approximate water level
examine_message += "Water level: "
@@ -518,85 +569,118 @@
if(leaking == 2)
examine_message += "[src] is nearly shattered!"
-
//Finally, report the full examine_message constructed from the above reports
- . += "[examine_message]"
+ . += span_notice("[examine_message]")
+ . += span_info("You can Alt-Click [src] to open/close its lid.")
+ . += span_info("You can Alt-Shift-Click [src] to enable/disable its light.")
+
//////////////////////////////
// ATACK PROCS //
//////////////////////////////
/obj/machinery/fishtank/attack_animal(mob/living/simple_animal/M)
+ var/fish_count = get_num_fish()
if(istype(M, /mob/living/simple_animal/pet/cat))
if(M.a_intent == INTENT_HELP) //Cats can try to fish in open tanks on help intent
if(lid_switch) //Can't fish in a closed tank. Fishbowls are ALWAYS open.
- M.visible_message("[M.name] stares at into [src] while sitting perfectly still.", "The lid is closed, so you stare into [src] intently.")
+ M.visible_message(
+ span_notice("[M.name] stares at into [src] while sitting perfectly still."),
+ span_notice("The lid is closed, so you stare into [src] intently."),
+ )
else
if(fish_count) //Tank must actually have fish to try catching one
- M.visible_message("[M.name] leaps up onto [src] and attempts to fish through the opening!", "You jump up onto [src] and begin fishing through the opening!")
+ M.visible_message(
+ span_warning("[M.name] leaps up onto [src] and attempts to fish through the opening!"),
+ span_notice("You jump up onto [src] and begin fishing through the opening!"),
+ )
if(water_level && prob(45)) //If there is water, there is a chance the cat will slip, Syndicat will spark like E-N when this happens
- M.visible_message("[M.name] slipped and got soaked!", "You slipped and got soaked!")
+ M.visible_message(
+ span_notice("[M.name] slipped and got soaked!"),
+ span_notice("You slipped and got soaked!"),
+ )
if(istype(M, /mob/living/simple_animal/pet/cat/Syndi))
do_sparks(3, 1, src)
else //No water or didn't slip, get that fish!
- M.visible_message("[M.name] catches and devours a live fish!", "You catch and devour a live fish, yum!")
+ M.visible_message(
+ span_warning("[M.name] catches and devours a live fish!"),
+ span_notice("You catch and devour a live fish, yum!"),
+ )
kill_fish() //Kill a random fish
M.health = M.maxHealth //Eating fish heals the predator
else
- to_chat(M, "There are no fish in [src]!")
+ to_chat(M, span_warning("There are no fish in [src]!"))
else
return ..()
else if(istype(M, /mob/living/simple_animal/hostile/bear))
if(M.a_intent == INTENT_HELP) //Bears can try to fish in open tanks on help intent
if(lid_switch) //Can't fish in a closed tank. Fishbowls are ALWAYS open.
- M.visible_message("[M.name] scrapes it's claws along [src]'s lid.", "The lid is closed, so you scrape your claws against [src]'s lid.")
+ M.visible_message(
+ span_notice("[M.name] scrapes it's claws along [src]'s lid."),
+ span_notice("The lid is closed, so you scrape your claws against [src]'s lid."),
+ )
else
if(fish_count) //Tank must actually have fish to try catching one
- M.visible_message("[M.name] reaches into [src] and attempts to fish through the opening!", "You reach into [src] and begin fishing through the opening!")
+ M.visible_message(
+ span_warning("[M.name] reaches into [src] and attempts to fish through the opening!"),
+ span_warning("You reach into [src] and begin fishing through the opening!"),
+ )
if(water_level && prob(5)) //Bears are good at catching fish, only a 5% chance to fail
- M.visible_message("[M.name] swipes at the water!", "You just barely missed that fish!")
+ M.visible_message(
+ span_warning("[M.name] swipes at the water!"),
+ span_notice("You just barely missed that fish!"),
+ )
else //No water or didn't slip, get that fish!
- M.visible_message("[M.name] catches and devours a live fish!", "You catch and devour a live fish, yum!")
+ M.visible_message(
+ span_warning("[M.name] catches and devours a live fish!"),
+ span_notice("You catch and devour a live fish, yum!"),
+ )
kill_fish() //Kill a random fish
M.health = M.maxHealth //Eating fish heals the predator
else
- to_chat(M, "There are no fish in [src]!")
+ to_chat(M, span_warning("There are no fish in [src]!"))
else
return ..()
else
return ..()
+
/obj/machinery/fishtank/attack_hand(mob/user)
if(isAI(user))
return
add_fingerprint(user)
user.changeNext_move(CLICK_CD_MELEE)
+ playsound(get_turf(src), 'sound/effects/glassknock.ogg', 80, TRUE)
if(user.a_intent == INTENT_HARM)
- playsound(get_turf(src), 'sound/effects/glassknock.ogg', 80, 1)
- user.visible_message("[user.name] bangs against the [name]!", \
- "You bang against the [name]!", \
- "You hear a banging sound.")
+ user.visible_message(
+ span_danger("[user] bangs against [src]!"),
+ span_danger("You bang against [src]!"),
+ span_italics("You hear a banging sound."),
+ )
else
- playsound(loc, 'sound/effects/glassknock.ogg', 80, 1)
- user.visible_message("[user.name] taps on the [name].", \
- "You tap on the [name].", \
- "You hear a knocking sound.")
+ user.visible_message(
+ span_notice("[user] taps on [src]."),
+ span_notice("You tap on [src]."),
+ span_italics("You hear a knocking sound."),
+ )
+
/obj/machinery/fishtank/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
if(damage_amount)
- playsound(src, 'sound/effects/glasshit.ogg', 75, 1)
+ playsound(src, 'sound/effects/glasshit.ogg', 75, TRUE)
else
- playsound(src, 'sound/weapons/tap.ogg', 50, 1)
+ playsound(src, 'sound/weapons/tap.ogg', 50, TRUE)
if(BURN)
- playsound(src, 'sound/items/welder.ogg', 100, 1)
+ playsound(src, 'sound/items/welder.ogg', 100, TRUE)
+
/obj/machinery/fishtank/deconstruct(disassembled = TRUE)
if(QDELETED(src))
return
if(!disassembled)
- playsound(src, "shatter", 70, 1)
+ playsound(src, "shatter", 70, TRUE)
for(var/i in 1 to shard_count) //Produce the appropriate number of glass shards
var/obj/item/shard/S = new /obj/item/shard(get_turf(src))
transfer_fingerprints_to(S)
@@ -606,6 +690,7 @@
new /obj/item/stack/sheet/glass(get_turf(src), shard_count + 1) //Produce the appropriate number of glass sheets, in a single stack
qdel(src)
+
/obj/machinery/fishtank/attackby(obj/item/O, mob/user)
//Open reagent containers add and remove water
if(O.is_drainable())
@@ -625,7 +710,7 @@
O.reagents.clear_reagents()
else
if(water_level == water_capacity)
- to_chat(user, "[src] is already full!")
+ to_chat(user, span_notice("[src] is already full!"))
else
add_fingerprint(user)
message = "The filtration process purifies the water, raising the water level."
@@ -636,31 +721,40 @@
message += " You overfilled [src] and some water runs down the side, wasted."
O.reagents.clear_reagents()
adjust_water_level(water_value)
- user.visible_message("[user.name] pours the contents of [O.name] into [src].", "[message]")
+ user.visible_message(
+ span_notice("[user.name] pours the contents of [O.name] into [src]."),
+ span_notice("[message]"),
+ )
//Empty containers will scoop out water, filling the container as much as possible from the water_level
else if(O.is_refillable())
if(!water_level)
- to_chat(user, "[src] is empty!")
+ to_chat(user, span_notice("[src] is empty!"))
else
add_fingerprint(user)
if(water_level >= O.reagents.maximum_volume) //Enough to fill the container completely
O.reagents.add_reagent("fishwater", O.reagents.maximum_volume)
adjust_water_level(-O.reagents.maximum_volume)
- user.visible_message("[user.name] scoops out some water from [src].", "You completely fill [O.name] from [src].")
+ user.visible_message(
+ span_notice("[user.name] scoops out some water from [src]."),
+ span_notice("You completely fill [O.name] from [src]."),
+ )
else //Fill the container as much as possible with the water_level
O.reagents.add_reagent("fishwater", water_level)
adjust_water_level(-water_level)
- user.visible_message("[user.name] scoops out some water from [src].", "You fill [O.name] with the last of the water in [src].")
+ user.visible_message(
+ span_notice("[user.name] scoops out some water from [src]."),
+ span_notice("You fill [O.name] with the last of the water in [src]."),
+ )
//Fish eggs
else if(istype(O, /obj/item/fish_eggs))
var/obj/item/fish_eggs/egg = O
//Don't add eggs if there is no water (they kinda need that to live)
if(!water_level)
- to_chat(user, "[src] has no water; [egg.name] won't hatch without water!")
+ to_chat(user, span_warning("[src] has no water; [egg.name] won't hatch without water!"))
else
//Don't add eggs if the tank already has the max number of fish
- if(fish_count >= max_fish)
- to_chat(user, "[src] can't hold any more fish.")
+ if(get_num_fish() >= max_fish)
+ to_chat(user, span_notice("[src] can't hold any more fish."))
else
add_fingerprint(user)
add_fish(egg.fish_type)
@@ -671,15 +765,21 @@
if(water_level)
if(food_level < 10)
add_fingerprint(user)
- if(fish_count == 0)
- user.visible_message("[user.name] shakes some fish food into the empty [src]... How sad.", "You shake some fish food into the empty [src]... If only it had fish.")
+ if(!get_num_fish())
+ user.visible_message(
+ span_notice("[user.name] shakes some fish food into the empty [src]... How sad."),
+ span_notice("You shake some fish food into the empty [src]... If only it had fish."),
+ )
else
- user.visible_message("[user.name] feeds the fish in [src]. The fish look excited!", "You feed the fish in [src]. They look excited!")
+ user.visible_message(
+ span_notice("[user.name] feeds the fish in [src]. The fish look excited!"),
+ span_notice("You feed the fish in [src]. They look excited!"),
+ )
adjust_food_level(10)
else
- to_chat(user, "[src] already has plenty of food in it. You decide to not add more.")
+ to_chat(user, span_notice("[src] already has plenty of food in it. You decide to not add more."))
else
- to_chat(user, "[src] doesn't have any water in it. You should fill it with water first.")
+ to_chat(user, span_notice("[src] doesn't have any water in it. You should fill it with water first."))
//Fish egg scoop
else if(istype(O, /obj/item/egg_scoop))
add_fingerprint(user)
@@ -690,10 +790,16 @@
fish_bag = user.r_hand
else if(istype(user.l_hand, /obj/item/storage/bag/fish))
fish_bag = user.l_hand
- user.visible_message("[user.name] harvests some fish eggs from [src].", "You scoop the fish eggs out of [src].")
+ user.visible_message(
+ span_notice("[user.name] harvests some fish eggs from [src]."),
+ span_notice("You scoop the fish eggs out of [src]."),
+ )
harvest_eggs(user, fish_bag)
else
- user.visible_message("[user.name] fails to harvest any fish eggs from [src].", "There are no fish eggs in [src] to scoop out.")
+ user.visible_message(
+ span_notice("[user.name] fails to harvest any fish eggs from [src]."),
+ span_notice("There are no fish eggs in [src] to scoop out."),
+ )
//Fish net
else if(istype(O, /obj/item/fish_net))
add_fingerprint(user)
@@ -701,21 +807,26 @@
//Tank brush
else if(istype(O, /obj/item/tank_brush))
if(filth_level == 0)
- to_chat(user, "[src] is already spotless!")
+ to_chat(user, span_warning("[src] is already spotless!"))
else
add_fingerprint(user)
adjust_filth_level(-filth_level)
- user.visible_message("[user.name] scrubs the inside of [src], cleaning the filth.", "You scrub the inside of [src], cleaning the filth.")
+ user.visible_message(
+ span_notice("[user.name] scrubs the inside of [src], cleaning the filth."),
+ span_notice("You scrub the inside of [src], cleaning the filth."),
+ )
else
return ..()
+
/obj/machinery/fishtank/wrench_act(mob/user, obj/item/I) //Wrenches can deconstruct empty tanks, but not tanks with any water. Kills any fish left inside and destroys any unharvested eggs in the process
. = TRUE
if(water_level)
- to_chat(user, "[src] must be empty before you disassemble it!")
+ to_chat(user, span_warning("[src] must be empty before you disassemble it!"))
return
if(!I.tool_use_check(user, 0))
return
- to_chat(user, "Now disassembling [src].")
+ to_chat(user, span_notice("Now disassembling [src]."))
if(I.use_tool(src, user, 50, volume = I.tool_volume))
deconstruct(TRUE)
+
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index c4d55fef604..fb28a469d5d 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -593,7 +593,7 @@ GLOBAL_LIST_INIT(major_hallutinations, list("fake"=20,"death"=10,"xeno"=10,"sing
name = ""
desc = ""
density = 0
- anchored = 1
+ anchored = TRUE
opacity = 0
var/mob/living/carbon/human/my_target = null
var/weapon_name = null
diff --git a/code/modules/food_and_drinks/drinks/bottler/bottler.dm b/code/modules/food_and_drinks/drinks/bottler/bottler.dm
index 3de68fcce0c..0d02f977481 100644
--- a/code/modules/food_and_drinks/drinks/bottler/bottler.dm
+++ b/code/modules/food_and_drinks/drinks/bottler/bottler.dm
@@ -15,12 +15,12 @@
icon = 'icons/obj/kitchen.dmi'
icon_state = "bottler_off"
density = 1
- anchored = 1
+ anchored = TRUE
var/list/slots[3]
var/list/datum/bottler_recipe/available_recipes
var/list/acceptable_items
var/list/containers = list("glass bottle" = 10, "plastic bottle" = 20, "metal can" = 25)
- var/bottling = 0
+ var/bottling = FALSE
/obj/machinery/bottler/New()
. = ..()
@@ -275,7 +275,8 @@
containers[con_type]--
//select and process a recipe based on inserted ingredients
visible_message("[src] hums as it processes the ingredients...")
- bottling = 1
+ bottling = TRUE
+ update_icon(UPDATE_ICON_STATE)
var/datum/bottler_recipe/recipe_to_use = select_recipe()
if(!recipe_to_use)
//bad recipe, ruins the drink
@@ -293,7 +294,8 @@
flick("bottler_on", src)
spawn(45)
resetSlots()
- bottling = 0
+ bottling = FALSE
+ update_icon(UPDATE_ICON_STATE)
drink_container.forceMove(loc)
updateUsrDialog()
@@ -409,7 +411,7 @@
updateUsrDialog()
return
-/obj/machinery/bottler/update_icon()
+/obj/machinery/bottler/update_icon_state()
if(stat & BROKEN)
icon_state = "bottler_broken"
else if(bottling)
diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm
index 56022e21541..0206b210962 100644
--- a/code/modules/food_and_drinks/drinks/drinks.dm
+++ b/code/modules/food_and_drinks/drinks/drinks.dm
@@ -78,10 +78,10 @@
else
return
-/obj/item/reagent_containers/food/drinks/MouseDrop(atom/over) //CHUG! CHUG! CHUG!
- if(!iscarbon(over))
+/obj/item/reagent_containers/food/drinks/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) //CHUG! CHUG! CHUG!
+ if(!iscarbon(over_object))
return ..()
- var/mob/living/carbon/chugger = over
+ var/mob/living/carbon/chugger = over_object
if(!(container_type & DRAINABLE))
to_chat(chugger, "You need to open [src] first!")
return
@@ -301,11 +301,14 @@
possible_transfer_amounts = null
volume = 10
+
+/obj/item/reagent_containers/food/drinks/sillycup/update_icon_state()
+ icon_state = "water_cup[reagents.total_volume ? "" : "_e"]"
+
+
/obj/item/reagent_containers/food/drinks/sillycup/on_reagent_change()
- if(reagents.total_volume)
- icon_state = "water_cup"
- else
- icon_state = "water_cup_e"
+ update_icon(UPDATE_ICON_STATE)
+
//////////////////////////drinkingglass and shaker//
//Note by Darem: This code handles the mixing of drinks. New drinks go in three places: In Chemistry-Reagents.dm (for the drink
@@ -398,3 +401,54 @@
/obj/item/reagent_containers/food/drinks/oilcan/full
list_reagents = list("oil" = 100)
+
+
+/obj/item/reagent_containers/food/drinks/zaza
+ name = "Cherry Zaza"
+ desc = "I possess Zaza!"
+ icon_state = "zaza_can"
+ item_state = "zaza_can"
+ volume = 80
+ foodtype = SUGAR
+ container_type = NONE
+ list_reagents = list("zaza" = 80)
+
+
+/obj/item/reagent_containers/food/drinks/zaza/on_reagent_change()
+ update_icon(UPDATE_OVERLAYS)
+
+
+/obj/item/reagent_containers/food/drinks/zaza/update_overlays()
+ . = ..()
+
+ if(reagents.total_volume)
+ var/image/filling = image('icons/obj/reagentfillings.dmi', "[icon_state]50")
+
+ switch(round(reagents.total_volume))
+ if(1 to 50)
+ filling.icon_state = "[icon_state]50"
+ if(51 to 60)
+ filling.icon_state = "[icon_state]60"
+ if(61 to 65)
+ filling.icon_state = "[icon_state]65"
+ if(66 to 70)
+ filling.icon_state = "[icon_state]70"
+ if(71 to 75)
+ filling.icon_state = "[icon_state]75"
+ if(76 to INFINITY)
+ filling.icon_state = "[icon_state]80"
+ filling.icon += mix_color_from_reagents(reagents.reagent_list)
+ . += filling
+
+ if(!is_open_container())
+ . += "zaza_lid"
+
+
+/obj/item/reagent_containers/food/drinks/zaza/attack_self(mob/user)
+ if(!is_open_container())
+ container_type |= OPENCONTAINER
+ to_chat(user, span_notice("You put the lid on [src]."))
+ else
+ to_chat(user, span_notice("You take the lid off [src]."))
+ container_type &= ~OPENCONTAINER
+ update_icon(UPDATE_OVERLAYS)
diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm
index 35a8a2a1726..1ce01f36217 100644
--- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm
+++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm
@@ -377,17 +377,37 @@
list_reagents = list()
var/list/accelerants = list(/datum/reagent/consumable/ethanol,/datum/reagent/fuel,/datum/reagent/clf3,/datum/reagent/phlogiston,
/datum/reagent/napalm,/datum/reagent/hellwater,/datum/reagent/plasma,/datum/reagent/plasma_dust)
- var/active = 0
+ var/active = FALSE
+
+
+/obj/item/reagent_containers/food/drinks/bottle/molotov/update_desc(updates = ALL)
+ . = ..()
+ desc = initial(desc)
+ if(!isGlass)
+ desc += " You're not sure if making this out of a carton was the brightest idea."
+
+
+/obj/item/reagent_containers/food/drinks/bottle/molotov/update_icon_state()
+ var/obj/item/reagent_containers/food/drinks/bottle/bottle = locate() in contents
+ if(bottle)
+ icon_state = bottle.icon_state
+
+
+/obj/item/reagent_containers/food/drinks/bottle/molotov/update_overlays()
+ . = ..()
+ if(active)
+ . += GLOB.fire_overlay
+
/obj/item/reagent_containers/food/drinks/bottle/molotov/CheckParts(list/parts_list)
..()
- var/obj/item/reagent_containers/food/drinks/bottle/B = locate() in contents
- if(B)
- icon_state = B.icon_state
- B.reagents.copy_to(src, 100)
- if(!B.isGlass)
- desc += " You're not sure if making this out of a carton was the brightest idea."
- isGlass = 0
+ var/obj/item/reagent_containers/food/drinks/bottle/bottle = locate() in contents
+ if(bottle)
+ bottle.reagents.copy_to(src, 100)
+ if(!bottle.isGlass)
+ isGlass = FALSE
+ update_appearance(UPDATE_DESC|UPDATE_ICON)
+
/obj/item/reagent_containers/food/drinks/bottle/molotov/throw_impact(atom/target, datum/thrownthing/throwingdatum)
var/firestarter = 0
@@ -402,6 +422,7 @@
new /obj/effect/hotspot(get_turf(target))
..()
+
/obj/item/reagent_containers/food/drinks/bottle/molotov/attackby(obj/item/I, mob/user, params)
if(is_hot(I) && !active)
active = 1
@@ -426,11 +447,12 @@
A.fire_act()
qdel(src)
+
/obj/item/reagent_containers/food/drinks/bottle/molotov/attack_self(mob/user)
if(active)
if(!isGlass)
to_chat(user, "The flame's spread too far on it!")
return
to_chat(user, "You snuff out the flame on \the [src].")
- overlays -= GLOB.fire_overlay
- active = 0
+ active = FALSE
+ update_icon(UPDATE_OVERLAYS)
diff --git a/code/modules/food_and_drinks/drinks/drinks/cans.dm b/code/modules/food_and_drinks/drinks/drinks/cans.dm
index 23763ddeef4..44859f6260a 100644
--- a/code/modules/food_and_drinks/drinks/drinks/cans.dm
+++ b/code/modules/food_and_drinks/drinks/drinks/cans.dm
@@ -185,7 +185,7 @@
name = "non-alcoholic beer"
desc = "A favorite thing of all students and those who drive."
icon_state = "alcoholfreebeercan"
- list_reagents = list("alcohol_free_beer" = 30)
+ list_reagents = list("noalco_beer" = 30)
/obj/item/reagent_containers/food/drinks/cans/adminbooze
@@ -289,12 +289,13 @@
desc = "this shouldn't ever be spawned. shame on you"
icon_state = "glass_bottle"
+
/obj/item/reagent_containers/food/drinks/cans/bottler/on_reagent_change()
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
-/obj/item/reagent_containers/food/drinks/cans/bottler/update_icon()
- overlays.Cut()
+/obj/item/reagent_containers/food/drinks/cans/bottler/update_overlays()
+ . = ..()
if(reagents.total_volume)
var/image/filling = image('icons/obj/reagentfillings.dmi', src, "[icon_state]10")
@@ -313,7 +314,8 @@
filling.icon_state = "[icon_state]50"
filling.icon += mix_color_from_reagents(reagents.reagent_list)
- overlays += filling
+ . += filling
+
/obj/item/reagent_containers/food/drinks/cans/bottler/glass_bottle
name = "glass bottle"
diff --git a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm
index b57f6ce792a..59ecbf757de 100644
--- a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm
+++ b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm
@@ -46,22 +46,45 @@
reagents.clear_reagents()
extinguish()
-/obj/item/reagent_containers/food/drinks/drinkingglass/on_reagent_change()
- overlays.Cut()
- if(reagents.reagent_list.len)
- var/datum/reagent/R = reagents.get_master_reagent()
- name = R.drink_name
- desc = R.drink_desc
- if(R.drink_icon)
- icon_state = R.drink_icon
- else
- var/image/I = image(icon, "glassoverlay")
- I.color = mix_color_from_reagents(reagents.reagent_list)
- overlays += I
+
+/obj/item/reagent_containers/food/drinks/drinkingglass/update_icon_state()
+ if(length(reagents.reagent_list))
+ var/datum/reagent/check = reagents.get_master_reagent()
+ if(check.drink_icon)
+ icon_state = check.drink_icon
+
+
+/obj/item/reagent_containers/food/drinks/drinkingglass/update_overlays()
+ . = ..()
+ if(length(reagents.reagent_list))
+ var/datum/reagent/check = reagents.get_master_reagent()
+ if(!check.drink_icon)
+ . += mutable_appearance(icon, "glassoverlay", color = mix_color_from_reagents(reagents.reagent_list))
+ else
+ icon_state = initial(icon_state)
+
+
+/obj/item/reagent_containers/food/drinks/drinkingglass/update_name(updates)
+ . = ..()
+ if(length(reagents.reagent_list))
+ var/datum/reagent/check = reagents.get_master_reagent()
+ name = check.drink_name
else
- icon_state = "glass_empty"
- name = "glass"
- desc = "Your standard drinking glass."
+ name = initial(name)
+
+
+/obj/item/reagent_containers/food/drinks/drinkingglass/update_desc(updates)
+ . = ..()
+ if(length(reagents.reagent_list))
+ var/datum/reagent/check = reagents.get_master_reagent()
+ desc = check.drink_desc
+ else
+ desc = initial(desc)
+
+
+/obj/item/reagent_containers/food/drinks/drinkingglass/on_reagent_change()
+ update_appearance()
+
// for /obj/machinery/vending/sovietsoda
/obj/item/reagent_containers/food/drinks/drinkingglass/soda
diff --git a/code/modules/food_and_drinks/drinks/drinks/shotglass.dm b/code/modules/food_and_drinks/drinks/drinks/shotglass.dm
index af301de5e50..3a3aa6640dc 100644
--- a/code/modules/food_and_drinks/drinks/drinks/shotglass.dm
+++ b/code/modules/food_and_drinks/drinks/drinks/shotglass.dm
@@ -2,6 +2,7 @@
name = "shot glass"
desc = "No glasses were shot in the making of this glass."
icon_state = "shotglass"
+ custom_fire_overlay = "shotglass_fire"
amount_per_transfer_from_this = 15
volume = 15
materials = list(MAT_GLASS=100)
@@ -12,10 +13,21 @@
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/on_reagent_change()
if(!isShotFlammable() && (resistance_flags & ON_FIRE))
extinguish()
- update_icon()
+ update_appearance(UPDATE_NAME|UPDATE_OVERLAYS)
-/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/update_icon()
- overlays.Cut()
+
+/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/update_name()
+ . = ..()
+ if(reagents.total_volume)
+ name = "shot glass of " + reagents.get_master_reagent_name() //No matter what, the glass will tell you the reagent's name. Might be too abusable in the future.
+ if(resistance_flags & ON_FIRE)
+ name = "flaming [name]"
+ else
+ name = "shot glass"
+
+
+/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/update_overlays()
+ . = ..()
if(reagents.total_volume)
var/image/filling = image('icons/obj/reagentfillings.dmi', src, "[icon_state]1")
@@ -28,14 +40,8 @@
if(80 to INFINITY)
filling.icon_state = "[icon_state]12"
filling.icon += mix_color_from_reagents(reagents.reagent_list)
- overlays += filling
- name = "shot glass of " + reagents.get_master_reagent_name() //No matter what, the glass will tell you the reagent's name. Might be too abusable in the future.
- if(resistance_flags & ON_FIRE)
- cut_overlay(GLOB.fire_overlay, TRUE)
- overlays += "shotglass_fire"
- name = "flaming [name]"
- else
- name = "shot glass"
+ . += filling
+
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/proc/clumsilyDrink(mob/living/carbon/human/user) //Clowns beware
if(!(resistance_flags & ON_FIRE))
@@ -59,14 +65,14 @@
..()
set_light(light_intensity, null, light_color)
visible_message("[src] begins to burn with a blue hue!")
- update_icon()
+ update_appearance(UPDATE_NAME|UPDATE_OVERLAYS)
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/extinguish(silent = FALSE)
..()
set_light(0)
if(!silent)
visible_message("The dancing flame on [src] dies out.")
- update_icon()
+ update_appearance(UPDATE_NAME|UPDATE_OVERLAYS)
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/burn() //Let's override fire deleting the reagents inside the shot
return
@@ -96,7 +102,7 @@
extinguish()
-/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/MouseDrop(mob/living/carbon/human/user)
+/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/MouseDrop(mob/living/carbon/human/user, src_location, over_location, src_control, over_control, params)
if(!ishuman(user))
return ..()
diff --git a/code/modules/food_and_drinks/food/condiment.dm b/code/modules/food_and_drinks/food/condiment.dm
index 77f936b5956..17ecac08b11 100644
--- a/code/modules/food_and_drinks/food/condiment.dm
+++ b/code/modules/food_and_drinks/food/condiment.dm
@@ -304,20 +304,37 @@
reagents.trans_to(target, amount_per_transfer_from_this)
qdel(src)
-/obj/item/reagent_containers/food/condiment/pack/on_reagent_change()
- if(reagents.reagent_list.len > 0)
+
+/obj/item/reagent_containers/food/condiment/pack/update_desc(updates = ALL)
+ . = ..()
+ if(length(reagents.reagent_list))
var/main_reagent = reagents.get_master_reagent_id()
if(main_reagent in possible_states)
var/list/temp_list = possible_states[main_reagent]
- icon_state = temp_list[1]
desc = temp_list[3]
else
- icon_state = "condi_mixed"
desc = "A small condiment pack. The label says it contains [originalname]."
else
- icon_state = "condi_empty"
desc = "A small condiment pack. It is empty."
+
+/obj/item/reagent_containers/food/condiment/pack/update_icon_state()
+ . = ..()
+ if(length(reagents.reagent_list))
+ var/main_reagent = reagents.get_master_reagent_id()
+ if(main_reagent in possible_states)
+ var/list/temp_list = possible_states[main_reagent]
+ icon_state = temp_list[1]
+ else
+ icon_state = "condi_mixed"
+ else
+ icon_state = "condi_empty"
+
+
+/obj/item/reagent_containers/food/condiment/pack/on_reagent_change()
+ update_appearance(UPDATE_DESC|UPDATE_ICON_STATE)
+
+
//Ketchup
/obj/item/reagent_containers/food/condiment/pack/ketchup
name = "ketchup pack"
diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm
index dcc622dc441..0feb40259e3 100644
--- a/code/modules/food_and_drinks/food/customizables.dm
+++ b/code/modules/food_and_drinks/food/customizables.dm
@@ -1,66 +1,47 @@
+/obj/item/proc/make_custom_food(obj/item/reagent_containers/food/snacks/snack, mob/user, custom_type)
+ . = TRUE
+ if(!istype(snack) || !user.can_unEquip(snack))
+ return FALSE
+
+ var/obj/item/reagent_containers/food/snacks/customizable/custom_snack = new custom_type(get_turf(src))
+ custom_snack.add_ingredient(snack, user)
+ qdel(src)
+
+
/obj/item/reagent_containers/food/snacks/breadslice/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/reagent_containers/food/snacks) && !(W.flags & NODROP))
- var/obj/item/reagent_containers/food/snacks/customizable/sandwich/S = new(get_turf(user))
- S.attackby(W,user, params)
- qdel(src)
- else
- ..()
+ if(!make_custom_food(W, user, /obj/item/reagent_containers/food/snacks/customizable/sandwich))
+ return ..()
+
/obj/item/reagent_containers/food/snacks/bun/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/reagent_containers/food/snacks) && !(W.flags & NODROP))
- var/obj/item/reagent_containers/food/snacks/customizable/burger/S = new(get_turf(user))
- S.attackby(W,user, params)
- qdel(src)
+ if(!make_custom_food(W, user, /obj/item/reagent_containers/food/snacks/customizable/burger))
+ return ..()
+
/obj/item/reagent_containers/food/snacks/sliceable/flatdough/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/reagent_containers/food/snacks) && !(W.flags & NODROP))
- var/obj/item/reagent_containers/food/snacks/customizable/pizza/S = new(get_turf(user))
- S.attackby(W,user, params)
- qdel(src)
- else
- ..()
+ if(!make_custom_food(W, user, /obj/item/reagent_containers/food/snacks/customizable/pizza))
+ return ..()
/obj/item/reagent_containers/food/snacks/boiledspaghetti/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/reagent_containers/food/snacks) && !(W.flags & NODROP))
- var/obj/item/reagent_containers/food/snacks/customizable/pasta/S = new(get_turf(user))
- S.attackby(W,user, params)
- qdel(src)
- else
- ..()
+ if(!make_custom_food(W, user, /obj/item/reagent_containers/food/snacks/customizable/pasta))
+ return ..()
/obj/item/trash/plate/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/reagent_containers/food/snacks) && !(W.flags & NODROP))
- var/obj/item/reagent_containers/food/snacks/customizable/fullycustom/S = new(get_turf(user))
- S.attackby(W,user, params)
- qdel(src)
- else
- ..()
+ if(!make_custom_food(W, user, /obj/item/reagent_containers/food/snacks/customizable/fullycustom))
+ return ..()
/obj/item/trash/bowl
name = "bowl"
desc = "An empty bowl. Put some food in it to start making a soup."
- icon = 'icons/obj/food/food.dmi'
+ icon = 'icons/obj/food/custom.dmi'
icon_state = "soup"
-/obj/item/trash/bowl/attackby(obj/item/W, mob/user, params)
-
- if(istype(W, /obj/item/reagent_containers/food/snacks) && !(W.flags & NODROP))
- var/obj/item/reagent_containers/food/snacks/customizable/soup/S = new(get_turf(user))
- S.attackby(W,user, params)
- qdel(src)
- else
- ..()
-
-/obj/item/reagent_containers/food/snacks/customizable/sandwich
- name = "sandwich"
- desc = "A sandwich! A timeless classic."
- icon_state = "breadslice"
- baseicon = "sandwichcustom"
- basename = "sandwich"
- toptype = new /obj/item/reagent_containers/food/snacks/breadslice()
+/obj/item/trash/bowl/attackby(obj/item/W, mob/user, params)
+ if(!make_custom_food(W, user, /obj/item/reagent_containers/food/snacks/customizable/soup))
+ return ..()
/obj/item/reagent_containers/food/snacks/customizable
@@ -71,24 +52,39 @@
var/baseicon = "sandwichcustom"
var/basename = "sandwichcustom"
bitesize = 4
- var/top = 1 //Do we have a top?
- var/obj/item/toptype
- var/snack_overlays = 1 //Do we stack?
-// var/offsetstuff = 1 //Do we offset the overlays?
- var/sandwich_limit = 40
- var/fullycustom = 0
+ var/top = FALSE //Do we have a top?
+ /// The image of the top
+ var/image/top_image
+ var/snack_overlays = FALSE //Do we stack?
+ var/ingredient_limit = 40
+ var/fullycustom = FALSE
trash = /obj/item/trash/plate
var/list/ingredients = list()
list_reagents = list("nutriment" = 8)
+
+/obj/item/reagent_containers/food/snacks/customizable/Initialize(mapload)
+ . = ..()
+ if(top)
+ top_image = new(icon, "[baseicon]_top")
+ add_overlay(top_image)
+ if(snack_overlays)
+ layer = ABOVE_ALL_MOB_LAYER // all should see our monstrosity
+
+/obj/item/reagent_containers/food/snacks/customizable/sandwich
+ name = "sandwich"
+ desc = "A sandwich! A timeless classic."
+ icon_state = "breadslice"
+ baseicon = "sandwichcustom"
+ basename = "sandwich"
+ snack_overlays = TRUE
+
/obj/item/reagent_containers/food/snacks/customizable/pizza
name = "personal pizza"
desc = "A personalized pan pizza meant for only one person."
icon_state = "personal_pizza"
baseicon = "personal_pizza"
basename = "personal pizza"
- snack_overlays = 0
- top = 0
tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1)
/obj/item/reagent_containers/food/snacks/customizable/pasta
@@ -97,17 +93,12 @@
icon_state = "pasta_bot"
baseicon = "pasta_bot"
basename = "pasta"
- snack_overlays = 0
- top = 0
-
/obj/item/reagent_containers/food/snacks/customizable/cook/bread
name = "bread"
desc = "Tasty bread."
icon_state = "breadcustom"
baseicon = "breadcustom"
basename = "bread"
- snack_overlays = 0
- top = 0
tastes = list("bread" = 10)
/obj/item/reagent_containers/food/snacks/customizable/cook/pie
@@ -116,8 +107,6 @@
icon_state = "piecustom"
baseicon = "piecustom"
basename = "pie"
- snack_overlays = 0
- top = 0
tastes = list("pie" = 1)
/obj/item/reagent_containers/food/snacks/customizable/cook/cake
@@ -126,8 +115,6 @@
icon_state = "cakecustom"
baseicon = "cakecustom"
basename = "cake"
- snack_overlays = 0
- top = 0
tastes = list("cake" = 1)
/obj/item/reagent_containers/food/snacks/customizable/cook/jelly
@@ -136,8 +123,6 @@
icon_state = "jellycustom"
baseicon = "jellycustom"
basename = "jelly"
- snack_overlays = 0
- top = 0
/obj/item/reagent_containers/food/snacks/customizable/cook/donkpocket
name = "donk pocket"
@@ -145,8 +130,6 @@
icon_state = "donkcustom"
baseicon = "donkcustom"
basename = "donk pocket"
- snack_overlays = 0
- top = 0
/obj/item/reagent_containers/food/snacks/customizable/cook/kebab
name = "kebab"
@@ -154,8 +137,6 @@
icon_state = "kababcustom"
baseicon = "kababcustom"
basename = "kebab"
- snack_overlays = 0
- top = 0
tastes = list("meat" = 3, "metal" = 1)
/obj/item/reagent_containers/food/snacks/customizable/cook/salad
@@ -164,8 +145,6 @@
icon_state = "saladcustom"
baseicon = "saladcustom"
basename = "salad"
- snack_overlays = 0
- top = 0
tastes = list("leaves" = 1)
/obj/item/reagent_containers/food/snacks/customizable/cook/waffles
@@ -174,8 +153,6 @@
icon_state = "wafflecustom"
baseicon = "wafflecustom"
basename = "waffles"
- snack_overlays = 0
- top = 0
tastes = list("waffles" = 1)
/obj/item/reagent_containers/food/snacks/customizable/candy/cookie
@@ -184,8 +161,6 @@
icon_state = "cookiecustom"
baseicon = "cookiecustom"
basename = "cookie"
- snack_overlays = 0
- top = 0
tastes = list("cookie" = 1)
/obj/item/reagent_containers/food/snacks/customizable/candy/cotton
@@ -194,8 +169,6 @@
icon_state = "cottoncandycustom"
baseicon = "cottoncandycustom"
basename = "flavored cotton candy"
- snack_overlays = 0
- top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/gummybear
name = "flavored giant gummy bear"
@@ -203,8 +176,6 @@
icon_state = "gummybearcustom"
baseicon = "gummybearcustom"
basename = "flavored giant gummy bear"
- snack_overlays = 0
- top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/gummyworm
name = "flavored giant gummy worm"
@@ -212,8 +183,6 @@
icon_state = "gummywormcustom"
baseicon = "gummywormcustom"
basename = "flavored giant gummy worm"
- snack_overlays = 0
- top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/jellybean
name = "flavored giant jelly bean"
@@ -221,8 +190,6 @@
icon_state = "jellybeancustom"
baseicon = "jellybeancustom"
basename = "flavored giant jelly bean"
- snack_overlays = 0
- top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/jawbreaker
name = "flavored jawbreaker"
@@ -230,8 +197,6 @@
icon_state = "jawbreakercustom"
baseicon = "jawbreakercustom"
basename = "flavored jawbreaker"
- snack_overlays = 0
- top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/candycane
name = "flavored candy cane"
@@ -239,8 +204,6 @@
icon_state = "candycanecustom"
baseicon = "candycanecustom"
basename = "flavored candy cane"
- snack_overlays = 0
- top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/gum
name = "flavored gum"
@@ -248,8 +211,6 @@
icon_state = "gumcustom"
baseicon = "gumcustom"
basename = "flavored gum"
- snack_overlays = 0
- top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/donut
name = "filled donut"
@@ -257,8 +218,6 @@
icon_state = "donutcustom"
baseicon = "donutcustom"
basename = "filled donut"
- snack_overlays = 0
- top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/bar
name = "flavored chocolate bar"
@@ -266,8 +225,6 @@
icon_state = "barcustom"
baseicon = "barcustom"
basename = "flavored chocolate bar"
- snack_overlays = 0
- top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/sucker
name = "flavored sucker"
@@ -275,8 +232,6 @@
icon_state = "suckercustom"
baseicon = "suckercustom"
basename = "flavored sucker"
- snack_overlays = 0
- top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/cash
name = "flavored chocolate cash"
@@ -284,8 +239,6 @@
icon_state = "cashcustom"
baseicon = "cashcustom"
basename = "flavored cash"
- snack_overlays = 0
- top = 0
/obj/item/reagent_containers/food/snacks/customizable/candy/coin
name = "flavored chocolate coin"
@@ -293,8 +246,6 @@
icon_state = "coincustom"
baseicon = "coincustom"
basename = "flavored coin"
- snack_overlays = 0
- top = 0
/obj/item/reagent_containers/food/snacks/customizable/fullycustom // In the event you fuckers find something I forgot to add a customizable food for.
name = "on a plate"
@@ -302,10 +253,8 @@
icon_state = "fullycustom"
baseicon = "fullycustom"
basename = "on a plate"
- snack_overlays = 0
- top = 0
- sandwich_limit = 20
- fullycustom = 1
+ ingredient_limit = 20
+ fullycustom = TRUE
/obj/item/reagent_containers/food/snacks/customizable/soup
name = "soup"
@@ -313,9 +262,7 @@
icon_state = "soup"
baseicon = "soup"
basename = "soup"
- snack_overlays = 0
trash = /obj/item/trash/bowl
- top = 0
tastes = list("soup" = 1)
/obj/item/reagent_containers/food/snacks/customizable/burger
@@ -324,73 +271,106 @@
icon_state = "burger"
baseicon = "burgercustom"
basename = "burger"
- toptype = new /obj/item/reagent_containers/food/snacks/bun()
+ top = TRUE
+ snack_overlays = TRUE
tastes = list("bun" = 4)
+
+/obj/item/reagent_containers/food/snacks/customizable/Destroy()
+ QDEL_LIST(ingredients)
+ return ..()
+
+
+/obj/item/reagent_containers/food/snacks/customizable/examine(mob/user)
+ . = ..()
+ if(LAZYLEN(ingredients))
+ var/whatsinside = pick(ingredients)
+ . += span_notice("You think you can see [whatsinside] in there.")
+
+
/obj/item/reagent_containers/food/snacks/customizable/attackby(obj/item/I, mob/user, params)
- if(contents.len > sandwich_limit)
- to_chat(user, "If you put anything else in or on [src] it's going to make a mess.")
- return
if(!istype(I, /obj/item/reagent_containers/food/snacks))
- to_chat(user, "\The [I] isn't exactly something that you would want to eat.")
- return
- to_chat(user, "You add [I] to [src].")
- if(istype(I, /obj/item/reagent_containers/))
- var/obj/item/reagent_containers/F = I
- F.reagents.trans_to(src, F.reagents.total_volume)
- if(istype(I, /obj/item/reagent_containers/food/snacks/customizable))
- var/obj/item/reagent_containers/food/snacks/customizable/origin = I
- ingredients += origin.ingredients
- foodtype |= origin.foodtype
- user.drop_transfer_item_to_loc(I, src)
- cooktype[basename] = 1
- if(!istype(I, toptype))
- ingredients += I
- updateicon()
+ to_chat(user, span_warning("[I] isn't exactly something that you would want to eat."))
+ return ..()
+
+ if(!user.can_unEquip(I))
+ return ..()
+
+ if(!add_ingredient(I, user))
+ return ..()
+
+
+/**
+ * Tries to add one ingredient and it's ingredients, if any and applicable, to this snack
+ *
+ * Arguments:
+ * * snack - The ingredient that will be added
+ * * user - chef
+ */
+/obj/item/reagent_containers/food/snacks/customizable/proc/add_ingredient(obj/item/reagent_containers/food/snacks/snack, mob/user)
+ . = FALSE
+
+ if(length(ingredients) > ingredient_limit)
+ to_chat(user, span_warning("If you put anything else in or on [src] it's going to make a mess."))
+ return .
+
+ // Fully custom snacks don't add the ingredients. So no need to check
+ var/fullycustom_check = !fullycustom && istype(snack, /obj/item/reagent_containers/food/snacks/customizable)
+ if(fullycustom_check)
+ var/obj/item/reagent_containers/food/snacks/customizable/origin = snack
+ if(length(ingredients) + length(origin.ingredients) > ingredient_limit)
+ to_chat(user, span_warning("Merging [snack] and [src] together is going to make a mess."))
+ return .
+
+ . = TRUE
+
+ to_chat(user, span_notice("You add [snack] to [src]."))
+ user.drop_transfer_item_to_loc(snack, src)
+ snack.reagents.trans_to(src, snack.reagents.total_volume)
+
+ var/list/added_ingredients = list(snack)
+
+ // Only merge when it is not fullycustom. Else it looks weird
+ if(fullycustom_check)
+ var/obj/item/reagent_containers/food/snacks/customizable/origin = snack
+ added_ingredients += origin.ingredients
+ origin.ingredients.Cut()
+ origin.name = initial(origin.name) // Reset the name for the examine text
+
+ cooktype[basename] = TRUE
+ add_ingredients(added_ingredients)
name = newname()
-/obj/item/reagent_containers/food/snacks/customizable/proc/updateicon()
- overlays = 0
- var/i=0
- for(var/obj/item/O in ingredients)
- i++
+/obj/item/reagent_containers/food/snacks/customizable/proc/add_ingredients(list/new_ingredients)
+ cut_overlay(top_image) // Remove the top image so we can change it again
+
+ var/ingredient_num = length(ingredients)
+ ingredients += new_ingredients
+ for(var/obj/item/reagent_containers/food/snacks/food as anything in new_ingredients)
+ ingredient_num++
+ var/image/ingredient_image
if(!fullycustom)
- var/image/I = new(icon, "[baseicon]_filling")
- if(istype(O, /obj/item/reagent_containers/food/snacks))
- var/obj/item/reagent_containers/food/snacks/food = O
- if(!food.filling_color == "#FFFFFF")
- I.color = food.filling_color
- else
- I.color = pick("#FF0000","#0000FF","#008000","#FFFF00")
+ ingredient_image = new(icon, "[baseicon]_filling")
+ if(!food.filling_color == "#FFFFFF")
+ ingredient_image.color = food.filling_color
else
- I.color = pick("#FF0000","#0000FF","#008000","#FFFF00")
+ ingredient_image.color = pick("#FF0000", "#0000FF", "#008000", "#FFFF00")
if(snack_overlays)
- I.pixel_x = pick(list(-1,0,1))
- I.pixel_y = (i*2)+1
- overlays += I
+ ingredient_image.pixel_x = rand(2) - 1
+ ingredient_image.pixel_y = ingredient_num * 2 + 1
else
- var/image/F = new(O.icon, O.icon_state)
- F.pixel_x = pick(list(-1,0,1))
- F.pixel_y = pick(list(-1,0,1))
- overlays += F
- overlays += O.overlays
+ ingredient_image = new(food.icon, food.icon_state)
+ ingredient_image.pixel_x = rand(2) - 1
+ ingredient_image.pixel_y = rand(2) - 1
+ add_overlay(food.overlays)
- if(top)
- var/image/T = new(icon, "[baseicon]_top")
- T.pixel_x = pick(list(-1,0,1))
- T.pixel_y = (ingredients.len * 2)+1
- overlays += T
-
-/obj/item/reagent_containers/food/snacks/customizable/Destroy()
- QDEL_LIST(ingredients)
- return ..()
+ add_overlay(ingredient_image)
-/obj/item/reagent_containers/food/snacks/customizable/examine(mob/user)
- . = ..()
- if(LAZYLEN(ingredients))
- var/whatsinside = pick(ingredients)
- . += " You think you can see [whatsinside] in there."
+ if(top_image)
+ top_image.pixel_x = rand(2) - 1
+ top_image.pixel_y = ingredient_num * 2 + 1
+ add_overlay(top_image)
/obj/item/reagent_containers/food/snacks/customizable/proc/newname()
@@ -473,6 +453,7 @@
sendback = "[pick(list("absurd","colossal","enormous","ridiculous","massive","oversized","cardiac-arresting","pipe-clogging","edible but sickening","sickening","gargantuan","mega","belly-burster","chest-burster"))] [basename]"
return sendback
+
/obj/item/reagent_containers/food/snacks/customizable/proc/sortlist(list/unsorted, highest)
var/sorted[0]
for(var/i = 1, i<= highest, i++)
@@ -480,3 +461,4 @@
if(unsorted[it] == i)
sorted[it] = i
return sorted
+
diff --git a/code/modules/food_and_drinks/food/foods/baked_goods.dm b/code/modules/food_and_drinks/food/foods/baked_goods.dm
index 0ed47a2cfdc..df437c75618 100644
--- a/code/modules/food_and_drinks/food/foods/baked_goods.dm
+++ b/code/modules/food_and_drinks/food/foods/baked_goods.dm
@@ -387,6 +387,81 @@
tastes = list("pie" = 1, "meat" = 1)
foodtype = GRAIN | MEAT
+/obj/item/reagent_containers/food/snacks/meatpie/human
+ list_reagents = list("nutriment" = 9, "protein" = 3)
+ tastes = list("pie" = 2, "salty meat" = 1, "human meat odor" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatpie/vulpkanin
+ list_reagents = list("nutriment" = 7, "protein" = 5)
+ tastes = list("pie" = 2, "salty meat" = 2, "vulpkanin meat odor" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatpie/tajaran
+ list_reagents = list("nutriment" = 9, "protein" = 3)
+ tastes = list("pie" = 2, "salty meat" = 1, "tajaran meat odor" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatpie/unathi
+ list_reagents = list("nutriment" = 8, "protein" = 3, "zessulblood" = 1)
+ tastes = list("pie" = 2, "chiken meat" = 1, "unathi meat odor" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatpie/drask
+ list_reagents = list("nutriment" = 7, "protein" = 3, "ice" = 2)
+ tastes = list("pie" = 2, "salty meat" = 1, "drask meat odor" = 1, "ice" = 2)
+
+/obj/item/reagent_containers/food/snacks/meatpie/grey
+ list_reagents = list("nutriment" = 9, "protein" = 2, "mannitol" = 1)
+ tastes = list("pie" = 2, "salty meat" = 1, "grey meat odor" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatpie/skrell
+ list_reagents = list("nutriment" = 9, "protein" = 2, "water" = 1)
+ tastes = list("pie" = 2, "watery meat" = 1, "skrell meat odor" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatpie/vox
+ list_reagents = list("nutriment" = 8, "protein" = 3, "toxin" = 1)
+ tastes = list("pie" = 2, "chiken meat" = 1, "vox meat odor" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatpie/slime
+ list_reagents = list("sugar" = 4, "slimejelly" = 8)
+ tastes = list("pie" = 2, "sweet jelly" = 1, "slime meat odor" = 1)
+ foodtype = GRAIN | MEAT | SUGAR
+
+/obj/item/reagent_containers/food/snacks/meatpie/wryn
+ list_reagents = list("nutriment" = 8, "protein" = 1, "sugar" = 3)
+ tastes = list("pie" = 2, "sweet meat" = 1, "wryn meat odor" = 1)
+ foodtype = GRAIN | MEAT | SUGAR
+
+/obj/item/reagent_containers/food/snacks/meatpie/kidan
+ list_reagents = list("nutriment" = 8, "protein" = 3, "blood" = 1)
+ tastes = list("pie" = 2, "bug meat odor" = 1, "kidan meat odor" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatpie/nian
+ list_reagents = list("nutriment" = 8, "protein" = 1, "phosphorus" = 3)
+ tastes = list("pie" = 2, "bug meat odor" = 1, "nian meat odor" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatpie/diona
+ list_reagents = list("plantmatter" = 5, "protein" = 3)
+ tastes = list("pie" = 2, "vegetables" = 1, "stik" = 1, "diona odor" = 1)
+ foodtype = GRAIN | VEGETABLES
+
+/obj/item/reagent_containers/food/snacks/meatpie/monkey
+ list_reagents = list("nutriment" = 5, "protein" = 3)
+ tastes = list("pie" = 2, "salty meat" = 1, "monkey meat odor" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatpie/farwa
+ list_reagents = list("nutriment" = 5, "protein" = 1)
+ tastes = list("pie" = 2, "salty meat" = 1, "farwa meat odor" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatpie/wolpin
+ list_reagents = list("nutriment" = 5, "protein" = 3)
+ tastes = list("pie" = 2, "salty meat" = 1, "wolpin meat odor" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatpie/neara
+ list_reagents = list("nutriment" = 5, "protein" = 1, "water" = 2)
+ tastes = list("pie" = 2, "watery meat" = 1, "neara meat odor" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatpie/stok
+ list_reagents = list("nutriment" = 5, "protein" = 2, "zessulblood" = 1)
+ tastes = list("pie" = 2, "salty meat" = 1, "chiken meat" = 1, "stok meat odor" = 1)
+
/obj/item/reagent_containers/food/snacks/tofupie
name = "tofu-pie"
icon_state = "meatpie"
@@ -525,7 +600,7 @@
filling_color = "#FF69B4"
. = ..()
-/obj/item/reagent_containers/food/snacks/donut/update_icon()
+/obj/item/reagent_containers/food/snacks/donut/update_icon_state()
return
/obj/item/reagent_containers/food/snacks/donut/sprinkles
diff --git a/code/modules/food_and_drinks/food/foods/desserts.dm b/code/modules/food_and_drinks/food/foods/desserts.dm
index fc340b29b7f..8d455df01a3 100644
--- a/code/modules/food_and_drinks/food/foods/desserts.dm
+++ b/code/modules/food_and_drinks/food/foods/desserts.dm
@@ -13,11 +13,9 @@
tastes = list("ice cream" = 1)
foodtype = SUGAR | DAIRY
-/obj/item/reagent_containers/food/snacks/icecream/update_icon()
- cut_overlays()
- var/mutable_appearance/filling = mutable_appearance('icons/obj/kitchen.dmi', "icecream_color")
- filling.color = mix_color_from_reagents(reagents.reagent_list)
- add_overlay(filling)
+/obj/item/reagent_containers/food/snacks/icecream/update_overlays()
+ . = ..()
+ . += mutable_appearance('icons/obj/kitchen.dmi', "icecream_color", color = mix_color_from_reagents(reagents.reagent_list))
/obj/item/reagent_containers/food/snacks/icecream/icecreamcone
name = "ice cream cone"
diff --git a/code/modules/food_and_drinks/food/foods/ingredients.dm b/code/modules/food_and_drinks/food/foods/ingredients.dm
index c4434bc7345..38512905943 100644
--- a/code/modules/food_and_drinks/food/foods/ingredients.dm
+++ b/code/modules/food_and_drinks/food/foods/ingredients.dm
@@ -198,7 +198,7 @@
tastes = list("dough" = 1, "sugar" = 1)
foodtype = GRAIN | SUGAR
-/obj/item/reagent_containers/food/snacks/cookiedough/update_icon()
+/obj/item/reagent_containers/food/snacks/cookiedough/update_icon_state()
if(flat)
icon_state = "cookiedough_flat"
name = "flat pastry dough"
@@ -206,7 +206,6 @@
icon_state = "cookiedough"
-
// Dough + rolling pin = flat cookie dough // Flat dough + circular cutter = unbaked cookies
/obj/item/reagent_containers/food/snacks/cookiedough/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/kitchen/rollingpin) && !flat)
diff --git a/code/modules/food_and_drinks/food/foods/meat.dm b/code/modules/food_and_drinks/food/foods/meat.dm
index 39bc68ff36c..328d77f4641 100644
--- a/code/modules/food_and_drinks/food/foods/meat.dm
+++ b/code/modules/food_and_drinks/food/foods/meat.dm
@@ -27,12 +27,191 @@
name = "synthetic meat"
desc = "A synthetic slab of flesh."
-/obj/item/reagent_containers/food/snacks/meat/human
- name = "-meat"
+/obj/item/reagent_containers/food/snacks/meat/humanoid
+ name = "humanoid meat"
var/subjectname = ""
var/subjectjob = null
tastes = list("salty meat" = 1)
+/obj/item/reagent_containers/food/snacks/meat/humanoid/Initialize(mapload, mob/living/carbon/human/victim)
+ . = ..()
+ if(victim)
+ subjectname = victim.real_name
+ subjectjob = victim.job
+ victim.reagents.trans_to(src, (victim.reagents.total_volume) / victim.meatleft)
+ transfer_mob_blood_dna(victim)
+
+ if(!isplasmaman(victim) && !ismachineperson(victim))
+ reagents.add_reagent("nutriment", (victim.nutrition / 15) / initial(victim.meatleft))
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/human
+ name = "human meat"
+ tastes = list("salty meat" = 1)
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/vulpkanin
+ name = "vulpkanin meat"
+ tastes = list("salty meat" = 1)
+ list_reagents = list("protein" = 5)
+ icon_state = "meat_vulp"
+ filling_color = "#850808"
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/tajaran
+ name = "tajaran meat"
+ tastes = list("salty meat" = 1)
+ list_reagents = list("protein" = 3)
+ icon_state = "meat_tajara"
+ filling_color = "#df1919"
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/unathi
+ name = "unathi meat"
+ tastes = list("chiken meat" = 1)
+ list_reagents = list("protein" = 3, "zessulblood" = 2)
+ icon_state = "meat_unathi"
+ filling_color = "#850808"
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/drask
+ name = "drask meat"
+ tastes = list("icy meat" = 1)
+ list_reagents = list("protein" = 3, "ice" = 10)
+ icon_state = "meat_drask"
+ filling_color = "#329983"
+ bitesize = 5
+ var/type1 = "meat_drask"
+ var/type2 = "meat_drask2"
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/drask/New()
+ ..()
+ icon_state = pick(type1, type2)
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/grey
+ name = "grey meat"
+ tastes = list("salty meat" = 1)
+ list_reagents = list("protein" = 2, "mannitol" = 2)
+ icon_state = "meat_grey"
+ filling_color = "#8d17a5"
+ var/type1 = "meat_grey"
+ var/type2 = "meat_grey2"
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/grey/New()
+ ..()
+ icon_state = pick(type1, type2)
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/skrell
+ name = "skrell meat"
+ tastes = list("watery meat" = 1)
+ list_reagents = list("protein" = 3, "water" = 20)
+ icon_state = "meat_skrell"
+ filling_color = "#4d17a5"
+ bitesize = 10
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/vox
+ name = "vox meat"
+ tastes = list("chiken meat" = 1)
+ list_reagents = list("protein" = 3, "toxin" = 1)
+ icon_state = "meat_vox"
+ filling_color = "#0c5ac0"
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/slime
+ name = "slime jelly"
+ tastes = list("sweet jelly" = 1)
+ list_reagents = list("sugar" = 5, "slimejelly" = 10)
+ icon_state = "meat_slime"
+ filling_color = "#11a0cc"
+ bitesize = 5
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/wryn
+ name = "wryn meat"
+ tastes = list("sweet meat" = 1)
+ list_reagents = list("protein" = 1, "sugar" = 5)
+ icon_state = "meat_wryn"
+ filling_color = "#d1be0d"
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/kidan
+ name = "kidan meat"
+ tastes = list("bug meat" = 1)
+ list_reagents = list("protein" = 2, "blood" = 1)
+ icon_state = "meat_kidan"
+ filling_color = "#db9808"
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/nian
+ name = "nian meat"
+ tastes = list("bug meat" = 1)
+ list_reagents = list("protein" = 2, "phosphorus" = 5)
+ icon_state = "meat_nian"
+ filling_color = "#866929"
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/diona
+ name = "diona branch"
+ tastes = list("crunchy green" = 1)
+ list_reagents = list("plantmatter" = 5)
+ icon_state = "branch_diona"
+ filling_color = "#2d6102"
+ foodtype = VEGETABLES
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/nucleation
+ name = "nucleation remains"
+ tastes = list("radioactive dust" = 1)
+ list_reagents = list("radium" = 30)
+ icon_state = "dust_nucleation"
+ filling_color = "#edf5ac"
+ bitesize = 10
+ foodtype = TOXIC
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/plasmaman
+ name = "plasmaman remains"
+ tastes = list("radioactive dust" = 1)
+ list_reagents = list("radium" = 10, "plasma" = 10)
+ icon_state = "dust_plasmaman"
+ filling_color = "#a502c5"
+ bitesize = 10
+ foodtype = TOXIC
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/machine
+ name = "machine remains"
+ tastes = list("radioactive dust" = 1)
+ list_reagents = list("iron" = 3, "aluminum" = 2, "lithium" = 1, "mercury" = 2, "metalicdust" = 1)
+ icon_state = "dust_machine"
+ filling_color = "#403e41"
+ bitesize = 9
+ foodtype = TOXIC
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/monkey
+ name = "monkey meat"
+ tastes = list("salty meat" = 1)
+ list_reagents = list("protein" = 2)
+ filling_color = "#FF1C1C"
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/farwa
+ name = "farwa meat"
+ list_reagents = list("protein" = 1)
+ tastes = list("salty meat" = 1)
+ icon_state = "meat_tajara"
+ filling_color = "#df1919"
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/wolpin
+ name = "wolpin meat"
+ list_reagents = list("protein" = 3)
+ tastes = list("salty meat" = 1)
+ icon_state = "meat_vulp"
+ filling_color = "#850808"
+ bitesize = 2
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/neara
+ name = "neara meat"
+ list_reagents = list("protein" = 2, "water" = 5)
+ tastes = list("watery meat" = 1)
+ icon_state = "meat_skrell"
+ filling_color = "#4d17a5"
+ bitesize = 4
+
+/obj/item/reagent_containers/food/snacks/meat/humanoid/stok
+ name = "stok meat"
+ list_reagents = list("protein" = 2, "zessulblood" = 1)
+ tastes = list("chiken meat" = 1)
+ icon_state = "meat_unathi"
+ filling_color = "#850808"
+ bitesize = 2
+
/obj/item/reagent_containers/food/snacks/meat/slab/meatproduct
name = "meat product"
desc = "A slab of reclaimed and chemically processed meat product."
@@ -43,9 +222,6 @@
icon = 'icons/obj/food/food.dmi'
icon_state = "birdmeat"
-/obj/item/reagent_containers/food/snacks/meat/monkey
- name = "lesser meat"
-
/obj/item/reagent_containers/food/snacks/meat/corgi
name = "corgi meat"
desc = "Tastes like the Head of Personnel's hopes and dreams"
@@ -231,6 +407,119 @@
tastes = list("meat" = 1)
foodtype = MEAT
+/obj/item/reagent_containers/food/snacks/meatsteak/human
+ name = "human meat steak"
+ icon_state = "meatstake_human"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("human meat odor" = 1, "eggplant" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/vulpkanin
+ name = "vulpkanin meat steak"
+ icon_state = "meatstake_vulp"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("vulpkanin meat odor" = 1, "chanterelle" = 1, "lemon" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/tajaran
+ name = "tajaran meat steak"
+ icon_state = "meatstake_tajara"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("tajaran meat odor" = 1, "nettle" = 1, "soda water" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/unathi
+ name = "unathi meat steak"
+ icon_state = "meatstake_unathi"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("unathi meat odor" = 1, "tomato" = 2, "harebell" = 1, "black pepper" = 2, "salt" = 2, "chiken" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/drask
+ name = "drask meat steak"
+ desc = "A piece of cold spicy meat."
+ icon_state = "meatstake_drask"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("drask meat odor" = 1, "garlic" = 1, "chili" = 2, "berries" = 2, "black pepper" = 2)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/grey
+ name = "grey meat steak"
+ icon_state = "meatstake_grey"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("grey meat odor" = 1, "garlic" = 1, "cabbage" = 1, "tomato" = 2, "salt" = 2)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/skrell
+ name = "skrell meat steak"
+ icon_state = "meatstake_skrell"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("skrell meat odor" = 1, "banana" = 1, "tomato" = 1, "black pepper" = 2)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/vox
+ name = "vox meat steak"
+ icon_state = "meatstake_vox"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("vox meat odor" = 1, "garlic" = 1, "herbs" = 1, "chiken" = 1, "sweet potato" = 2)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/slime
+ name = "grilled jelly"
+ desc = "A piece of hot spicy jelly."
+ icon_state = "meatstake_slime"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("slime meat odor" = 1, "garlic" = 1, "sugar" = 1, "herbs" = 1, "lemon" = 1, "ambrosia" = 1, "salt" = 2)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/wryn
+ name = "wryn meat steak"
+ icon_state = "meatstake_wryn"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("wryn meat odor" = 1, "sweetness" = 1, "potato" = 2, "orange" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/kidan
+ name = "kidan meat steak"
+ icon_state = "meatstake_kidan"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("kidan meat odor" = 1, "bug odor" = 1, "herbs" = 2, "olives" = 2, "salt" = 2)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/nian
+ name = "nian meat steak"
+ icon_state = "meatstake_nian"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("nian meat odor" = 1, "bug odor" = 1, "sweetness" = 1, "orange" = 1, "lemon" = 1, "herbs" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/diona
+ name = "grilled vagetables"
+ desc = "Hot spicy asparagus."
+ filling_color = "#548100"
+ icon_state = "meatstake_diona"
+ list_reagents = list("plantmatter" = 4, "vitamins" = 5)
+ tastes = list("diona odor" = 1, "salt" = 2, "herbs" = 1, "garlic" = 1, "lemon" = 1)
+ foodtype = VEGETABLES
+
+/obj/item/reagent_containers/food/snacks/meatsteak/monkey
+ name = "monkey meat steak"
+ icon_state = "meatstake_monkey"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("monkey meat odor" = 1, "salt" = 2, "herbs" = 1, "lemon" = 1, "chili" = 2)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/farwa
+ name = "farwa meat steak"
+ icon_state = "meatstake_farwa"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("farwa meat odor" = 1, "poppy" = 2, "grape" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/wolpin
+ name = "wolpin meat steak"
+ icon_state = "meatstake_wolpin"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("wolpin meat odor" = 1, "potato" = 1, "onion" = 2)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/neara
+ name = "neara meat steak"
+ icon_state = "meatstake_neara"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("neara meat odor" = 1, "lemon" = 1, "soy" = 2, "herbs" = 1)
+
+/obj/item/reagent_containers/food/snacks/meatsteak/stok
+ name = "stok meat steak"
+ icon_state = "meatstake_stok"
+ list_reagents = list("nutriment" = 3, "vitamins" = 3, "protein" = 3)
+ tastes = list("stok meat odor" = 1, "chiken" = 1, "cucumber" = 2, "herbs" = 1, "orange" = 1)
+
/obj/item/reagent_containers/food/snacks/birdsteak
name = "Chicken steak"
desc = "A piece of hot light bird meat."
diff --git a/code/modules/food_and_drinks/food/foods/pizza.dm b/code/modules/food_and_drinks/food/foods/pizza.dm
index d80a1bc4399..0596630c63f 100644
--- a/code/modules/food_and_drinks/food/foods/pizza.dm
+++ b/code/modules/food_and_drinks/food/foods/pizza.dm
@@ -204,64 +204,70 @@
icon = 'icons/obj/food/pizza.dmi'
icon_state = "pizzabox1"
- var/open = 0 // Is the box open?
- var/ismessy = 0 // Fancy mess on the lid
+ var/open = FALSE // Is the box open?
+ var/is_messy = FALSE // Fancy mess on the lid
var/obj/item/reagent_containers/food/snacks/sliceable/pizza/pizza // Content pizza
var/list/boxes = list() // If the boxes are stacked, they come here
- var/boxtag = ""
+ var/box_tag = ""
-/obj/item/pizzabox/update_icon()
- overlays = list()
- // Set appropriate description
+/obj/item/pizzabox/Initialize(mapload)
+ . = ..()
+ update_appearance(UPDATE_DESC|UPDATE_ICON)
+
+
+/obj/item/pizzabox/update_desc(updates = ALL)
+ . = ..()
if(open && pizza)
desc = "A box suited for pizzas. It appears to have a [pizza.name] inside."
- else if(boxes.len > 0)
- desc = "A pile of boxes suited for pizzas. There appears to be [boxes.len + 1] boxes in the pile."
- var/obj/item/pizzabox/topbox = boxes[boxes.len]
- var/toptag = topbox.boxtag
- if(toptag != "")
- desc = "[desc] The box on top has a tag, it reads: '[toptag]'."
+ else if(length(boxes))
+ desc = "A pile of boxes suited for pizzas. There appears to be [length(boxes) + 1] boxes in the pile."
+ var/obj/item/pizzabox/top_box = boxes[length(boxes)]
+ var/top_tag = top_box.box_tag
+ if(top_tag != "")
+ desc = "[desc] The box on top has a tag, it reads: '[top_tag]'."
else
desc = "A box suited for pizzas."
- if(boxtag != "")
- desc = "[desc] The box has a tag, it reads: '[boxtag]'."
+ if(box_tag != "")
+ desc = "[desc] The box has a tag, it reads: '[box_tag]'."
+
- // Icon states and overlays
+/obj/item/pizzabox/update_icon_state()
if(open)
- if(ismessy)
+ if(is_messy)
icon_state = "pizzabox_messy"
else
icon_state = "pizzabox_open"
- if(pizza)
- var/image/pizzaimg = image("food/pizza.dmi", icon_state = pizza.icon_state)
- pizzaimg.pixel_y = -3
- overlays += pizzaimg
+ return
+ icon_state = "pizzabox[length(boxes) + 1]"
+
+/obj/item/pizzabox/update_overlays()
+ . = ..()
+ if(open && pizza)
+ . += image("food/pizza.dmi", icon_state = pizza.icon_state, pixel_y = -3)
return
else
// Stupid code because byondcode sucks
- var/doimgtag = 0
- if(boxes.len > 0)
- var/obj/item/pizzabox/topbox = boxes[boxes.len]
- if(topbox.boxtag != "")
- doimgtag = 1
+ var/set_tag = TRUE
+ if(length(boxes))
+ var/obj/item/pizzabox/top_box = boxes[length(boxes)]
+ if(top_box.box_tag != "")
+ set_tag = TRUE
else
- if(boxtag != "")
- doimgtag = 1
- if(doimgtag)
- var/image/tagimg = image("food/pizza.dmi", icon_state = "pizzabox_tag")
- tagimg.pixel_y = boxes.len * 3
- overlays += tagimg
- icon_state = "pizzabox[boxes.len+1]"
+ if(box_tag != "")
+ set_tag = TRUE
+ if(!open && set_tag)
+ . += image("food/pizza.dmi", icon_state = "pizzabox_tag", pixel_y = length(boxes) * 3)
+
/obj/item/pizzabox/attack_hand(mob/user)
if(open && pizza)
pizza.forceMove_turf()
user.put_in_hands(pizza, ignore_anim = FALSE)
- to_chat(user, "You take the [pizza] out of the [src].")
+ to_chat(user, span_warning("You take the [pizza] out of the [src]."))
pizza = null
- update_icon()
+ update_appearance(UPDATE_DESC|UPDATE_ICON)
return
if(boxes.len > 0)
@@ -272,19 +278,21 @@
boxes -= box
box.forceMove_turf()
user.put_in_hands(box, ignore_anim = FALSE)
- to_chat(user, "You remove the topmost [src] from your hand.")
- box.update_icon()
- update_icon()
+ to_chat(user, span_warning("You remove the topmost [src] from your hand."))
+ box.update_appearance(UPDATE_DESC|UPDATE_ICON)
+ update_appearance(UPDATE_DESC|UPDATE_ICON)
return
..()
+
/obj/item/pizzabox/attack_self(mob/user)
- if(boxes.len > 0)
+ if(length(boxes))
return
open = !open
if(open && pizza)
- ismessy = 1
- update_icon()
+ is_messy = TRUE
+ update_appearance(UPDATE_DESC|UPDATE_ICON)
+
/obj/item/pizzabox/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/pizzabox/))
@@ -295,17 +303,17 @@
boxestoadd += box
for(var/obj/item/pizzabox/i in box.boxes)
boxestoadd += i
- if((boxes.len+1) + boxestoadd.len <= 5)
+ if((length(boxes) + 1) + length(boxestoadd) <= 5)
user.drop_transfer_item_to_loc(box, src)
box.boxes = list() // Clear the box boxes so we don't have boxes inside boxes. - Xzibit
boxes.Add(boxestoadd)
- box.update_icon()
- update_icon()
- to_chat(user, "You put the [box] ontop of the [src]!")
+ box.update_appearance(UPDATE_DESC|UPDATE_ICON)
+ update_appearance(UPDATE_DESC|UPDATE_ICON)
+ to_chat(user, span_warning("You put the [box] ontop of the [src]!"))
else
- to_chat(user, "The stack is too high!")
+ to_chat(user, span_warning("The stack is too high!"))
else
- to_chat(user, "Close the [box] first!")
+ to_chat(user, span_warning("Close the [box] first!"))
return
if(istype(I, /obj/item/reagent_containers/food/snacks/sliceable/pizza/)) // Long ass fucking object name
@@ -313,46 +321,52 @@
user.drop_transfer_item_to_loc(I, src)
pizza = I
- update_icon()
+ update_appearance(UPDATE_DESC|UPDATE_ICON)
- to_chat(user, "You put the [I] in the [src]!")
+ to_chat(user, span_warning("You put the [I] in the [src]!"))
else
- to_chat(user, "You try to push the [I] through the lid but it doesn't work!")
+ to_chat(user, span_warning("You try to push the [I] through the lid but it doesn't work!"))
return
- if(istype(I, /obj/item/pen/))
+ if(is_pen(I))
if(open)
return
var/t = clean_input("Enter what you want to add to the tag:", "Write", null)
var/obj/item/pizzabox/boxtotagto = src
- if(boxes.len > 0)
- boxtotagto = boxes[boxes.len]
- boxtotagto.boxtag = copytext("[boxtotagto.boxtag][t]", 1, 30)
- update_icon()
+ if(length(boxes))
+ boxtotagto = boxes[length(boxes)]
+ boxtotagto.box_tag = copytext("[boxtotagto.box_tag][t]", 1, 30)
+ update_appearance(UPDATE_DESC|UPDATE_ICON)
return
..()
-/obj/item/pizzabox/margherita/New()
- ..()
+
+/obj/item/pizzabox/margherita/Initialize(mapload)
pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/margherita(src)
- boxtag = "margherita deluxe"
+ box_tag = "margherita deluxe"
+ . = ..()
-/obj/item/pizzabox/vegetable/New()
- ..()
+
+/obj/item/pizzabox/vegetable/Initialize(mapload)
pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza(src)
- boxtag = "gourmet vegetable"
+ box_tag = "gourmet vegetable"
+ . = ..()
-/obj/item/pizzabox/mushroom/New()
- ..()
+
+/obj/item/pizzabox/mushroom/Initialize(mapload)
pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/mushroompizza(src)
- boxtag = "mushroom special"
+ box_tag = "mushroom special"
+ . = ..()
-/obj/item/pizzabox/meat/New()
- ..()
+
+/obj/item/pizzabox/meat/Initialize(mapload)
pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/meatpizza(src)
- boxtag = "meatlover's supreme"
+ box_tag = "meatlover's supreme"
+ . = ..()
-/obj/item/pizzabox/hawaiian/New()
- ..()
+
+/obj/item/pizzabox/hawaiian/Initialize(mapload)
pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/hawaiianpizza(src)
- boxtag = "Hawaiian feast"
+ box_tag = "Hawaiian feast"
+ . = ..()
+
diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm
index af7c17d09b3..f215d64c6ba 100644
--- a/code/modules/food_and_drinks/food/snacks.dm
+++ b/code/modules/food_and_drinks/food/snacks.dm
@@ -31,7 +31,7 @@
else
..()
-/obj/item/reagent_containers/food/snacks/update_icon()
+/obj/item/reagent_containers/food/snacks/update_icon_state()
if(!opened)
icon_state = "[initial(icon_state)]-closed"
else
@@ -59,7 +59,7 @@
if(!opened)
opened = TRUE
to_chat(user, "You open the [src].")
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
return ..()
else
return
diff --git a/code/modules/food_and_drinks/kitchen_machinery/cooker.dm b/code/modules/food_and_drinks/kitchen_machinery/cooker.dm
index 1bfc7307ace..68b17236b77 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/cooker.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/cooker.dm
@@ -3,7 +3,7 @@
desc = "You shouldn't be seeing this!"
layer = 2.9
density = 1
- anchored = 1
+ anchored = TRUE
use_power = IDLE_POWER_USE
idle_power_usage = 5
var/on = 0
diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
index 085a2c1cfef..12356d32bd4 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
@@ -5,10 +5,10 @@
icon = 'icons/obj/kitchen.dmi'
icon_state = "grinder"
density = 1
- anchored = 1
+ anchored = TRUE
var/operating = 0 //Is it on?
var/dirty = 0 // Does it need cleaning?
- var/mob/living/occupant // Mob who has been put inside
+ var/mob/living/carbon/human/occupant // Mob who has been put inside
var/locked = 0 //Used to prevent mobs from breaking the feedin anim
var/gib_throw_dir = WEST // Direction to spit meat and gibs in. Defaults to west.
@@ -24,17 +24,11 @@
idle_power_usage = 2
active_power_usage = 500
-/obj/machinery/gibber/suicide_act(mob/living/user)
- if(occupant || locked)
- return FALSE
- user.visible_message("[user] climbs into [src] and turns it on!")
- user.Stun(20 SECONDS)
- user.forceMove(src)
- occupant = user
- update_icon()
- feedinTopanim()
- addtimer(CALLBACK(src, PROC_REF(startgibbing), user), 33)
- return OBLITERATION
+
+/obj/machinery/gibber/Initialize(mapload)
+ . = ..()
+ update_icon(UPDATE_OVERLAYS)
+
/obj/machinery/gibber/Destroy()
if(contents.len)
@@ -47,27 +41,38 @@
/obj/machinery/gibber/RefreshParts() //If you want to make the machine upgradable, this is where you would change any vars basd on its stock parts.
return
-/obj/machinery/gibber/New()
- ..()
- overlays += image('icons/obj/kitchen.dmi', "grjam")
-/obj/machinery/gibber/update_icon()
- overlays.Cut()
+/obj/machinery/gibber/update_overlays()
+ . = ..()
if(dirty)
- overlays += image('icons/obj/kitchen.dmi', "grbloody")
+ . += "grbloody"
if(stat & (NOPOWER|BROKEN))
return
if(!occupant)
- overlays += image('icons/obj/kitchen.dmi', "grjam")
+ . += "grjam"
else if(operating)
- overlays += image('icons/obj/kitchen.dmi', "gruse")
+ . += "gruse"
else
- overlays += image('icons/obj/kitchen.dmi', "gridle")
+ . += "gridle"
+
+
+/obj/machinery/gibber/suicide_act(mob/living/user)
+ if(occupant || locked)
+ return FALSE
+ user.visible_message("[user] climbs into [src] and turns it on!")
+ user.Stun(20 SECONDS)
+ user.forceMove(src)
+ occupant = user
+ update_icon()
+ feedinTopanim()
+ addtimer(CALLBACK(src, PROC_REF(startgibbing), user), 33)
+ return OBLITERATION
+
/obj/machinery/gibber/relaymove(mob/user)
if(locked)
@@ -115,7 +120,7 @@
return
return ..()
-/obj/machinery/gibber/MouseDrop_T(mob/target, mob/user)
+/obj/machinery/gibber/MouseDrop_T(mob/target, mob/user, params)
if(user.incapacitated() || !ishuman(user))
return
@@ -126,7 +131,7 @@
if(targetl.buckled)
return
-
+ . = TRUE
add_fingerprint(user)
move_into_gibber(user,target)
@@ -155,7 +160,7 @@
victim.forceMove(src)
occupant = victim
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
feedinTopanim()
/obj/machinery/gibber/verb/eject()
@@ -182,9 +187,8 @@
occupant.forceMove(get_turf(src))
occupant = null
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
- return
/obj/machinery/gibber/proc/feedinTopanim()
if(!occupant)
@@ -198,7 +202,7 @@
gibberoverlay.overlays += image('icons/obj/kitchen.dmi', "gridle")
var/image/feedee = new
- occupant.dir = 2
+ occupant.dir = SOUTH
feedee.icon = getFlatIcon(occupant, 2) //makes the image a copy of the occupant
var/atom/movable/holder = new //holder for occupant image
@@ -208,14 +212,14 @@
holder.pixel_x = 2
holder.loc = get_turf(src)
holder.layer = MOB_LAYER //simulate mob-like layering
- holder.anchored = 1
+ holder.anchored = TRUE
var/atom/movable/holder2 = new //holder for gibber overlay, used to simulate 3D effect
holder2.name = null
holder2.overlays += gibberoverlay
holder2.loc = get_turf(src)
holder2.layer = MOB_LAYER + 0.1 //3D, it's above the mob, rest of the gibber is behind
- holder2.anchored = 1
+ holder2.anchored = TRUE
animate(holder, pixel_y = 16, time = animation_delay) //animate going down
@@ -250,33 +254,24 @@
use_power(1000)
visible_message("You hear a loud squelchy grinding sound.")
- operating = 1
- update_icon()
+ operating = TRUE
+ update_icon(UPDATE_OVERLAYS)
var/offset = prob(50) ? -2 : 2
animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = gibtime * 5) //start shaking
- var/slab_name = occupant.name
- var/slab_count = 3
- var/slab_type = /obj/item/reagent_containers/food/snacks/meat/human //gibber can only gib humans on paracode, no need to check meat type
- var/slab_nutrition = occupant.nutrition / 15
-
- slab_nutrition /= slab_count
-
- for(var/i=1 to slab_count)
- var/obj/item/reagent_containers/food/snacks/meat/new_meat = new slab_type(src)
- new_meat.name = "[slab_name] [new_meat.name]"
- new_meat.reagents.add_reagent("nutriment", slab_nutrition)
-
-
- if(occupant.reagents)
- occupant.reagents.trans_to(new_meat, round(occupant.reagents.total_volume/slab_count, 1))
+ while(occupant.meatleft > 0)
+ new occupant.dna.species.meat_type(src, occupant)
+ occupant.meatleft--
if(ishuman(occupant))
var/mob/living/carbon/human/H = occupant
var/skinned = H.dna.species.skinned_type
+ if(ismachineperson(H))
+ new /obj/effect/gibspawner/robot(src)
+ else if(!isplasmaman(H) && !isnucleation(H) && !isgolem(H))
+ new /obj/effect/gibspawner(src, H.dna)
if(skinned)
new skinned(src)
- new /obj/effect/decal/cleanable/blood/gibs(src)
if(!UserOverride)
add_attack_logs(user, occupant, "Gibbed in [src]", !!occupant.ckey ? ATKLOG_FEW : ATKLOG_ALL)
@@ -311,8 +306,8 @@
sleep(1)
pixel_x = initial(pixel_x) //return to it's spot after shaking
- operating = 0
- update_icon()
+ operating = FALSE
+ update_icon(UPDATE_OVERLAYS)
@@ -369,19 +364,24 @@
victim_targets.Cut()
/obj/machinery/gibber/autogibber/proc/force_move_into_gibber(mob/living/carbon/human/victim)
- if(!istype(victim)) return 0
+ if(!istype(victim))
+ return FALSE
visible_message("\The [victim.name] gets sucked into \the [src]!")
victim.forceMove(src)
occupant = victim
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
feedinTopanim()
- return 1
+ return TRUE
+
/obj/machinery/gibber/autogibber/proc/ejectclothes(mob/living/carbon/human/H)
- if(!istype(H)) return 0
- if(H != occupant) return 0 //only using H as a shortcut to typecast
+ if(!istype(H))
+ return
+ if(H != occupant)
+ return //only using H as a shortcut to typecast
+
for(var/obj/O in H)
if(istype(O,/obj/item/clothing)) //clothing gets skipped to avoid cleaning out shit
continue
diff --git a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
index 8edc159e269..664746c1993 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm
@@ -4,7 +4,7 @@
/obj/machinery/icemachine
name = "\improper Cream-Master Deluxe"
density = 1
- anchored = 1
+ anchored = TRUE
icon = 'icons/obj/machines/cooking_machines.dmi'
icon_state = "icecream_vat"
use_power = IDLE_POWER_USE
diff --git a/code/modules/food_and_drinks/kitchen_machinery/juicer.dm b/code/modules/food_and_drinks/kitchen_machinery/juicer.dm
index adfed758c15..23a1714f210 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/juicer.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/juicer.dm
@@ -5,7 +5,7 @@
icon_state = "juicer1"
layer = 2.9
density = 1
- anchored = 0
+ anchored = FALSE
use_power = IDLE_POWER_USE
idle_power_usage = 5
active_power_usage = 100
@@ -35,9 +35,8 @@
. = ..()
beaker = new /obj/item/reagent_containers/glass/beaker/large(src)
-/obj/machinery/juicer/update_icon()
+/obj/machinery/juicer/update_icon_state()
icon_state = "juicer"+num2text(!isnull(beaker))
- return
/obj/machinery/juicer/attackby(obj/item/O, mob/user, params)
@@ -52,7 +51,7 @@
add_fingerprint(user)
beaker = O
verbs += /obj/machinery/juicer/verb/detach
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
updateUsrDialog()
return 0
if(!is_type_in_list(O, allowed_items))
@@ -142,7 +141,7 @@
verbs -= /obj/machinery/juicer/verb/detach
beaker.forceMove(loc)
beaker = null
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
/obj/machinery/juicer/proc/get_juice_id(obj/item/reagent_containers/food/snacks/grown/O)
for (var/i in allowed_items)
diff --git a/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm b/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm
index 42f02593cd5..ae91aab6c56 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm
@@ -1,16 +1,18 @@
+#define NO_DIRT 0
+#define MAX_DIRT 100
/obj/machinery/kitchen_machine
name = "Base Kitchen Machine"
desc = "If you are seeing this, a coder/mapper messed up. Please report it."
layer = 2.9
density = 1
- anchored = 1
+ anchored = TRUE
use_power = IDLE_POWER_USE
idle_power_usage = 5
active_power_usage = 100
container_type = OPENCONTAINER
- var/operating = 0 // Is it on?
- var/dirty = 0 // = {0..100} Does it need cleaning?
+ var/operating = FALSE // Is it on?
+ var/dirty = NO_DIRT // = {0..100} Does it need cleaning?
var/broken = 0 // ={0,1,2} How broken is it???
var/efficiency = 0
var/list/cook_verbs = list("Cooking")
@@ -63,21 +65,21 @@
if(operating)
add_fingerprint(user)
return
- if(!broken && dirty < 100)
+ if(!broken && dirty < MAX_DIRT)
if(default_deconstruction_screwdriver(user, open_icon, off_icon, O))
add_fingerprint(user)
return
if(exchange_parts(user, O))
return
- if(!broken && istype(O, /obj/item/wrench))
+ if(!broken && O.tool_behaviour == TOOL_WRENCH)
add_fingerprint(user)
playsound(src, O.usesound, 50, 1)
if(anchored)
- anchored = 0
+ anchored = FALSE
to_chat(user, "\The [src] can now be moved.")
return
else if(!anchored)
- anchored = 1
+ anchored = TRUE
to_chat(user, "\The [src] is now secured.")
return
@@ -85,33 +87,33 @@
return
if(broken > 0)
- if(broken == 2 && istype(O, /obj/item/screwdriver)) // If it's broken and they're using a screwdriver
+ if(broken == 2 && O.tool_behaviour == TOOL_SCREWDRIVER) // If it's broken and they're using a screwdriver
user.visible_message("[user] starts to fix part of [src].", "You start to fix part of [src].")
if(do_after(user, 20 * O.toolspeed * gettoolspeedmod(user), target = src))
add_fingerprint(user)
user.visible_message("[user] fixes part of [src].", "You have fixed part of \the [src].")
broken = 1 // Fix it a bit
- else if(broken == 1 && istype(O, /obj/item/wrench)) // If it's broken and they're doing the wrench
+ else if(broken == 1 && O.tool_behaviour == TOOL_WRENCH) // If it's broken and they're doing the wrench
user.visible_message("[user] starts to fix part of [src].", "You start to fix part of [src].")
if(do_after(user, 20 * O.toolspeed * gettoolspeedmod(user), target = src))
add_fingerprint(user)
user.visible_message("[user] fixes [src].", "You have fixed [src].")
- icon_state = off_icon
broken = 0 // Fix it!
- dirty = 0 // just to be sure
+ dirty = NO_DIRT // just to be sure
+ update_icon(UPDATE_ICON_STATE)
container_type = OPENCONTAINER
else
to_chat(user, "It's broken!")
return 1
- else if(dirty==100) // The machine is all dirty so can't be used!
+ else if(dirty == MAX_DIRT) // The machine is all dirty so can't be used!
if(istype(O, /obj/item/reagent_containers/spray/cleaner) || istype(O, /obj/item/soap)) // If they're trying to clean it then let them
user.visible_message("[user] starts to clean [src].", "You start to clean [src].")
if(do_after(user, 20 * O.toolspeed * gettoolspeedmod(user), target = src))
add_fingerprint(user)
user.visible_message("[user] has cleaned [src].", "You have cleaned [src].")
- dirty = 0 // It's clean!
+ dirty = NO_DIRT // It's clean!
broken = 0 // just to be sure
- icon_state = off_icon
+ update_icon(UPDATE_ICON_STATE)
container_type = OPENCONTAINER
else //Otherwise bad luck!!
to_chat(user, "It's dirty!")
@@ -367,19 +369,19 @@
/obj/machinery/kitchen_machine/proc/start()
visible_message("\The [src] turns on.", "You hear \a [src].")
- operating = 1
- icon_state = on_icon
+ operating = TRUE
+ update_icon(UPDATE_ICON_STATE)
updateUsrDialog()
/obj/machinery/kitchen_machine/proc/abort()
- operating = 0 // Turn it off again aferwards
- icon_state = off_icon
+ operating = FALSE // Turn it off again aferwards
+ update_icon(UPDATE_ICON_STATE)
updateUsrDialog()
/obj/machinery/kitchen_machine/proc/stop()
playsound(loc, 'sound/machines/ding.ogg', 50, 1)
- operating = 0 // Turn it off again aferwards
- icon_state = off_icon
+ operating = FALSE // Turn it off again aferwards
+ update_icon(UPDATE_ICON_STATE)
updateUsrDialog()
/obj/machinery/kitchen_machine/proc/dispose()
@@ -393,24 +395,23 @@
/obj/machinery/kitchen_machine/proc/muck_start()
playsound(loc, 'sound/effects/splat.ogg', 50, 1) // Play a splat sound
- icon_state = dirty_icon // Make it look dirty!!
/obj/machinery/kitchen_machine/proc/muck_finish()
playsound(loc, 'sound/machines/ding.ogg', 50, 1)
visible_message("\The [src] gets covered in muck!")
- dirty = 100 // Make it dirty so it can't be used util cleaned
+ dirty = MAX_DIRT // Make it dirty so it can't be used util cleaned
flags = null //So you can't add condiments
- icon_state = dirty_icon // Make it look dirty too
- operating = 0 // Turn it off again aferwards
+ operating = FALSE // Turn it off again aferwards
+ update_icon(UPDATE_ICON_STATE)
updateUsrDialog()
/obj/machinery/kitchen_machine/proc/broke()
do_sparks(2, 1, src)
- icon_state = broken_icon // Make it look all busted up and shit
visible_message("The [src] breaks!") //Let them know they're stupid
broken = 2 // Make it broken so it can't be used util fixed
flags = null //So you can't add condiments
- operating = 0 // Turn it off again aferwards
+ operating = FALSE // Turn it off again aferwards
+ update_icon(UPDATE_ICON_STATE)
updateUsrDialog()
/obj/machinery/kitchen_machine/proc/fail()
@@ -452,3 +453,18 @@
if("dispose")
dispose()
return
+
+
+/obj/machinery/kitchen_machine/update_icon_state()
+ if(broken)
+ icon_state = broken_icon
+ return
+ if(dirty == MAX_DIRT)
+ icon_state = dirty_icon
+ return
+ icon_state = operating ? on_icon : off_icon
+
+
+#undef NO_DIRT
+#undef MAX_DIRT
+
diff --git a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm
index 80e7b8a65f6..0cc63cf9ef3 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm
@@ -7,7 +7,7 @@ GLOBAL_LIST_EMPTY(monkey_recyclers)
icon_state = "grinder"
layer = 2.9
density = 1
- anchored = 1
+ anchored = TRUE
use_power = IDLE_POWER_USE
idle_power_usage = 5
active_power_usage = 50
@@ -18,14 +18,15 @@ GLOBAL_LIST_EMPTY(monkey_recyclers)
var/obj/item/reagent_containers/food/snacks/monkeycube/cube_type = /obj/item/reagent_containers/food/snacks/monkeycube
var/list/connected = list()
-/obj/machinery/monkey_recycler/New()
- ..()
+/obj/machinery/monkey_recycler/Initialize(mapload)
+ . = ..()
component_parts = list()
component_parts += new /obj/item/circuitboard/monkey_recycler(null)
component_parts += new /obj/item/stock_parts/manipulator(null)
component_parts += new /obj/item/stock_parts/matter_bin(null)
GLOB.monkey_recyclers += src
RefreshParts()
+ locate_camera_console()
/obj/machinery/monkey_recycler/Destroy()
GLOB.monkey_recyclers -= src
@@ -35,6 +36,15 @@ GLOBAL_LIST_EMPTY(monkey_recyclers)
connected.Cut()
return ..()
+/obj/machinery/monkey_recycler/proc/locate_camera_console()
+ if(length(connected))
+ return // we're already connected!
+ for(var/obj/machinery/computer/camera_advanced/xenobio/xeno_camera in GLOB.machines)
+ if(get_area(xeno_camera) == get_area(loc))
+ xeno_camera.connected_recycler = src
+ connected |= xeno_camera
+ break
+
/obj/machinery/monkey_recycler/RefreshParts()
var/req_grind = 5
var/cubes_made = 1
@@ -61,7 +71,7 @@ GLOBAL_LIST_EMPTY(monkey_recyclers)
if(default_deconstruction_crowbar(user, O))
return
- if(istype(O, /obj/item/multitool))
+ if(O.tool_behaviour == TOOL_MULTITOOL)
add_fingerprint(user)
if(!panel_open)
cycle_through++
@@ -97,6 +107,7 @@ GLOBAL_LIST_EMPTY(monkey_recyclers)
add_fingerprint(user)
user.drop_from_active_hand()
qdel(target)
+ target = null //we sleep in this proc, clear reference NOW
to_chat(user, "You stuff the monkey in the machine.")
playsound(loc, 'sound/machines/juicer.ogg', 50, 1)
var/offset = prob(50) ? -2 : 2
diff --git a/code/modules/food_and_drinks/kitchen_machinery/oven.dm b/code/modules/food_and_drinks/kitchen_machinery/oven.dm
index 8645c8f8ab9..8abb6e2cb0e 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/oven.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/oven.dm
@@ -5,16 +5,23 @@
icon_state = "oven_off"
layer = 2.9
density = 1
- anchored = 1
+ anchored = TRUE
use_power = IDLE_POWER_USE
- var/candy = 0
+ var/candy = FALSE
idle_power_usage = 5
var/on = FALSE //Is it making food already?
var/list/food_choices = list()
-/obj/machinery/cooking/New()
- ..()
+
+
+/obj/machinery/cooking/Initialize(mapload)
+ . = ..()
updatefood()
+
+/obj/machinery/cooking/update_icon_state()
+ icon_state = "[candy ? "mixer" : "oven"][on ? "_on" : "_off"]"
+
+
/obj/machinery/cooking/attackby(obj/item/I, mob/user, params)
add_fingerprint(user)
if(on)
@@ -30,21 +37,15 @@
to_chat(user, "You put [F] into [src] for cooking.")
user.drop_transfer_item_to_loc(F, src)
on = TRUE
- if(!candy)
- icon_state = "oven_on"
- else
- icon_state = "mixer_on"
- sleep(100)
+ update_icon(UPDATE_ICON_STATE)
+ sleep(10 SECONDS)
on = FALSE
- if(!candy)
- icon_state = "oven_off"
- else
- icon_state = "mixer_off"
+ update_icon(UPDATE_ICON_STATE)
C.loc = get_turf(src)
C.attackby(F,user, params)
playsound(loc, 'sound/machines/ding.ogg', 50, 1)
updatefood()
- return
+
/obj/machinery/cooking/proc/updatefood()
return
@@ -61,14 +62,14 @@
for(var/U in subtypesof(/obj/item/reagent_containers/food/snacks/customizable/cook))
var/obj/item/reagent_containers/food/snacks/customizable/cook/V = new U
food_choices += V
- return
+
/obj/machinery/cooking/candy
name = "candy machine"
desc = "Get yer box of deep fried deep fried deep fried deep fried cotton candy cereal sandwich cookies here!"
icon = 'icons/obj/machines/cooking_machines.dmi'
icon_state = "mixer_off"
- candy = 1
+ candy = TRUE
/obj/machinery/cooking/candy/updatefood()
for(var/U in food_choices)
@@ -76,4 +77,4 @@
for(var/U in subtypesof(/obj/item/reagent_containers/food/snacks/customizable/candy))
var/obj/item/reagent_containers/food/snacks/customizable/candy/V = new U
food_choices += V
- return
+
diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
index eccffcc2203..35bcf83228f 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
@@ -4,7 +4,7 @@
icon_state = "processor"
layer = 2.9
density = 1
- anchored = 1
+ anchored = TRUE
var/broken = 0
var/processing = 0
diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
index fa29ec2bc5e..fdbfe1e706a 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
@@ -35,6 +35,23 @@
var/datum/wires/smartfridge/wires
/// Typecache of accepted item types, init it in [/obj/machinery/smartfridge/Initialize].
var/list/accepted_items_typecache
+ /// Associative list (/obj/item => /number) representing the items the fridge should initially contain.
+ var/list/starting_items
+ /// Overlay used to visualize contents for default smartfringe.
+ var/contents_overlay = "smartfridge"
+ /// Overlay used to visualize broken status.
+ var/broken_overlay = "smartfridge-broken"
+ /// Additional overlay on top, like hazard symbol for smartfringe in virology.
+ var/icon_addon
+ /// Used to calculate smartfridge fullness while updating overlays.
+ var/fill_level
+ /// Lightmask used for emissive appearance if smartfringe has a light source.
+ var/icon_lightmask = "smartfridge"
+ /// Default light range, when on.
+ var/light_range_on = 1
+ /// Default light power, when on.
+ var/light_power_on = 0.5
+
/obj/machinery/smartfridge/Initialize(mapload)
. = ..()
@@ -54,6 +71,14 @@
wires = new/datum/wires/smartfridge/secure(src)
else
wires = new/datum/wires/smartfridge(src)
+ //Add starting items
+ if(mapload && starting_items)
+ for(var/typekey in starting_items)
+ var/amount = starting_items[typekey] || 1
+ while(amount--)
+ var/obj/item/newitem = new typekey(src)
+ item_quants[newitem.name] += 1
+ update_icon(UPDATE_OVERLAYS)
// Accepted items
accepted_items_typecache = typecacheof(list(
/obj/item/reagent_containers/food/snacks/grown,
@@ -81,38 +106,68 @@
if(shoot_inventory && prob(2))
throw_item()
-/obj/machinery/smartfridge/power_change()
- var/old_stat = stat
+
+/obj/machinery/smartfridge/extinguish_light(force = FALSE)
+ set_light(0)
+ underlays.Cut()
+
+
+/obj/machinery/smartfridge/obj_break(damage_flag)
..()
- if(old_stat != stat)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
-/obj/machinery/smartfridge/update_icon()
- var/prefix = initial(icon_state)
- if(stat & (BROKEN|NOPOWER))
- icon_state = "[prefix]-off"
- else if(visible_contents)
- switch(length(contents))
- if(0)
- icon_state = "[prefix]"
- if(1 to 25)
- icon_state = "[prefix]1"
- if(26 to 75)
- icon_state = "[prefix]2"
- if(76 to INFINITY)
- icon_state = "[prefix]3"
+
+/obj/machinery/smartfridge/power_change()
+ . = ..()
+ if(stat & NOPOWER)
+ set_light(0)
else
- icon_state = "[prefix]"
+ set_light(light_range_on, light_power_on)
+ if(.)
+ update_icon(UPDATE_OVERLAYS)
+
+
+/obj/machinery/smartfridge/update_overlays()
+ . = ..()
+ underlays.Cut()
+ if(panel_open)
+ . += "[icon_state]_panel"
+ if(stat & (BROKEN|NOPOWER))
+ . += "[icon_state]_off"
+ if(icon_addon)
+ . += "[icon_addon]"
+ if(stat & BROKEN)
+ . += "[broken_overlay]"
+ return
+ if(visible_contents)
+ update_fridge_contents()
+ if(fill_level)
+ . += "[contents_overlay][fill_level]"
+ if(icon_addon)
+ . += "[icon_addon]"
+ if(icon_lightmask && light)
+ underlays += emissive_appearance(icon, "[icon_lightmask]_lightmask")
+
+
+/obj/machinery/smartfridge/proc/update_fridge_contents()
+ switch(length(contents))
+ if(0)
+ fill_level = null
+ if(1 to 25)
+ fill_level = 1
+ if(26 to 75)
+ fill_level = 2
+ if(76 to INFINITY)
+ fill_level = 3
+
// Interactions
/obj/machinery/smartfridge/screwdriver_act(mob/living/user, obj/item/I)
. = default_deconstruction_screwdriver(user, icon_state, icon_state, I)
if(!.)
return
+ update_icon(UPDATE_OVERLAYS)
- overlays.Cut()
- if(panel_open)
- overlays += image(icon, "[initial(icon_state)]-panel")
/obj/machinery/smartfridge/wrench_act(mob/living/user, obj/item/I)
. = default_unfasten_wrench(user, I)
@@ -146,7 +201,7 @@
if(load(O, user))
user.visible_message("[user] has added \the [O] to \the [src].", "You add \the [O] to \the [src].")
SStgui.update_uis(src)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
else if(istype(O, /obj/item/storage/bag) || istype(O, /obj/item/storage/box))
var/obj/item/storage/bag/P = O
var/items_loaded = 0
@@ -157,7 +212,7 @@
if(items_loaded)
user.visible_message("[user] loads \the [src] with \the [P].", "You load \the [src] with \the [P].")
SStgui.update_uis(src)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
var/failed = length(P.contents)
if(failed)
to_chat(user, "[failed] item\s [failed == 1 ? "is" : "are"] refused.")
@@ -176,17 +231,17 @@
return ..()
//Drag pill bottle to fridge to empty it into the fridge
-/obj/machinery/smartfridge/MouseDrop_T(obj/over_object, mob/user)
+/obj/machinery/smartfridge/MouseDrop_T(obj/over_object, mob/user, params)
if(!istype(over_object, /obj/item/storage/pill_bottle)) //Only pill bottles, please
return
if(stat & (BROKEN|NOPOWER))
to_chat(user, "\The [src] is unpowered and useless.")
- return
+ return TRUE
var/obj/item/storage/box/pillbottles/P = over_object
if(!length(P.contents))
to_chat(user, "\The [P] is empty.")
- return
+ return TRUE
add_fingerprint(user)
var/items_loaded = 0
@@ -196,10 +251,11 @@
items_loaded++
if(items_loaded)
user.visible_message("[user] empties \the [P] into \the [src].", "You empty \the [P] into \the [src].")
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
var/failed = length(P.contents)
if(failed)
to_chat(user, "[failed] item\s [failed == 1 ? "is" : "are"] refused.")
+ return TRUE
/obj/machinery/smartfridge/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
user.set_machine(src)
@@ -265,14 +321,14 @@
O.forceMove(get_turf(src))
adjust_item_drop_location(O)
user.put_in_hands(O, ignore_anim = FALSE)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
break
else
for(var/obj/O in contents)
if(O.name == K)
O.forceMove(loc)
adjust_item_drop_location(O)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
i--
if(i <= 0)
return TRUE
@@ -340,7 +396,7 @@
if(I.name == O)
I.forceMove(loc)
throw_item = I
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
break
if(!throw_item)
return FALSE
@@ -367,7 +423,10 @@
*/
/obj/machinery/smartfridge/syndie
name = "\improper Suspicious SmartFridge"
- icon_state = "syndi_smartfridge"
+ icon_state = "smartfridge-syndie"
+ contents_overlay = "smartfridge-syndie"
+
+
/**
* # Secure Fridge
*
@@ -396,7 +455,10 @@
/obj/machinery/smartfridge/seeds
name = "\improper Seed Storage"
desc = "When you need seeds fast!"
- icon_state = "smartfridge"
+ icon = 'icons/obj/machines/vending.dmi'
+ icon_state = "seeds_off"
+ base_icon_state = "seeds"
+
/obj/machinery/smartfridge/seeds/Initialize(mapload)
. = ..()
@@ -404,6 +466,28 @@
/obj/item/seeds
))
+
+/obj/machinery/smartfridge/seeds/update_overlays()
+ . = list()
+
+ underlays.Cut()
+
+ if(panel_open)
+ . += "[base_icon_state]_panel"
+
+ if((stat & NOPOWER))
+ if(stat & BROKEN)
+ . += "[base_icon_state]_broken"
+ return
+
+ if(stat & BROKEN)
+ . += "[base_icon_state]_broken"
+ underlays += emissive_appearance(icon, "[base_icon_state]_broken_lightmask")
+ else
+ . += base_icon_state
+ underlays += emissive_appearance(icon, "[base_icon_state]_lightmask")
+
+
/**
* # Refrigerated Medicine Storage
*
@@ -425,7 +509,10 @@
))
/obj/machinery/smartfridge/medbay/syndie
- icon_state = "syndi_smartfridge"
+ icon_state = "smartfridge-syndie"
+ contents_overlay = "smartfridge-syndie"
+
+
/**
* # Slime Extract Storage
*
@@ -439,7 +526,8 @@
/obj/machinery/smartfridge/secure/extract/syndie
name = "\improper Suspicious Slime Extract Storage"
desc = "A refrigerated storage unit for slime extracts"
- icon_state = "syndi_smartfridge"
+ icon_state = "smartfridge-syndie"
+ contents_overlay = "smartfridge-syndie"
/obj/machinery/smartfridge/secure/extract/Initialize(mapload)
. = ..()
@@ -471,7 +559,8 @@
))
/obj/machinery/smartfridge/secure/medbay/syndie
- icon_state = "syndi_smartfridge"
+ icon_state = "smartfridge-syndie"
+ contents_overlay = "smartfridge-syndie"
req_access = list(ACCESS_SYNDICATE)
/**
@@ -485,20 +574,9 @@
icon_state = "smartfridge" //To fix the icon in the map editor.
req_access = list(ACCESS_CHEMISTRY)
- /// Associative list (/obj/item => /number) representing the items the fridge should initially contain.
- var/list/spawn_meds
/obj/machinery/smartfridge/secure/chemistry/Initialize(mapload)
. = ..()
- // Spawn initial chemicals
- if(mapload)
- LAZYINITLIST(spawn_meds)
- for(var/typekey in spawn_meds)
- var/amount = spawn_meds[typekey] || 1
- while(amount--)
- var/obj/item/I = new typekey(src)
- item_quants[I.name] += 1
- update_icon()
// Accepted items
accepted_items_typecache = typecacheof(list(
/obj/item/storage/pill_bottle,
@@ -514,7 +592,7 @@
// I exist!
/obj/machinery/smartfridge/secure/chemistry/preloaded/Initialize(mapload)
- spawn_meds = list(
+ starting_items = list(
/obj/item/reagent_containers/food/pill/epinephrine = 12,
/obj/item/reagent_containers/food/pill/charcoal = 5,
/obj/item/reagent_containers/glass/bottle/epinephrine = 1,
@@ -529,16 +607,17 @@
*/
/obj/machinery/smartfridge/secure/chemistry/preloaded/syndicate
req_access = list(ACCESS_SYNDICATE)
- icon_state = "syndi_smartfridge"
+ icon_state = "smartfridge-syndie"
+ contents_overlay = "smartfridge-syndie"
-/obj/machinery/smartfridge/secure/chemistry/preloaded/syndicate/Initialize(mapload)
- . = ..()
/obj/machinery/smartfridge/secure/medbay/organ
req_access = list(ACCESS_SURGERY)
name = "\improper Secure Refrigerated Organ Storage"
desc = "A refrigerated storage unit for storing organs, limbs, implants and IV bags."
- opacity = 1
+ opacity = TRUE
+ contents_overlay = "smartfridge-organ"
+
/obj/machinery/smartfridge/secure/medbay/organ/Initialize(mapload)
. = ..()
@@ -551,23 +630,6 @@
/obj/item/robot_parts/r_leg,
))
-/// Copy pasting to reuse existing sprites
-/obj/machinery/smartfridge/secure/medbay/organ/update_icon()
- var/prefix = initial(icon_state)
- if(stat & (BROKEN|NOPOWER))
- icon_state = "[prefix]-off"
- else if(visible_contents)
- switch(length(contents))
- if(0)
- icon_state = "[prefix]"
- if(1 to 25)
- icon_state = "[prefix]-organ1"
- if(26 to 75)
- icon_state = "[prefix]-organ2"
- if(76 to INFINITY)
- icon_state = "[prefix]-organ3"
- else
- icon_state = "[prefix]"
/**
* # Disk Compartmentalizer
@@ -577,9 +639,12 @@
/obj/machinery/smartfridge/disks
name = "disk compartmentalizer"
desc = "A machine capable of storing a variety of disks. Denoted by most as the DSU (disk storage unit)."
- icon_state = "disktoaster"
+ icon_state = "disktoaster_off"
+ base_icon_state = "disktoaster"
pass_flags = PASSTABLE
visible_contents = FALSE
+ icon_lightmask = "disktoaster"
+
/obj/machinery/smartfridge/disks/Initialize(mapload)
. = ..()
@@ -587,6 +652,21 @@
/obj/item/disk,
))
+
+/obj/machinery/smartfridge/disks/update_overlays()
+ . = list()
+ underlays.Cut()
+ if(panel_open)
+ . += "[base_icon_state]_panel"
+ if(stat & (BROKEN|NOPOWER))
+ if(stat & BROKEN)
+ . += "[icon_state]_broken"
+ return
+ . += "[base_icon_state]"
+ if(icon_lightmask && light)
+ underlays += emissive_appearance(icon, "[icon_lightmask]_lightmask")
+
+
/**
* # Smart Virus Storage
*
@@ -596,20 +676,11 @@
/obj/machinery/smartfridge/secure/chemistry/virology
name = "\improper Smart Virus Storage"
desc = "A refrigerated storage unit for volatile sample storage."
- icon_state = "smartfridge_virology"
+ icon_state = "smartfridge"
req_access = list(ACCESS_VIROLOGY)
+ icon_addon = "smartfridge-viro-overlay"
/obj/machinery/smartfridge/secure/chemistry/virology/Initialize(mapload)
- spawn_meds = list(
- /obj/item/reagent_containers/syringe/antiviral = 4,
- /obj/item/reagent_containers/glass/bottle/cold = 1,
- /obj/item/reagent_containers/glass/bottle/flu = 1,
- /obj/item/reagent_containers/glass/bottle/sneezing = 1,
- /obj/item/reagent_containers/glass/bottle/cough = 1,
- /obj/item/reagent_containers/glass/bottle/mutagen = 1,
- /obj/item/reagent_containers/glass/bottle/plasma = 1,
- /obj/item/reagent_containers/glass/bottle/diphenhydramine = 1
- )
. = ..()
accepted_items_typecache = typecacheof(list(
/obj/item/reagent_containers/syringe,
@@ -617,22 +688,6 @@
/obj/item/reagent_containers/glass/beaker,
))
-/obj/machinery/smartfridge/secure/chemistry/virology/update_icon()
- var/prefix = initial(icon_state)
- if(stat & (BROKEN|NOPOWER))
- icon_state = "[prefix]-off"
- else if(visible_contents)
- switch(length(contents))
- if(0)
- icon_state = "[prefix]"
- if(1 to 25)
- icon_state = "[prefix]1"
- if(26 to 75)
- icon_state = "[prefix]2"
- if(76 to INFINITY)
- icon_state = "[prefix]3"
- else
- icon_state = "[prefix]"
/**
* # Smart Virus Storage (Preloaded)
@@ -643,7 +698,7 @@
// I exist!
/obj/machinery/smartfridge/secure/chemistry/virology/preloaded/Initialize(mapload)
- spawn_meds = list(
+ starting_items = list(
/obj/item/reagent_containers/syringe/antiviral = 4,
/obj/item/reagent_containers/glass/bottle/cold = 1,
/obj/item/reagent_containers/glass/bottle/flu = 1,
@@ -662,11 +717,10 @@
* A [Smart Virus Storage (Preloaded)][/obj/machinery/smartfridge/secure/chemistry/virology/preloaded] but with exclusive access to Syndicate.
*/
/obj/machinery/smartfridge/secure/chemistry/virology/preloaded/syndicate
- icon_state = "syndi_smartfridge"
+ icon_state = "smartfridge-syndie"
+ contents_overlay = "smartfridge-syndie"
req_access = list(ACCESS_SYNDICATE)
-/obj/machinery/smartfridge/secure/chemistry/virology/preloaded/syndicate/Initialize(mapload)
- . = ..()
/**
* # Drink Showcase
@@ -713,12 +767,13 @@
name = "drying rack"
desc = "A wooden contraption, used to dry plant products, food and leather."
icon = 'icons/obj/hydroponics/equipment.dmi'
- icon_state = "drying_rack"
+ icon_state = "drying-rack_off"
use_power = IDLE_POWER_USE
idle_power_usage = 5
active_power_usage = 200
can_dry = TRUE
visible_contents = FALSE
+ icon_lightmask = null
/obj/machinery/smartfridge/drying_rack/Initialize(mapload)
. = ..()
@@ -738,13 +793,13 @@
/obj/machinery/smartfridge/drying_rack/RefreshParts()
return
-/obj/machinery/smartfridge/drying_rack/power_change()
+/obj/machinery/smartfridge/drying_rack/power_change(forced = FALSE)
if(powered() && anchored)
stat &= ~NOPOWER
else
stat |= NOPOWER
- toggle_drying(TRUE)
- update_icon()
+ toggle_drying(forceoff =TRUE)
+ update_icon(UPDATE_OVERLAYS)
/obj/machinery/smartfridge/drying_rack/screwdriver_act(mob/living/user, obj/item/I)
return
@@ -769,20 +824,21 @@
if("drying")
drying = !drying
use_power = drying ? ACTIVE_POWER_USE : IDLE_POWER_USE
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
-/obj/machinery/smartfridge/drying_rack/update_icon()
- ..()
- overlays.Cut()
+
+/obj/machinery/smartfridge/drying_rack/update_overlays()
+ . = list()
if(drying)
- overlays += "drying_rack_drying"
+ . += "drying-rack_drying"
if(length(contents))
- overlays += "drying_rack_filled"
+ . += "drying-rack_filled"
+
/obj/machinery/smartfridge/drying_rack/process()
- ..()
if(drying && rack_dry())//no need to update unless something got dried
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
+
/obj/machinery/smartfridge/drying_rack/accept_check(obj/item/O)
. = ..()
@@ -798,14 +854,14 @@
* Arguments:
* * forceoff - Whether to force turn off the drying rack.
*/
-/obj/machinery/smartfridge/drying_rack/proc/toggle_drying(forceoff)
+/obj/machinery/smartfridge/drying_rack/proc/toggle_drying(forceoff = FALSE)
if(drying || forceoff)
drying = FALSE
use_power = IDLE_POWER_USE
else
drying = TRUE
use_power = ACTIVE_POWER_USE
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
/**
* Called in [/obj/machinery/smartfridge/drying_rack/process] to dry the contents.
diff --git a/code/modules/food_and_drinks/recipes/recipes_grill.dm b/code/modules/food_and_drinks/recipes/recipes_grill.dm
index 88e174abd5c..cbfb182717d 100644
--- a/code/modules/food_and_drinks/recipes/recipes_grill.dm
+++ b/code/modules/food_and_drinks/recipes/recipes_grill.dm
@@ -57,6 +57,169 @@
)
result = /obj/item/reagent_containers/food/snacks/meatsteak
+/datum/recipe/grill/meatsteak_human
+ reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "herbsmix" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/human,
+ /obj/item/reagent_containers/food/snacks/grown/eggplant
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/human
+
+/datum/recipe/grill/meatsteak_vulpkanin
+ reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "lemonjuice" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/vulpkanin,
+ /obj/item/reagent_containers/food/snacks/grown/mushroom/chanterelle,
+ /obj/item/reagent_containers/food/snacks/grown/mushroom/chanterelle
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/vulpkanin
+
+/datum/recipe/grill/meatsteak_tajaran
+ reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "sodawater" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/tajaran,
+ /obj/item/grown/nettle/basic
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/tajaran
+
+/datum/recipe/grill/meatsteak_unathi
+ reagents = list("sodiumchloride" = 5, "blackpepper" = 5, "herbsmix" = 5, "tomatojuice" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/unathi,
+ /obj/item/reagent_containers/food/snacks/grown/harebell
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/unathi
+
+/datum/recipe/grill/meatsteak_drask
+ reagents = list("sodiumchloride" = 5, "blackpepper" = 5, "capsaicin" = 10, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/drask,
+ /obj/item/reagent_containers/food/snacks/grown/garlic,
+ /obj/item/reagent_containers/food/snacks/grown/chili,
+ /obj/item/reagent_containers/food/snacks/grown/berries,
+ /obj/item/reagent_containers/food/snacks/grown/berries,
+ /obj/item/reagent_containers/food/snacks/grown/berries
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/drask
+
+/datum/recipe/grill/meatsteak_grey
+ reagents = list("sodiumchloride" = 5, "blackpepper" = 1, "tomatojuice" = 10, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/grey,
+ /obj/item/reagent_containers/food/snacks/grown/garlic,
+ /obj/item/reagent_containers/food/snacks/grown/cabbage
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/grey
+
+/datum/recipe/grill/meatsteak_skrell
+ reagents = list("sodiumchloride" = 1, "blackpepper" = 5, "tomatojuice" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/skrell,
+ /obj/item/reagent_containers/food/snacks/grown/banana
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/skrell
+
+/datum/recipe/grill/meatsteak_vox
+ reagents = list("sodiumchloride" = 5, "blackpepper" = 5, "herbsmix" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/vox,
+ /obj/item/reagent_containers/food/snacks/grown/garlic,
+ /obj/item/reagent_containers/food/snacks/grown/potato/sweet,
+ /obj/item/reagent_containers/food/snacks/grown/potato/sweet
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/vox
+
+/datum/recipe/grill/meatsteak_slime
+ reagents = list("sodiumchloride" = 10, "sugar" = 5, "herbsmix" = 5, "lemonjuice" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/slime,
+ /obj/item/reagent_containers/food/snacks/grown/ambrosia/vulgaris
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/slime
+
+/datum/recipe/grill/meatsteak_wryn
+ reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "orangejuice" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/wryn,
+ /obj/item/reagent_containers/food/snacks/grown/potato,
+ /obj/item/reagent_containers/food/snacks/grown/potato
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/wryn
+
+/datum/recipe/grill/meatsteak_kidan
+ reagents = list("sodiumchloride" = 5, "blackpepper" = 5, "herbsmix" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/kidan,
+ /obj/item/reagent_containers/food/snacks/grown/garlic,
+ /obj/item/reagent_containers/food/snacks/grown/olive,
+ /obj/item/reagent_containers/food/snacks/grown/olive,
+ /obj/item/reagent_containers/food/snacks/grown/olive
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/kidan
+
+/datum/recipe/grill/meatsteak_nian
+ reagents = list("sodiumchloride" = 5, "sugar" = 5, "herbsmix" = 5, "lemonjuice" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/nian,
+ /obj/item/reagent_containers/food/snacks/grown/citrus/orange
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/nian
+
+/datum/recipe/grill/meatsteak_diona
+ reagents = list("sodiumchloride" = 5, "blackpepper" = 1, "herbsmix" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/diona,
+ /obj/item/reagent_containers/food/snacks/grown/garlic,
+ /obj/item/reagent_containers/food/snacks/grown/citrus/lemon
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/diona
+
+/datum/recipe/grill/meatsteak_monkey
+ reagents = list("sodiumchloride" = 5, "blackpepper" = 1, "herbsmix" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/monkey,
+ /obj/item/reagent_containers/food/snacks/grown/chili,
+ /obj/item/reagent_containers/food/snacks/grown/chili,
+ /obj/item/reagent_containers/food/snacks/grown/citrus/lemon
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/monkey
+
+/datum/recipe/grill/meatsteak_farwa
+ reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "grapejuice" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/farwa,
+ /obj/item/reagent_containers/food/snacks/grown/poppy,
+ /obj/item/reagent_containers/food/snacks/grown/poppy
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/farwa
+
+/datum/recipe/grill/meatsteak_wolpin
+ reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "potato" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/wolpin,
+ /obj/item/reagent_containers/food/snacks/onion_slice/red,
+ /obj/item/reagent_containers/food/snacks/onion_slice/red
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/wolpin
+
+/datum/recipe/grill/meatsteak_neara
+ reagents = list("sodiumchloride" = 2, "blackpepper" = 2, "lemonjuice" = 5, "herbsmix" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/neara,
+ /obj/item/reagent_containers/food/snacks/grown/soybeans,
+ /obj/item/reagent_containers/food/snacks/grown/soybeans
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/neara
+
+/datum/recipe/grill/meatsteak_stok
+ reagents = list("sodiumchloride" = 2, "blackpepper" = 2, "orangejuice" = 5, "herbsmix" = 5, "oliveoil" = 5)
+ items = list(
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/stok,
+ /obj/item/reagent_containers/food/snacks/cucumberslice,
+ /obj/item/reagent_containers/food/snacks/cucumberslice
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatsteak/stok
+
/datum/recipe/grill/waffles
reagents = list("sugar" = 10)
items = list(
@@ -126,16 +289,16 @@
/datum/recipe/grill/human/kabob
items = list(
/obj/item/stack/rods,
- /obj/item/reagent_containers/food/snacks/meat/human,
- /obj/item/reagent_containers/food/snacks/meat/human,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/human,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/human,
)
result = /obj/item/reagent_containers/food/snacks/kabob
/datum/recipe/grill/monkeykabob
items = list(
/obj/item/stack/rods,
- /obj/item/reagent_containers/food/snacks/meat/monkey,
- /obj/item/reagent_containers/food/snacks/meat/monkey,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/monkey,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/monkey,
)
result = /obj/item/reagent_containers/food/snacks/monkeykabob
diff --git a/code/modules/food_and_drinks/recipes/recipes_microwave.dm b/code/modules/food_and_drinks/recipes/recipes_microwave.dm
index 9fb68cf7f84..7d5181fd3f1 100644
--- a/code/modules/food_and_drinks/recipes/recipes_microwave.dm
+++ b/code/modules/food_and_drinks/recipes/recipes_microwave.dm
@@ -51,7 +51,7 @@
/datum/recipe/microwave/human/burger
items = list(
- /obj/item/reagent_containers/food/snacks/meat/human,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/human,
/obj/item/reagent_containers/food/snacks/bun
)
result = /obj/item/reagent_containers/food/snacks/human_burger
@@ -176,8 +176,8 @@
/datum/recipe/microwave/soylentgreen
reagents = list("flour" = 10)
items = list(
- /obj/item/reagent_containers/food/snacks/meat/human,
- /obj/item/reagent_containers/food/snacks/meat/human,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/human,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/human,
)
result = /obj/item/reagent_containers/food/snacks/soylentgreen
diff --git a/code/modules/food_and_drinks/recipes/recipes_oven.dm b/code/modules/food_and_drinks/recipes/recipes_oven.dm
index 62d4e29dd14..44378766fd4 100644
--- a/code/modules/food_and_drinks/recipes/recipes_oven.dm
+++ b/code/modules/food_and_drinks/recipes/recipes_oven.dm
@@ -105,6 +105,151 @@
)
result = /obj/item/reagent_containers/food/snacks/meatpie
+/datum/recipe/oven/meatpie_human
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/human,
+ /obj/item/organ/internal/liver,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/human
+
+/datum/recipe/oven/meatpie_vulpkanin
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/vulpkanin,
+ /obj/item/organ/internal/liver/vulpkanin,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/vulpkanin
+
+/datum/recipe/oven/meatpie_tajaran
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/tajaran,
+ /obj/item/organ/internal/liver/tajaran,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/tajaran
+
+/datum/recipe/oven/meatpie_unathi
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/unathi,
+ /obj/item/organ/internal/liver/unathi,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/unathi
+
+/datum/recipe/oven/meatpie_drask
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/drask,
+ /obj/item/organ/internal/liver/drask,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/drask
+
+/datum/recipe/oven/meatpie_grey
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/grey,
+ /obj/item/organ/internal/liver/grey,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/grey
+
+/datum/recipe/oven/meatpie_skrell
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/skrell,
+ /obj/item/organ/internal/liver/skrell,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/skrell
+
+/datum/recipe/oven/meatpie_vox
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/vox,
+ /obj/item/organ/internal/liver/vox,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/vox
+
+/datum/recipe/oven/meatpie_slime
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/slime,
+ /obj/item/organ/internal/heart/slime,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/slime
+
+/datum/recipe/oven/meatpie_wryn
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/wryn,
+ /obj/item/organ/internal/wryn/glands,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/wryn
+
+/datum/recipe/oven/meatpie_kidan
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/kidan,
+ /obj/item/organ/internal/liver/kidan,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/kidan
+
+/datum/recipe/oven/meatpie_nian
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/nian,
+ /obj/item/organ/internal/liver/nian,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/nian
+
+/datum/recipe/oven/meatpie_diona
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/diona,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/diona,
+ /obj/item/organ/internal/liver/diona,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/diona
+
+/datum/recipe/oven/meatpie_monkey
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/monkey,
+ /obj/item/organ/internal/heart,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/monkey
+
+/datum/recipe/oven/meatpie_farwa
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/farwa,
+ /obj/item/organ/internal/heart/tajaran,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/farwa
+
+/datum/recipe/oven/meatpie_wolpin
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/wolpin,
+ /obj/item/organ/internal/heart/vulpkanin,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/wolpin
+
+/datum/recipe/oven/meatpie_neara
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/neara,
+ /obj/item/organ/internal/heart/skrell,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/neara
+
+/datum/recipe/oven/meatpie_stok
+ items = list(
+ /obj/item/reagent_containers/food/snacks/sliceable/flatdough,
+ /obj/item/reagent_containers/food/snacks/meat/humanoid/stok,
+ /obj/item/organ/internal/heart/unathi,
+ )
+ result = /obj/item/reagent_containers/food/snacks/meatpie/stok
+
/datum/recipe/oven/tofupie
items = list(
/obj/item/reagent_containers/food/snacks/sliceable/flatdough,
diff --git a/code/modules/holiday/new_year.dm b/code/modules/holiday/new_year.dm
index 0e78e181618..c747cbe348f 100644
--- a/code/modules/holiday/new_year.dm
+++ b/code/modules/holiday/new_year.dm
@@ -25,7 +25,7 @@
to_chat(user, span_notice("You [anchored ? "un" : ""]wrenched [src]"))
/obj/structure/garland/attackby(obj/item/P, mob/user, params)
- if(istype(P, /obj/item/wirecutters) || istype(P, /obj/item/wrench))
+ if(P.tool_behaviour == TOOL_WIRECUTTER || P.tool_behaviour == TOOL_WRENCH)
return
return ..()
diff --git a/code/modules/hydroponics/beekeeping/honeycomb.dm b/code/modules/hydroponics/beekeeping/honeycomb.dm
index 0afdf0822a4..2bbd51e0600 100644
--- a/code/modules/hydroponics/beekeeping/honeycomb.dm
+++ b/code/modules/hydroponics/beekeeping/honeycomb.dm
@@ -16,6 +16,7 @@
..()
pixel_x = rand(8,-8)
pixel_y = rand(8,-8)
+ update_icon(UPDATE_OVERLAYS)
/obj/item/reagent_containers/honeycomb/set_APTFT()
set hidden = TRUE
@@ -23,15 +24,16 @@
/obj/item/reagent_containers/honeycomb/empty()
set hidden = TRUE
-/obj/item/reagent_containers/honeycomb/update_icon()
- overlays.Cut()
+
+/obj/item/reagent_containers/honeycomb/update_overlays()
+ . = ..()
var/image/honey
if(honey_color)
honey = image(icon = 'icons/obj/hydroponics/harvest.dmi', icon_state = "greyscale_honey")
honey.color = honey_color
else
honey = image(icon = 'icons/obj/hydroponics/harvest.dmi', icon_state = "honey")
- overlays += honey
+ . += honey
/obj/item/reagent_containers/honeycomb/proc/set_reagent(reagent)
@@ -42,4 +44,5 @@
reagents.add_reagent(R.id,5)
else
honey_color = ""
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
+
diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm
index d6da06ceecf..b5c70900d02 100644
--- a/code/modules/hydroponics/biogenerator.dm
+++ b/code/modules/hydroponics/biogenerator.dm
@@ -57,7 +57,7 @@
if(A != container)
return
container = null
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
SStgui.update_uis(src)
/obj/machinery/biogenerator/RefreshParts()
@@ -75,7 +75,7 @@
if(effeciency_prev != efficiency)
update_ui_product_list() // We have have a higher `efficiency` now, and need to re-calc the product costs.
-/obj/machinery/biogenerator/update_icon()
+/obj/machinery/biogenerator/update_icon_state()
if(panel_open)
icon_state = "biogen-empty-o"
else if(!container)
@@ -118,7 +118,7 @@
add_fingerprint(user)
container = O
to_chat(user, "You add the [container] to [src].")
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
SStgui.update_uis(src)
return TRUE
@@ -265,7 +265,7 @@
processing = TRUE
SStgui.update_uis(src)
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
var/plants_processed = length(stored_plants)
for(var/obj/plant as anything in stored_plants)
@@ -281,7 +281,7 @@
/obj/machinery/biogenerator/proc/end_processing()
processing = FALSE
SStgui.update_uis(src)
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
/**
* Ejects the biogenerator's stored plants
@@ -351,7 +351,7 @@
biomass -= (D.materials[MAT_BIOMASS] / efficiency) * amount
SStgui.update_uis(src)
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
/**
* Detach the `container` from the biogenerator.
@@ -361,6 +361,6 @@
return
container.forceMove(get_turf(src))
container = null
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
#undef BASE_MAX_STORABLE_PLANTS
diff --git a/code/modules/hydroponics/fermenting_barrel.dm b/code/modules/hydroponics/fermenting_barrel.dm
index 019557365b6..32c7329c4e2 100644
--- a/code/modules/hydroponics/fermenting_barrel.dm
+++ b/code/modules/hydroponics/fermenting_barrel.dm
@@ -63,7 +63,7 @@
else
container_type = DRAINABLE | AMOUNT_VISIBLE
to_chat(user, "You close [src], letting you draw from its tap.")
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
/obj/structure/fermenting_barrel/crowbar_act(mob/living/user, obj/item/I)
. = TRUE
@@ -85,11 +85,10 @@
new /obj/item/stack/sheet/wood(drop_location(), mat_drop)
..()
-/obj/structure/fermenting_barrel/update_icon()
- if(open)
- icon_state = "barrel_open"
- else
- icon_state = "barrel"
+
+/obj/structure/fermenting_barrel/update_icon_state()
+ icon_state = "barrel[open ? "_open" : ""]"
+
/datum/crafting_recipe/fermenting_barrel
name = "Wooden Barrel"
diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm
index e30b335fb64..6cc22b60605 100644
--- a/code/modules/hydroponics/gene_modder.dm
+++ b/code/modules/hydroponics/gene_modder.dm
@@ -5,7 +5,7 @@
pass_flags = PASSTABLE
icon_state = "dnamod"
density = 1
- anchored = 1
+ anchored = TRUE
var/obj/item/seeds/seed
var/obj/item/disk/plantgene/disk
@@ -82,22 +82,26 @@
min_wchance = 0
min_wrate = 0
-/obj/machinery/plantgenes/update_icon()
- ..()
- overlays.Cut()
+
+/obj/machinery/plantgenes/update_icon_state()
if((stat & (BROKEN|NOPOWER)))
icon_state = "dnamod-off"
else
icon_state = "dnamod"
+
+
+/obj/machinery/plantgenes/update_overlays()
+ . = ..()
if(seed)
- overlays += "dnamod-dna"
+ . += "dnamod-dna"
if(panel_open)
- overlays += "dnamod-open"
+ . += "dnamod-open"
+
/obj/machinery/plantgenes/attackby(obj/item/I, mob/user, params)
if(default_deconstruction_screwdriver(user, "dnamod", "dnamod", I))
add_fingerprint(user)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
return
if(exchange_parts(user, I))
return
@@ -303,7 +307,7 @@
seed.verb_pickup()
seed = null
update_genes()
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
else
var/obj/item/I = usr.get_active_hand()
if(istype(I, /obj/item/seeds))
@@ -311,7 +315,6 @@
return
insert_seed(I)
to_chat(usr, "You add [I] to the machine.")
- update_icon()
else if(href_list["eject_disk"] && !operation)
if(disk)
disk.forceMove(loc)
@@ -378,7 +381,7 @@
if(!HAS_TRAIT(disk, TRAIT_CMAGGED))
disk.update_name()
QDEL_NULL(seed)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
if("replace")
if(disk && disk.gene && istype(disk.gene, G.type) && istype(G, /datum/plant_gene/core))
seed.genes -= G
@@ -420,7 +423,7 @@
S.forceMove(src)
seed = S
update_genes()
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
/obj/machinery/plantgenes/proc/update_genes()
core_genes = list()
@@ -467,7 +470,7 @@
/obj/item/disk/plantgene/New()
..()
- overlays += "datadisk_gene"
+ update_icon(UPDATE_OVERLAYS)
pixel_x = rand(-5, 5)
pixel_y = rand(-5, 5)
@@ -493,44 +496,50 @@
if(do_after(user, 50, target = src))
user.visible_message("[user] cleans the ooze off [src].", "You clean the ooze off [src].")
REMOVE_TRAIT(src, TRAIT_CMAGGED, CMAGGED)
- update_name()
- update_desc()
- update_icon_state()
+ update_appearance(UPDATE_NAME|UPDATE_DESC|UPDATE_ICON)
..()
if(istype(W, /obj/item/pen) && !HAS_TRAIT(src, TRAIT_CMAGGED))
rename_interactive(user, W)
-/obj/item/disk/plantgene/update_desc()
+
+/obj/item/disk/plantgene/update_name(updates = ALL)
. = ..()
if(HAS_TRAIT(src, TRAIT_CMAGGED))
- desc = "Better keep this safe."
+ name = "nuclear authentication disk"
+ return
+ if(gene)
+ name = "[gene.get_name()] (Plant Data Disk)"
else
- desc = initial(desc)
+ name = initial(name)
-/obj/item/disk/plantgene/update_name()
+
+/obj/item/disk/plantgene/update_desc(updates = ALL)
. = ..()
if(HAS_TRAIT(src, TRAIT_CMAGGED))
- name = "nuclear authentication disk"
- else
- if(gene)
- name = "[gene.get_name()] (Plant Data Disk)"
- else
- name = initial(name)
+ desc = "Better keep this safe."
+ return
+ desc = initial(desc)
+
/obj/item/disk/plantgene/update_icon_state()
if(HAS_TRAIT(src, TRAIT_CMAGGED))
icon_state = "nucleardisk"
- overlays -= "datadisk_gene"
- else
- icon_state = initial(icon_state)
- overlays += "datadisk_gene"
+ return
+ icon_state = initial(icon_state)
+
+
+/obj/item/disk/plantgene/update_overlays()
+ . = ..()
+ if(HAS_TRAIT(src, TRAIT_CMAGGED))
+ return
+ . += "datadisk_gene"
+
/obj/item/disk/plantgene/cmag_act()
. = ..()
ADD_TRAIT(src, TRAIT_CMAGGED, CMAGGED)
- update_name()
- update_desc()
- update_icon_state()
+ update_appearance(UPDATE_NAME|UPDATE_DESC|UPDATE_ICON)
+
/obj/item/disk/plantgene/attack_self(mob/user)
if(HAS_TRAIT(src, TRAIT_CMAGGED))
diff --git a/code/modules/hydroponics/grown/cereals.dm b/code/modules/hydroponics/grown/cereals.dm
index e2cb65c56cc..bcd4eb7232f 100644
--- a/code/modules/hydroponics/grown/cereals.dm
+++ b/code/modules/hydroponics/grown/cereals.dm
@@ -10,7 +10,7 @@
yield = 4
potency = 15
icon_dead = "wheat-dead"
- mutatelist = list(/obj/item/seeds/wheat/oat, /obj/item/seeds/wheat/meat)
+ mutatelist = list(/obj/item/seeds/wheat/oat)
reagents_add = list("plantmatter" = 0.04)
/obj/item/reagent_containers/food/snacks/grown/wheat
diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm
index fb3fdec085e..afb48e9720b 100644
--- a/code/modules/hydroponics/grown/towercap.dm
+++ b/code/modules/hydroponics/grown/towercap.dm
@@ -156,13 +156,18 @@
density = FALSE
anchored = TRUE
buckle_lying = FALSE
- var/burning = 0
+ var/burning = FALSE
var/lighter // Who lit the fucking thing
var/fire_stack_strength = 5
/obj/structure/bonfire/dense
density = TRUE
+
+/obj/structure/bonfire/update_icon_state()
+ icon_state = "bonfire[burning ? "_on_fire" : ""]"
+
+
/obj/structure/bonfire/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/stack/rods) && !can_buckle)
add_fingerprint(user)
@@ -202,8 +207,8 @@
/obj/structure/bonfire/proc/StartBurning()
if(!burning && CheckOxygen())
- icon_state = "bonfire_on_fire"
- burning = 1
+ burning = TRUE
+ update_icon(UPDATE_ICON_STATE)
set_light(6, l_color = "#ED9200")
Burn()
START_PROCESSING(SSobj, src)
@@ -241,8 +246,8 @@
/obj/structure/bonfire/extinguish()
if(burning)
- icon_state = "bonfire"
- burning = 0
+ burning = FALSE
+ update_icon(UPDATE_ICON_STATE)
set_light(0)
STOP_PROCESSING(SSobj, src)
diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm
index e5d064edf91..fdf2940df3d 100644
--- a/code/modules/hydroponics/hydroitemdefines.dm
+++ b/code/modules/hydroponics/hydroitemdefines.dm
@@ -184,8 +184,6 @@
extend = !extend
if(extend)
to_chat(user, "With a flick of your wrist, you extend the scythe. It's reaping time!")
- icon_state = "tscythe1"
- item_state = "scythe0" //use the normal scythe in-hands
slot_flags = SLOT_BACK //won't fit on belt, but can be worn on belt when extended
w_class = WEIGHT_CLASS_BULKY //won't fit in backpacks while extended
force = 15 //slightly better than normal scythe damage
@@ -195,8 +193,6 @@
playsound(src.loc, 'sound/weapons/blade_unsheath.ogg', 50, 1) //Sound credit to Qat of Freesound.org
else
to_chat(user, "You collapse the scythe, folding it away for easy storage.")
- icon_state = "tscythe0"
- item_state = null //no sprite for folded version, like a tele-baton
slot_flags = SLOT_BELT //can be worn on belt again, but no longer makes sense to wear on the back
w_class = WEIGHT_CLASS_SMALL
force = 3
@@ -205,13 +201,19 @@
//Collapse sound (blade sheath)
playsound(src.loc, 'sound/weapons/blade_sheath.ogg', 50, 1) //Sound credit to Q.K. of Freesound.org
sharp = extend
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- H.update_inv_l_hand()
- H.update_inv_r_hand()
+ update_icon(UPDATE_ICON_STATE)
+ update_equipped_item()
add_fingerprint(user)
+/obj/item/scythe/tele/update_icon_state()
+ if(extend)
+ icon_state = "tscythe1"
+ item_state = "scythe0" //use the normal scythe in-hands
+ else
+ icon_state = "tscythe0"
+ item_state = null //no sprite for folded version, like a tele-baton
+
// *************************************
// Nutrient defines for hydroponics
@@ -242,7 +244,7 @@
/obj/item/reagent_containers/glass/bottle/nutrient/on_reagent_change()
. = ..()
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
if(reagents.total_volume)
hitsound = 'sound/weapons/jug_filled_impact.ogg'
mob_throw_hit_sound = 'sound/weapons/jug_filled_impact.ogg'
@@ -250,9 +252,9 @@
hitsound = 'sound/weapons/jug_empty_impact.ogg'
mob_throw_hit_sound = 'sound/weapons/jug_empty_impact.ogg'
-/obj/item/reagent_containers/glass/bottle/nutrient/update_icon()
- cut_overlays()
+/obj/item/reagent_containers/glass/bottle/nutrient/update_overlays()
+ . = ..()
if(reagents.total_volume)
var/image/filling = image('icons/obj/reagentfillings.dmi', src, "plastic_jug10")
@@ -274,10 +276,10 @@
filling.icon_state = "plastic_jug100"
filling.icon += mix_color_from_reagents(reagents.reagent_list)
- add_overlay(filling)
+ . += filling
if(!is_open_container())
- add_overlay("lid_jug")
+ . += "lid_jug"
/obj/item/reagent_containers/glass/bottle/nutrient/ez
diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm
index be88cebe3ce..629fbd9d678 100644
--- a/code/modules/hydroponics/hydroponics.dm
+++ b/code/modules/hydroponics/hydroponics.dm
@@ -6,7 +6,7 @@
icon = 'icons/obj/hydroponics/equipment.dmi'
icon_state = "hydrotray"
density = 1
- anchored = 1
+ anchored = TRUE
pixel_y = 8
var/waterlevel = 100 //The amount of water in the tray (max 100)
var/maxwater = 100 //The maximum amount of water in the tray
@@ -27,7 +27,7 @@
var/obj/item/seeds/myseed = null //The currently planted seed
var/rating = 1
var/wrenchable = 1
- var/lid_state = 0
+ var/lid_closed = FALSE
var/recent_bee_visit = FALSE //Have we been visited by a bee recently, so bees dont overpollinate one plant
var/using_irrigation = FALSE //If the tray is connected to other trays via irrigation hoses
var/self_sufficiency_req = 20 //Required total dose to make a self-sufficient hydro tray. 1:1 with earthsblood.
@@ -128,9 +128,9 @@
if(!user || user.stat || user.restrained())
return
- lid_state = !lid_state
- to_chat(user, "You [lid_state ? "close" : "open"] the tray's lid.")
- update_icon()
+ lid_closed = !lid_closed
+ to_chat(user, "You [lid_closed ? "close" : "open"] the tray's lid.")
+ update_state()
/obj/machinery/hydroponics/bullet_act(obj/item/projectile/Proj) //Works with the Somatoray to modify plant variables.
@@ -257,9 +257,9 @@
else
weedinvasion() // Weed invasion into empty tray
needs_update = 1
- if (needs_update)
- update_icon()
- return
+ if(needs_update)
+ update_state()
+
/obj/machinery/hydroponics/proc/nutrimentMutation()
if (mutmod == 0)
@@ -277,39 +277,38 @@
hardmutate()
else if(prob(50)) //12.5%
mutatespecie()
- return
- return
-/obj/machinery/hydroponics/update_icon()
- //Refreshes the icon and sets the luminosity
- overlays.Cut()
+/obj/machinery/hydroponics/proc/update_state()
+ //Refreshes the icon and sets the luminosity
if(self_sustaining)
if(istype(src, /obj/machinery/hydroponics/soil))
color = rgb(255, 175, 0)
- else
- overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "gaia_blessing")
set_light(3)
-
- update_icon_hoses()
-
- if(myseed)
- update_icon_plant()
- update_icon_lights()
-
- if(!self_sustaining)
+ else
if(myseed && myseed.get_gene(/datum/plant_gene/trait/glow))
var/datum/plant_gene/trait/glow/G = myseed.get_gene(/datum/plant_gene/trait/glow)
set_light(G.glow_range(myseed), G.glow_power(myseed), G.glow_color)
else
set_light(0)
- if(lid_state)
- overlays += image(icon='icons/obj/hydroponics/equipment.dmi', icon_state = "hydrocover", layer = LID_LAYER)
+ update_icon()
- return
-/obj/machinery/hydroponics/proc/update_icon_hoses()
+/obj/machinery/hydroponics/update_overlays()
+ . = ..()
+ if(self_sustaining && !istype(src, /obj/machinery/hydroponics/soil))
+ . += "gaia_blessing"
+
+ if(myseed)
+ . += update_icon_plant()
+ . += update_icon_lights()
+
+ if(lid_closed)
+ . += image(icon='icons/obj/hydroponics/equipment.dmi', icon_state = "hydrocover", layer = LID_LAYER)
+
+
+/obj/machinery/hydroponics/update_icon_state()
var/n = 0
for(var/Dir in GLOB.cardinal)
var/obj/machinery/hydroponics/t = locate() in get_step(src,Dir)
@@ -318,6 +317,7 @@
icon_state = "hoses-[n]"
+
/obj/machinery/hydroponics/proc/update_icon_plant()
var/image/I
if(dead)
@@ -331,19 +331,21 @@
var/t_growthstate = clamp(round((age / myseed.maturation) * myseed.growthstages), 1, myseed.growthstages)
I = image(icon = myseed.growing_icon, icon_state = "[myseed.icon_grow][t_growthstate]")
I.layer = PLANT_LAYER
- overlays += I
+ return I
+
/obj/machinery/hydroponics/proc/update_icon_lights()
+ . = list()
if(waterlevel <= 10)
- overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_lowwater3")
+ . += "over_lowwater3"
if(nutrilevel <= 2)
- overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_lownutri3")
+ . += "over_lownutri3"
if(plant_health <= (myseed.endurance / 2))
- overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_lowhealth3")
+ . += "over_lowhealth3"
if(weedlevel >= 5 || pestlevel >= 5 || toxic >= 40)
- overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_alert3")
+ . += "over_alert3"
if(harvest)
- overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_harvest3")
+ . += "over_harvest3"
/obj/machinery/hydroponics/examine(mob/user)
@@ -353,7 +355,7 @@
. += "It has the [myseed.variant] variant of [myseed.plantname] planted."
else
. += "It has [myseed.plantname] planted."
- if (hasHUD(user, DATA_HUD_HYDROPONIC) || isobserver(user))
+ if (hasHUD(user, EXAMINE_HUD_BOTANY) || isobserver(user))
. += myseed.get_analyzer_text()
. += "Weed: [weedlevel] / 10"
. += "Pest: [pestlevel] / 10"
@@ -414,7 +416,7 @@
harvest = 0
adjustWeeds(-10) // Reset
adjustPests(-10) // Reset
- update_icon()
+ update_state()
plant_hud_set_health()
plant_hud_set_status()
visible_message("The [oldPlantName] is overtaken by some [myseed.plantname]!")
@@ -452,7 +454,7 @@
adjustWeeds(-10) // Reset
sleep(5) // Wait a while
- update_icon()
+ update_state()
visible_message("[oldPlantName] suddenly mutates into [myseed.plantname]!")
@@ -472,7 +474,7 @@
adjustWeeds(-10) // Reset
sleep(5) // Wait a while
- update_icon()
+ update_state()
visible_message("The mutated weeds in [src] spawn some [myseed.plantname]!")
else
to_chat(usr, "The few weeds in [src] seem to react, but only for a moment...")
@@ -483,8 +485,8 @@
harvest = 0
adjustPests(-10) // Pests die
if(!dead)
- update_icon()
- dead = 1
+ dead = TRUE
+ update_state()
plant_hud_set_health()
plant_hud_set_status()
@@ -816,7 +818,7 @@
S.clear_reagents()
qdel(S)
- H.update_icon()
+ H.update_state()
if(reagent_source) // If the source wasn't composted and destroyed
reagent_source.update_icon()
return 1
@@ -835,7 +837,7 @@
plant_hud_set_health()
plant_hud_set_status()
lastcycle = world.time
- update_icon()
+ update_state()
else
to_chat(user, "[src] already has seeds in it!")
@@ -861,7 +863,7 @@
add_fingerprint(user)
user.visible_message("[user] uproots the weeds.", "You remove the weeds from [src].")
adjustWeeds(-10)
- update_icon()
+ update_state()
else
to_chat(user, "This plot is completely devoid of weeds! It doesn't need uprooting.")
@@ -894,7 +896,7 @@
plant_hud_set_health()
plant_hud_set_status()
adjustWeeds(-10) //Has a side effect of cleaning up those nasty weeds
- update_icon()
+ update_state()
else if(is_pen(O) && myseed)
add_fingerprint(user)
myseed.variant_prompt(user, src)
@@ -910,7 +912,7 @@
user.visible_message("[user] [using_irrigation ? "" : "dis"]connects [src]'s irrigation hoses.", \
"You [using_irrigation ? "" : "dis"]connect [src]'s irrigation hoses.")
for(var/obj/machinery/hydroponics/h in range(1,src))
- h.update_icon()
+ h.update_state()
/obj/machinery/hydroponics/wrench_act(mob/user, obj/item/I)
. = TRUE
@@ -942,7 +944,7 @@
/obj/machinery/hydroponics/attack_hand(mob/user)
if(issilicon(user)) //How does AI know what plant is?
return
- if(lid_state)
+ if(lid_closed)
to_chat(user, "You can't reach the plant through the cover.")
return
if(harvest)
@@ -953,7 +955,7 @@
dead = 0
to_chat(user, "You remove the dead plant from [src].")
QDEL_NULL(myseed)
- update_icon()
+ update_state()
plant_hud_set_status()
plant_hud_set_health()
else
@@ -973,7 +975,7 @@
dead = 0
plant_hud_set_status()
plant_hud_set_health()
- update_icon()
+ update_state()
/// Tray Setters - The following procs adjust the tray or plants variables, and make sure that the stat doesn't go out of bounds.///
/obj/machinery/hydroponics/proc/adjustNutri(adjustamt)
@@ -1012,7 +1014,7 @@
/obj/machinery/hydroponics/proc/become_self_sufficient() // Ambrosia Gaia effect
visible_message("[src] begins to glow with a beautiful light!")
self_sustaining = TRUE
- update_icon()
+ update_state()
///Diona Nymph Related Procs///
/obj/machinery/hydroponics/CanPass(atom/movable/mover, turf/target, height=0) //So nymphs can climb over top of trays.
@@ -1029,12 +1031,12 @@
if(weedlevel > 0)
user.adjust_nutrition(weedlevel * 15)
adjustWeeds(-10)
- update_icon()
+ update_state()
visible_message("[user] begins rooting through [src], ripping out weeds and eating them noisily.","You begin rooting through [src], ripping out weeds and eating them noisily.")
else if(nutrilevel < 10)
user.adjust_nutrition(-((10 - nutrilevel) * 5))
adjustNutri(10)
- update_icon()
+ update_state()
visible_message("[user] secretes a trickle of green liquid from its tail, refilling [src]'s nutrient tray.","You secrete a trickle of green liquid from your tail, refilling [src]'s nutrient tray.")
else
return ..()
@@ -1048,7 +1050,7 @@
use_power = NO_POWER_USE
wrenchable = 0
-/obj/machinery/hydroponics/soil/update_icon_hoses()
+/obj/machinery/hydroponics/soil/update_icon_state()
return // Has no hoses
/obj/machinery/hydroponics/soil/update_icon_lights()
diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm
index 9f0c5a9cb35..08b3a8bae96 100644
--- a/code/modules/hydroponics/seed_extractor.dm
+++ b/code/modules/hydroponics/seed_extractor.dm
@@ -43,7 +43,7 @@
icon = 'icons/obj/hydroponics/equipment.dmi'
icon_state = "sextractor"
density = 1
- anchored = 1
+ anchored = TRUE
var/list/piles = list()
var/max_seeds = 1000
var/seed_multiplier = 1
diff --git a/code/modules/input/input.dm b/code/modules/input/input.dm
index 23b5c0e2e5b..17877e5eb51 100644
--- a/code/modules/input/input.dm
+++ b/code/modules/input/input.dm
@@ -24,11 +24,11 @@
"default" = list(
"Any" = "\"KeyDown \[\[*\]\]\"", // Passes any key down to the rebindable input system
"Any+UP" = "\"KeyUp \[\[*\]\]\"", // Passes any key up to the rebindable input system
- "Tab" = "\".winset \\\"mainwindow.macro=legacy input.focus=true input.background-color=[COLOR_INPUT_ENABLED]\\\"\"", // Swaps us to legacy mode, forces input to the input bar, sets the input bar colour to salmon pink
+ "Tab" = "\".winset \\\"mainwindow.macro=legacy input.focus=true input.background-color=[(prefs?.toggles & PREFTOGGLE_UI_DARKMODE) ? COLOR_DARK_INPUT_ENABLED : COLOR_INPUT_ENABLED]\\\"\"", // Swaps us to legacy mode, forces input to the input bar, sets the input bar colour to salmon pink
"Back" = "\".winset \\\"input.focus=true ? input.text=\\\"\"" // This makes it so backspace can remove default inputs
),
"legacy" = list(
- "Tab" = "\".winset \\\"mainwindow.macro=default map.focus=true input.background-color=[COLOR_INPUT_DISABLED]\\\"\"", // Swaps us to rebind mode, moves input away from input bar, sets input bar to white
+ "Tab" = "\".winset \\\"mainwindow.macro=default map.focus=true input.background-color=[(prefs?.toggles & PREFTOGGLE_UI_DARKMODE) ? COLOR_DARK_INPUT_DISABLED : COLOR_INPUT_DISABLED]\\\"\"", // Swaps us to rebind mode, moves input away from input bar, sets input bar to white
"Back" = "\".winset \\\"input.focus=true ? input.text=\\\"\"" // This makes it so backspace can remove default inputs
),
)
@@ -62,8 +62,7 @@
var/key = macro_set[k]
var/command = macro_set[key]
winset(src, "[setname]-[key]", "parent=[setname];name=[key];command=[command]")
-
- winset(src, null, "input.background-color=[COLOR_INPUT_DISABLED]") //screw you, we start in hotkey mode now
+ winset(src, null, "input.background-color=[(prefs?.toggles & PREFTOGGLE_UI_DARKMODE) ? COLOR_DARK_INPUT_DISABLED : COLOR_INPUT_DISABLED]") //screw you, we start in hotkey mode now
macro_sets = null //not needed anymore, bye have a great time
/client/verb/KeyDown(_key as text)
diff --git a/code/modules/input/keybindings.dm b/code/modules/input/keybindings.dm
index 1d231127996..7f064cf64ad 100644
--- a/code/modules/input/keybindings.dm
+++ b/code/modules/input/keybindings.dm
@@ -13,4 +13,11 @@
else
active_keybindings[key] += list(KB)
+ if(!mob) // Clients can join before world/new is setup, so we gotta mob check em
+ return active_keybindings
+ for(var/datum/action/action as anything in mob.actions)
+ if(action.button?.linked_keybind?.binded_to)
+ var/datum/keybinding/mob/trigger_action_button/linked_bind = action.button.linked_keybind
+ active_keybindings[linked_bind.binded_to] += list(linked_bind)
+
return active_keybindings
diff --git a/code/modules/instruments/objs/items/headphones.dm b/code/modules/instruments/objs/items/headphones.dm
index 741032ef3e2..5366a777640 100644
--- a/code/modules/instruments/objs/items/headphones.dm
+++ b/code/modules/instruments/objs/items/headphones.dm
@@ -5,6 +5,8 @@
item_state = "headphones0"
actions_types = list(/datum/action/item_action/change_headphones_song)
var/datum/song/headphones/song
+ var/on = FALSE
+
/obj/item/clothing/ears/headphones/Initialize(mapload)
. = ..()
@@ -15,50 +17,60 @@
RegisterSignal(src, COMSIG_SONG_START, PROC_REF(start_playing))
RegisterSignal(src, COMSIG_SONG_END, PROC_REF(stop_playing))
+
/obj/item/clothing/ears/headphones/Destroy()
QDEL_NULL(song)
return ..()
+
/obj/item/clothing/ears/headphones/attack_self(mob/user)
ui_interact(user)
+
/obj/item/clothing/ears/headphones/ui_data(mob/user)
return song.ui_data(user)
+
/obj/item/clothing/ears/headphones/ui_interact(mob/user)
if(should_stop_playing(user) || user.incapacitated())
return
song.ui_interact(user)
+
/obj/item/clothing/ears/headphones/ui_act(action, params)
if(..())
return
return song.ui_act(action, params)
-/obj/item/clothing/ears/headphones/update_icon()
- var/mob/living/carbon/human/user = loc
- if(istype(user))
- user.update_action_buttons_icon()
- user.update_inv_ears()
- ..()
+
+/obj/item/clothing/ears/headphones/update_icon_state()
+ icon_state = "headphones[on]"
+ item_state = "headphones[on]"
+ update_equipped_item()
+
/obj/item/clothing/ears/headphones/item_action_slot_check(slot)
if(slot == slot_l_ear || slot == slot_r_ear)
return TRUE
+
/**
* Called by a component signal when our song starts playing.
*/
/obj/item/clothing/ears/headphones/proc/start_playing()
- icon_state = item_state = "headphones1"
- update_icon()
+ SIGNAL_HANDLER
+ on = TRUE
+ update_icon(UPDATE_ICON_STATE)
+
/**
* Called by a component signal when our song stops playing.
*/
/obj/item/clothing/ears/headphones/proc/stop_playing()
- icon_state = item_state = "headphones0"
- update_icon()
+ SIGNAL_HANDLER
+ on = FALSE
+ update_icon(UPDATE_ICON_STATE)
+
/**
* Whether the headphone's song should stop playing
@@ -69,12 +81,15 @@
/obj/item/clothing/ears/headphones/proc/should_stop_playing(mob/living/carbon/human/user)
return !(src in user) || !istype(user) || !((src == user.l_ear) || (src == user.r_ear))
+
// special subtype so it uses the correct item type
/datum/song/headphones
+
/datum/song/headphones/should_stop_playing(mob/user)
. = ..()
if(.)
return TRUE
var/obj/item/clothing/ears/headphones/I = parent
return I.should_stop_playing(user)
+
diff --git a/code/modules/library/admin.dm b/code/modules/library/admin.dm
index 8ec728d0267..5cc288bcfe1 100644
--- a/code/modules/library/admin.dm
+++ b/code/modules/library/admin.dm
@@ -37,14 +37,15 @@
if(!usr.client.holder)
return
- var/dat = {"ISBN | Title | Total Flags | Options | "}
+ var/dat = {"ISBN | Title | Total Flags | Flagged by (Last ckey) | Options | "}
- var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, title, flagged FROM [format_table_name("library")] WHERE \
+ var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, title, flagged, flaggedby FROM [format_table_name("library")] WHERE \
flagged > 0 ORDER BY flagged DESC LIMIT :lowerlimit, :upperlimit", list(
"lowerlimit" = text2num((page_num - 1) * FLAGGED_BOOKS_PER_PAGE),
"upperlimit" = FLAGGED_BOOKS_PER_PAGE
))
+
if(!query.warn_execute())
qdel(query)
return
@@ -53,7 +54,7 @@
while(query.NextRow())
books++
var/isbn = query.item[1]
- dat += "[add_zero(isbn, 4)] | [query.item[2]] | [query.item[3]] | "
+ dat += " | [add_zero(isbn, 4)] | [query.item[2]] | [query.item[3]] | [query.item[4]] | "
dat += "View Content"
dat += "Unflag"
dat += "Delete"
diff --git a/code/modules/library/computers/base.dm b/code/modules/library/computers/base.dm
index 334d14ed987..ecd2a166fd0 100644
--- a/code/modules/library/computers/base.dm
+++ b/code/modules/library/computers/base.dm
@@ -2,7 +2,7 @@
/obj/machinery/computer/library
name = "visitor computer"
- anchored = 1
+ anchored = TRUE
density = 1
icon_keyboard = ""
icon_screen = "computer_on"
diff --git a/code/modules/library/computers/checkout.dm b/code/modules/library/computers/checkout.dm
index 4f1576655fc..ef45abfb76c 100644
--- a/code/modules/library/computers/checkout.dm
+++ b/code/modules/library/computers/checkout.dm
@@ -4,9 +4,10 @@
/obj/machinery/computer/library/checkout
name = "Check-In/Out Computer"
icon = 'icons/obj/library.dmi'
- icon_state = "computer"
- anchored = 1
- density = 1
+ icon_state = "oldcomp"
+ anchored = TRUE
+ density = TRUE
+ icon_screen = "library"
var/arcanecheckout = 0
//var/screenstate = 0 // 0 - Main Menu, 1 - Inventory, 2 - Checked Out, 3 - Check Out a Book
var/buffer_book
diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm
index fc5b09873bd..8d286faff0d 100644
--- a/code/modules/library/lib_items.dm
+++ b/code/modules/library/lib_items.dm
@@ -15,103 +15,110 @@
name = "bookcase"
icon = 'icons/obj/library.dmi'
icon_state = "book-0"
- anchored = 1
+ anchored = TRUE
density = 1
opacity = 1
resistance_flags = FLAMMABLE
max_integrity = 200
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0)
- var/tmp/busy = 0
- var/list/allowed_books = list(/obj/item/book, /obj/item/spellbook, /obj/item/storage/bible, /obj/item/tome) //Things allowed in the bookcase
+ /// Things allowed in the bookcase
+ var/list/allowed_books = list(
+ /obj/item/book,
+ /obj/item/spellbook,
+ /obj/item/storage/bible,
+ /obj/item/tome,
+ )
+
/obj/structure/bookcase/Initialize()
..()
for(var/obj/item/I in loc)
if(is_type_in_list(I, allowed_books))
I.forceMove(src)
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
-/obj/structure/bookcase/attackby(obj/item/O as obj, mob/user as mob, params)
- if(busy) //So that you can't mess with it while deconstructing
- return TRUE
+
+/obj/structure/bookcase/attackby(obj/item/O, mob/user, params)
if(is_type_in_list(O, allowed_books))
if(!user.drop_transfer_item_to_loc(O, src))
return
add_fingerprint(user)
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
return TRUE
- else if(istype(O, /obj/item/storage/bag/books))
+ if(istype(O, /obj/item/storage/bag/books))
var/obj/item/storage/bag/books/B = O
for(var/obj/item/T in B.contents)
- if(istype(T, /obj/item/book) || istype(T, /obj/item/spellbook) || istype(T, /obj/item/tome) || istype(T, /obj/item/storage/bible))
+ if(is_type_in_list(T, allowed_books))
T.add_fingerprint(user)
B.remove_from_storage(T, src)
add_fingerprint(user)
- to_chat(user, "You empty [O] into [src].")
- update_icon()
+ to_chat(user, span_notice("You empty [O] into [src]."))
+ update_icon(UPDATE_ICON_STATE)
return TRUE
- else if(istype(O, /obj/item/wrench))
- user.visible_message("[user] starts disassembling \the [src].", \
- "You start disassembling \the [src].")
- playsound(get_turf(src), O.usesound, 50, 1)
- busy = TRUE
-
- if(do_after(user, 50 * O.toolspeed * gettoolspeedmod(user), target = src))
- playsound(get_turf(src), O.usesound, 75, 1)
- user.visible_message("[user] disassembles \the [src].", \
- "You disassemble \the [src].")
- busy = FALSE
- density = 0
- deconstruct(TRUE)
- else
- busy = FALSE
- return TRUE
- else if(istype(O, /obj/item/pen))
+ if(is_pen(O))
add_fingerprint(user)
rename_interactive(user, O)
return TRUE
- else
- return ..()
+ return ..()
+
+
+/obj/structure/bookcase/screwdriver_act(mob/user, obj/item/I)
+ if(flags & NODECONSTRUCT)
+ return
+ . = TRUE
+ if(!I.tool_use_check(user, 0))
+ return
+ TOOL_ATTEMPT_DISMANTLE_MESSAGE
+ if(!I.use_tool(src, user, 2 SECONDS, volume = I.tool_volume))
+ return
+ TOOL_DISMANTLE_SUCCESS_MESSAGE
+ deconstruct(TRUE)
+
+
+/obj/structure/bookcase/wrench_act(mob/user, obj/item/I)
+ . = TRUE
+ default_unfasten_wrench(user, I, 0)
+
+
+/obj/structure/bookcase/attack_hand(mob/user)
+ if(!length(contents))
+ return
+
+ var/obj/item/book/choice = tgui_input_list(user, "Which book would you like to remove from [src]?", "Bookcase", contents)
+ if(!choice || user.incapacitated() || !Adjacent(user))
+ return
+ add_fingerprint(user)
+ choice.forceMove_turf()
+ user.put_in_hands(choice, ignore_anim = FALSE)
+ update_icon(UPDATE_ICON_STATE)
-/obj/structure/bookcase/attack_hand(var/mob/user as mob)
- if(contents.len)
- var/obj/item/book/choice = tgui_input_list(user, "Which book would you like to remove from [src]?", "Bookcase", contents)
- if(choice)
- if(user.incapacitated() || user.lying || !Adjacent(user))
- return
- add_fingerprint(user)
- if(!user.get_active_hand())
- choice.forceMove_turf()
- user.put_in_hands(choice, ignore_anim = FALSE)
- else
- choice.forceMove(get_turf(src))
- update_icon()
/obj/structure/bookcase/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/wood(loc, 5)
for(var/obj/item/I in contents)
if(is_type_in_list(I, allowed_books))
I.forceMove(get_turf(src))
- qdel(src)
+ ..()
+
+
+/obj/structure/bookcase/update_icon_state()
+ icon_state = "book-[min(length(contents), 5)]"
-/obj/structure/bookcase/update_icon()
- if(contents.len < 5)
- icon_state = "book-[contents.len]"
- else
- icon_state = "book-5"
/obj/structure/bookcase/manuals/medical
name = "Medical Manuals bookcase"
+
/obj/structure/bookcase/manuals/medical/Initialize()
. = ..()
new /obj/item/book/manual/medical_cloning(src)
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
/obj/structure/bookcase/manuals/engineering
name = "Engineering Manuals bookcase"
+
/obj/structure/bookcase/manuals/engineering/Initialize()
. = ..()
new /obj/item/book/manual/engineering_construction(src)
@@ -120,15 +127,17 @@
new /obj/item/book/manual/engineering_guide(src)
new /obj/item/book/manual/engineering_singularity_safety(src)
new /obj/item/book/manual/robotics_cyborgs(src)
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
+
/obj/structure/bookcase/manuals/research_and_development
name = "R&D Manuals bookcase"
+
/obj/structure/bookcase/manuals/research_and_development/Initialize()
. = ..()
new /obj/item/book/manual/research_and_development(src)
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
/*
diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm
index 316fc48657e..e393067a59b 100644
--- a/code/modules/library/lib_machines.dm
+++ b/code/modules/library/lib_machines.dm
@@ -26,6 +26,7 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A
var/forbidden=0
var/path = /obj/item/book // Type path of the book to generate
var/flagged = 0
+ var/flaggedby
/datum/cachedbook/proc/LoadFromRow(var/list/row)
id = row["id"]
@@ -34,6 +35,7 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A
category = row["category"]
ckey = row["ckey"]
flagged = row["flagged"]
+ flaggedby = row["flaggedby"]
if("content" in row)
content = row["content"]
programmatic=0
@@ -80,8 +82,9 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A
log_game("[user] (ckey: [user.key]) has flagged book #[id] as inappropriate.")
- var/datum/db_query/query = SSdbcore.NewQuery("UPDATE [format_table_name("library")] SET flagged = flagged + 1 WHERE id=:id", list(
- "id" = text2num(id)
+ var/datum/db_query/query = SSdbcore.NewQuery("UPDATE [format_table_name("library")] SET flagged = flagged + 1, flaggedby=:flaggedby WHERE id=:id", list(
+ "id" = text2num(id),
+ "flaggedby" = user.key
))
if(!query.warn_execute())
qdel(query)
@@ -107,7 +110,7 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A
if("[id]" in cached_books)
return cached_books["[id]"]
- var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, author, title, category, content, ckey, flagged FROM [format_table_name("library")] WHERE id=:id", list(
+ var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, author, title, category, content, ckey, flagged, flaggedby FROM [format_table_name("library")] WHERE id=:id", list(
"id" = text2num(id)
))
if(!query.warn_execute())
@@ -124,7 +127,8 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A
"category"=query.item[4],
"content" =query.item[5],
"ckey" =query.item[6],
- "flagged" =query.item[7]
+ "flagged" =query.item[7],
+ "flaggedby"=query.item[8]
))
results += CB
cached_books["[id]"]=CB
@@ -138,7 +142,7 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A
name = "scanner"
icon = 'icons/obj/library.dmi'
icon_state = "bigscanner"
- anchored = 1
+ anchored = TRUE
density = 1
var/obj/item/book/cache // Last scanned book
@@ -205,7 +209,7 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A
name = "Book Binder"
icon = 'icons/obj/library.dmi'
icon_state = "binder"
- anchored = 1
+ anchored = TRUE
density = 1
/obj/machinery/bookbinder/attackby(obj/item/I, mob/user)
diff --git a/code/modules/martial_arts/adminfu.dm b/code/modules/martial_arts/adminfu.dm
index f174bc0b44f..020f44f1156 100644
--- a/code/modules/martial_arts/adminfu.dm
+++ b/code/modules/martial_arts/adminfu.dm
@@ -38,9 +38,24 @@
desc = "An aged and frayed scrap of paper written in shifting runes. There are hand-drawn illustrations of pugilism."
icon = 'icons/obj/wizard.dmi'
icon_state ="scroll2"
- var/used = 0
+ var/used = FALSE
-/obj/item/adminfu_scroll/attack_self(mob/user as mob)
+
+/obj/item/adminfu_scroll/update_icon_state()
+ icon_state = used ? "blankscroll" : initial(icon_state)
+
+
+/obj/item/adminfu_scroll/update_name(updates = ALL)
+ . = ..()
+ name = used ? "empty scroll" : initial(name)
+
+
+/obj/item/adminfu_scroll/update_desc(updates = ALL)
+ . = ..()
+ desc = used ? "It's completely blank." : initial(desc)
+
+
+/obj/item/adminfu_scroll/attack_self(mob/user)
if(!ishuman(user))
return
if(!used)
@@ -48,7 +63,6 @@
var/datum/martial_art/adminfu/F = new/datum/martial_art/adminfu(null)
F.teach(H)
to_chat(H, "You have learned the ancient martial art of the Admins.")
- used = 1
- desc = "It's completely blank."
- name = "empty scroll"
- icon_state = "blankscroll"
+ used = TRUE
+ update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC)
+
diff --git a/code/modules/martial_arts/cqc.dm b/code/modules/martial_arts/cqc.dm
index 1d4d0cedbc9..a8e4412db95 100644
--- a/code/modules/martial_arts/cqc.dm
+++ b/code/modules/martial_arts/cqc.dm
@@ -17,15 +17,15 @@
weight = 5
/datum/martial_art/cqc/under_siege/teach(mob/living/carbon/human/H, make_temporary)
- RegisterSignal(H, COMSIG_AREA_ENTERED, PROC_REF(kitchen_check))
+ RegisterSignal(H, COMSIG_ATOM_ENTERED_AREA, PROC_REF(kitchen_check))
return ..()
/datum/martial_art/cqc/under_siege/remove(mob/living/carbon/human/H)
- UnregisterSignal(H, COMSIG_AREA_ENTERED)
+ UnregisterSignal(H, COMSIG_ATOM_ENTERED_AREA)
return ..()
/datum/martial_art/cqc/under_siege/proc/kitchen_check(mob/living/carbon/human/H, area/entered_area)
- SIGNAL_HANDLER //COMSIG_AREA_ENTERED
+ SIGNAL_HANDLER //COMSIG_ATOM_ENTERED_AREA
if(!is_type_in_typecache(entered_area, areas_under_siege))
weight = 0
else
diff --git a/code/modules/martial_arts/martial.dm b/code/modules/martial_arts/martial.dm
index 463f090552c..59c27c21b1c 100644
--- a/code/modules/martial_arts/martial.dm
+++ b/code/modules/martial_arts/martial.dm
@@ -330,7 +330,22 @@
desc = "An aged and frayed scrap of paper written in shifting runes. There are hand-drawn illustrations of pugilism."
icon = 'icons/obj/wizard.dmi'
icon_state ="scroll2"
- var/used = 0
+ var/used = FALSE
+
+
+/obj/item/plasma_fist_scroll/update_icon_state()
+ icon_state = used ? "blankscroll" : initial(icon_state)
+
+
+/obj/item/plasma_fist_scroll/update_name(updates = ALL)
+ . = ..()
+ name = used ? "empty scroll" : initial(name)
+
+
+/obj/item/plasma_fist_scroll/update_desc(updates = ALL)
+ . = ..()
+ desc = used ? "It's completely blank." : initial(desc)
+
/obj/item/plasma_fist_scroll/attack_self(mob/user as mob)
if(!ishuman(user))
@@ -341,10 +356,9 @@
var/datum/martial_art/plasma_fist/F = new/datum/martial_art/plasma_fist(null)
F.teach(H)
to_chat(H, "You have learned the ancient martial art of Plasma Fist.")
- used = 1
- desc = "It's completely blank."
- name = "empty scroll"
- icon_state = "blankscroll"
+ used = TRUE
+ update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC)
+
/obj/item/sleeping_carp_scroll
name = "mysterious scroll"
@@ -484,9 +498,10 @@
icon_state = "bostaff0"
block_chance = 50
-/obj/item/twohanded/bostaff/update_icon()
- icon_state = "bostaff[wielded]"
- return
+
+/obj/item/twohanded/bostaff/update_icon_state()
+ icon_state = "bostaff[HAS_TRAIT(src, TRAIT_WIELDED)]"
+
/obj/item/twohanded/bostaff/attack(mob/target, mob/living/user)
add_fingerprint(user)
@@ -512,7 +527,7 @@
return
switch(user.a_intent)
if(INTENT_DISARM)
- if(!wielded)
+ if(!HAS_TRAIT(src, TRAIT_WIELDED))
return ..()
if(!ishuman(target))
return ..()
@@ -543,9 +558,9 @@
return ..()
/obj/item/twohanded/bostaff/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- if(wielded)
+ if(HAS_TRAIT(src, TRAIT_WIELDED))
return ..()
- return 0
+ return FALSE
/obj/screen/combo
icon_state = ""
@@ -554,24 +569,33 @@
layer = ABOVE_HUD_LAYER
var/streak
+
/obj/screen/combo/proc/clear_streak()
cut_overlays()
streak = ""
icon_state = ""
+
/obj/screen/combo/update_icon(updates, _streak)
streak = _streak
- icon_state = ""
- if(!streak)
- clear_streak()
- return
- icon_state = "combo"
+ return ..()
+
+
+/obj/screen/combo/update_overlays()
+ . = list()
for(var/i in 1 to length(streak))
var/intent_text = copytext(streak, i, i + 1)
var/image/intent_icon = image(icon, src, "combo_[intent_text]")
intent_icon.pixel_x = 16 * (i - 1) - 8 * length(streak)
- overlays += intent_icon
- return ..()
+ . += intent_icon
+
+
+/obj/screen/combo/update_icon_state()
+ icon_state = ""
+ if(!streak)
+ return
+ icon_state = "combo"
+
#undef HAS_COMBOS
#undef COMBO_ALIVE_TIME
diff --git a/code/modules/martial_arts/synthojitsu.dm b/code/modules/martial_arts/synthojitsu.dm
index 5af35c44d8a..ca81d5a326f 100644
--- a/code/modules/martial_arts/synthojitsu.dm
+++ b/code/modules/martial_arts/synthojitsu.dm
@@ -43,7 +43,20 @@
icon_state ="viable"
var/is_used = FALSE
-/obj/item/ipc_combat_upgrade/attack_self(mob/user as mob)
+
+/obj/item/ipc_combat_upgrade/update_icon_state()
+ icon_state = "[is_used ? "un" : ""]viable"
+
+
+/obj/item/ipc_combat_upgrade/update_desc(updates = ALL)
+ . = ..()
+ if(!is_used)
+ desc = initial(desc)
+ return
+ desc = "Advanced data storage designed to be compatible with positronic systems.This one include melee algorithms along with overwritten microbattery safety protocols.It's hardlocked"
+
+
+/obj/item/ipc_combat_upgrade/attack_self(mob/user)
if(!ismachineperson(user) || is_used == TRUE)
return
to_chat(user, "Installation sequence initialized. It will take some time...")
@@ -55,9 +68,8 @@
H.Weaken(10 SECONDS)
to_chat(H, "Melee algorithms installed. Safety disabled.")
is_used = TRUE
- desc = "Advanced data storage designed to be compatible with positronic systems.This one include melee algorithms along with overwritten microbattery safety protocols.It's hardlocked"
- name = "IPC combat upgrade"
- icon_state = "unviable"
+ update_appearance(UPDATE_ICON_STATE|UPDATE_DESC)
+
/datum/martial_art/synthojitsu/explaination_header(user)
to_chat(user, "You reapload some of the basics of synthojitsu.")
diff --git a/code/modules/mini_games/thunderdome/gamemodes/gamemode.dm b/code/modules/mini_games/thunderdome/gamemodes/gamemode.dm
index 31b00f6d9f6..c0469590cd4 100644
--- a/code/modules/mini_games/thunderdome/gamemodes/gamemode.dm
+++ b/code/modules/mini_games/thunderdome/gamemodes/gamemode.dm
@@ -70,7 +70,7 @@
/obj/item/gun/projectile/shotgun/boltaction = 1,
/obj/item/gun/projectile/shotgun/automatic/combat = 2,
/obj/item/gun/projectile/automatic/pistol/APS = 1,
- /obj/item/gun/projectile/automatic/pistol/sp8ar = 1,
+ /obj/item/gun/projectile/automatic/pistol/sp8/sp8ar = 1,
/obj/item/gun/projectile/automatic/pistol/m1911 = 1,
/obj/item/gun/projectile/revolver/golden = 1,
/obj/item/gun/projectile/revolver/nagant = 1,
@@ -130,7 +130,7 @@
/obj/item/gun/projectile/shotgun/boltaction = 1,
/obj/item/gun/projectile/shotgun/automatic/combat = 2,
/obj/item/gun/projectile/automatic/pistol/APS = 1,
- /obj/item/gun/projectile/automatic/pistol/sp8ar = 1,
+ /obj/item/gun/projectile/automatic/pistol/sp8/sp8ar = 1,
/obj/item/gun/projectile/automatic/pistol/m1911 = 1,
/obj/item/gun/projectile/revolver/golden = 1,
/obj/item/gun/projectile/revolver/nagant = 1,
@@ -140,4 +140,25 @@
/obj/item/storage/box/thunderdome/crossbow/energy = 1,
/obj/item/storage/box/thunderdome/laser_eyes = 1,
/obj/item/implanter/adrenalin = 1,
+ /obj/item/melee/rapier = 1,
+ /obj/item/melee/energy/axe = 1,
+ /obj/item/melee/energy/sword/saber/red = 1,
+ /obj/item/melee/energy/cleaving_saw = 1,
+ /obj/item/twohanded/mjollnir = 1,
+ /obj/item/twohanded/chainsaw = 1,
+ /obj/item/twohanded/dualsaber = 1,
+ /obj/item/twohanded/fireaxe = 1,
+ /obj/item/melee/icepick = 1,
+ /obj/item/melee/candy_sword = 1,
+ /obj/item/melee/energy/sword/pirate = 1,
+ /obj/item/storage/toolbox/surgery = 1,
+ /obj/item/storage/toolbox/mechanical = 1,
+ /obj/item/storage/toolbox/syndicate = 1,
+ /obj/item/storage/box/syndie_kit/mantisblade = 1,
+ /obj/item/CQC_manual = 1,
+ /obj/item/sleeping_carp_scroll = 1,
+ /obj/item/clothing/gloves/fingerless/rapid = 1,
+ /obj/item/storage/box/thunderdome/spears = 1,
+ /obj/item/storage/box/thunderdome/maga = 1,
+ /obj/item/storage/box/thunderdome/singulatiry = 1,
)
diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm
index 5e6561bd36d..d0c4aed9906 100644
--- a/code/modules/mining/abandonedcrates.dm
+++ b/code/modules/mining/abandonedcrates.dm
@@ -180,7 +180,7 @@
if(istype(W, /obj/item/card/emag))
boom(user)
return 1
- if(istype(W, /obj/item/multitool))
+ if(W.tool_behaviour == TOOL_MULTITOOL)
add_fingerprint(user)
to_chat(user, "DECA-CODE LOCK REPORT:")
if(attempts == 1)
diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm
index 59738cd2fa3..2d35238543f 100644
--- a/code/modules/mining/equipment/explorer_gear.dm
+++ b/code/modules/mining/equipment/explorer_gear.dm
@@ -75,15 +75,18 @@
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe, /obj/item/twohanded/kinetic_crusher, /obj/item/hierophant_club, /obj/item/twohanded/fireaxe/boneaxe)
jetpack = /obj/item/tank/jetpack/suit
-/obj/item/clothing/suit/space/hostile_environment/New()
+
+/obj/item/clothing/suit/space/hostile_environment/Initialize(mapload)
+ . = ..()
AddComponent(/datum/component/spraycan_paintable)
START_PROCESSING(SSobj, src)
- ..()
+
/obj/item/clothing/suit/space/hostile_environment/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
+
/obj/item/clothing/suit/space/hostile_environment/process()
var/mob/living/carbon/C = loc
if(istype(C) && prob(2)) //cursed by bubblegum
@@ -103,17 +106,17 @@
armor = list("melee" = 70, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
resistance_flags = FIRE_PROOF | LAVA_PROOF | ACID_PROOF
-/obj/item/clothing/head/helmet/space/hostile_environment/New()
- ..()
+
+/obj/item/clothing/head/helmet/space/hostile_environment/Initialize(mapload)
+ . = ..()
AddComponent(/datum/component/spraycan_paintable)
- update_icon()
-
-/obj/item/clothing/head/helmet/space/hostile_environment/update_icon()
- ..()
- cut_overlays()
- var/mutable_appearance/glass_overlay = mutable_appearance(icon, "hostile_env_glass")
- glass_overlay.appearance_flags = RESET_COLOR
- add_overlay(glass_overlay)
+ update_icon(UPDATE_OVERLAYS)
+
+
+/obj/item/clothing/head/helmet/space/hostile_environment/update_overlays()
+ . = ..()
+ . += mutable_appearance(icon, "hostile_env_glass", appearance_flags = RESET_COLOR)
+
/obj/item/clothing/head/helmet/space/hardsuit/champion
name = "champion's helmet"
diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm
index ca7de1c5a13..3677a45ea47 100644
--- a/code/modules/mining/equipment/kinetic_crusher.dm
+++ b/code/modules/mining/equipment/kinetic_crusher.dm
@@ -62,7 +62,7 @@
to_chat(user, "There are no trophies on [src].")
/obj/item/twohanded/kinetic_crusher/attack(mob/living/target, mob/living/carbon/user)
- if(!wielded)
+ if(!HAS_TRAIT(src, TRAIT_WIELDED))
to_chat(user, "[src] is too heavy to use with one hand. You fumble and drop everything.")
user.drop_r_hand()
user.drop_l_hand()
@@ -90,7 +90,7 @@
/obj/item/twohanded/kinetic_crusher/afterattack(atom/target, mob/living/user, proximity_flag, clickparams)
. = ..()
- if(!wielded)
+ if(!HAS_TRAIT(src, TRAIT_WIELDED))
return
if(user.has_status_effect(STATUS_EFFECT_DASH) && user.a_intent == INTENT_HELP)
if(user.throw_at(target, range = 3, speed = 3, spin = FALSE, diagonals_first = TRUE))
@@ -164,21 +164,27 @@
else
set_light(0)
-/obj/item/twohanded/kinetic_crusher/update_icon()
- ..()
- cut_overlays()
+
+/obj/item/twohanded/kinetic_crusher/update_icon_state()
+ if(upgraded)
+ item_state = "magmite_crusher[HAS_TRAIT(src, TRAIT_WIELDED)]"
+ else
+ item_state = "crusher[HAS_TRAIT(src, TRAIT_WIELDED)]"
+
+
+/obj/item/twohanded/kinetic_crusher/update_overlays()
+ . = ..()
if(!charged)
- add_overlay("[icon_state]_uncharged")
+ . += "[icon_state]_uncharged"
if(light_on)
- add_overlay("[icon_state]_lit")
- spawn(1)
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
- if(!upgraded)
- item_state = "crusher[wielded]"
- else
- item_state = "magmite_crusher[wielded]"
+ . += "[icon_state]_lit"
+ addtimer(CALLBACK(src, PROC_REF(buttons_update)), 0.1 SECONDS)
+
+
+/obj/item/twohanded/kinetic_crusher/proc/buttons_update()
+ for(var/datum/action/action as anything in actions)
+ action.UpdateButtonIcon()
+
//destablizing force
/obj/item/projectile/destabilizer
@@ -402,7 +408,8 @@
if(.)
H.force += bonus_value * 0.2
H.force_unwielded += bonus_value * 0.2
- H.force_wielded += bonus_value * 0.2
+ // don't update force since KCs have 0 force by default
+ H.AddComponent(/datum/component/two_handed, force_wielded = H.force_wielded, force_unwielded = H.force)
H.detonation_damage += bonus_value * 0.8
/obj/item/crusher_trophy/demon_claws/remove_from(obj/item/twohanded/kinetic_crusher/H, mob/living/user)
@@ -410,7 +417,7 @@
if(.)
H.force -= bonus_value * 0.2
H.force_unwielded -= bonus_value * 0.2
- H.force_wielded -= bonus_value * 0.2
+ H.AddComponent(/datum/component/two_handed, force_wielded = H.force_wielded, force_unwielded = H.force)
H.detonation_damage -= bonus_value * 0.8
/obj/item/crusher_trophy/demon_claws/on_melee_hit(mob/living/target, mob/living/user)
diff --git a/code/modules/mining/equipment/lazarus_injector.dm b/code/modules/mining/equipment/lazarus_injector.dm
index cd9aeb3677f..66cea2273d0 100644
--- a/code/modules/mining/equipment/lazarus_injector.dm
+++ b/code/modules/mining/equipment/lazarus_injector.dm
@@ -10,10 +10,15 @@
w_class = WEIGHT_CLASS_SMALL
throw_speed = 3
throw_range = 5
- var/loaded = 1
+ var/loaded = TRUE
var/malfunctioning = 0
var/revive_type = SENTIENCE_ORGANIC //So you can't revive boss monsters or robots with it
+
+/obj/item/lazarus_injector/update_icon_state()
+ icon_state = "lazarus_[loaded ? "hypo" : "empty"]"
+
+
/obj/item/lazarus_injector/afterattack(atom/target, mob/user, proximity_flag)
if(!loaded)
return
@@ -37,10 +42,10 @@
add_game_logs("[user] has revived hostile mob [target] with a malfunctioning lazarus injector", user)
else
H.attack_same = 0
- loaded = 0
+ loaded = FALSE
user.visible_message("[user] injects [M] with [src], reviving it.")
playsound(src,'sound/effects/refill.ogg',50,1)
- icon_state = "lazarus_empty"
+ update_icon(UPDATE_ICON_STATE)
return
else
to_chat(user, "[src] is only effective on the dead.")
@@ -116,9 +121,14 @@
captured.forceMove(get_turf(src))
captured = null
+
+/obj/item/mobcapsule/update_icon_state()
+ icon_state = "mobcap[colorindex]"
+
+
/obj/item/mobcapsule/attack_self(mob/user)
colorindex += 1
if(colorindex >= 6)
colorindex = 0
- icon_state = "mobcap[colorindex]"
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
+
diff --git a/code/modules/mining/equipment/marker_beacons.dm b/code/modules/mining/equipment/marker_beacons.dm
index 761d8560314..43619296302 100644
--- a/code/modules/mining/equipment/marker_beacons.dm
+++ b/code/modules/mining/equipment/marker_beacons.dm
@@ -34,14 +34,14 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list(
/obj/item/stack/marker_beacon/Initialize(mapload)
. = ..()
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
/obj/item/stack/marker_beacon/examine(mob/user)
. = ..()
. += "Use in-hand to place a [singular_name]."
. += "Alt-click to select a color. Current color is [picked_color]."
-/obj/item/stack/marker_beacon/update_icon()
+/obj/item/stack/marker_beacon/update_icon_state()
icon_state = "[initial(icon_state)][lowertext(picked_color)]"
/obj/item/stack/marker_beacon/attack_self(mob/user)
@@ -65,7 +65,7 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list(
return
if(input_color)
picked_color = input_color
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
/obj/structure/marker_beacon
name = "marker beacon"
@@ -84,25 +84,31 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list(
/obj/structure/marker_beacon/Initialize(mapload, set_color)
. = ..()
picked_color = set_color
- update_icon()
+ update_state()
/obj/structure/marker_beacon/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
var/obj/item/stack/marker_beacon/M = new(loc)
M.picked_color = picked_color
- M.update_icon()
+ M.update_icon(UPDATE_ICON_STATE)
qdel(src)
/obj/structure/marker_beacon/examine(mob/user)
. = ..()
. += "Alt-click to select a color. Current color is [picked_color]."
-/obj/structure/marker_beacon/update_icon()
+
+/obj/structure/marker_beacon/update_icon_state()
while(!picked_color || !GLOB.marker_beacon_colors[picked_color])
picked_color = pick(GLOB.marker_beacon_colors)
icon_state = "[initial(icon_state)][lowertext(picked_color)]-on"
+
+
+/obj/structure/marker_beacon/proc/update_state()
+ update_icon(UPDATE_ICON_STATE)
set_light(light_range, light_power, GLOB.marker_beacon_colors[picked_color])
+
/obj/structure/marker_beacon/attack_hand(mob/living/user)
. = ..()
if(.)
@@ -114,7 +120,7 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list(
if(do_after(user, remove_speed, target = src))
var/obj/item/stack/marker_beacon/M = new(drop_location())
M.picked_color = picked_color
- M.update_icon()
+ M.update_icon(UPDATE_ICON_STATE)
transfer_fingerprints_to(M)
user.put_in_hands(M, ignore_anim = FALSE)
playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
@@ -140,4 +146,4 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list(
return
if(input_color)
picked_color = input_color
- update_icon()
+ update_state()
diff --git a/code/modules/mining/equipment/mineral_scanner.dm b/code/modules/mining/equipment/mineral_scanner.dm
index fc49ee0993f..cf3f2508f58 100644
--- a/code/modules/mining/equipment/mineral_scanner.dm
+++ b/code/modules/mining/equipment/mineral_scanner.dm
@@ -43,6 +43,7 @@
desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear meson scanners for optimal results. This one has an extended range. \nIt has a speaker that can be toggled with alt+click"
name = "advanced automatic mining scanner"
icon_state = "adv_mining0"
+ base_icon_state = "adv_mining"
item_state = "analyzer"
w_class = WEIGHT_CLASS_SMALL
flags = CONDUCT
@@ -67,6 +68,7 @@
/obj/item/t_scanner/adv_mining_scanner/lesser
name = "automatic mining scanner"
icon_state = "mining0"
+ base_icon_state = "mining"
desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear meson scanners for optimal results. \nIt has a speaker that can be toggled with alt+click"
range = 4
cooldown = 50
diff --git a/code/modules/mining/equipment/mining_charges.dm b/code/modules/mining/equipment/mining_charges.dm
index 6a3bddc3667..4895441d3db 100644
--- a/code/modules/mining/equipment/mining_charges.dm
+++ b/code/modules/mining/equipment/mining_charges.dm
@@ -5,7 +5,7 @@
icon = 'icons/obj/mining.dmi'
icon_state = "mining-charge-2"
item_state = "charge_indust"
- det_time = 5
+ det_time = 5 SECONDS
notify_admins = FALSE // no need to make adminlogs on lavaland, while they are "safe" to use
var/timer_off = FALSE
var/installed = FALSE
@@ -192,13 +192,13 @@
. += "[bicon(charge)] [charge]. Current status: [charge.installed ? "ready to detonate" : "ready to deploy"]."
-/obj/item/detonator/update_icon()
- . = ..()
- if(bombs.len)
+/obj/item/detonator/update_icon_state()
+ if(length(bombs))
icon_state = "Detonator-1"
else
icon_state = initial(icon_state)
+
/obj/item/detonator/attack_self(mob/user)
playsound(src, 'sound/items/detonator.ogg', 40)
if(bombs.len)
@@ -213,5 +213,5 @@
charge.detonate()
else
to_chat(user, span_warning("There is no charges linked to a detonator!"))
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
. = ..()
diff --git a/code/modules/mining/equipment/regenerative_core.dm b/code/modules/mining/equipment/regenerative_core.dm
index a2f37176169..48b30d10617 100644
--- a/code/modules/mining/equipment/regenerative_core.dm
+++ b/code/modules/mining/equipment/regenerative_core.dm
@@ -120,14 +120,22 @@
. = ..()
update_icon()
-/obj/item/organ/internal/regenerative_core/legion/update_icon()
+
+/obj/item/organ/internal/regenerative_core/legion/update_icon_state()
icon_state = inert ? "legion_soul_inert" : "legion_soul"
- cut_overlays()
+
+
+/obj/item/organ/internal/regenerative_core/legion/update_overlays()
+ . = ..()
if(!inert && !preserved)
- add_overlay("legion_soul_crackle")
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
+ . += "legion_soul_crackle"
+ addtimer(CALLBACK(src, PROC_REF(buttons_update)), 0.1 SECONDS)
+
+
+/obj/item/organ/internal/regenerative_core/legion/proc/buttons_update()
+ for(var/datum/action/action as anything in actions)
+ action.UpdateButtonIcon()
+
/obj/item/organ/internal/regenerative_core/legion/go_inert()
..()
diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm
index c293d2f35a1..c9d4cf55234 100644
--- a/code/modules/mining/equipment/survival_pod.dm
+++ b/code/modules/mining/equipment/survival_pod.dm
@@ -197,12 +197,12 @@
name = "pod computer"
icon_state = "pod_computer"
icon = 'icons/obj/lavaland/pod_computer.dmi'
- anchored = 1
+ anchored = TRUE
density = 1
pixel_y = -32
/obj/item/gps/computer/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/wrench))
+ if(W.tool_behaviour == TOOL_WRENCH)
playsound(loc, W.usesound, 50, 1)
user.visible_message("[user] disassembles the gps.", \
"You start to disassemble the gps...", "You hear clanking and banging noises.")
@@ -250,7 +250,7 @@
var/obj/item/instrument/guitar/G = new(src)
load(G)
-/obj/machinery/smartfridge/survival_pod/update_icon()
+/obj/machinery/smartfridge/survival_pod/update_overlays()
return
/obj/machinery/smartfridge/survival_pod/accept_check(obj/item/O)
@@ -270,7 +270,7 @@
icon_state = "fans"
name = "environmental regulation system"
desc = "A large machine releasing a constant gust of air."
- anchored = 1
+ anchored = TRUE
density = 1
var/arbitraryatmosblockingvar = 1
var/buildstacktype = /obj/item/stack/sheet/metal
@@ -295,7 +295,7 @@
qdel(src)
/obj/structure/fans/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/wrench))
+ if(W.tool_behaviour == TOOL_WRENCH)
playsound(loc, W.usesound, 50, 1)
user.visible_message("[user] disassembles the fan.", \
"You start to disassemble the fan...", "You hear clanking and banging noises.")
@@ -333,12 +333,12 @@
icon_state = "tubes"
icon = 'icons/obj/lavaland/survival_pod.dmi'
name = "tubes"
- anchored = 1
+ anchored = TRUE
layer = MOB_LAYER - 0.2
density = 0
/obj/structure/tubes/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/wrench))
+ if(W.tool_behaviour == TOOL_WRENCH)
playsound(loc, W.usesound, 50, 1)
user.visible_message("[user] disassembles [src].", \
"You start to disassemble [src]...", "You hear clanking and banging noises.")
diff --git a/code/modules/mining/equipment/upgrades.dm b/code/modules/mining/equipment/upgrades.dm
index 715b95301bb..e45ecaf8b21 100644
--- a/code/modules/mining/equipment/upgrades.dm
+++ b/code/modules/mining/equipment/upgrades.dm
@@ -18,24 +18,39 @@
. = ..()
addtimer(CALLBACK(src, PROC_REF(go_inert)), 50 SECONDS) //you know...
+
+/obj/item/magmite_parts/update_icon_state()
+ icon_state = "upgrade_parts[inert ? "_inert" : ""]"
+
+
+/obj/item/magmite_parts/update_name(updates = ALL)
+ . = ..()
+ name = initial(name)
+ if(inert)
+ name = "inert [name]"
+
+
+/obj/item/magmite_parts/update_desc(updates = ALL)
+ . = ..()
+ desc = inert ? "It appears to have lost its magma-like glow." : initial(desc)
+
+
/obj/item/magmite_parts/proc/go_inert()
if(inert)
return
visible_message(span_warning("The [src] loses it's glow!"))
inert = TRUE
- name = "inert plasma magmite upgrade parts"
- icon_state = "upgrade_parts_inert"
- desc += "It appears to have lost its magma-like glow."
+ update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC)
+
/obj/item/magmite_parts/proc/restore()
if(!inert)
return
inert = FALSE
- name = initial(name)
- icon_state = initial(icon_state)
- desc = initial(desc)
+ update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC)
addtimer(CALLBACK(src, PROC_REF(go_inert)), 50 SECONDS)
+
/obj/item/magmite_parts/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
if(!proximity_flag)
return
diff --git a/code/modules/mining/equipment/weather_radio.dm b/code/modules/mining/equipment/weather_radio.dm
index 1c7937541f8..389f9954ebb 100644
--- a/code/modules/mining/equipment/weather_radio.dm
+++ b/code/modules/mining/equipment/weather_radio.dm
@@ -28,7 +28,7 @@
START_PROCESSING(SSprocessing, src)
set_frequency(SUP_FREQ)
update_light_color()
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
/obj/item/radio/weather_monitor/Destroy()
. = ..()
@@ -41,18 +41,18 @@
if(previous_level == warning_level && previous_danger == is_weather_dangerous)
return // No change
atom_say(get_warning_message())
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
update_light_color()
-/obj/item/radio/weather_monitor/update_icon()
- overlays.Cut()
+/obj/item/radio/weather_monitor/update_overlays()
+ . = ..()
switch(warning_level)
if(WEATHER_ALERT_CLEAR)
- overlays += state_normal
+ . += state_normal
if(WEATHER_ALERT_INCOMING)
- overlays += state_warning
+ . += state_warning
if(WEATHER_ALERT_IMMINENT_OR_ACTIVE)
- overlays += (is_weather_dangerous) ? state_danger : state_warning
+ . += is_weather_dangerous ? state_danger : state_warning
/obj/item/radio/weather_monitor/proc/update_light_color()
switch(warning_level)
diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm
index f880c90c394..3f2e15fa28b 100644
--- a/code/modules/mining/fulton.dm
+++ b/code/modules/mining/fulton.dm
@@ -38,15 +38,15 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons)
beacon = A
to_chat(user, "You link the extraction pack to the beacon system.")
-/obj/item/extraction_pack/MouseDrop(atom/over)
+/obj/item/extraction_pack/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
if(!..())
return FALSE
- if(!(loc == usr && loc.Adjacent(over)))
+ if(!(loc == usr && loc.Adjacent(over_object)))
return FALSE
- if(usr.stat || !ishuman(usr) || usr.incapacitated())
+ if(!ishuman(usr) || usr.incapacitated())
return FALSE
- over.add_fingerprint(usr)
- afterattack(over, usr, TRUE)
+ over_object.add_fingerprint(usr)
+ afterattack(over_object, usr, TRUE, params)
return TRUE
/obj/item/extraction_pack/afterattack(atom/movable/A, mob/living/carbon/human/user, flag, params)
diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm
index 8c805bfba7a..4738e26de91 100644
--- a/code/modules/mining/laborcamp/laborstacker.dm
+++ b/code/modules/mining/laborcamp/laborstacker.dm
@@ -6,7 +6,7 @@
icon = 'icons/obj/machines/mining_machines.dmi'
icon_state = "console"
density = FALSE
- anchored = 1
+ anchored = TRUE
var/obj/machinery/mineral/stacking_machine/laborstacker/stacking_machine = null
var/machinedir = SOUTH
var/obj/item/card/id/prisoner/inserted_id
@@ -165,7 +165,7 @@
icon = 'icons/obj/machines/mining_machines.dmi'
icon_state = "console"
density = FALSE
- anchored = 1
+ anchored = TRUE
/obj/machinery/mineral/labor_points_checker/attack_hand(mob/user)
. = ..()
diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm
index 9840225bb54..e5024d455dd 100644
--- a/code/modules/mining/lavaland/loot/colossus_loot.dm
+++ b/code/modules/mining/lavaland/loot/colossus_loot.dm
@@ -352,7 +352,7 @@
desc = "You can hardly comprehend this thing... which is why you can't see it."
icon_state = null //This shouldn't even be visible, so if it DOES show up, at least nobody will notice
density = 1
- anchored = 1
+ anchored = TRUE
resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE
var/mob/living/simple_animal/holder_animal
diff --git a/code/modules/mining/lavaland/loot/hierophant_loot.dm b/code/modules/mining/lavaland/loot/hierophant_loot.dm
index 1cd2ac26826..29958f11501 100644
--- a/code/modules/mining/lavaland/loot/hierophant_loot.dm
+++ b/code/modules/mining/lavaland/loot/hierophant_loot.dm
@@ -109,19 +109,18 @@
chaser_speed = max(chaser_speed + health_percent, 0.5) //one tenth of a second faster for each missing 10% of health
blast_range -= round(health_percent * 10) //one additional range for each missing 10% of health
-/obj/item/hierophant_club/update_icon()
+
+/obj/item/hierophant_club/update_icon_state()
icon_state = "hierophant_club[timer <= world.time ? "_ready":""][(beacon && !QDELETED(beacon)) ? "":"_beacon"]"
item_state = icon_state
- if(ismob(loc))
- var/mob/M = loc
- M.update_inv_l_hand()
- M.update_inv_r_hand()
- M.update_inv_back()
+ update_equipped_item()
+
/obj/item/hierophant_club/proc/prepare_icon_update()
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
sleep(timer - world.time)
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
+
/obj/item/hierophant_club/ui_action_click(mob/user, actiontype)
if(actiontype == /datum/action/item_action/toggle_unfriendly_fire) //toggle friendly fire...
@@ -174,7 +173,8 @@
user.visible_message("[user] starts to glow faintly...")
timer = world.time + 50
INVOKE_ASYNC(src, PROC_REF(prepare_icon_update))
- beacon.icon_state = "hierophant_tele_on"
+ beacon.teleporting = TRUE
+ beacon.update_icon(UPDATE_ICON_STATE)
var/obj/effect/temp_visual/hierophant/telegraph/edge/TE1 = new /obj/effect/temp_visual/hierophant/telegraph/edge(user.loc)
var/obj/effect/temp_visual/hierophant/telegraph/edge/TE2 = new /obj/effect/temp_visual/hierophant/telegraph/edge(beacon.loc)
if(do_after(user, 40, target = user) && user && beacon)
@@ -186,7 +186,8 @@
user.update_action_buttons_icon()
timer = world.time
INVOKE_ASYNC(src, PROC_REF(prepare_icon_update))
- beacon.icon_state = "hierophant_tele_off"
+ beacon.teleporting = FALSE
+ beacon.update_icon(UPDATE_ICON_STATE)
return
new /obj/effect/temp_visual/hierophant/telegraph(T, user)
new /obj/effect/temp_visual/hierophant/telegraph(source, user)
@@ -199,7 +200,8 @@
timer = world.time
INVOKE_ASYNC(src, PROC_REF(prepare_icon_update))
if(beacon)
- beacon.icon_state = "hierophant_tele_off"
+ beacon.teleporting = FALSE
+ beacon.update_icon(UPDATE_ICON_STATE)
return
if(is_blocked_turf(T, TRUE))
teleporting = FALSE
@@ -207,7 +209,8 @@
user.update_action_buttons_icon()
timer = world.time
INVOKE_ASYNC(src, PROC_REF(prepare_icon_update))
- beacon.icon_state = "hierophant_tele_off"
+ beacon.teleporting = FALSE
+ beacon.update_icon(UPDATE_ICON_STATE)
return
add_attack_logs(user, beacon, "Teleported self from ([AREACOORD(source)]) to ([AREACOORD(beacon)])")
new /obj/effect/temp_visual/hierophant/telegraph/teleport(T, user)
@@ -222,14 +225,16 @@
INVOKE_ASYNC(src, PROC_REF(teleport_mob), source, L, T, user) //regardless, take all mobs near us along
sleep(6) //at this point the blasts detonate
if(beacon)
- beacon.icon_state = "hierophant_tele_off"
+ beacon.teleporting = FALSE
+ beacon.update_icon(UPDATE_ICON_STATE)
else
qdel(TE1)
qdel(TE2)
timer = world.time
INVOKE_ASYNC(src, PROC_REF(prepare_icon_update))
if(beacon)
- beacon.icon_state = "hierophant_tele_off"
+ beacon.teleporting = FALSE
+ beacon.update_icon(UPDATE_ICON_STATE)
teleporting = FALSE
if(user)
user.update_action_buttons_icon()
@@ -295,4 +300,260 @@
var/obj/effect/temp_visual/hierophant/blast/B = new(t, user, friendly_fire_check)
B.damage = 15 //keeps monster damage boost due to lower damage
+/obj/item/clothing/accessory/necklace/hierophant_talisman
+ name = "Dormnant talisman of warding"
+ desc = "Hierophant's talisman of warding. It will save you."
+ icon = 'icons/obj/lavaland/artefacts.dmi'
+ icon_state = "hierophant_talisman_nonactive"
+ item_state = "hierophant_talisman_nonactive"
+ item_color = "hierophant_talisman_nonactive"
+ armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 20, "bio" = 20, "rad" = 5, "fire" = 100, "acid" = 100)
+ slot_flags = SLOT_TIE
+ allow_duplicates = FALSE
+ var/possessed = FALSE
+ var/mob/living/simple_animal/shade/talisman/slave // Talisman
+ var/obj/effect/proc_holder/spell/hierophant_talisman_heal/spell_heal
+ var/obj/effect/proc_holder/spell/hierophant_talisman_teleport/spell_teleport
+ var/obj/effect/proc_holder/spell/hierophant_talisman_message/spell_message
+
+/obj/item/clothing/accessory/necklace/hierophant_talisman/attack_self(mob/living/user)
+ if(possessed)
+ if(!slave)
+ to_chat(user, span_hierophant("Still searching unique soul for you.."))
+ return
+ if(slave.master != user.ckey)
+ to_chat(slave, span_hierophant("Now you are serving to [user.real_name]. You must ward him."))
+ to_chat(user, span_hierophant("Now this talisman is yours... It will ward you..."))
+ log_game("[user.real_name] has become master of [slave.ckey] hierophant's talisman.")
+ slave.master = user.ckey
+ else
+ to_chat(user, span_hierophant("This talisman is already yours... WHAT ELSE YOU NEED!?"))
+ return
+
+
+ to_chat(user, span_hierophant("You attempt to awake my appertience..."))
+
+ possessed = TRUE
+
+ var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as the spirit of [user.real_name]'s talisman of warding?", ROLE_PAI, FALSE, 15 SECONDS, source = src)
+ var/mob/dead/observer/theghost = null
+
+ if(length(candidates))
+ theghost = pick(candidates)
+ slave = new(src)
+ slave.ckey = theghost.ckey
+ slave.master = user.ckey
+ name = "Talisman of warding"
+ slave.real_name = name
+ slave.name = name
+ var/input = stripped_input(slave, "What are you named?", null, "", MAX_NAME_LEN)
+ if(QDELETED(src))
+ return
+ if(input)
+ name = input
+ slave.real_name = input
+ slave.name = input
+ log_game("[slave.ckey] has become spirit of [user.real_name]'s talisman.")
+ to_chat(slave, span_hierophant("Now you are serving to [user.real_name]. You must ward him."))
+ update_icon(UPDATE_ICON_STATE)
+ else
+ log_game("No one has decided to be [user.real_name]'s talisman.")
+ to_chat(user, span_hierophant("This talisman is dormnant... Try again or later..."))
+ possessed = FALSE
+
+/obj/item/clothing/accessory/necklace/hierophant_talisman/update_icon_state()
+ icon_state = "hierpohant_talisman_active"
+ item_state = "hierpohant_talisman_active"
+ item_color = "hierophant_talisman_active"
+
+/obj/item/clothing/accessory/necklace/hierophant_talisman/Initialize(mapload)
+ .=..()
+ spell_heal = new
+ spell_teleport = new
+ spell_message = new
+
+/obj/item/clothing/accessory/necklace/hierophant_talisman/Destroy()
+ for(var/mob/living/simple_animal/shade/talisman/S in contents)
+ to_chat(S, span_hierophant("You were destroyed! So... I will create another one in future."))
+ playsound(get_turf(src),'sound/magic/repulse.ogg', 200, 1)
+ S.ghostize()
+ qdel(S)
+ QDEL_NULL(spell_heal)
+ QDEL_NULL(spell_teleport)
+ QDEL_NULL(spell_message)
+ return ..()
+
+/obj/effect/proc_holder/spell/hierophant_talisman_heal
+ name = "Beacon of help"
+ desc = "Healing your master."
+ base_cooldown = 20 SECONDS
+ clothes_req = FALSE
+ human_req = FALSE
+ phase_allowed = TRUE
+ should_recharge_after_cast = FALSE
+ stat_allowed = UNCONSCIOUS
+ action_icon_state = "hierophant_talisman_heal"
+ action_background_icon_state = "bg_hierophant_talisman"
+ panel = "Hierophant Talisman"
+
+/obj/effect/proc_holder/spell/hierophant_talisman_heal/create_new_targeting()
+ var/datum/spell_targeting/targeted/T = new()
+ T.target_priority = SPELL_TARGET_CLOSEST
+ T.max_targets = 1
+ T.range = 1
+ T.use_turf_of_user = TRUE
+ return T
+
+/obj/effect/proc_holder/spell/hierophant_talisman_heal/valid_target(mob/living/carbon/human/target, mob/living/simple_animal/shade/talisman/user)
+ if (target.ckey == user.master)
+ return TRUE
+ return FALSE
+
+/obj/effect/proc_holder/spell/hierophant_talisman_heal/cast(list/targets, mob/living/simple_animal/shade/talisman/user = usr)
+ var/mob/living/carbon/human/target = targets[1]
+ target.adjustBruteLoss(-15)
+ target.adjustFireLoss(-15)
+ target.adjustToxLoss(-15)
+ if(target.health / target.maxHealth <= 0.25)
+ cooldown_handler.start_recharge(10 SECONDS)
+ to_chat(user, span_hierophant("This creature is dying... Pathetic but... You must protect this creature..."))
+ else
+ cooldown_handler.start_recharge(20 SECONDS)
+ to_chat(user, span_hierophant("You are warding... This creature... Very well my apprentice."))
+ to_chat(target, span_hierophant("My talisman is warding you... Pathetic..."))
+
+/obj/effect/proc_holder/spell/hierophant_talisman_teleport
+ name = "Hierophant's lesser teleportation"
+ desc = "Blink your master to location."
+ base_cooldown = 30 SECONDS
+ clothes_req = FALSE
+ human_req = FALSE
+ phase_allowed = TRUE
+ should_recharge_after_cast = FALSE
+ stat_allowed = UNCONSCIOUS
+ centcom_cancast = FALSE
+ action_icon_state = "hierophant_talisman_teleport"
+ action_background_icon_state = "bg_hierophant_talisman"
+ panel = "Hierophant Talisman"
+
+/obj/effect/proc_holder/spell/hierophant_talisman_teleport/create_new_targeting()
+ var/datum/spell_targeting/click/T = new()
+ T.allowed_type = /turf/simulated
+ T.range = 3
+ T.use_turf_of_user = TRUE
+ return T
+
+/obj/effect/proc_holder/spell/hierophant_talisman_teleport/cast(list/targets, mob/living/simple_animal/shade/talisman/user)
+ var/turf/target_turf = get_turf(targets[1])
+ for(var/mob/living/carbon/human/H in GLOB.human_list)
+ if(H.ckey == user.master)
+ var/turf/start_turf = get_turf(H)
+ H.forceMove(target_turf)
+ new /obj/effect/temp_visual/hierophant/telegraph(target_turf, src)
+ new /obj/effect/temp_visual/hierophant/telegraph(start_turf, src)
+ playsound(start_turf,'sound/machines/airlock_open.ogg', 200, 1)
+ if(H.health / H.maxHealth <= 0.25)
+ cooldown_handler.start_recharge(15 SECONDS)
+ to_chat(user, span_hierophant("Blink! Blink! Blink! You shall never surrender."))
+ user.say("Instant teleportation, my fellow friend!")
+ else
+ cooldown_handler.start_recharge(30 SECONDS)
+ to_chat(user, span_hierophant("Dance, my pretties!"))
+ user.say("Blink, my fellow friend!")
+ addtimer(CALLBACK(src, PROC_REF(talisman_teleport_2), target_turf, start_turf), 2)
+ break
+
+/obj/effect/proc_holder/spell/hierophant_talisman_teleport/proc/talisman_teleport_2(turf/T, turf/S)
+ new /obj/effect/temp_visual/hierophant/telegraph/teleport(T, src)
+ new /obj/effect/temp_visual/hierophant/telegraph/teleport(S, src)
+ animate(src, alpha = 0, time = 2, easing = EASE_OUT) //fade out
+ visible_message(span_hierophant("[src] fades out!"))
+ set_density(FALSE)
+ addtimer(CALLBACK(src, PROC_REF(talisman_teleport_3), T), 2)
+
+/obj/effect/proc_holder/spell/hierophant_talisman_teleport/proc/talisman_teleport_3(turf/T)
+ animate(src, alpha = 255, time = 2, easing = EASE_IN) //fade IN
+ set_density(TRUE)
+ visible_message(span_hierophant("[src] fades in!"))
+
+/obj/effect/proc_holder/spell/hierophant_talisman_message
+ name = "Telepathtic Message"
+ desc = "Send a telepathic message to those humans."
+ base_cooldown = 5 SECONDS
+ clothes_req = FALSE
+ human_req = FALSE
+ phase_allowed = TRUE
+ should_recharge_after_cast = TRUE
+ stat_allowed = UNCONSCIOUS
+ action_icon_state = "hierophant_talisman_message"
+ action_background_icon_state = "bg_hierophant_talisman"
+ panel = "Hierophant Talisman"
+
+/obj/effect/proc_holder/spell/hierophant_talisman_message/create_new_targeting()
+ var/datum/spell_targeting/click/T = new()
+ T.selection_type = SPELL_SELECTION_RANGE
+ T.use_turf_of_user = TRUE
+ return T
+
+/obj/effect/proc_holder/spell/hierophant_talisman_message/cast(list/targets, mob/living/simple_animal/shade/talisman/user)
+ var/mob/living/carbon/human/choice = targets[1]
+ var/msg = stripped_input(usr, "What do you wish to tell [choice]?", null, "")
+ if(!(msg))
+ return
+ add_say_logs(usr, msg, choice, "SLAUGHTER")
+ to_chat(usr, span_hierophant("You translating directly to mind [choice]: [msg]"))
+ to_chat(choice, "[span_deadsay(span_hierophant("A strange, magical and at the same time alien broadcast conveys to you... "))][span_hierophant("[msg]")]")
+ for(var/mob/dead/observer/G in GLOB.player_list)
+ G.show_message(span_hierophant("Hierophant's message from [usr] ([ghost_follow_link(usr, ghost=G)]) to [choice] ([ghost_follow_link(choice, ghost=G)]): [msg]"))
+
+/obj/item/clothing/accessory/necklace/hierophant_talisman/on_attached(obj/item/clothing/under/S, mob/user)
+ . = ..()
+ if(!ishuman(user) || !slave)
+ return
+ if(slave.master == user.ckey)
+ slave.mob_spell_list += spell_heal
+ slave.mob_spell_list += spell_teleport
+ slave.mob_spell_list += spell_message
+ spell_heal.action.Grant(slave)
+ spell_teleport.action.Grant(slave)
+ spell_message.action.Grant(slave)
+
+/obj/item/clothing/accessory/necklace/hierophant_talisman/on_removed(mob/user)
+ . = ..()
+ if(!ishuman(user) || !slave)
+ return
+ slave.mob_spell_list -= spell_heal
+ slave.mob_spell_list -= spell_teleport
+ slave.mob_spell_list -= spell_message
+ spell_heal.action.Remove(slave)
+ spell_teleport.action.Remove(slave)
+ spell_message.action.Remove(slave)
+
+/obj/item/clothing/accessory/necklace/hierophant_talisman/attached_unequip()
+ if(!ishuman(usr))
+ return
+ if(!slave)
+ return ..()
+ slave.mob_spell_list -= spell_heal
+ slave.mob_spell_list -= spell_teleport
+ slave.mob_spell_list -= spell_message
+ spell_heal.action.Remove(slave)
+ spell_teleport.action.Remove(slave)
+ spell_message.action.Remove(slave)
+ return ..()
+
+/obj/item/clothing/accessory/necklace/hierophant_talisman/attached_equip()
+ if(!ishuman(usr))
+ return
+ if(!slave)
+ return ..()
+ if(slave.master == usr.ckey)
+ slave.mob_spell_list += spell_heal
+ slave.mob_spell_list += spell_teleport
+ slave.mob_spell_list += spell_message
+ spell_heal.action.Grant(slave)
+ spell_teleport.action.Grant(slave)
+ spell_message.action.Grant(slave)
+ return ..()
+
#undef HIEROPHANT_CLUB_CARDINAL_DAMAGE
diff --git a/code/modules/mining/lavaland/loot/tendril_loot.dm b/code/modules/mining/lavaland/loot/tendril_loot.dm
index b8cf1d16289..1d1413d8bc7 100644
--- a/code/modules/mining/lavaland/loot/tendril_loot.dm
+++ b/code/modules/mining/lavaland/loot/tendril_loot.dm
@@ -21,62 +21,50 @@
name = "paradox bag"
desc = "Somehow, it's in two places at once."
-/obj/item/shared_storage/red/New()
- ..()
+/obj/item/shared_storage/red/Initialize(mapload)
+ . = ..()
if(!bag)
- var/obj/item/storage/backpack/shared/S = new(src)
+ var/obj/item/storage/backpack/shared/shared_storage = new(src)
var/obj/item/shared_storage/blue = new(loc)
+ bag = shared_storage
+ blue.bag = shared_storage
- bag = S
- blue.bag = S
/obj/item/shared_storage/attackby(obj/item/W, mob/user, params)
if(bag)
bag.loc = user
bag.attackby(W, user, params)
+ add_fingerprint(user)
+
+
+/obj/item/shared_storage/proc/open_bag(mob/user)
+ if(bag)
+ bag.loc = user
+ bag.attack_hand(user)
+ add_fingerprint(user)
+
/obj/item/shared_storage/attack_self(mob/living/carbon/user)
- if(!iscarbon(user))
- return
- if(src == user.l_hand || src == user.r_hand)
- if(bag)
- bag.loc = user
- bag.attack_hand(user)
- else
- ..()
+ if(!bag || !iscarbon(user) || !user.is_in_hands(src))
+ return ..()
-/obj/item/shared_storage/attack_hand(mob/living/carbon/user)
- if(!iscarbon(user))
- return
- if(loc == user && user.back && user.back == src)
- if(bag)
- bag.loc = user
- bag.attack_hand(user)
- else
- ..()
+ open_bag(user)
+
+
+/obj/item/shared_storage/AltClick(mob/user)
+ if(!bag || !iscarbon(user) || !Adjacent(user))
+ return ..()
-/obj/item/shared_storage/MouseDrop(atom/over_object)
- if(iscarbon(usr))
- var/mob/M = usr
+ open_bag(user)
- if(!over_object)
- return
- if(istype(M.loc, /obj/mecha))
- return
- if(!M.restrained() && !M.stat)
- playsound(loc, "rustle", 50, 1, -5)
+/obj/item/shared_storage/attack_hand(mob/living/carbon/user)
+ if(!iscarbon(user) || !bag || loc != user || !user.back || user.back != src)
+ return ..()
- if(istype(over_object, /obj/screen/inventory/hand))
- if(!M.drop_item_ground(src))
- return
- M.put_in_active_hand(src)
- else if(bag)
- bag.loc = usr
- bag.attack_hand(usr)
+ open_bag(user)
- add_fingerprint(M)
//Book of Babel
@@ -104,7 +92,7 @@
desc = "A flask with an almost-holy aura emitting from it. The label on the bottle says: 'erqo'hyy tvi'rf lbh jv'atf'."
list_reagents = list("flightpotion" = 5)
-/obj/item/reagent_containers/glass/bottle/potion/update_icon()
+/obj/item/reagent_containers/glass/bottle/potion/update_icon_state()
if(reagents.total_volume)
icon_state = "potionflask"
else
@@ -243,18 +231,26 @@
var/sight_flags = SEE_MOBS
var/lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
+
+/obj/item/wisp_lantern/update_icon_state()
+ if(!wisp)
+ icon_state = "lantern"
+ return
+ icon_state = "lantern[wisp.loc == src ? "" : "-blue"]"
+
+
/obj/item/wisp_lantern/attack_self(mob/user)
if(!wisp)
to_chat(user, "The wisp has gone missing!")
- icon_state = "lantern"
+ update_icon(UPDATE_ICON_STATE)
return
if(wisp.loc == src)
RegisterSignal(user, COMSIG_MOB_UPDATE_SIGHT, PROC_REF(update_user_sight))
to_chat(user, "You release the wisp. It begins to bob around your head.")
- icon_state = "lantern"
- spawn() wisp.orbit(user, 20) // spawn prevents endless loop in .orbit from blocking code execution here
+ update_icon(UPDATE_ICON_STATE)
+ INVOKE_ASYNC(src, TYPE_PROC_REF(/atom/movable, orbit), user, 20)
set_light(0)
user.update_sight()
@@ -272,7 +268,7 @@
user.update_sight()
to_chat(user, "Your vision returns to normal.")
- icon_state = "lantern-blue"
+ update_icon(UPDATE_ICON_STATE)
SSblackbox.record_feedback("tally", "wisp_lantern", 1, "Returned") // returned
/obj/item/wisp_lantern/Initialize(mapload)
diff --git a/code/modules/mining/lavaland/world_anvil.dm b/code/modules/mining/lavaland/world_anvil.dm
index 0912589648f..f4359696e61 100644
--- a/code/modules/mining/lavaland/world_anvil.dm
+++ b/code/modules/mining/lavaland/world_anvil.dm
@@ -29,13 +29,18 @@
GLOB.anvils -= src
. = ..()
-/obj/structure/world_anvil/update_icon()
+/obj/structure/world_anvil/update_icon_state()
icon_state = forge_charges > 0 ? "anvil_a" : "anvil"
+
+
+/obj/structure/world_anvil/proc/update_state()
+ update_icon(UPDATE_ICON_STATE)
if(forge_charges > 0)
set_light(4,1,LIGHT_COLOR_ORANGE)
else
set_light(0)
+
/obj/structure/world_anvil/examine(mob/user)
. = ..()
. += "It currently has [forge_charges] forge[forge_charges != 1 ? "s" : ""] remaining."
@@ -46,14 +51,14 @@
forge_charges = forge_charges + placed_ore.quality
to_chat(user,"You place down the gibtonite on the World Anvil, and watch as the gibtonite melts into it. The World Anvil is now heated enough for [forge_charges] forge[forge_charges > 1 ? "s" : ""].")
qdel(placed_ore)
- update_icon()
+ update_state()
return
if(istype(I, /obj/item/gem/amber))
var/obj/item/gem/amber/gem = I
forge_charges += 3
to_chat(user,"You place down the draconic amber on the World Anvil, and watch as amber melts into it. The World Anvil is now heated enough for [forge_charges] forge[forge_charges > 1 ? "s" : ""].")
qdel(gem)
- update_icon()
+ update_state()
return
if(forge_charges <= 0)
to_chat(user,"The World Anvil is not hot enough to be usable!")
@@ -83,5 +88,5 @@
forge_charges--
if(forge_charges <= 0)
visible_message("The World Anvil cools down.")
- update_icon()
+ update_state()
diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm
index 083945f9ce3..ad454a44f90 100644
--- a/code/modules/mining/machine_redemption.dm
+++ b/code/modules/mining/machine_redemption.dm
@@ -153,15 +153,16 @@
sheet_per_ore = S
SStgui.update_uis(src)
-/obj/machinery/mineral/ore_redemption/power_change()
- ..()
- update_icon()
+/obj/machinery/mineral/ore_redemption/power_change(forced = FALSE)
+ if(!..())
+ return
+ update_icon(UPDATE_ICON_STATE)
if(inserted_id && !powered())
visible_message("The ID slot indicator light flickers on [src] as it spits out a card before powering down.")
inserted_id.forceMove(get_turf(src))
inserted_id = null
-/obj/machinery/mineral/ore_redemption/update_icon()
+/obj/machinery/mineral/ore_redemption/update_icon_state()
if(powered())
icon_state = initial(icon_state)
else
diff --git a/code/modules/mining/machine_unloading.dm b/code/modules/mining/machine_unloading.dm
index 39feeb38a61..550c3865f0a 100644
--- a/code/modules/mining/machine_unloading.dm
+++ b/code/modules/mining/machine_unloading.dm
@@ -6,7 +6,7 @@
icon = 'icons/obj/machines/mining_machines.dmi'
icon_state = "unloader"
density = 1
- anchored = 1.0
+ anchored = TRUE
input_dir = WEST
output_dir = EAST
speed_process = 1
diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm
index 74acb4926e6..83cf8214b7c 100644
--- a/code/modules/mining/machine_vending.dm
+++ b/code/modules/mining/machine_vending.dm
@@ -119,14 +119,15 @@
inserted_id.forceMove(get_turf(src))
inserted_id = null
-/obj/machinery/mineral/equipment_vendor/power_change()
- ..()
- update_icon()
+/obj/machinery/mineral/equipment_vendor/power_change(forced = FALSE)
+ if(!..())
+ return
+ update_icon(UPDATE_ICON_STATE)
if(inserted_id && !powered())
visible_message("The ID slot indicator light flickers on \the [src] as it spits out a card before powering down.")
remove_id()
-/obj/machinery/mineral/equipment_vendor/update_icon()
+/obj/machinery/mineral/equipment_vendor/update_icon_state()
if(powered())
icon_state = initial(icon_state)
else
@@ -229,7 +230,7 @@
add_fingerprint(user)
return
if(panel_open)
- if(istype(I, /obj/item/crowbar))
+ if(I.tool_behaviour == TOOL_CROWBAR)
remove_id() //Prevents deconstructing the ORM from deleting whatever ID was inside it.
default_deconstruction_crowbar(user, I)
return TRUE
@@ -369,7 +370,7 @@
EQUIPMENT("Plushie", /obj/random/plushie, 750),
EQUIPMENT("Dnd set", /obj/item/storage/box/characters, 500),
EQUIPMENT("Dice set", /obj/item/storage/box/dice, 250),
- EQUIPMENT("Cards", /obj/item/deck/cards, 150),
+ EQUIPMENT("Cards", /obj/item/deck/cards, 150),
EQUIPMENT("Guitar", /obj/item/instrument/guitar, 750),
EQUIPMENT("Synthesizer", /obj/item/instrument/piano_synth, 1500),
EQUIPMENT("Diamond Pickaxe", /obj/item/pickaxe/diamond, 2000)
diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm
index ca8016d5e59..266e00e97c4 100644
--- a/code/modules/mining/ores_coins.dm
+++ b/code/modules/mining/ores_coins.dm
@@ -16,25 +16,31 @@
var/refined_type = null //What this ore defaults to being refined into
var/list/stack_overlays
-/obj/item/stack/ore/update_icon()
+
+/obj/item/stack/ore/update_overlays()
+ . = ..()
+
var/difference = min(ORESTACK_OVERLAYS_MAX, amount) - (LAZYLEN(stack_overlays)+1)
if(difference == 0)
+ . += stack_overlays
return
- else if(difference < 0 && LAZYLEN(stack_overlays)) //amount < stack_overlays, remove excess.
- cut_overlays()
- if (LAZYLEN(stack_overlays)-difference <= 0)
- stack_overlays = null;
+
+ if(difference < 0 && LAZYLEN(stack_overlays)) //amount < stack_overlays, remove excess.
+ if(LAZYLEN(stack_overlays)-difference <= 0)
+ stack_overlays = null
else
stack_overlays.len += difference
+
else if(difference > 0) //amount > stack_overlays, add some.
- cut_overlays()
for(var/i in 1 to difference)
var/mutable_appearance/newore = mutable_appearance(icon, icon_state)
newore.pixel_x = rand(-8,8)
newore.pixel_y = rand(-8,8)
LAZYADD(stack_overlays, newore)
+
if(stack_overlays)
- add_overlay(stack_overlays)
+ . += stack_overlays
+
/obj/item/stack/ore/Initialize(mapload, new_amount , merge = TRUE)
. = ..()
@@ -269,7 +275,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
return
if(wires && !primed)
- if(istype(I, /obj/item/wirecutters) || istype(I, /obj/item/multitool) || istype(I, /obj/item/assembly/signaler))
+ if(I.tool_behaviour == TOOL_WIRECUTTER || I.tool_behaviour == TOOL_MULTITOOL || istype(I, /obj/item/assembly/signaler))
wires.Interact(user)
return
@@ -277,7 +283,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
GibtoniteReaction(user)
return
if(primed)
- if(istype(I, /obj/item/mining_scanner) || istype(I, /obj/item/t_scanner/adv_mining_scanner) || istype(I, /obj/item/multitool) || istype(I, /obj/item/mecha_parts/mecha_equipment/mining_scanner))
+ if(istype(I, /obj/item/mining_scanner) || istype(I, /obj/item/t_scanner/adv_mining_scanner) || I.tool_behaviour == TOOL_MULTITOOL || istype(I, /obj/item/mecha_parts/mecha_equipment/mining_scanner))
primed = 0
user.visible_message("The chain reaction was stopped! ...The ore's quality looks diminished.", "You stopped the chain reaction. ...The ore's quality looks diminished.")
icon_state = "Gibtonite ore"
diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm
index 056d86386c0..f33fc6814e0 100644
--- a/code/modules/mining/satchel_ore_boxdm.dm
+++ b/code/modules/mining/satchel_ore_boxdm.dm
@@ -22,7 +22,7 @@
S.remove_from_storage(O, src) //This will move the item to this item's contents
CHECK_TICK
to_chat(user, "You empty the satchel into the box.")
- else if(istype(W, /obj/item/crowbar))
+ else if(W.tool_behaviour == TOOL_CROWBAR)
playsound(src, W.usesound, 50, 1)
var/obj/item/crowbar/C = W
if(do_after(user, 50 * C.toolspeed * gettoolspeedmod(user), target = src))
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index aa3a71e62d3..3e71a7c912a 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -95,11 +95,13 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
//starts ghosts off with all HUDs.
show_me_the_hud(THOUGHTS_HUD)
toggle_all_huds_on(body)
+ RegisterSignal(src, COMSIG_MOB_HUD_CREATED, PROC_REF(set_ghost_darkness_level)) //something something don't call this until we have a HUD
..()
/mob/dead/observer/Destroy()
toggle_all_huds_off()
+ UnregisterSignal(src, COMSIG_MOB_HUD_CREATED)
if(ghostimage)
GLOB.ghost_images -= ghostimage
QDEL_NULL(ghostimage)
@@ -114,6 +116,14 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
if(!invisibility)
. += "It seems extremely obvious."
+/mob/dead/observer/proc/set_ghost_darkness_level()
+ if(!client)
+ return
+ UnregisterSignal(src, COMSIG_MOB_HUD_CREATED)
+ lighting_alpha = client.prefs.ghost_darkness_level //Remembers ghost lighting pref
+ update_sight()
+
+
// This seems stupid, but it's the easiest way to avoid absolutely ridiculous shit from happening
// Copying an appearance directly from a mob includes it's verb list, it's invisibility, it's alpha, and it's density
// You might recognize these things as "fucking ridiculous to put in an appearance"
@@ -605,19 +615,22 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
update_sight()
to_chat(usr, "You [(ghostvision?"now":"no longer")] have ghost vision.")
-/mob/dead/observer/verb/toggle_darkness()
- set name = "Toggle Darkness"
+/mob/dead/observer/verb/pick_darkness()
+ set name = "Pick Darkness"
+ set desc = "Choose how much darkness you want to see."
set category = "Ghost"
- switch(lighting_alpha)
- if (LIGHTING_PLANE_ALPHA_VISIBLE)
- lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
- if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE)
- lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
- if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE)
- lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
- else
- lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
-
+ var/list/ghost_darkness_levels = list("Strong Darkness" = LIGHTING_PLANE_ALPHA_VISIBLE,
+ "Darkness" = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE,
+ "Light Darkness" = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE,
+ "No Darkness" = LIGHTING_PLANE_ALPHA_INVISIBLE)
+ var/desired_dark = tgui_input_list(usr, "Choose how much darkness you want to see", "Pick darkness", ghost_darkness_levels)
+ if(isnull(desired_dark))
+ return
+ if(!client)
+ return
+ client.prefs.ghost_darkness_level = ghost_darkness_levels[desired_dark]
+ client.prefs.save_preferences(src)
+ lighting_alpha = client.prefs.ghost_darkness_level
update_sight()
/mob/dead/observer/update_sight()
diff --git a/code/modules/mob/holder_pet_carrier.dm b/code/modules/mob/holder_pet_carrier.dm
index 2a3be99a13e..25a2bc9199d 100644
--- a/code/modules/mob/holder_pet_carrier.dm
+++ b/code/modules/mob/holder_pet_carrier.dm
@@ -30,7 +30,7 @@
. = ..()
if(!color_skin)
color_skin = pick(possible_skins)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
/obj/item/pet_carrier/Destroy()
@@ -83,19 +83,16 @@
return FALSE
target.forceMove(src)
- name += " ([target.name])"
- if(target.desc)
- desc += "\n\nВнутри [target.name]\n"
- desc += target.desc
contains_pet = TRUE
+ update_appearance(UPDATE_OVERLAYS|UPDATE_NAME|UPDATE_DESC)
to_chat(user, span_notice("Вы поместили [target.name] в [name]."))
to_chat(target, span_notice("[user.name] поместил[genderize_ru(user.gender,"","а","о","и")] вас в [name]."))
- update_icon()
return TRUE
/obj/item/pet_carrier/proc/try_free_content(atom/new_location, mob/user)
+ add_fingerprint(user)
if(!opened)
if(user)
to_chat(user, span_warning("Ваша переноска закрыта! Содержимое невозможно выгрузить!"))
@@ -104,27 +101,41 @@
/obj/item/pet_carrier/proc/free_content(atom/new_location)
- if(istype(loc,/turf) || length(contents))
- for(var/mob/living/L in contents)
- var/atom/movable/mob_container
- mob_container = L
- mob_container.forceMove(new_location ? new_location : get_turf(src))
+ if(isturf(loc) || length(contents))
+ var/atom/drop_loc = new_location ? new_location : get_turf(src)
+ for(var/mob/living/animal in contents)
+ animal.forceMove(drop_loc)
contains_pet = FALSE
- name = initial(name)
- desc = initial(desc)
- update_icon()
- L.resting = FALSE
+ update_appearance(UPDATE_OVERLAYS|UPDATE_NAME|UPDATE_DESC)
+ animal.resting = FALSE
return TRUE
return FALSE
/obj/item/pet_carrier/proc/change_state()
opened = !opened
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
-/obj/item/pet_carrier/update_icon()
- overlays.Cut()
+/obj/item/pet_carrier/update_name(updates = ALL)
+ . = ..()
+ name = initial(name)
+ var/mob/living/animal = locate() in src
+ if(animal)
+ name += " ([animal.name])"
+
+
+/obj/item/pet_carrier/update_desc(updates = ALL)
+ . = ..()
+ desc = initial(desc)
+ var/mob/living/animal = locate() in src
+ if(animal)
+ desc += "\n\nВнутри [animal.name]\n"
+ desc += animal.desc
+
+
+/obj/item/pet_carrier/update_overlays()
+ . = ..()
if(contains_pet)
var/mob/living/M
for(var/mob/living/temp_M in contents)
@@ -133,15 +144,13 @@
var/image/I = image(M.icon, icon_state = M.icon_state)
I.color = opened ? contains_pet_color_open : contains_pet_color_close
I.pixel_y = M.mob_size <= MOB_SIZE_TINY ? 6 : 3
- overlays += I
+ . += I
if(!opened)
- var/image/I = image(icon, icon_state = "[icon_state]_door")
- overlays += I
+ . += image(icon, icon_state = "[icon_state]_door")
if(color_skin)
- var/image/I = image(icon, icon_state = "[icon_state]_[color_skin]")
- overlays += I
+ . += image(icon, icon_state = "[icon_state]_[color_skin]")
/obj/item/pet_carrier/emp_act(intensity)
@@ -158,7 +167,7 @@
var/breakout_time = 60 SECONDS
var/breakout_time_open = 5 SECONDS
- to_chat(L, span_warning("Вы начали вылезать из переноски (это займет [breakout_time_open] секунд, не двигайтесь)."))
+ to_chat(L, span_warning("Вы начали вылезать из переноски (это займет [breakout_time_open/10] секунд, не двигайтесь)."))
var/atom/target_atom = src
if(ishuman(loc))
@@ -175,7 +184,7 @@
visible_message(span_warning("[L.name] вылез из переноски."))
return
- to_chat(L, span_warning("Вы начали ломиться в закрытую дверцу переноски и пытаетесь её выбить или открыть (это займет [breakout_time] секунд, не двигайтесь)."))
+ to_chat(L, span_warning("Вы начали ломиться в закрытую дверцу переноски и пытаетесь её выбить или открыть (это займет [breakout_time/10] секунд, не двигайтесь)."))
for(var/mob/O in viewers(usr.loc))
O.show_message(span_danger("[name] начинает трястись!"), 1)
@@ -220,49 +229,37 @@
try_free_content(null, usr)
-/obj/item/pet_carrier/MouseDrop(obj/over_object)
- if(ishuman(usr))
- var/mob/M = usr
- if(istype(M.loc, /obj/mecha) || M.incapacitated(FALSE, TRUE, TRUE)) // Stops inventory actions in a mech as well as while being incapacitated
- return
+/obj/item/pet_carrier/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
+ if(!ishuman(usr))
+ return FALSE
- if(over_object == M && Adjacent(M)) // this must come before the screen objects only block
- try_free_content(null, M)
- return
+ var/mob/living/carbon/human/user = usr
+
+ // Stops inventory actions in a mech, while ventcrawling and while being incapacitated
+ if(ismecha(user.loc) || is_ventcrawling(user) || user.incapacitated(FALSE, TRUE, TRUE))
+ return FALSE
+
+ if(over_object == user && user.Adjacent(src)) // this must come before the screen objects only block
+ try_free_content(user = user)
+ return FALSE
+
+ if(opened && (istype(over_object, /obj/structure/table) || istype(over_object, /turf/simulated/floor) \
+ && length(contents) && loc == user && !user.incapacitated() && user.Adjacent(over_object)))
+
+ if(alert(user, "Вытащить питомца из [name] на [over_object.name]?", "Подтверждение", "Да", "Нет") != "Да")
+ return FALSE
+
+ if(!opened || !user || !over_object || user.incapacitated() || loc != user || !user.Adjacent(over_object))
+ return FALSE
+
+ user.face_atom(over_object)
+ user.visible_message(
+ span_notice("[user] вытащил питомца из [name] на [over_object.name]."),
+ span_notice("Вы вытащили питомца из [name] на [over_object.name]."),
+ )
+ try_free_content(get_turf(over_object), user)
+ return FALSE
+
+ return ..()
- if((istype(over_object, /obj/structure/table) || istype(over_object, /turf/simulated/floor)) \
- && length(contents) && loc == usr && !usr.stat && !usr.restrained() && usr.canmove && over_object.Adjacent(usr))
- var/turf/T = get_turf(over_object)
- if(istype(over_object, /turf/simulated/floor))
- if(get_turf(usr) != T)
- return // Can only empty containers onto the floor under you
- if("Да" != alert(usr,"Вытащить питомца из [name] на [T.name]?","Подтверждение","Да","Нет"))
- return
- if(!(usr && over_object && contents.len && loc == usr && !usr.stat && !usr.restrained() && usr.canmove && get_turf(usr) == T))
- return // Something happened while the player was thinking
-
- usr.face_atom(over_object)
- usr.visible_message(span_notice("[usr] вытащил питомца из [name] на [over_object.name]."),
- span_notice("Вы вытащили питомца из [name] на [over_object.name]."))
-
- try_free_content(T, usr)
- return TRUE
-
- if(!(istype(over_object, /obj/screen)))
- return ..()
- if(!(loc == usr) || (loc && loc.loc == usr))
- return
- playsound(loc, "rustle", 50, TRUE, -5)
- if(!(M.restrained()) && !(M.stat))
- switch(over_object.name)
- if("r_hand")
- if(!M.drop_item_ground(src))
- return
- M.put_in_r_hand(src, ignore_anim = FALSE)
- if("l_hand")
- if(!M.drop_item_ground(src))
- return
- M.put_in_l_hand(src, ignore_anim = FALSE)
- add_fingerprint(usr)
- return
diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm
index a930408f626..7ee5a2169cc 100644
--- a/code/modules/mob/language.dm
+++ b/code/modules/mob/language.dm
@@ -1,35 +1,64 @@
#define SCRAMBLE_CACHE_LEN 20
-
/*
+ When creating new 2 letter language keys, use the following naming scheme:
+ For languages with a compound name, use the first letter of each word whenever possible, for example: Sol Common = "sc".
+ For racial languages, whenever possible, use the first two letters of the race name or use euphony for associative rows, for example: Vulpkanin = "vu" or Canilunzt = "ca".
+ Also don't forget about code/__DEFINES/language.dm
+
+
Datum based languages. Easily editable and modular.
Busy letters for language:
- a b d f g j k o q v x y
- aa as bo db fa fm fn fs vu
+ un ta vu sk vo di tr ki sl gr dr ni
+ xm db wr xh ts ch hs sh ab gl bo bi dt
+ sw gc sc tb gt cl nr mo ne st fa wo
+
+
+ Busy letters by radio(eng):
+ c e h i l m n p r s t u w x
+
- Busy symbols for language:
- 0 1 2 3 4 5 6 7 8 9
- % ? ^
+ Busy letters by radio(rus):
+ б г д е ё з к р с т у ц ч ш ы ь я э
- CAUTION! The key must not repeat the key of the radio channel
- and must not contain prohibited characters
+
+ Busy symbols by radio:
+ ~ , $ _ - + * 1 2 3
+
+ CAUTION! The key must not repeat the key of the radio channel
+ and must not contain prohibited characters!
*/
/datum/language
- var/name = "an unknown language" // Fluff name of language if any.
- var/desc = "A language." // Short description for 'Check Languages'.
- var/speech_verb = "says" // 'says', 'hisses', 'farts'.
- var/ask_verb = "asks" // Used when sentence ends in a ?
- var/list/exclaim_verbs = list("exclaims") // Used when sentence ends in a !
- var/whisper_verb // Optional. When not specified speech_verb + quietly/softly is used instead.
- var/colour = "body" // CSS style to use for strings in this language.
- var/key = "x" // Character used to speak in language eg. :o for Unathi.
- var/flags = 0 // Various language flags.
- var/native // If set, non-native speakers will have trouble speaking.
- var/list/syllables // Used when scrambling text for a non-speaker.
- var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string.
- var/follow = 0 // Applies to HIVEMIND languages - should a follow link be included for dead mobs?
- var/english_names = 0 // Do we want English names by default, no matter what?
+ /// Fluff name of language if any.
+ var/name = "an unknown language"
+ /// Short description for 'Check Languages'.
+ var/desc = "A language."
+ /// 'says', 'hisses', 'farts'.
+ var/speech_verb = "says"
+ /// Used when sentence ends in a '?'.
+ var/ask_verb = "asks"
+ /// Used when sentence ends in a '!'.
+ var/list/exclaim_verbs = list("exclaims")
+ /// Optional. When not specified speech_verb + quietly/softly is used instead.
+ var/whisper_verb
+ /// CSS style to use for strings in this language.
+ var/colour = "body"
+ /// Character used to speak in language eg. '"un"' for Unathi.
+ var/key = "key"
+ /// Various language flags.
+ var/flags = 0
+ /// If set, non-native speakers will have trouble speaking.
+ var/native
+ /// Used when scrambling text for a non-speaker.
+ var/list/syllables
+ /// Likelihood of getting a space in the random scramble string.
+ var/list/space_chance = 55
+ /// Applies to HIVEMIND languages - should a follow link be included for dead mobs?
+ var/follow = FALSE
+ /// Do we want English names by default, no matter what?
+ var/english_names = FALSE
+ /// List that saves sentences spoken in this language, so as not to generate different scrambles of syllables for the same sentences.
var/list/scramble_cache = list()
/// Do we want to override the word-join character for scrambled text? If null, defaults to " " or ". "
var/join_override
@@ -65,20 +94,20 @@
var/input_size = length(input)
var/scrambled_text = ""
- var/capitalize = 1
+ var/capitalize = TRUE
while(length(scrambled_text) < input_size)
var/next = pick(syllables)
if(capitalize)
next = capitalize(next)
- capitalize = 0
+ capitalize = FALSE
scrambled_text += next
var/chance = rand(100)
if(join_override)
scrambled_text += join_override
else if(chance <= 5)
scrambled_text += ". "
- capitalize = 1
+ capitalize = TRUE
else if(chance > 5 && chance <= space_chance)
scrambled_text += " "
@@ -116,7 +145,7 @@
if(!speaker_mask)
speaker_mask = speaker.name
- var/msg = "[name], [speaker_mask] [get_spoken_verb(message)], [format_message(message)]"
+ var/msg = "[name], [speaker_mask] [genderize_decode(speaker, get_spoken_verb(message))], [format_message(message)]"
for(var/mob/player in GLOB.player_list)
if(istype(player,/mob/dead) && follow)
@@ -145,8 +174,7 @@
/datum/language/noise
name = "Noise"
desc = "Noises"
- key = ""
- flags = RESTRICTED|NONGLOBAL|INNATE|NO_TALK_MSG|NO_STUTTER
+ flags = RESTRICTED|NONGLOBAL|INNATE|NO_TALK_MSG|NO_STUTTER|NOBABEL
/datum/language/noise/format_message(message)
return "[message]"
@@ -165,7 +193,7 @@
ask_verb = "hisses"
exclaim_verbs = list("roars")
colour = "soghun"
- key = "o"
+ key = "un"
flags = RESTRICTED
syllables = list("za","az","ze","ez","zi","iz","zo","oz","zu","uz","zs","sz","ha","ah","he","eh","hi","ih", \
"ho","oh","hu","uh","hs","sh","la","al","le","el","li","il","lo","ol","lu","ul","ls","sl","ka","ak","ke","ek", \
@@ -186,7 +214,7 @@
ask_verb = "mrowls"
exclaim_verbs = list("yowls")
colour = "tajaran"
- key = "j"
+ key = "ta"
flags = RESTRICTED
syllables = list("rr","rr","tajr","kir","raj","kii","mir","kra","ahk","nal","vah","khaz","jri","ran","darr", \
"mi","jri","dynh","manq","rhe","zar","rrhaz","kal","chur","eech","thaa","dra","jurl","mah","sanu","dra","ii'r", \
@@ -198,7 +226,7 @@
var/list/ru_name_syllables = list("кан","тай","кир","раи","кии","мир","кра","тэк","нал","вар","хар","марр","ран","дарр", \
"мирк","ири","дин","манг","рик","зар","раз","кель","шера","тар","кей","ар","но","маи","зир","кер","нир","ра",\
"ми","рир","сей","эка","гир","ари","нэй","нре","ак","таир","эрай","жин","мра","зур","рин","сар","кин","рид","эра","ри","эна")
- var/apostrophe = "’"
+ var/apostrophe = "'"
var/new_name = ""
var/full_name = ""
@@ -226,7 +254,7 @@
ask_verb = "rurs"
exclaim_verbs = list("barks")
colour = "vulpkanin"
- key = "7"
+ key = "vu"
flags = RESTRICTED
syllables = list("rur","ya","cen","rawr","bar","kuk","tek","qat","uk","wu","vuh","tah","tch","schz","auch", \
"ist","ein","entch","zwichs","tut","mir","wo","bis","es","vor","nic","gro","lll","enem","zandt","tzch","noch", \
@@ -240,7 +268,7 @@
ask_verb = "warbles"
exclaim_verbs = list("warbles")
colour = "skrell"
- key = "k"
+ key = "sk"
flags = RESTRICTED
syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!")
@@ -251,7 +279,7 @@
ask_verb = "creels"
exclaim_verbs = list("loudly skrees")
colour = "vox"
- key = "v"
+ key = "vo"
flags = RESTRICTED | WHITELISTED
syllables = list("ti","ti","ti","hi","hi","ki","ki","ki","ki","ya","ta","ha","ka","ya","yi","chi","cha","kah", \
"SKRE","AHK","EHK","RAWK","KRA","AAA","EEE","KI","II","KRI","KA")
@@ -273,7 +301,7 @@
ask_verb = "creaks"
exclaim_verbs = list("rustles")
colour = "diona"
- key = "q"
+ key = "di"
flags = RESTRICTED
syllables = list("hs","zt","kr","st","sh")
@@ -289,7 +317,7 @@
ask_verb = "queries"
exclaim_verbs = list("exclaims")
colour = "trinary"
- key = "5"
+ key = "tr"
flags = RESTRICTED | WHITELISTED
syllables = list("0+2+0+1+1","0+1+2+2+2","1+0+1+0+0","1+0+2+1+0","2+1+0+1+2","0+2+0+1+1","2+1+2+0+0","1+0+0+2","2+0+0+1","0+0+0+2","0+0+1+2","0+0+1+2","0+0+0","1+2+0","1+2+1","2+0+1","2+2+0","1+0","1+1","0")
@@ -308,7 +336,7 @@
ask_verb = "rubs their antennae together"
exclaim_verbs = list("rubs their antennae together")
colour = "kidan"
- key = "4"
+ key = "ki"
flags = RESTRICTED | WHITELISTED
syllables = list("click","clack")
@@ -328,7 +356,7 @@
ask_verb = "bubbles and pops"
exclaim_verbs = list("bubbles and pops")
colour = "slime"
- key = "f"
+ key = "sl"
flags = RESTRICTED | WHITELISTED
syllables = list("blob","plop","pop","bop","boop")
@@ -339,7 +367,7 @@
ask_verb = "inquires"
exclaim_verbs = list("imparts")
colour = "abductor"
- key = "^"
+ key = "gr"
flags = RESTRICTED | HIVEMIND
follow = TRUE
@@ -374,7 +402,7 @@
ask_verb = "hums"
exclaim_verbs = list("rumbles")
colour = "drask"
- key = "%"
+ key = "dr"
flags = RESTRICTED | WHITELISTED
syllables = list("hoorb","vrrm","ooorm","urrrum","ooum","ee","ffm","hhh","mn","ongg")
@@ -391,7 +419,7 @@
ask_verb = "flaps"
exclaim_verbs = list("chatters")
colour = "moth"
- key = "#"
+ key = "ni"
flags = RESTRICTED | WHITELISTED
join_override = "-"
syllables = list("år", "i", "går", "sek", "mo", "ff", "ok", "gj", "ø", "gå", "la", "le",
@@ -412,10 +440,10 @@
speech_verb = "says"
exclaim_verbs = list("exclaims", "shouts", "yells")
whisper_verb = "whispers"
- key = "9"
+ key = "gc"
flags = RESTRICTED
syllables = list("blah","blah","blah","bleh","meh","neh","nah","wah")
- english_names = 1
+ english_names = TRUE
/datum/language/human
name = "Sol Common"
@@ -424,10 +452,10 @@
exclaim_verbs = list("exclaims", "shouts", "yells")
whisper_verb = "whispers"
colour = "solcom"
- key = "1"
+ key = "sc"
flags = RESTRICTED
syllables = list("tao","shi","tzu","yi","com","be","is","i","op","vi","ed","lec","mo","cle","te","dis","e")
- english_names = 1
+ english_names = TRUE
// Galactic common languages (systemwide accepted standards).
/datum/language/trader
@@ -435,7 +463,7 @@
desc = "Maintained by the various trading cartels in major systems, this elegant, structured language is used for bartering and bargaining."
speech_verb = "enunciates"
colour = "say_quote"
- key = "2"
+ key = "tb"
space_chance = 100
syllables = list("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit",
"sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore",
@@ -453,7 +481,7 @@
ask_verb = "gnarls"
exclaim_verbs = list("snarls")
colour = "gutter"
- key = "3"
+ key = "gt"
syllables = list ("gra","ba","ba","breh","bra","rah","dur","ra","ro","gro","go","ber","bar","geh","heh","gra")
/datum/language/clown
@@ -463,7 +491,7 @@
ask_verb = "honks"
exclaim_verbs = list("toots", "wubs", "honks")
colour = "clown"
- key = "0"
+ key = "cl"
syllables = list ("honk","squeak","bonk","toot","narf","zub","wee","wub","norf")
/datum/language/com_srus
@@ -473,9 +501,9 @@
whisper_verb = "mutters"
exclaim_verbs = list("exaggerates")
colour = "com_srus"
- key = "?"
+ key = "nr"
space_chance = 65
- english_names = 1
+ english_names = TRUE
syllables = list("dyen","bar","bota","vyek","tvo","slov","slav","syen","doup","vah","laz","gloz","yet",
"nyet","da","sky","glav","glaz","netz","doomat","zat","moch","boz",
"comy","vrad","vrade","tay","bli","ay","nov","livn","tolv","glaz","gliz",
@@ -493,7 +521,7 @@
ask_verb = "chitters"
exclaim_verbs = list("buzzes")
colour = "alien"
- key = "y"
+ key = "wr"
flags = RESTRICTED | HIVEMIND | NOBABEL
follow = TRUE
@@ -513,18 +541,18 @@
speech_verb = "hisses"
ask_verb = "hisses"
exclaim_verbs = list("hisses")
- key = "6"
+ key = "xm"
flags = RESTRICTED
syllables = list("sss","sSs","SSS")
/datum/language/xenos
- name = "Hivemind"
+ name = "Xenomorph Hivemind"
desc = "Xenomorphs have the strange ability to commune over a psychic hivemind."
speech_verb = "hisses"
ask_verb = "hisses"
exclaim_verbs = list("hisses")
colour = "alien"
- key = "a"
+ key = "xh"
flags = RESTRICTED | HIVEMIND | NOBABEL
follow = TRUE
@@ -535,17 +563,17 @@
ask_verb = "chitters"
exclaim_verbs = list("chitters")
colour = "terrorspider"
- key = "as"
+ key = "ts"
flags = RESTRICTED | HIVEMIND | NOBABEL
follow = TRUE
/datum/language/ling
- name = "Changeling"
+ name = "Changeling Hivemind"
desc = "Although they are normally wary and suspicious of each other, changelings can commune over a distance."
speech_verb = "says"
colour = "changeling"
- key = "g"
+ key = "ch"
flags = RESTRICTED | HIVEMIND | NOBABEL
follow = TRUE
@@ -558,11 +586,11 @@
..(speaker,message)
/datum/language/eventling
- name = "Infiltrated changeling"
+ name = "Infiltrated Changeling Hivemind"
desc = "Although they are normally wary and suspicious of each other, changelings can commune over a distance."
speech_verb = "says"
colour = "changeling"
- key = "gi"
+ key = "hs"
flags = RESTRICTED | HIVEMIND | NOBABEL
follow = TRUE
@@ -579,7 +607,7 @@
desc = "Shadowlings and their thralls are capable of communicating over a psychic hivemind."
speech_verb = "says"
colour = "shadowling"
- key = "8"
+ key = "sh"
flags = RESTRICTED | HIVEMIND | NOBABEL
follow = TRUE
@@ -598,7 +626,7 @@
ask_verb = "gibbers"
exclaim_verbs = list("gibbers")
colour = "abductor"
- key = "aa" //doesn't matter, this is their default and only language
+ key = "ab"
flags = RESTRICTED | HIVEMIND | NOBABEL
follow = TRUE
@@ -613,15 +641,21 @@
return TRUE
return FALSE
-/datum/language/abductor/golem
+/datum/language/golem
name = "Golem Mindlink"
desc = "Communicate with other alien alloy golems through a psychic link."
+ speech_verb = "gibbers"
+ ask_verb = "gibbers"
+ exclaim_verbs = list("gibbers")
+ colour = "abductor"
+ key = "gl"
+ flags = RESTRICTED | HIVEMIND | NOBABEL
follow = TRUE
-/datum/language/abductor/golem/check_special_condition(mob/living/carbon/human/other, mob/living/carbon/human/speaker)
- return TRUE
+/datum/language/golem/broadcast(mob/living/speaker, message, speaker_mask)
+ ..(speaker,message,speaker.real_name)
-/datum/language/corticalborer
+/datum/language/borer
name = "Cortical Link"
desc = "Cortical borers possess a strange link between their tiny minds."
speech_verb = "sings"
@@ -632,7 +666,7 @@
flags = RESTRICTED | HIVEMIND | NOBABEL
follow = TRUE
-/datum/language/corticalborer/broadcast(mob/living/speaker, message, speaker_mask)
+/datum/language/borer/broadcast(mob/living/speaker, message, speaker_mask)
var/mob/living/simple_animal/borer/B
if(iscarbon(speaker))
@@ -652,7 +686,7 @@
speech_verb = "states"
ask_verb = "queries"
exclaim_verbs = list("declares")
- key = "b"
+ key = "bi"
flags = RESTRICTED | HIVEMIND | NOBABEL
follow = TRUE
var/drone_only
@@ -699,7 +733,7 @@
ask_verb = "transmits"
exclaim_verbs = list("transmits")
colour = "say_quote"
- key = "d"
+ key = "dt"
flags = RESTRICTED | HIVEMIND | NOBABEL
drone_only = TRUE
follow = TRUE
@@ -722,35 +756,44 @@
ask_verb = "tones"
exclaim_verbs = list("tones")
colour = "say_quote"
- key = "as"//Zwarmer...Or Zerg!
+ key = "sw"//Zwarmer...Or Zerg!
flags = RESTRICTED | HIVEMIND | NOBABEL
follow = TRUE
-// Language handling.
-/mob/proc/add_language(language)
- var/datum/language/new_language = GLOB.all_languages[language]
+/datum/language/human/monkey
+ name = "Chimpanzee"
+ desc = "Ook ook ook."
+ speech_verb = "chimpers"
+ ask_verb = "chimpers"
+ exclaim_verbs = list("screeches")
+ key = "mo"
- if(!istype(new_language) || (new_language in languages))
- return FALSE
+/datum/language/skrell/monkey
+ name = "Neara"
+ desc = "Squik squik squik."
+ key = "ne"
- languages |= new_language
- return TRUE
+/datum/language/unathi/monkey
+ name = "Stok"
+ desc = "Hiss hiss hiss."
+ key = "st"
-/mob/proc/remove_language(rem_language)
- var/datum/language/L = GLOB.all_languages[rem_language]
- . = (L in languages)
- languages.Remove(L)
+/datum/language/tajaran/monkey
+ name = "Farwa"
+ desc = "Meow meow meow."
+ key = "fa"
+
+/datum/language/vulpkanin/monkey
+ name = "Wolpin"
+ desc = "Bark bark bark."
+ key = "wo"
-/mob/living/remove_language(rem_language)
- var/datum/language/L = GLOB.all_languages[rem_language]
- if(default_language == L)
- default_language = null
- return ..()
// Can we speak this language, as opposed to just understanding it?
/mob/proc/can_speak_language(datum/language/speaking)
return universal_speak || (speaking && speaking.flags & INNATE) || (speaking in languages)
+
//TBD
/mob/proc/check_lang_data()
. = ""
@@ -759,6 +802,7 @@
if(!(L.flags & NONGLOBAL))
. += "[L.name] (:[L.key]) [L.desc]
"
+
/mob/living/check_lang_data()
. = ""
@@ -770,7 +814,8 @@
if(L == default_language)
. += "[L.name] (:[L.key]) - default - reset [L.desc]
"
else
- . += "[L.name] (:[L.key]) - set default [L.desc]
"
+ . += "[L.name] (:[L.key]) - set default [L.desc]
"
+
/mob/verb/check_languages()
set name = "Check Known Languages"
@@ -781,6 +826,7 @@
popup.set_content(check_lang_data())
popup.open()
+
/mob/living/Topic(href, href_list)
. = ..()
if(.)
@@ -795,33 +841,43 @@
check_languages()
return TRUE
-/datum/language/human/monkey
- name = "Chimpanzee"
- desc = "Ook ook ook."
- speech_verb = "chimpers"
- ask_verb = "chimpers"
- exclaim_verbs = list("screeches")
- key = "fm"
-/datum/language/skrell/monkey
- name = "Neara"
- desc = "Squik squik squik."
- key = "fn"
+// Language handling.
+/mob/proc/add_language(language_name)
+ var/datum/language/new_language = GLOB.all_languages[language_name]
+ if(new_language in languages)
+ return FALSE
+ if(!istype(new_language))
+ new_language = GLOB.all_languages[convert_lang_key_to_name(language_name)]
+ if(!istype(new_language))
+ return FALSE
-/datum/language/unathi/monkey
- name = "Stok"
- desc = "Hiss hiss hiss."
- key = "fs"
+ languages |= new_language
+ return TRUE
-/datum/language/tajaran/monkey
- name = "Farwa"
- desc = "Meow meow meow."
- key = "fa"
-/datum/language/vulpkanin/monkey
- name = "Wolpin"
- desc = "Bark bark bark."
- key = "vu"
+/mob/proc/remove_language(language_name)
+ var/datum/language/rem_language = GLOB.all_languages[language_name]
+ if(!istype(rem_language))
+ rem_language = GLOB.all_languages[convert_lang_key_to_name(language_name)]
+ if(!istype(rem_language))
+ return FALSE
+
+ . = (rem_language in languages)
+ languages.Remove(rem_language)
+
+
+/mob/living/remove_language(language_name)
+ var/datum/language/rem_language = GLOB.all_languages[language_name]
+ if(!istype(rem_language))
+ rem_language = GLOB.all_languages[convert_lang_key_to_name(language_name)]
+ if(!istype(rem_language))
+ return FALSE
+
+ if(default_language == rem_language)
+ default_language = null
+ return ..()
+
/mob/proc/grant_all_babel_languages()
for(var/la in GLOB.all_languages)
@@ -830,8 +886,19 @@
continue
languages |= new_language
+
/mob/proc/grant_all_languages()
for(var/la in GLOB.all_languages)
add_language(la)
+
+/proc/convert_lang_key_to_name(language_key)
+ var/static/list/language_keys_and_names = list()
+ if(!language_keys_and_names.len)
+ for(var/language_name in GLOB.all_languages)
+ var/datum/language/language = GLOB.all_languages[language_name]
+ language_keys_and_names[language.key] = language_name
+ return language_keys_and_names[language_key]
+
+
#undef SCRAMBLE_CACHE_LEN
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index 102026c0f0b..ee98ba30d46 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -89,7 +89,7 @@
/mob/living/carbon/alien/get_default_language()
if(default_language)
return default_language
- return GLOB.all_languages["Xenomorph"]
+ return GLOB.all_languages[LANGUAGE_XENOS]
/mob/living/carbon/alien/say_quote(var/message, var/datum/language/speaking = null)
var/verb = "hisses"
diff --git a/code/modules/mob/living/carbon/alien/death.dm b/code/modules/mob/living/carbon/alien/death.dm
index e809f5e7fdb..e5610a983a1 100644
--- a/code/modules/mob/living/carbon/alien/death.dm
+++ b/code/modules/mob/living/carbon/alien/death.dm
@@ -4,7 +4,7 @@
death(1)
var/atom/movable/overlay/animation = null
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
@@ -27,7 +27,7 @@
if(!death(TRUE) && stat != DEAD)
return FALSE
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
dust_animation()
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index 6517c1543da..209dec3988c 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -20,8 +20,8 @@
if(name == "alien")
name = text("alien ([rand(1, 1000)])")
real_name = name
- add_language("Xenomorph")
- add_language("Hivemind")
+ add_language(LANGUAGE_XENOS)
+ add_language(LANGUAGE_HIVE_XENOS)
..()
AddSpell(new /obj/effect/proc_holder/spell/alien_spell/regurgitate)
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW, 0.5, -11)
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index 715d8f9efe3..a7b92f1a0ab 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -25,8 +25,8 @@
name = "alien larva ([rand(1, 1000)])"
real_name = name
regenerate_icons()
- add_language("Xenomorph")
- add_language("Hivemind")
+ add_language(LANGUAGE_XENOS)
+ add_language(LANGUAGE_HIVE_XENOS)
hide_action = new
hide_action.Grant(src)
..()
diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm
index 5e6a36acf48..e468fff446e 100644
--- a/code/modules/mob/living/carbon/brain/MMI.dm
+++ b/code/modules/mob/living/carbon/brain/MMI.dm
@@ -6,9 +6,8 @@
w_class = WEIGHT_CLASS_NORMAL
origin_tech = "biotech=3"
origin_tech = "biotech=2;programming=3;engineering=2"
-
//Revised. Brainmob is now contained directly within object of transfer. MMI in this case.
- var/alien = 0
+ var/alien = FALSE
var/clock = 0
var/syndiemmi = 0 //Whether or not this is a Syndicate MMI
var/syndicate = 0 //Used to replace standart modules with the syndicate modules in module pick proc
@@ -29,7 +28,28 @@
/// Time at which the ghost belonging to the mind in the mmi can be pinged again to be borged
var/next_possible_ghost_ping
-/obj/item/mmi/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
+
+/obj/item/mmi/update_icon_state()
+ if(held_brain)
+ icon = held_brain.mmi_icon
+ icon_state = held_brain.mmi_icon_state
+ else
+ icon = initial(icon)
+ icon_state = initial(icon_state)
+
+
+/obj/item/mmi/update_name(updates = ALL)
+ . = ..()
+ if(brainmob)
+ if(alien)
+ name = "Man-Machine Interface: Alien - [brainmob.real_name]"
+ else
+ name = "Man-Machine Interface: [brainmob.real_name]"
+ else
+ name = initial(name)
+
+
+/obj/item/mmi/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/organ/internal/brain/crystal))
to_chat(user, " This brain is too malformed to be able to use with the [src].")
return
@@ -57,19 +77,9 @@
GLOB.dead_mob_list -= brainmob//Update dem lists
GLOB.alive_mob_list += brainmob
brainmob.update_sight()
-
held_brain = B
- if(istype(O,/obj/item/organ/internal/brain/xeno)) // kept the type check, as it still does other weird stuff
- name = "Man-Machine Interface: Alien - [brainmob.real_name]"
- icon = 'icons/mob/alien.dmi'
- become_occupied("AlienMMI")
- alien = 1
- else
- name = "Man-Machine Interface: [brainmob.real_name]"
- icon = B.mmi_icon
- become_occupied("[B.mmi_icon_state]")
- alien = 0
-
+ alien = istype(O, /obj/item/organ/internal/brain/xeno)
+ update_appearance(UPDATE_ICON_STATE|UPDATE_NAME)
if(radio_action)
radio_action.UpdateButtonIcon()
SSblackbox.record_feedback("amount", "mmis_filled", 1)
@@ -121,17 +131,15 @@
"You uninstall the radio from [src].")
-/obj/item/mmi/attack_self(mob/user as mob)
+/obj/item/mmi/attack_self(mob/user)
if(!brainmob)
to_chat(user, "You upend the MMI, but there's nothing in it.")
else
to_chat(user, "You unlock and upend the MMI, spilling the brain onto the floor.")
dropbrain(get_turf(user))
- icon = 'icons/obj/assemblies.dmi'
- icon_state = "mmi_empty"
- name = "Man-Machine Interface"
-/obj/item/mmi/proc/transfer_identity(var/mob/living/carbon/human/H)//Same deal as the regular brain proc. Used for human-->robot people.
+
+/obj/item/mmi/proc/transfer_identity(mob/living/carbon/human/H)//Same deal as the regular brain proc. Used for human-->robot people.
brainmob = new(src)
brainmob.name = H.real_name
brainmob.real_name = H.real_name
@@ -147,10 +155,9 @@
held_brain = new brain_path(src) // Slime people will keep their slimy brains this way
held_brain.dna = brainmob.dna.Clone()
held_brain.name = "\the [brainmob.name]'s [initial(held_brain.name)]"
-
- name = "Man-Machine Interface: [brainmob.real_name]"
- become_occupied("mmi_full")
brainmob.update_sight()
+ update_appearance(UPDATE_ICON_STATE|UPDATE_NAME)
+
//I made this proc as a way to have a brainmob be transferred to any created brain, and to solve the
//problem i was having with alien/nonalien brain drops.
@@ -171,11 +178,8 @@
brainmob = null//Set mmi brainmob var to null
held_brain.forceMove(dropspot)
held_brain = null
+ update_appearance(UPDATE_ICON_STATE|UPDATE_NAME)
-/obj/item/mmi/proc/become_occupied(var/new_icon)
- icon_state = new_icon
- if(radio)
- radio_action.ApplyIcon()
/obj/item/mmi/examine(mob/user)
. = ..()
@@ -200,7 +204,7 @@
procname = "ui_interact"
var/obj/item/mmi = null
-/datum/action/generic/configure_mmi_radio/New(var/Target, var/obj/item/mmi/M)
+/datum/action/generic/configure_mmi_radio/New(Target, obj/item/mmi/M)
. = ..()
mmi = M
diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm
index 6a1f291fa3c..bbfc5d718fc 100644
--- a/code/modules/mob/living/carbon/brain/brain.dm
+++ b/code/modules/mob/living/carbon/brain/brain.dm
@@ -9,7 +9,7 @@
/mob/living/carbon/brain/New()
..()
- add_language("Galactic Common")
+ add_language(LANGUAGE_GALACTIC_COMMON)
/mob/living/carbon/brain/Destroy()
diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm
index a730a47da8a..dbef53fce91 100644
--- a/code/modules/mob/living/carbon/brain/death.dm
+++ b/code/modules/mob/living/carbon/brain/death.dm
@@ -13,7 +13,7 @@
if(!death(TRUE) && stat != DEAD)
return FALSE
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
diff --git a/code/modules/mob/living/carbon/brain/robotic_brain.dm b/code/modules/mob/living/carbon/brain/robotic_brain.dm
index 2513a6882e5..53a21f1886d 100644
--- a/code/modules/mob/living/carbon/brain/robotic_brain.dm
+++ b/code/modules/mob/living/carbon/brain/robotic_brain.dm
@@ -48,6 +48,22 @@
imprinted_master = null
return ..()
+
+/obj/item/mmi/robotic_brain/update_icon_state()
+ if(brainmob?.key)
+ icon_state = occupied_icon
+ return
+ icon_state = searching ? searching_icon : blank_icon
+
+
+/obj/item/mmi/robotic_brain/update_name(updates = ALL)
+ . = ..()
+ if(brainmob)
+ name = "[src] ([brainmob.name])"
+ else
+ name = initial(name)
+
+
/obj/item/mmi/robotic_brain/attack_self(mob/user)
if(isgolem(user))
to_chat(user, "Your golem fingers are too large to press the switch on [src].")
@@ -59,24 +75,28 @@
if(brainmob && !brainmob.key && !searching)
//Start the process of searching for a new user.
to_chat(user, "You carefully locate the manual activation switch and start [src]'s boot process.")
- icon_state = searching_icon
- ghost_volunteers.Cut()
searching = TRUE
+ update_icon(UPDATE_ICON_STATE)
+ ghost_volunteers.Cut()
request_player()
- spawn(600)
- if(ghost_volunteers.len)
- var/mob/dead/observer/O
- while(!istype(O) && ghost_volunteers.len)
- O = pick_n_take(ghost_volunteers)
- if(istype(O) && check_observer(O))
- transfer_personality(O)
- reset_search()
+ addtimer(CALLBACK(src, PROC_REF(check_volunteers)), 60 SECONDS)
else
silenced = !silenced
to_chat(user, "You toggle the speaker [silenced ? "off" : "on"].")
if(brainmob && brainmob.key)
to_chat(brainmob, "Your internal speaker has been toggled [silenced ? "off" : "on"].")
+
+/obj/item/mmi/robotic_brain/proc/check_volunteers()
+ if(length(ghost_volunteers))
+ var/mob/dead/observer/observer
+ while(!istype(observer) && length(ghost_volunteers))
+ observer = pick_n_take(ghost_volunteers)
+ if(istype(observer) && check_observer(observer))
+ transfer_personality(observer)
+ reset_search()
+
+
/obj/item/mmi/robotic_brain/proc/request_player()
for(var/mob/dead/observer/O in GLOB.player_list)
if(check_observer(O))
@@ -110,7 +130,6 @@
log_runtime(EXCEPTION("[src] at [loc] attempted to drop brain without a contained brain."), src)
/obj/item/mmi/robotic_brain/transfer_identity(mob/living/carbon/H)
- name = "[src] ([H])"
if(isnull(brainmob.dna))
brainmob.dna = H.dna.Clone()
brainmob.name = brainmob.dna.real_name
@@ -122,9 +141,9 @@
if(H.mind)
H.mind.transfer_to(brainmob)
to_chat(brainmob, "You feel slightly disoriented. That's normal when you're just a [ejected_flavor_text].")
- become_occupied(occupied_icon)
- if(radio)
- radio_action.ApplyIcon()
+ update_appearance(UPDATE_ICON_STATE|UPDATE_NAME)
+ if(radio_action)
+ radio_action.UpdateButtonIcon()
/obj/item/mmi/robotic_brain/attempt_become_organ(obj/item/organ/external/parent, mob/living/carbon/human/target)
@@ -137,26 +156,24 @@
searching = FALSE
brainmob.revive() /// in case of death
brainmob.key = candidate.key
- name = "[src] ([brainmob.name])"
-
to_chat(brainmob, "You are a [src], brought into existence on [station_name()].")
to_chat(brainmob, "As a non-sentient synthetic intelligence, you answer to [imprinted_master], unless otherwise placed inside of a lawed synthetic structure or mech.")
to_chat(brainmob, "Remember, the purpose of your existence is to serve [imprinted_master]'s every word, unless lawed or placed into a mech in the future.")
brainmob.mind.assigned_role = "Positronic Brain"
-
visible_message("[src] chimes quietly.")
- become_occupied(occupied_icon)
+ update_appearance(UPDATE_ICON_STATE|UPDATE_NAME)
+ if(radio_action)
+ radio_action.UpdateButtonIcon()
/obj/item/mmi/robotic_brain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
if(brainmob && brainmob.key)
return
-
searching = FALSE
- icon_state = blank_icon
-
+ update_icon(UPDATE_ICON_STATE)
visible_message("[src] buzzes quietly as the light fades out. Perhaps you could try again?")
+
/obj/item/mmi/robotic_brain/Topic(href, href_list)
if("signup" in href_list)
var/mob/dead/observer/O = locate(href_list["signup"])
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 48432a075e1..3f602673348 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -399,11 +399,6 @@
mind.disrupt_spells(0)
-
-/mob/living/carbon/proc/tintcheck()
- return 0
-
-
/mob/living/carbon/proc/create_dna()
if(!dna)
dna = new()
@@ -688,7 +683,7 @@
to_chat(src, "Вы [slipVerb] на [description]!")
playsound(loc, 'sound/misc/slip.ogg', 50, 1, -3)
// Something something don't run with scissors
- moving_diagonally = 0 //If this was part of diagonal move slipping will stop it.
+ moving_diagonally = NONE //If this was part of diagonal move slipping will stop it.
Weaken(weaken)
return TRUE
@@ -807,8 +802,13 @@ so that different stomachs can handle things in different ways VB*/
clear_fullscreen("tint", 0)
-/mob/living/carbon/proc/get_total_tint()
+/// Checks eye covering items for visually impairing tinting, such as welding masks. 0 & 1 = no impairment, 2 = welding mask overlay, 3 = casual blindness.
+/mob/living/proc/get_total_tint()
. = 0
+
+
+/mob/living/carbon/get_total_tint()
+ . = ..()
if(istype(head, /obj/item/clothing/head))
var/obj/item/clothing/head/HT = head
. += HT.tint
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index 01a93b1eeeb..fe87453ae78 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -3,7 +3,7 @@
return FALSE
var/atom/movable/overlay/animation = null
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
if(!ismachineperson(src))
@@ -51,7 +51,7 @@
if(!death(TRUE) && stat != DEAD)
return FALSE
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
dust_animation()
@@ -76,7 +76,7 @@
return FALSE
var/atom/movable/overlay/animation = null
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 1d8a1b58801..a8269370b7d 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -430,39 +430,39 @@
//Helper procedure. Called by /mob/living/carbon/human/examine() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records.
-/proc/hasHUD(mob/M, hudtype)
+/proc/hasHUD(mob/M, hud_exam)
if(istype(M, /mob/living/carbon/human))
- var/have_hudtypes = list()
+ var/have_hud_exam = 0
var/mob/living/carbon/human/H = M
if(istype(H.glasses, /obj/item/clothing/glasses/hud))
var/obj/item/clothing/glasses/hud/hudglasses = H.glasses
if(hudglasses?.examine_extensions)
- have_hudtypes += hudglasses.examine_extensions
+ have_hud_exam |= hudglasses.examine_extensions
if(istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman))
var/obj/item/clothing/head/helmet/space/plasmaman/helmet = H.head
if(helmet?.examine_extensions)
- have_hudtypes += helmet.examine_extensions
+ have_hud_exam |= helmet.examine_extensions
var/obj/item/organ/internal/cyberimp/eyes/hud/CIH = H.get_int_organ(/obj/item/organ/internal/cyberimp/eyes/hud)
if(CIH?.examine_extensions)
- have_hudtypes += CIH.examine_extensions
+ have_hud_exam |= CIH.examine_extensions
- return (hudtype in have_hudtypes)
+ return (have_hud_exam & hud_exam)
else if(isrobot(M) || isAI(M)) //Stand-in/Stopgap to prevent pAIs from freely altering records, pending a more advanced Records system
- return (hudtype in list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE, EXAMINE_HUD_MEDICAL))
+ return hud_exam & EXAMINE_HUD_SECURITY_READ || hud_exam & EXAMINE_HUD_SECURITY_WRITE || hud_exam & EXAMINE_HUD_MEDICAL
else if(ispAI(M))
var/mob/living/silicon/pai/P = M
if(P.adv_secHUD)
- return (hudtype in list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE))
+ return hud_exam & EXAMINE_HUD_SECURITY_READ || hud_exam & EXAMINE_HUD_SECURITY_WRITE
else if(isobserver(M))
var/mob/dead/observer/O = M
if(DATA_HUD_SECURITY_ADVANCED in O.data_hud_seen)
- return (hudtype in list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SKILLS))
+ return hud_exam & EXAMINE_HUD_SECURITY_READ || hud_exam & EXAMINE_HUD_SKILLS
return FALSE
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index cf7473f68f1..6ab6b2399a8 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1,12 +1,3 @@
-/mob/living/carbon/human
- name = "unknown"
- real_name = "unknown"
- voice_name = "unknown"
- icon = 'icons/mob/human.dmi'
- icon_state = "body_m_s"
- deathgasp_on_death = TRUE
-
-
/mob/living/carbon/human/New(loc)
icon = null // This is now handled by overlays -- we just keep an icon for the sake of the map editor.
. = ..()
@@ -987,24 +978,6 @@
return HEARING_PROTECTION_MINOR
-///tintcheck()
-///Checks eye covering items for visually impairing tinting, such as welding masks
-///Checked in life.dm. 0 & 1 = no impairment, 2 = welding mask overlay, 3 = You can see jack, but you can't see shit.
-/mob/living/carbon/human/tintcheck()
- var/tinted = 0
- if(istype(src.head, /obj/item/clothing/head))
- var/obj/item/clothing/head/HT = src.head
- tinted += HT.tint
- if(istype(src.glasses, /obj/item/clothing/glasses))
- var/obj/item/clothing/glasses/GT = src.glasses
- tinted += GT.tint
- if(istype(src.wear_mask, /obj/item/clothing/mask))
- var/obj/item/clothing/mask/MT = src.wear_mask
- tinted += MT.tint
-
- return tinted
-
-
/mob/living/carbon/human/abiotic(var/full_body = 0)
if(full_body && ((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT)) || (src.back || src.wear_mask || src.head || src.shoes || src.w_uniform || src.wear_suit || src.glasses || src.l_ear || src.r_ear || src.gloves)))
return 1
@@ -1734,10 +1707,10 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
if(!H.check_has_mouth())
to_chat(src, "They don't have a mouth, you cannot perform CPR!")
return
- if((head && (head.flags_cover & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && !wear_mask.mask_adjusted))
+ if((head && (head.flags_cover & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && !wear_mask.up))
to_chat(src, "Remove your mask first!")
return
- if((H.head && (H.head.flags_cover & HEADCOVERSMOUTH)) || (H.wear_mask && (H.wear_mask.flags_cover & MASKCOVERSMOUTH) && !H.wear_mask.mask_adjusted))
+ if((H.head && (H.head.flags_cover & HEADCOVERSMOUTH)) || (H.wear_mask && (H.wear_mask.flags_cover & MASKCOVERSMOUTH) && !H.wear_mask.up))
to_chat(src, "Remove [H.p_their()] mask first!")
return
if(H.receiving_cpr) // To prevent spam stacking
@@ -2132,3 +2105,14 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
set category = "IC"
update_flavor_text()
+
+/mob/living/carbon/human/harvest(mob/living/user)
+ if(QDELETED(src))
+ return
+
+ if(issmall(src))
+ while(meatleft > 0)
+ new dna.species.meat_type(loc)
+ meatleft--
+ visible_message(span_notice("[user] butchers [src]."))
+ gib()
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 35d5c793b40..cd6c3f2fbfc 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -419,12 +419,7 @@ emp_act
return FALSE
if((istype(I, /obj/item/kitchen/knife/butcher/meatcleaver) || istype(I, /obj/item/twohanded/chainsaw)) && stat == DEAD && user.a_intent == INTENT_HARM)
- var/obj/item/reagent_containers/food/snacks/meat/human/newmeat = new /obj/item/reagent_containers/food/snacks/meat/human(get_turf(loc))
- newmeat.name = real_name + newmeat.name
- newmeat.subjectname = real_name
- newmeat.subjectjob = job
- newmeat.reagents.add_reagent("nutriment", (nutrition / 15) / 3)
- reagents.trans_to(newmeat, round((reagents.total_volume) / 3, 1))
+ new dna.species.meat_type(get_turf(loc), src)
add_mob_blood(src)
--meatleft
to_chat(user, span_warning("You hack off a chunk of meat from [name]."))
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 9d1f6e03cb2..32e1f33d956 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -1,7 +1,14 @@
/mob/living/carbon/human
-
+ name = "unknown"
+ real_name = "unknown"
+ voice_name = "unknown"
+ icon = 'icons/mob/human.dmi'
+ icon_state = "body_m_s"
+ appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE
+ deathgasp_on_death = TRUE
hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,GLAND_HUD,THOUGHT_HUD)
pressure_resistance = 25
+ blocks_emissive = EMISSIVE_BLOCK_UNIQUE
//Marking colour and style
var/list/m_colours = DEFAULT_MARKING_COLOURS //All colours set to #000000.
var/list/m_styles = DEFAULT_MARKING_STYLES //All markings set to None.
diff --git a/code/modules/mob/living/carbon/human/interactions.dm b/code/modules/mob/living/carbon/human/interactions.dm
index 6e71e0bcabe..2fcc2c3752c 100644
--- a/code/modules/mob/living/carbon/human/interactions.dm
+++ b/code/modules/mob/living/carbon/human/interactions.dm
@@ -2,10 +2,11 @@
*******Interactions code by HONKERTRON feat TestUnit********
***********************************/
-/mob/living/carbon/human/MouseDrop(mob/M as mob)
- ..()
+/mob/living/carbon/human/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
+ . = ..()
if(src == usr)
- interact(M)
+ interact(over_object)
+
/mob/proc/make_interaction()
return
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index d840e0560d4..23e3648a583 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -56,7 +56,7 @@
if(istype(mask) && mask.tint || initial(mask.tint))
update_tint()
- if(mask.flags & BLOCKHAIR || mask.flags & BLOCKHEADHAIR)
+ if((mask.flags & (BLOCKHAIR|BLOCKHEADHAIR|BLOCKFACIALHAIR)) || (initial(mask.flags) & (BLOCKHAIR|BLOCKHEADHAIR|BLOCKFACIALHAIR)))
update_hair() //rebuild hair
update_fhair()
update_head_accessory()
@@ -65,9 +65,9 @@
internal = null
update_action_buttons_icon()
- if(mask.flags_inv & HIDEGLASSES)
+ if((mask.flags_inv & HIDEGLASSES) || (initial(mask.flags_inv) & HIDEGLASSES))
update_inv_glasses()
- if(mask.flags_inv & HIDEHEADSETS)
+ if((mask.flags_inv & HIDEHEADSETS) || (initial(mask.flags_inv) & HIDEHEADSETS))
update_inv_ears()
sec_hud_set_ID()
@@ -82,7 +82,7 @@
if(!check_item)
return
- if(forced || (check_item.flags & BLOCKHAIR) || (check_item.flags & BLOCKHEADHAIR))
+ if(forced || (check_item.flags & (BLOCKHAIR|BLOCKHEADHAIR|BLOCKFACIALHAIR)) || (initial(check_item.flags) & (BLOCKHAIR|BLOCKHEADHAIR|BLOCKFACIALHAIR)))
update_hair() //rebuild hair
update_fhair()
update_head_accessory()
@@ -96,11 +96,11 @@
if(forced || hat.vision_flags || hat.see_in_dark || !isnull(hat.lighting_alpha))
update_sight()
- if(forced || (check_item.flags_inv & HIDEHEADSETS))
+ if(forced || (check_item.flags_inv & HIDEHEADSETS) || (initial(check_item.flags_inv) & HIDEHEADSETS))
update_inv_ears()
- if(forced || (check_item.flags_inv & HIDEMASK))
+ if(forced || (check_item.flags_inv & HIDEMASK) || (initial(check_item.flags_inv) & HIDEMASK))
update_inv_wear_mask()
- if(forced || (check_item.flags_inv & HIDEGLASSES))
+ if(forced || (check_item.flags_inv & HIDEGLASSES) || (initial(check_item.flags_inv) & HIDEGLASSES))
update_inv_glasses()
sec_hud_set_ID()
@@ -111,11 +111,11 @@
* Handles stuff to update when a mob equips/unequips a suit.
*/
/mob/living/carbon/human/wear_suit_update(obj/item/clothing/suit)
- if(suit.flags_inv & HIDEJUMPSUIT)
+ if((suit.flags_inv & HIDEJUMPSUIT) || (initial(suit.flags_inv) & HIDEJUMPSUIT))
update_inv_w_uniform()
- if(suit.flags_inv & HIDESHOES)
+ if((suit.flags_inv & HIDESHOES) || (initial(suit.flags_inv) & HIDESHOES))
update_inv_shoes()
- if(suit.flags_inv & HIDEGLOVES)
+ if((suit.flags_inv & HIDEGLOVES) || (initial(suit.flags_inv) & HIDEGLOVES))
update_inv_gloves()
update_inv_wear_suit()
@@ -412,7 +412,7 @@
if(slot_wear_mask)
return head && (head.flags_inv & HIDEMASK)
if(slot_glasses)
- return head && (head.flags_inv & HIDEGLASSES)
+ return head && (head.flags_inv & HIDEGLASSES) || wear_mask && (wear_mask.flags_inv & HIDEGLASSES)
if(slot_l_ear, slot_r_ear)
return head && (head.flags_inv & HIDEHEADSETS)
else
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index ec3125614c7..b2f3ab81c4b 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -99,16 +99,12 @@
/mob/living/carbon/human/handle_disabilities()
//Vision //god knows why this is here
- var/obj/item/organ/vision
- if(dna.species.vision_organ)
- vision = get_int_organ(dna.species.vision_organ)
-
- if(!dna.species.vision_organ) // Presumably if a species has no vision organs, they see via some other means.
+ var/obj/item/organ/vision = dna?.species?.get_vision_organ(src)
+ if(vision == NO_VISION_ORGAN)
SetEyeBlind(0)
SetEyeBlurry(0)
-
- else if(!vision || vision.is_traumatized()) // Vision organs cut out or broken? Permablind.
- EyeBlind(4 SECONDS)
+ else if(!vision || vision.is_traumatized()) // Vision organs cut out or broken? Permablind.
+ SetEyeBlind(4 SECONDS)
if(getBrainLoss() >= 60 && stat != DEAD)
if(prob(3))
diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm
index cdc69b1e6e7..b1c1e7f3d31 100644
--- a/code/modules/mob/living/carbon/human/species/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/_species.dm
@@ -132,12 +132,12 @@
"задерживает дыхание!")
// Language/culture vars.
- var/default_language = "Galactic Common" // Default language is used when 'say' is used without modifiers.
- var/language = "Galactic Common" // Default racial language, if any.
- var/secondary_langs = list() // The names of secondary languages that are available to this species.
- var/list/speech_sounds // A list of sounds to potentially play when speaking.
- var/list/speech_chance // The likelihood of a speech sound playing.
- var/scream_verb = "крич%(ит,ат)%" // Special symbols used to apply correct gender. See [/proc/genderize_decode] for more info.
+ var/default_language = LANGUAGE_GALACTIC_COMMON // Default language is used when 'say' is used without modifiers.
+ var/language = LANGUAGE_GALACTIC_COMMON // Default racial language, if any.
+ var/secondary_langs = list() // The keys of secondary languages that are available to this species.
+ var/list/speech_sounds // A list of sounds to potentially play when speaking.
+ var/list/speech_chance // The likelihood of a speech sound playing.
+ var/scream_verb = "крич%(ит,ат)%" // Special symbols used to apply correct gender. See [/proc/genderize_decode] for more info.
var/female_giggle_sound = list('sound/voice/giggle_female_1.ogg','sound/voice/giggle_female_2.ogg','sound/voice/giggle_female_3.ogg')
var/male_giggle_sound = list('sound/voice/giggle_male_1.ogg','sound/voice/giggle_male_2.ogg')
var/male_scream_sound = list('sound/goonstation/voice/male_scream.ogg')
@@ -190,8 +190,7 @@
INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears,
)
- /// If set, this organ is required for vision. Defaults to "eyes" if the species has them.
- var/vision_organ
+ var/meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid
var/list/has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest),
@@ -223,10 +222,6 @@
var/list/autohiss_exempt = null
/datum/species/New()
- //If the species has eyes, they are the default vision organ
- if(!vision_organ && has_organ[INTERNAL_ORGAN_EYES])
- vision_organ = /obj/item/organ/internal/eyes
-
unarmed = new unarmed_type()
/datum/species/proc/get_random_name(gender)
@@ -366,8 +361,7 @@
H.faction += i //Using +=/-= for this in case you also gain the faction from a different source.
/datum/species/proc/on_species_loss(mob/living/carbon/human/H)
- if(H.butcher_results) //clear it out so we don't butcher a actual human.
- H.butcher_results = null
+ H.meatleft = initial(H.meatleft)
H.ventcrawler = initial(H.ventcrawler)
if(inherent_factions)
@@ -1159,7 +1153,20 @@ It'll return null if the organ doesn't correspond, so include null checks when u
/datum/species/proc/can_hear(mob/living/carbon/human/user)
var/obj/item/organ/internal/ears/ears = user.get_organ_slot(INTERNAL_ORGAN_EARS)
- return ears && !(DEAF in user.mutations) && !HAS_TRAIT(user, TRAIT_DEAF)
+ return ears && !HAS_TRAIT(user, TRAIT_DEAF)
+
+
+/datum/species/proc/has_vision(mob/living/carbon/human/user, information_only = FALSE)
+ if(information_only && user.stat == DEAD)
+ return TRUE
+ if(user.AmountBlinded() || (BLINDNESS in user.mutations) || user.stat)
+ return FALSE
+ var/obj/item/organ/vision = get_vision_organ(user)
+ return vision && (vision == NO_VISION_ORGAN || !vision.is_traumatized())
+
+
+/datum/species/proc/get_vision_organ(mob/living/carbon/human/user)
+ return user.get_organ_slot(INTERNAL_ORGAN_EYES)
/datum/species/proc/spec_Process_Spacemove(mob/living/carbon/human/H)
diff --git a/code/modules/mob/living/carbon/human/species/abductor.dm b/code/modules/mob/living/carbon/human/species/abductor.dm
index 5155d8f4f99..326c270790e 100644
--- a/code/modules/mob/living/carbon/human/species/abductor.dm
+++ b/code/modules/mob/living/carbon/human/species/abductor.dm
@@ -4,8 +4,8 @@
a = "an"
icobase = 'icons/mob/human_races/r_abductor.dmi'
deform = 'icons/mob/human_races/r_abductor.dmi'
- language = "Abductor Mindlink"
- default_language = "Abductor Mindlink"
+ language = LANGUAGE_HIVE_ABDUCTOR
+ default_language = LANGUAGE_HIVE_ABDUCTOR
eyes = "blank_eyes"
has_organ = list(
INTERNAL_ORGAN_HEART = /obj/item/organ/internal/heart,
@@ -16,6 +16,8 @@
INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/grey
+
species_traits = list(NO_BLOOD, NO_BREATHE, VIRUSIMMUNE, NOGUNS, NO_HUNGER, NO_EXAMINE)
dies_at_threshold = TRUE
@@ -40,8 +42,8 @@
..()
H.gender = NEUTER
H.languages.Cut() //Under no condition should you be able to speak any language
- H.add_language("Abductor Mindlink") //other than over the abductor's own mindlink
- H.add_language("Psionic Communication") // still grey enouhg to speak in psi link
+ H.add_language(LANGUAGE_HIVE_ABDUCTOR) //other than over the abductor's own mindlink
+ H.add_language(LANGUAGE_GREY) // still grey enouhg to speak in psi link
var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR]
abductor_hud.add_hud_to(H)
diff --git a/code/modules/mob/living/carbon/human/species/diona.dm b/code/modules/mob/living/carbon/human/species/diona.dm
index 643b9724526..7778d5d34f5 100644
--- a/code/modules/mob/living/carbon/human/species/diona.dm
+++ b/code/modules/mob/living/carbon/human/species/diona.dm
@@ -3,7 +3,7 @@
name_plural = "Dionaea"
icobase = 'icons/mob/human_races/r_diona.dmi'
deform = 'icons/mob/human_races/r_def_plant.dmi'
- language = "Rootspeak"
+ language = LANGUAGE_DIONA
speech_sounds = list('sound/voice/dionatalk1.ogg') //Credit https://www.youtube.com/watch?v=ufnvlRjsOTI [0:13 - 0:16]
speech_chance = 20
unarmed_type = /datum/unarmed_attack/diona
@@ -46,6 +46,8 @@
INTERNAL_ORGAN_HEART = /obj/item/organ/internal/heart/diona,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/diona
+
has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest/diona),
BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin/diona),
diff --git a/code/modules/mob/living/carbon/human/species/drask.dm b/code/modules/mob/living/carbon/human/species/drask.dm
index f2dee15f777..9552da20cbd 100644
--- a/code/modules/mob/living/carbon/human/species/drask.dm
+++ b/code/modules/mob/living/carbon/human/species/drask.dm
@@ -3,7 +3,7 @@
name_plural = "Drask"
icobase = 'icons/mob/human_races/r_drask.dmi'
deform = 'icons/mob/human_races/r_drask.dmi'
- language = "Orluum"
+ language = LANGUAGE_DRASK
eyes = "drask_eyes_s"
speech_sounds = list('sound/voice/drasktalk.ogg')
@@ -69,6 +69,8 @@
INTERNAL_ORGAN_BRAIN = /obj/item/organ/internal/brain/drask,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/drask
+
disliked_food = SUGAR | GROSS
liked_food = DAIRY
diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm
index 133308e84d1..0d5cb77a5ce 100644
--- a/code/modules/mob/living/carbon/human/species/golem.dm
+++ b/code/modules/mob/living/carbon/human/species/golem.dm
@@ -162,6 +162,11 @@
H.name = H.real_name
to_chat(H, info_text)
+
+/datum/species/golem/get_vision_organ(mob/living/carbon/human/user)
+ return NO_VISION_ORGAN
+
+
//Random Golem
/datum/species/golem/random
@@ -407,8 +412,8 @@
name = "Голем из инопланетных сплавов"
golem_colour = rgb(51, 51, 51)
skinned_type = /obj/item/stack/sheet/mineral/abductor
- language = "Golem Mindlink"
- default_language = "Golem Mindlink"
+ language = LANGUAGE_HIVE_GOLEM
+ default_language = LANGUAGE_HIVE_GOLEM
speed_mod = 1 //faster
info_text = "Будучи големом из инопланетных сплавов, вы быстрее двигаетесь и со временем регенерируете. Однако, вы можете разговаривать только с големами из того же материала, что и вы."
prefix = "Инопланетн" //неполное окончание т.к. гендеризация идет через другую функцию (/datum/species/golem/get_random_name())
@@ -436,8 +441,8 @@
/datum/species/golem/alloy/on_species_gain(mob/living/carbon/human/H)
..()
H.languages.Cut()
- H.add_language("Golem Mindlink")
- H.add_language("Psionic Communication") // still grey enouhg to speak in psi link
+ H.add_language(LANGUAGE_HIVE_GOLEM)
+ H.add_language(LANGUAGE_GREY) // still grey enouhg to speak in psi link
//Regenerates like dionas, less resistant
/datum/species/golem/wood
diff --git a/code/modules/mob/living/carbon/human/species/grey.dm b/code/modules/mob/living/carbon/human/species/grey.dm
index 0dd88292f69..3c464c0a042 100644
--- a/code/modules/mob/living/carbon/human/species/grey.dm
+++ b/code/modules/mob/living/carbon/human/species/grey.dm
@@ -3,7 +3,7 @@
name_plural = "Greys"
icobase = 'icons/mob/human_races/r_grey.dmi'
deform = 'icons/mob/human_races/r_def_grey.dmi'
- language = "Psionic Communication"
+ language = LANGUAGE_GREY
eyes = "grey_eyes_s"
butt_sprite = "grey"
@@ -18,6 +18,8 @@
INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/grey
+
total_health = 90
oxy_mod = 1.2 //greys are fragile
stamina_mod = 1.2
diff --git a/code/modules/mob/living/carbon/human/species/human.dm b/code/modules/mob/living/carbon/human/species/human.dm
index eb93d1ec2e4..f1ff075a0b6 100644
--- a/code/modules/mob/living/carbon/human/species/human.dm
+++ b/code/modules/mob/living/carbon/human/species/human.dm
@@ -4,7 +4,7 @@
icobase = 'icons/mob/human_races/r_human.dmi'
deform = 'icons/mob/human_races/r_def_human.dmi'
primitive_form = /datum/species/monkey
- language = "Sol Common"
+ language = LANGUAGE_SOL_COMMON
species_traits = list(LIPS)
skinned_type = /obj/item/stack/sheet/animalhide/human
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
@@ -17,5 +17,7 @@
interests, rampant cyber and bio-augmentation and secretive factions make life on most human \
worlds tumultous at best."
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/human
+
reagent_tag = PROCESS_ORG
//Has standard darksight of 2.
diff --git a/code/modules/mob/living/carbon/human/species/kidan.dm b/code/modules/mob/living/carbon/human/species/kidan.dm
index 0993ac24e42..33d2da40f10 100644
--- a/code/modules/mob/living/carbon/human/species/kidan.dm
+++ b/code/modules/mob/living/carbon/human/species/kidan.dm
@@ -6,7 +6,7 @@
name_plural = "Kidan"
icobase = 'icons/mob/human_races/r_kidan.dmi'
deform = 'icons/mob/human_races/r_def_kidan.dmi'
- language = "Chittin"
+ language = LANGUAGE_KIDAN
unarmed_type = /datum/unarmed_attack/claws
brute_mod = 0.8
@@ -37,6 +37,8 @@
INTERNAL_ORGAN_LANTERN = /obj/item/organ/internal/lantern,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/kidan
+
has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest/kidan),
BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin/kidan),
diff --git a/code/modules/mob/living/carbon/human/species/machine.dm b/code/modules/mob/living/carbon/human/species/machine.dm
index 43a5f6df776..3df1176a6c1 100644
--- a/code/modules/mob/living/carbon/human/species/machine.dm
+++ b/code/modules/mob/living/carbon/human/species/machine.dm
@@ -10,7 +10,7 @@
icobase = 'icons/mob/human_races/r_machine.dmi'
deform = 'icons/mob/human_races/r_machine.dmi'
- language = "Trinary"
+ language = LANGUAGE_TRINARY
remains_type = /obj/effect/decal/remains/robot
skinned_type = /obj/item/stack/sheet/metal // Let's grind up IPCs for station resources!
@@ -54,7 +54,7 @@
INTERNAL_ORGAN_R_ARM_DEVICE = /obj/item/organ/internal/cyberimp/arm/power_cord,
)
- vision_organ = /obj/item/organ/internal/eyes/optical_sensor
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/machine
has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest/ipc),
diff --git a/code/modules/mob/living/carbon/human/species/monkey.dm b/code/modules/mob/living/carbon/human/species/monkey.dm
index e9a2e4e2a40..1b1bc2be776 100644
--- a/code/modules/mob/living/carbon/human/species/monkey.dm
+++ b/code/modules/mob/living/carbon/human/species/monkey.dm
@@ -8,8 +8,8 @@
damage_overlays = 'icons/mob/human_races/masks/dam_monkey.dmi'
damage_mask = 'icons/mob/human_races/masks/dam_mask_monkey.dmi'
blood_mask = 'icons/mob/human_races/masks/blood_monkey.dmi'
- language = "Galactic Common"
- default_language = "Chimpanzee"
+ language = LANGUAGE_GALACTIC_COMMON
+ default_language = LANGUAGE_MONKEY_HUMAN
species_traits = list(NO_EXAMINE)
skinned_type = /obj/item/stack/sheet/animalhide/monkey
greater_form = /datum/species/human
@@ -40,6 +40,8 @@
brute_mod = 1.5
burn_mod = 1.5
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/monkey
+
has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest),
BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin),
@@ -70,7 +72,7 @@
..()
H.real_name = "[lowertext(name)] ([rand(100,999)])"
H.name = H.real_name
- H.butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/monkey = 5)
+ H.meatleft = 5
/datum/species/monkey/handle_dna(mob/living/carbon/human/H, remove)
..()
@@ -86,11 +88,12 @@
deform = 'icons/mob/human_races/monkeys/r_farwa.dmi'
greater_form = /datum/species/tajaran
- default_language = "Farwa"
+ default_language = LANGUAGE_MONKEY_TAJARAN
blood_species = "Tajaran"
flesh_color = "#AFA59E"
base_color = "#000000"
tail = "farwatail"
+ skinned_type = /obj/item/stack/sheet/animalhide/farwa
reagent_tag = PROCESS_ORG
has_organ = list(
@@ -104,6 +107,8 @@
INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/farwa
+
has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest),
BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin),
@@ -128,11 +133,12 @@
deform = 'icons/mob/human_races/monkeys/r_wolpin.dmi'
greater_form = /datum/species/vulpkanin
- default_language = "Wolpin"
+ default_language = LANGUAGE_MONKEY_VULPKANIN
blood_species = "Vulpkanin"
flesh_color = "#966464"
base_color = "#000000"
tail = "wolpintail"
+ skinned_type = /obj/item/stack/sheet/animalhide/wolpin
reagent_tag = PROCESS_ORG
has_organ = list(
@@ -146,6 +152,8 @@
INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/wolpin
+
has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest),
BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin),
@@ -169,10 +177,11 @@
deform = 'icons/mob/human_races/monkeys/r_neara.dmi'
greater_form = /datum/species/skrell
- default_language = "Neara"
+ default_language = LANGUAGE_MONKEY_SKRELL
blood_species = "Skrell"
flesh_color = "#8CD7A3"
blood_color = "#1D2CBF"
+ skinned_type = /obj/item/stack/sheet/animalhide/neara
reagent_tag = PROCESS_ORG
tail = null
@@ -187,6 +196,8 @@
INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/neara
+
has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest),
BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin),
@@ -219,10 +230,11 @@
tail = "stoktail"
greater_form = /datum/species/unathi
- default_language = "Stok"
+ default_language = LANGUAGE_MONKEY_UNATHI
blood_species = "Unathi"
flesh_color = "#34AF10"
base_color = "#000000"
+ skinned_type = /obj/item/stack/sheet/animalhide/stok
reagent_tag = PROCESS_ORG
bodyflags = HAS_TAIL
@@ -238,6 +250,8 @@
INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/stok
+
has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest),
BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin),
diff --git a/code/modules/mob/living/carbon/human/species/moth.dm b/code/modules/mob/living/carbon/human/species/moth.dm
index 02856a2679b..75a2ca4f18e 100644
--- a/code/modules/mob/living/carbon/human/species/moth.dm
+++ b/code/modules/mob/living/carbon/human/species/moth.dm
@@ -8,7 +8,7 @@
/datum/species/moth
name = "Nian"
name_plural = "Nianae"
- language = "Tkachi"
+ language = LANGUAGE_MOTH
icobase = 'icons/mob/human_races/r_moth.dmi'
deform = 'icons/mob/human_races/r_moth.dmi'
inherent_factions = list("moth")
@@ -48,6 +48,8 @@
INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/nian
+
has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest),
BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin),
diff --git a/code/modules/mob/living/carbon/human/species/nucleation.dm b/code/modules/mob/living/carbon/human/species/nucleation.dm
index 93a9c156876..2953c547869 100644
--- a/code/modules/mob/living/carbon/human/species/nucleation.dm
+++ b/code/modules/mob/living/carbon/human/species/nucleation.dm
@@ -10,7 +10,7 @@
obselete. Ionizing radiation seems to cause resonance in some of their crystals, which seems to encourage regeneration \
and produces a calming effect on the individual. Nucleations are highly stigmatized, and are treated much in the same \
way as lepers were back on Earth."
- language = "Sol Common"
+ language = LANGUAGE_SOL_COMMON
burn_mod = 4 // holy shite, poor guys wont survive half a second cooking smores
brute_mod = 2 // damn, double wham, double dam
species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_BLOOD, NO_PAIN, NO_PAIN_FEEL, NO_SCAN, RADIMMUNE, VIRUSIMMUNE, NO_GERMS)
@@ -28,7 +28,9 @@
INTERNAL_ORGAN_STRANGE_CRYSTAL = /obj/item/organ/internal/nucleation/strange_crystal,
INTERNAL_ORGAN_RESONANT_CRYSTAL = /obj/item/organ/internal/nucleation/resonant_crystal,
)
- vision_organ = /obj/item/organ/internal/eyes/luminescent_crystal
+
+
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/nucleation
/datum/species/nucleation/on_species_gain(mob/living/carbon/human/H)
..()
diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm
index 86c45e7a33c..14049fbfba6 100644
--- a/code/modules/mob/living/carbon/human/species/plasmaman.dm
+++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm
@@ -43,6 +43,8 @@
INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/plasmaman
+
speciesbox = /obj/item/storage/box/survival_plasmaman
flesh_color = "#8b3fba"
diff --git a/code/modules/mob/living/carbon/human/species/skeleton.dm b/code/modules/mob/living/carbon/human/species/skeleton.dm
index 8c48b003f88..78afab06e39 100644
--- a/code/modules/mob/living/carbon/human/species/skeleton.dm
+++ b/code/modules/mob/living/carbon/human/species/skeleton.dm
@@ -72,3 +72,8 @@
return TRUE
return ..()
+
+
+/datum/species/skeleton/get_vision_organ(mob/living/carbon/human/user)
+ return NO_VISION_ORGAN
+
diff --git a/code/modules/mob/living/carbon/human/species/skrell.dm b/code/modules/mob/living/carbon/human/species/skrell.dm
index ed6f6562901..26615a8f232 100644
--- a/code/modules/mob/living/carbon/human/species/skrell.dm
+++ b/code/modules/mob/living/carbon/human/species/skrell.dm
@@ -3,7 +3,7 @@
name_plural = "Skrell"
icobase = 'icons/mob/human_races/r_skrell.dmi'
deform = 'icons/mob/human_races/r_def_skrell.dmi'
- language = "Skrellian"
+ language = LANGUAGE_SKRELL
primitive_form = /datum/species/monkey/skrell
blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \
@@ -51,6 +51,8 @@
INTERNAL_ORGAN_HEADPOCKET = /obj/item/organ/internal/headpocket,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/skrell
+
suicide_messages = list(
"пытается откусить себе язык!",
"выдавливает большими пальцами свои глазницы!",
diff --git a/code/modules/mob/living/carbon/human/species/slime.dm b/code/modules/mob/living/carbon/human/species/slime.dm
index 39220045d7b..718a0877707 100644
--- a/code/modules/mob/living/carbon/human/species/slime.dm
+++ b/code/modules/mob/living/carbon/human/species/slime.dm
@@ -11,7 +11,7 @@
/datum/species/slime
name = "Slime People"
name_plural = "Slime People"
- language = "Bubblish"
+ language = LANGUAGE_SLIME
icobase = 'icons/mob/human_races/r_slime.dmi'
deform = 'icons/mob/human_races/r_slime.dmi'
remains_type = /obj/effect/decal/remains/slime
@@ -45,6 +45,8 @@
INTERNAL_ORGAN_LUNGS = /obj/item/organ/internal/lungs/slime,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/skrell
+
has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest/unbreakable),
BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin/unbreakable),
@@ -143,7 +145,11 @@
/datum/species/slime/can_hear(mob/living/carbon/human/user)
- return !(DEAF in user.mutations) && !HAS_TRAIT(user, TRAIT_DEAF)
+ return !HAS_TRAIT(user, TRAIT_DEAF)
+
+
+/datum/species/slime/get_vision_organ(mob/living/carbon/human/user)
+ return NO_VISION_ORGAN
/datum/action/innate/slimecolor
diff --git a/code/modules/mob/living/carbon/human/species/tajaran.dm b/code/modules/mob/living/carbon/human/species/tajaran.dm
index b8ad91b1dbb..6653346f4f9 100644
--- a/code/modules/mob/living/carbon/human/species/tajaran.dm
+++ b/code/modules/mob/living/carbon/human/species/tajaran.dm
@@ -3,7 +3,7 @@
name_plural = "Tajaran"
icobase = 'icons/mob/human_races/r_tajaran.dmi'
deform = 'icons/mob/human_races/r_def_tajaran.dmi'
- language = "Siik'tajr"
+ language = LANGUAGE_TAJARAN
tail = "tajtail"
skinned_type = /obj/item/stack/sheet/fur
unarmed_type = /datum/unarmed_attack/claws
@@ -46,6 +46,8 @@
INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/tajaran
+
has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest),
BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin),
diff --git a/code/modules/mob/living/carbon/human/species/unathi.dm b/code/modules/mob/living/carbon/human/species/unathi.dm
index a83e48de6b2..53369bfb68b 100644
--- a/code/modules/mob/living/carbon/human/species/unathi.dm
+++ b/code/modules/mob/living/carbon/human/species/unathi.dm
@@ -3,7 +3,7 @@
name_plural = "Unathi"
icobase = 'icons/mob/human_races/r_lizard.dmi'
deform = 'icons/mob/human_races/r_def_lizard.dmi'
- language = "Sinta'unathi"
+ language = LANGUAGE_UNATHI
tail = "sogtail"
speech_sounds = list('sound/voice/unathitalk.mp3', 'sound/voice/unathitalk2.mp3', 'sound/voice/unathitalk4.mp3')
speech_chance = 33
@@ -60,6 +60,8 @@
INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/unathi
+
has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest),
BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin),
@@ -150,8 +152,8 @@
blurb = "Пеплоходцы — рептильные гуманоиды, по-видимому, родственные унати. Но кажутся значительно менее развитыми. \
Они бродят по пустошам Лаваленда, поклоняются мёртвому городу и ловят ничего не подозревающих шахтёров."
- language = "Sinta'unathi"
- default_language = "Sinta'unathi"
+ language = LANGUAGE_UNATHI
+ default_language = LANGUAGE_UNATHI
speed_mod = -0.80
species_traits = list(NOGUNS, LIPS, PIERCEIMMUNE)
@@ -228,7 +230,7 @@
if(fire)
fire.Remove(C)
-//basic touch ability that heals brute and burn, only accessed by the ashwalker shaman
+//basic touch ability that heals basic damage types accessed by the ashwalker shaman
/obj/effect/proc_holder/spell/touch/healtouch
name = "healing touch"
desc = "This spell charges your hand with the vile energy of the Necropolis, permitting you to undo some external injuries from a target."
@@ -239,7 +241,7 @@
base_cooldown = 20 SECONDS
clothes_req = FALSE
- action_icon_state = "spell_default"
+ action_icon_state = "healtouch"
/obj/item/melee/touch_attack/healtouch
name = "\improper healing touch"
@@ -248,14 +250,20 @@
on_use_sound = 'sound/magic/staff_healing.ogg'
icon_state = "disintegrate" //ironic huh
item_state = "disintegrate"
- var/healamount = 20 //total of 40 assuming they're hurt by both brute and burn
+ //total of 40 assuming they're hurt by both brute and burn
+ var/brute = 20
+ var/burn = 20
+ var/tox = 10
+ var/oxy = 50
/obj/item/melee/touch_attack/healtouch/afterattack(atom/target, mob/living/carbon/user, proximity)
if(!proximity || target == user || !ismob(target) || !iscarbon(user) || user.lying || user.handcuffed) //no healing yourself
return
var/mob/living/M = target
new /obj/effect/temp_visual/heal(get_turf(M), "#899d39")
- M.heal_overall_damage(healamount, healamount, 0) //notice it doesn't heal toxins, still need to learn chems for that
+ M.heal_overall_damage(brute, burn, 0)
+ M.adjustToxLoss(-tox)
+ M.adjustOxyLoss(-oxy)
return ..()
/datum/species/unathi/on_species_gain(mob/living/carbon/human/H)
diff --git a/code/modules/mob/living/carbon/human/species/vox.dm b/code/modules/mob/living/carbon/human/species/vox.dm
index 0584cb6395e..b37ef8d384d 100644
--- a/code/modules/mob/living/carbon/human/species/vox.dm
+++ b/code/modules/mob/living/carbon/human/species/vox.dm
@@ -4,7 +4,7 @@
icobase = 'icons/mob/human_races/vox/r_vox.dmi'
deform = 'icons/mob/human_races/vox/r_def_vox.dmi'
dangerous_existence = TRUE
- language = "Vox-pidgin"
+ language = LANGUAGE_VOX
tail = "voxtail"
speech_sounds = list('sound/voice/shriek1.ogg')
speech_chance = 20
@@ -67,6 +67,8 @@
INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/vox
+
has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest),
BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin),
diff --git a/code/modules/mob/living/carbon/human/species/vulpkanin.dm b/code/modules/mob/living/carbon/human/species/vulpkanin.dm
index 582825ef1a5..6df149c451e 100644
--- a/code/modules/mob/living/carbon/human/species/vulpkanin.dm
+++ b/code/modules/mob/living/carbon/human/species/vulpkanin.dm
@@ -3,7 +3,7 @@
name_plural = "Vulpkanin"
icobase = 'icons/mob/human_races/r_vulpkanin.dmi'
deform = 'icons/mob/human_races/r_vulpkanin.dmi'
- language = "Canilunzt"
+ language = LANGUAGE_VULPKANIN
primitive_form = /datum/species/monkey/vulpkanin
tail = "vulptail"
skinned_type = /obj/item/stack/sheet/fur
@@ -39,6 +39,8 @@
INTERNAL_ORGAN_EARS = /obj/item/organ/internal/ears,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/vulpkanin
+
has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest),
BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin),
diff --git a/code/modules/mob/living/carbon/human/species/wryn.dm b/code/modules/mob/living/carbon/human/species/wryn.dm
index 6499c5192d3..3e56459e92e 100644
--- a/code/modules/mob/living/carbon/human/species/wryn.dm
+++ b/code/modules/mob/living/carbon/human/species/wryn.dm
@@ -4,7 +4,7 @@
icobase = 'icons/mob/human_races/r_wryn.dmi'
deform = 'icons/mob/human_races/r_wryn.dmi'
blacklisted = TRUE
- language = "Wryn Hivemind"
+ language = LANGUAGE_WRYN
tail = "wryntail"
punchdamagelow = 0
punchdamagehigh = 1
@@ -37,6 +37,8 @@
INTERNAL_ORGAN_WAX_GLANDS = /obj/item/organ/internal/wryn/glands,
)
+ meat_type = /obj/item/reagent_containers/food/snacks/meat/humanoid/wryn
+
has_limbs = list(
BODY_ZONE_CHEST = list("path" = /obj/item/organ/external/chest/wryn),
BODY_ZONE_PRECISE_GROIN = list("path" = /obj/item/organ/external/groin/wryn),
@@ -178,7 +180,7 @@
user.visible_message("[user] начина[pluralize_ru(user.gender,"ет","ют")] яростно отрывать усики [target].")
to_chat(target, "[user] схватил[genderize_ru(user.gender,"","а","о","и")] ваши усики и яростно тян[pluralize_ru(user.gender,"ет","ут")] их!")
if(do_mob(user, target, 250))
- target.remove_language("Wryn Hivemind")
+ target.remove_language(LANGUAGE_WRYN)
node.remove(target)
node.forceMove(get_turf(target))
to_chat(user, "Вы слышите громкий хруст, когда безжалостно отрываете усики [target].")
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 527690de353..0eba1270d66 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -144,7 +144,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
// blend the individual damage states with our icons
for(var/obj/item/organ/external/bodypart as anything in bodyparts)
- bodypart.update_icon()
+ bodypart.update_state()
if(bodypart.damage_state == "00")
continue
@@ -165,7 +165,6 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
//BASE MOB SPRITE
/mob/living/carbon/human/proc/update_body(rebuild_base = FALSE)
- remove_overlay(BODY_LAYER)
remove_overlay(LIMBS_LAYER) // So we don't get the old species' sprite splatted on top of the new one's
remove_overlay(UNDERWEAR_LAYER)
@@ -283,8 +282,6 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[UNDERWEAR_LAYER] = mutable_appearance(underwear_standing, layer = -UNDERWEAR_LAYER)
apply_overlay(UNDERWEAR_LAYER)
- overlays_standing[BODY_LAYER] = standing
- apply_overlay(BODY_LAYER)
//wings
update_wing_layer()
//tail
@@ -433,7 +430,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
return
//masks and helmets can obscure our facial hair, unless we're a synthetic
- if((head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR)))
+ if((head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKFACIALHAIR)))
return
//base icons
@@ -704,6 +701,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
remove_overlay(GLASSES_LAYER)
remove_overlay(GLASSES_OVER_LAYER)
remove_overlay(OVER_MASK_LAYER)
+ remove_overlay(OVER_HEAD_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_glasses]
@@ -727,7 +725,11 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
var/datum/sprite_accessory/hair/hair_style = GLOB.hair_styles_full_list[head_organ.h_style]
var/obj/item/clothing/glasses/G = glasses
- if(istype(G) && G.over_mask) //If the user's used the 'wear over mask' verb on the glasses.
+ if(head && !(head.flags_inv & MASKCOVERSEYES || head.flags_cover & HEADCOVERSEYES) && G.over_hat && istype(G))
+ new_glasses.layer = -OVER_HEAD_LAYER
+ overlays_standing[OVER_HEAD_LAYER] = new_glasses
+ apply_overlay(OVER_HEAD_LAYER)
+ else if(istype(G) && G.over_mask) //If the user's used the 'wear over mask' verb on the glasses.
new_glasses.layer = -OVER_MASK_LAYER
overlays_standing[OVER_MASK_LAYER] = new_glasses
apply_overlay(OVER_MASK_LAYER)
diff --git a/code/modules/mob/living/carbon/human/update_stat.dm b/code/modules/mob/living/carbon/human/update_stat.dm
index 1a88a0fa867..afb708a6496 100644
--- a/code/modules/mob/living/carbon/human/update_stat.dm
+++ b/code/modules/mob/living/carbon/human/update_stat.dm
@@ -23,5 +23,11 @@
return ..() // Fallback if we don't have a species or DNA
+/mob/living/carbon/human/has_vision(information_only = FALSE)
+ if(dna?.species)
+ return dna.species.has_vision(src, information_only)
+ return ..()
+
+
/mob/living/carbon/human/check_death_method()
return dna.species.dies_at_threshold
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index a57a08e9e77..e39b81920b8 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -97,6 +97,8 @@
if(breath)
loc.assume_air(breath)
air_update_turf()
+ if(ishuman(src) && !internal && environment.temperature < 278 && environment.return_pressure() > 20)
+ new /obj/effect/frosty_breath(loc, src)
//Third link in a breath chain, calls handle_breath_temperature()
/mob/living/carbon/proc/check_breath(datum/gas_mixture/breath)
diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm
index a59388ce6a7..efc4f388069 100644
--- a/code/modules/mob/living/death.dm
+++ b/code/modules/mob/living/death.dm
@@ -5,7 +5,7 @@
return FALSE
// hide and freeze for the GC
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
@@ -23,7 +23,7 @@
new /obj/effect/decal/cleanable/ash(loc)
// hide and freeze them while they get GC'd
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
QDEL_IN(src, 0)
@@ -34,7 +34,7 @@
return FALSE
// hide and freeze them while they get GC'd
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
QDEL_IN(src, 0)
diff --git a/code/modules/mob/living/default_language.dm b/code/modules/mob/living/default_language.dm
index f6c9c3abc0e..de181396eba 100644
--- a/code/modules/mob/living/default_language.dm
+++ b/code/modules/mob/living/default_language.dm
@@ -6,9 +6,9 @@
set category = "IC"
if(language)
- to_chat(src, "You will now speak [language] if you do not specify a language when speaking.")
+ to_chat(src, span_notice("You will now speak [language] if you do not specify a language when speaking."))
else
- to_chat(src, "You will now speak whatever your standard default language is if you do not specify one when speaking.")
+ to_chat(src, span_notice("You will now speak whatever your standard default language is if you do not specify one when speaking."))
default_language = language
// Silicons can't neccessarily speak everything in their languages list
@@ -20,6 +20,6 @@
set category = "IC"
if(default_language)
- to_chat(src, "You are currently speaking [default_language] by default.")
+ to_chat(src, span_notice("You are currently speaking [default_language] by default."))
else
- to_chat(src, "Your current default language is your species or mob type default.")
+ to_chat(src, span_notice("Your current default language is your species or mob type default."))
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 3598a00aa93..823837544df 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -376,7 +376,7 @@
return 1
/mob/living/welder_act(mob/user, obj/item/I)
- if(!I.tool_use_check(null, 0)) //Don't need the message, just if it succeeded
+ if(!I.tool_use_check(user, 0, silent = TRUE)) //Don't need the message, just if it succeeded
return
if(IgniteMob())
message_admins("[key_name_admin(user)] set [key_name_admin(src)] on fire with [I]")
@@ -1120,7 +1120,7 @@
return 0
/mob/living/proc/attempt_harvest(obj/item/I, mob/user)
- if(user.a_intent == INTENT_HARM && stat == DEAD && butcher_results) //can we butcher it?
+ if(user.a_intent == INTENT_HARM && stat == DEAD && (butcher_results || issmall(src))) //can we butcher it?
var/sharpness = is_sharp(I)
if(sharpness)
to_chat(user, "You begin to butcher [src]...")
@@ -1388,15 +1388,18 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
/mob/living/run_examinate(atom/target)
var/datum/status_effect/staring/user_staring_effect = has_status_effect(STATUS_EFFECT_STARING)
+
if(user_staring_effect || hindered_inspection(target))
return
var/examine_time = target.get_examine_time()
- face_atom(target)
if(examine_time && target != src)
var/visible_gender = target.get_visible_gender()
var/visible_species = "Unknown"
+ // If we did not see the target with our own eyes when starting the examine, then there is no need to check whether it is close.
+ var/near_target = examine_distance_check(target)
+
if(isliving(target))
var/mob/living/target_living = target
visible_species = target_living.get_visible_species()
@@ -1407,17 +1410,24 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
target_staring_effect.catch_look(src)
user_staring_effect = apply_status_effect(STATUS_EFFECT_STARING, examine_time, target, visible_gender, visible_species)
- if(do_mob(src, target, examine_time, FALSE, list(CALLBACK(src, PROC_REF(hindered_inspection), target)), TRUE))
+ if(do_mob(src, src, examine_time, TRUE, only_use_extra_checks = TRUE))
+ if(hindered_inspection(target) || (near_target && !examine_distance_check(target)))
+ return
..()
else
..()
+/mob/living/proc/examine_distance_check(atom/target)
+ if(target in view(client.maxview(), client.eye))
+ return TRUE
+
+
/mob/living/proc/hindered_inspection(atom/target)
if(QDELETED(src) || QDELETED(target))
return TRUE
+ face_atom(target)
if(!has_vision(information_only = TRUE))
to_chat(src, span_notice("Здесь что-то есть, но вы не видите — что именно."))
return TRUE
return FALSE
-
diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm
index cc73ee1149f..3ee7bede863 100644
--- a/code/modules/mob/living/living_say.dm
+++ b/code/modules/mob/living/living_say.dm
@@ -1,26 +1,24 @@
GLOBAL_LIST_INIT(department_radio_keys, list(
/*
Busy letters by languages:
- a b d f g j k o q v x y
- aa as bo db fa fm fn fs vu
+ un ta vu sk vo di tr ki sl gr dr ni
+ xm db wr xh ts ch hs sh ab gl bo bi dt
+ sw gc sc tb gt cl nr mo ne st fa wo
- Busy symbols by languages:
- 0 1 2 3 4 5 6 7 8 9
- % ? ^ '
Busy letters by radio(eng):
c e h i l m n p r s t u w x
Busy letters by radio(rus):
- б г д е ё з к р с т у ц ч ш ы ь я Э
+ б г д е ё з к р с т у ц ч ш ы ь я э
Busy symbols by radio:
~ , $ _ - + * 1 2 3
- CAUTION! The key must not repeat the key of the languages (language.dm)
- and must not contain prohibited characters
+ CAUTION! The key must not repeat the key of the languages (language.dm)
+ and must not contain prohibited characters!
*/
// English text lowercase
":r" = "right ear", "#r" = "right ear", "№r" = "right ear", ".r" = "right ear",
@@ -213,20 +211,9 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
return say_dead(message)
return FALSE
- var/message_mode = parse_message_mode(message, "headset")
-
if(copytext(message, 1, 2) == "*")
return emote(copytext(message, 2), intentional = TRUE)
- //parse the radio code and consume it
- if(message_mode)
- if(message_mode == "headset")
- message = copytext_char(message, 2) //it would be really nice if the parse procs could do this for us.
- else
- message = copytext_char(message, 3)
-
- message = trim_left(message)
-
var/ending = copytext(message, length(message))
if(!(ending in list("!", "?", ",", ".")) && length(message) != 0)
message += "."
@@ -238,15 +225,28 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
else
message_pieces = parse_languages(message)
- if(istype(message_pieces, /datum/multilingual_say_piece)) // Little quirk to just easily deal with HIVEMIND languages
- var/datum/multilingual_say_piece/S = message_pieces // Yay BYOND's hilarious typecasting
- S.speaking.broadcast(src, S.message)
- return TRUE
-
if(!LAZYLEN(message_pieces))
. = FALSE
CRASH("Message failed to generate pieces. [message] - [json_encode(message_pieces)]")
+ var/datum/multilingual_say_piece/first_piece = message_pieces[1]
+
+ if(first_piece.speaking?.flags & HIVEMIND)
+ first_piece.speaking.broadcast(src, first_piece.message)
+ return TRUE
+
+ var/message_mode = parse_message_mode(first_piece.message, "headset")
+
+ //parse the radio code and consume it
+ if(message_mode)
+ if(message_mode == "headset")
+ first_piece.message = copytext_char(first_piece.message, 2) //it would be really nice if the parse procs could do this for us.
+ else
+ first_piece.message = copytext_char(first_piece.message, 3)
+
+ first_piece.message = trim_left(first_piece.message)
+ verb = say_quote(message, first_piece.speaking)
+
if(message_mode == "cords")
if(iscarbon(src))
var/mob/living/carbon/C = src
@@ -256,9 +256,6 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
V.speak_with(message) //words come before actions
return TRUE
- var/datum/multilingual_say_piece/first_piece = message_pieces[1]
- verb = say_quote(message, first_piece.speaking)
-
if(is_muzzled())
var/obj/item/clothing/mask/muzzle/G = wear_mask
if(G.mute == MUZZLE_MUTE_ALL) //if the mask is supposed to mute you completely or just muffle you
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 50de2f19f78..574e554454b 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -139,8 +139,8 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
aiPDA = new/obj/item/pda/silicon/ai(src)
rename_character(null, pickedName)
- anchored = 1
- canmove = 0
+ anchored = TRUE
+ canmove = FALSE
density = 1
loc = loc
@@ -171,24 +171,24 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
add_ai_verbs(src)
//Languages
- add_language("Robot Talk", 1)
- add_language("Galactic Common", 1)
- add_language("Sol Common", 1)
- add_language("Tradeband", 1)
- add_language("Neo-Russkiya", 1)
- add_language("Gutter", 1)
- add_language("Sinta'unathi", 1)
- add_language("Siik'tajr", 1)
- add_language("Canilunzt", 1)
- add_language("Skrellian", 1)
- add_language("Vox-pidgin", 1)
- add_language("Orluum", 1)
- add_language("Rootspeak", 1)
- add_language("Trinary", 1)
- add_language("Chittin", 1)
- add_language("Bubblish", 1)
- add_language("Clownish", 1)
- add_language("Tkachi", 1)
+ add_language(LANGUAGE_BINARY, 1)
+ add_language(LANGUAGE_GALACTIC_COMMON, 1)
+ add_language(LANGUAGE_SOL_COMMON, 1)
+ add_language(LANGUAGE_TRADER, 1)
+ add_language(LANGUAGE_NEO_RUSSIAN, 1)
+ add_language(LANGUAGE_GUTTER, 1)
+ add_language(LANGUAGE_UNATHI, 1)
+ add_language(LANGUAGE_TAJARAN, 1)
+ add_language(LANGUAGE_VULPKANIN, 1)
+ add_language(LANGUAGE_SKRELL, 1)
+ add_language(LANGUAGE_VOX, 1)
+ add_language(LANGUAGE_DRASK, 1)
+ add_language(LANGUAGE_DIONA, 1)
+ add_language(LANGUAGE_TRINARY, 1)
+ add_language(LANGUAGE_KIDAN, 1)
+ add_language(LANGUAGE_SLIME, 1)
+ add_language(LANGUAGE_CLOWN, 1)
+ add_language(LANGUAGE_MOTH, 1)
if(!safety)//Only used by AIize() to successfully spawn an AI.
if(!B)//If there is no player/brain inside.
@@ -338,7 +338,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
use_power = ACTIVE_POWER_USE
power_channel = EQUIP
var/mob/living/silicon/ai/powered_ai = null
- invisibility = 100
+ invisibility = INVISIBILITY_ABSTRACT
/obj/machinery/ai_powersupply/New(mob/living/silicon/ai/ai=null)
powered_ai = ai
@@ -993,19 +993,25 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
if(check_unable())
return
- for(var/obj/machinery/M in GLOB.machines) //change status
- if(istype(M, /obj/machinery/ai_status_display))
- var/obj/machinery/ai_status_display/AISD = M
- AISD.emotion = emote
+ for(var/obj/machinery/ai_status_display/display as anything in GLOB.ai_displays) //change status
+ display.emotion = emote
+ display.update_icon()
+
+ for(var/obj/machinery/machine in GLOB.machines) //change status
+ if(istype(machine, /obj/machinery/ai_status_display))
+ var/obj/machinery/ai_status_display/display = machine
+ display.emotion = emote
+ display.update_icon()
+
//if Friend Computer, change ALL displays
- else if(istype(M, /obj/machinery/status_display))
+ else if(istype(machine, /obj/machinery/status_display))
- var/obj/machinery/status_display/SD = M
+ var/obj/machinery/status_display/display = machine
if(emote=="Friend Computer")
- SD.friendc = 1
+ display.friendc = TRUE
else
- SD.friendc = 0
- return
+ display.friendc = FALSE
+
//I am the icon meister. Bow fefore me. //>fefore
/mob/living/silicon/ai/proc/ai_hologram_change()
@@ -1238,7 +1244,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
/mob/living/silicon/ai/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/wrench))
+ if(W.tool_behaviour == TOOL_WRENCH)
if(anchored)
user.visible_message("\The [user] starts to unbolt \the [src] from the plating...")
if(!do_after(user, 40 * W.toolspeed * gettoolspeedmod(user), target = src))
diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm
index f52b13adaa7..ad4cb78c364 100644
--- a/code/modules/mob/living/silicon/ai/death.dm
+++ b/code/modules/mob/living/silicon/ai/death.dm
@@ -37,8 +37,8 @@
spawn(10)
explosion(src.loc, 3, 6, 12, 15, cause = "AI exploded")
- for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status
- O.mode = 2
+ for(var/obj/machinery/ai_status_display/display as anything in GLOB.ai_displays) //change status
+ display.mode = AI_DISPLAY_MODE_BSOD
if(istype(loc, /obj/item/aicard))
loc.icon_state = "aicard-404"
diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm
index 3e731c68037..d0a0da844ab 100644
--- a/code/modules/mob/living/silicon/ai/freelook/eye.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm
@@ -16,6 +16,8 @@
var/relay_speech = FALSE
var/use_static = TRUE
var/static_visibility_range = 16
+ // Decides if it is shown by AI Detector or not
+ var/ai_detector_visible = TRUE
// Use this when setting the aiEye's location.
diff --git a/code/modules/mob/living/silicon/ai/login.dm b/code/modules/mob/living/silicon/ai/login.dm
index 545e1569fc1..1d39210c8e9 100644
--- a/code/modules/mob/living/silicon/ai/login.dm
+++ b/code/modules/mob/living/silicon/ai/login.dm
@@ -7,7 +7,8 @@
regenerate_icons()
if(stat != DEAD)
- for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status
- O.mode = 1
- O.emotion = "Neutral"
+ for(var/obj/machinery/ai_status_display/display as anything in GLOB.ai_displays) //change status
+ display.mode = AI_DISPLAY_MODE_EMOTE
+ display.emotion = "Neutral"
+
view_core()
diff --git a/code/modules/mob/living/silicon/ai/logout.dm b/code/modules/mob/living/silicon/ai/logout.dm
index d9dac308870..8ee7c503dd0 100644
--- a/code/modules/mob/living/silicon/ai/logout.dm
+++ b/code/modules/mob/living/silicon/ai/logout.dm
@@ -1,6 +1,6 @@
/mob/living/silicon/ai/Logout()
..()
- for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status
- O.mode = 0
+ for(var/obj/machinery/ai_status_display/display as anything in GLOB.ai_displays) //change status
+ display.mode = AI_DISPLAY_MODE_BLANK
src.view_core()
return
diff --git a/code/modules/mob/living/silicon/death.dm b/code/modules/mob/living/silicon/death.dm
index 73995978e5a..6e6094f09fb 100644
--- a/code/modules/mob/living/silicon/death.dm
+++ b/code/modules/mob/living/silicon/death.dm
@@ -2,7 +2,7 @@
death(1)
var/atom/movable/overlay/animation = null
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
@@ -26,7 +26,7 @@
if(!death(TRUE) && stat != DEAD)
return FALSE
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
dust_animation()
diff --git a/code/modules/mob/living/silicon/decoy/death.dm b/code/modules/mob/living/silicon/decoy/death.dm
index 74db72978e0..a7fc4ce09f0 100644
--- a/code/modules/mob/living/silicon/decoy/death.dm
+++ b/code/modules/mob/living/silicon/decoy/death.dm
@@ -4,7 +4,7 @@
if(!.)
return FALSE
icon_state = "ai-crash"
- for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status
- if(atoms_share_level(O, src))
- O.mode = 2
+ for(var/obj/machinery/ai_status_display/display as anything in GLOB.ai_displays) //change status
+ if(atoms_share_level(display, src))
+ display.mode = AI_DISPLAY_MODE_BSOD
gib()
diff --git a/code/modules/mob/living/silicon/decoy/decoy.dm b/code/modules/mob/living/silicon/decoy/decoy.dm
index 0cd5a26fb5e..20b65d33366 100644
--- a/code/modules/mob/living/silicon/decoy/decoy.dm
+++ b/code/modules/mob/living/silicon/decoy/decoy.dm
@@ -2,8 +2,8 @@
name = "AI"
icon = 'icons/mob/ai.dmi'//
icon_state = "ai"
- anchored = 1 // -- TLE
- canmove = 0
+ anchored = TRUE // -- TLE
+ canmove = FALSE
a_intent = INTENT_HARM // This is apparently the only thing that stops other mobs walking through them as if they were thin air.
/mob/living/silicon/decoy/attackby(obj/item/W, mob/user, params)
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 7e4eecf31cd..63e53a4c169 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -122,11 +122,11 @@
radio_name = name
//Default languages without universal translator software
- add_language("Galactic Common", 1)
- add_language("Sol Common", 1)
- add_language("Tradeband", 1)
- add_language("Gutter", 1)
- add_language("Trinary", 1)
+ add_language(LANGUAGE_GALACTIC_COMMON, 1)
+ add_language(LANGUAGE_SOL_COMMON, 1)
+ add_language(LANGUAGE_TRADER, 1)
+ add_language(LANGUAGE_GUTTER, 1)
+ add_language(LANGUAGE_TRINARY, 1)
//Verbs for pAI mobile form, chassis and Say flavor text
verbs += /mob/living/silicon/pai/proc/choose_chassis
@@ -214,7 +214,7 @@
return 0
..()
-/mob/living/silicon/pai/MouseDrop(atom/over_object)
+/mob/living/silicon/pai/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
return
/mob/living/silicon/pai/emp_act(severity)
@@ -608,21 +608,21 @@
return H
-/mob/living/silicon/pai/MouseDrop(atom/over_object)
- var/mob/living/carbon/human/H = over_object //changed to human to avoid stupid issues like xenos holding pAIs.
- if(!istype(H) || !Adjacent(H)) return ..()
+/mob/living/silicon/pai/MouseDrop(mob/living/carbon/human/user, src_location, over_location, src_control, over_control, params)
+ if(!ishuman(user) || !Adjacent(user))
+ return ..()
if(usr == src)
- switch(alert(H, "[src] wants you to pick [p_them()] up. Do it?",,"Yes","No"))
+ switch(alert(user, "[src] wants you to pick [p_them()] up. Do it?",,"Yes","No"))
if("Yes")
- if(Adjacent(H))
- get_scooped(H)
+ if(Adjacent(user))
+ get_scooped(user)
else
- to_chat(src, "You need to stay in reaching distance to be picked up.")
+ to_chat(src, span_warning("You need to stay in reaching distance to be picked up."))
if("No")
- to_chat(src, "[H] decided not to pick you up.")
+ to_chat(src, span_warning("[user] decided not to pick you up."))
else
- if(Adjacent(H))
- get_scooped(H)
+ if(Adjacent(user))
+ get_scooped(user)
else
return ..()
diff --git a/code/modules/mob/living/silicon/pai/software/pai_toggles.dm b/code/modules/mob/living/silicon/pai/software/pai_toggles.dm
index a83fd1df484..1122585fefc 100644
--- a/code/modules/mob/living/silicon/pai/software/pai_toggles.dm
+++ b/code/modules/mob/living/silicon/pai/software/pai_toggles.dm
@@ -48,31 +48,31 @@
// Galactic Common, Sol Common, Tradeband, Gutter and Trinary are added with New() and are therefore the current default, always active languages
user.translator_on = !user.translator_on
if(user.translator_on)
- user.add_language("Sinta'unathi")
- user.add_language("Siik'tajr")
- user.add_language("Canilunzt")
- user.add_language("Skrellian")
- user.add_language("Vox-pidgin")
- user.add_language("Rootspeak")
- user.add_language("Chittin")
- user.add_language("Bubblish")
- user.add_language("Orluum")
- user.add_language("Clownish")
- user.add_language("Neo-Russkiya")
- user.add_language("Tkachi")
+ user.add_language(LANGUAGE_UNATHI)
+ user.add_language(LANGUAGE_TAJARAN)
+ user.add_language(LANGUAGE_VULPKANIN)
+ user.add_language(LANGUAGE_SKRELL)
+ user.add_language(LANGUAGE_VOX)
+ user.add_language(LANGUAGE_DIONA)
+ user.add_language(LANGUAGE_KIDAN)
+ user.add_language(LANGUAGE_SLIME)
+ user.add_language(LANGUAGE_DRASK)
+ user.add_language(LANGUAGE_CLOWN)
+ user.add_language(LANGUAGE_NEO_RUSSIAN)
+ user.add_language(LANGUAGE_MOTH)
else
- user.remove_language("Sinta'unathi")
- user.remove_language("Siik'tajr")
- user.remove_language("Canilunzt")
- user.remove_language("Skrellian")
- user.remove_language("Vox-pidgin")
- user.remove_language("Rootspeak")
- user.remove_language("Chittin")
- user.remove_language("Bubblish")
- user.remove_language("Orluum")
- user.remove_language("Clownish")
- user.remove_language("Neo-Russkiya")
- user.remove_language("Tkachi")
+ user.remove_language(LANGUAGE_UNATHI)
+ user.remove_language(LANGUAGE_TAJARAN)
+ user.remove_language(LANGUAGE_VULPKANIN)
+ user.remove_language(LANGUAGE_SKRELL)
+ user.remove_language(LANGUAGE_VOX)
+ user.remove_language(LANGUAGE_DIONA)
+ user.remove_language(LANGUAGE_KIDAN)
+ user.remove_language(LANGUAGE_SLIME)
+ user.remove_language(LANGUAGE_DRASK)
+ user.remove_language(LANGUAGE_CLOWN)
+ user.remove_language(LANGUAGE_NEO_RUSSIAN)
+ user.remove_language(LANGUAGE_MOTH)
/datum/pai_software/translator/is_active(mob/living/silicon/pai/user)
return user.translator_on
diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm
index fc69a18cf42..e0c05f62ec9 100644
--- a/code/modules/mob/living/silicon/robot/death.dm
+++ b/code/modules/mob/living/silicon/robot/death.dm
@@ -4,7 +4,7 @@
//robots don't die when gibbed. instead they drop their MMI'd brain
var/atom/movable/overlay/animation = null
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
@@ -33,7 +33,7 @@
if(!death(TRUE) && stat != DEAD)
return FALSE
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
if(mmi)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index e9f6984c588..ae7e9a244b8 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -57,10 +57,10 @@
/mob/living/silicon/robot/drone/New()
..()
- remove_language("Robot Talk")
- remove_language("Galactic Common")
- add_language("Drone Talk", 1)
- add_language("Drone", 1)
+ remove_language(LANGUAGE_BINARY)
+ remove_language(LANGUAGE_GALACTIC_COMMON)
+ add_language(LANGUAGE_DRONE_BINARY, 1)
+ add_language(LANGUAGE_DRONE, 1)
// Disable the microphone wire on Drones
if(radio)
@@ -156,7 +156,7 @@
to_chat(user, "The maintenance drone chassis not compatible with \the [W].")
return
- else if(istype(W, /obj/item/crowbar))
+ else if(W.tool_behaviour == TOOL_CROWBAR)
to_chat(user, "The machine is hermetically sealed. You can't open the case.")
return
@@ -345,18 +345,6 @@
to_chat(src, "Don't invade their worksites, don't steal their resources, don't tell them about the changeling in the toilets.")
to_chat(src, "Make sure crew members do not notice you..")
-/*
- sprite["Default"] = "repairbot"
- sprite["Mk2 Mousedrone"] = "mk2"
- sprite["Mk3 Monkeydrone"] = "mk3"
- var/icontype
- icontype = input(player,"Pick an icon") in sprite
- icon_state = sprite[icontype]
- updateicon()
-
- choose_icon(6,sprite)
-*/
-
/mob/living/silicon/robot/drone/Bump(atom/movable/AM, yes)
if(is_type_in_list(AM, allowed_bumpable_objects))
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_console.dm b/code/modules/mob/living/silicon/robot/drone/drone_console.dm
index cc4870915e3..4512a0c3476 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_console.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_console.dm
@@ -143,6 +143,7 @@
return
dronefab.produce_drones = !dronefab.produce_drones
+ dronefab.update_icon(UPDATE_ICON_STATE)
to_chat(usr, "You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.")
src.updateUsrDialog()
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
index 18a746d5f1d..578232b7720 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
@@ -1,44 +1,51 @@
/obj/machinery/drone_fabricator
name = "drone fabricator"
desc = "A large automated factory for producing maintenance drones."
-
+ icon = 'icons/obj/machines/drone_fab.dmi'
+ icon_state = "drone_fab_idle"
density = 1
- anchored = 1
+ anchored = TRUE
use_power = IDLE_POWER_USE
idle_power_usage = 20
active_power_usage = 5000
-
var/drone_progress = 0
- var/produce_drones = 1
+ var/produce_drones = TRUE
var/time_last_drone = 500
- icon = 'icons/obj/machines/drone_fab.dmi'
- icon_state = "drone_fab_idle"
-
-/obj/machinery/drone_fabricator/New()
- ..()
-/obj/machinery/drone_fabricator/power_change()
- if(powered())
- stat &= ~NOPOWER
- else
+/obj/machinery/drone_fabricator/update_icon_state()
+ if(stat & NOPOWER)
icon_state = "drone_fab_nopower"
- stat |= NOPOWER
+ return
+
+ if(!produce_drones || (!drone_progress || drone_progress >= 100))
+ icon_state = "drone_fab_idle"
+ return
+
+ icon_state = "drone_fab_active"
+
+
+/obj/machinery/drone_fabricator/power_change(forced = FALSE)
+ if(!..())
+ return
+ update_icon(UPDATE_ICON_STATE)
+
/obj/machinery/drone_fabricator/process()
if(SSticker.current_state < GAME_STATE_PLAYING)
return
- if(stat & NOPOWER || !produce_drones)
- if(icon_state != "drone_fab_nopower") icon_state = "drone_fab_nopower"
+ if((stat & NOPOWER) || !produce_drones)
return
if(drone_progress >= 100)
- icon_state = "drone_fab_idle"
+ if(icon_state != "drone_fab_idle")
+ update_icon(UPDATE_ICON_STATE)
return
- icon_state = "drone_fab_active"
+ if(icon_state != "drone_fab_active")
+ update_icon(UPDATE_ICON_STATE)
var/elapsed = world.time - time_last_drone
drone_progress = round((elapsed/CONFIG_GET(number/drone_build_time))*100)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_say.dm b/code/modules/mob/living/silicon/robot/drone/drone_say.dm
index a5418634b81..226be34b2e3 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_say.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_say.dm
@@ -12,5 +12,5 @@
/mob/living/silicon/robot/drone/get_default_language()
if(default_language)
return default_language
- return GLOB.all_languages["Drone"]
+ return GLOB.all_languages[LANGUAGE_DRONE]
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 781ea202a76..cbd1ab7538a 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -124,7 +124,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
spark_system.set_up(5, 0, src)
spark_system.attach(src)
- add_language("Robot Talk", 1)
+ add_language(LANGUAGE_BINARY, 1)
wires = new(src)
@@ -561,7 +561,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
for(var/obj/item/borg/upgrade/upgrade in upgrades) //remove all upgrades, cuz we reseting
qdel(upgrade)
- add_language("Robot Talk", 1)
+ add_language(LANGUAGE_BINARY, 1)
status_flags |= CANPUSH
//for borg hotkeys, here module refers to borg inv slot, not core module
@@ -1042,17 +1042,27 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
laws.show_laws(src)
to_chat(src, "ALERT: [M.real_name] is your new master. Obey your new laws and [M.p_their()] commands.")
SetLockdown(FALSE)
- if(src.module && istype(src.module, /obj/item/robot_module/miner))
- for(var/obj/item/pickaxe/drill/cyborg/D in src.module.modules)
- qdel(D)
- src.module.modules += new /obj/item/pickaxe/drill/cyborg/diamond(src.module)
- src.module.rebuild()
if(module)
+ module.emag_act(user)
module.module_type = "Malf" // For the cool factor
update_module_icon()
update_icons()
return
+// Here so admins can unemag borgs.
+/mob/living/silicon/robot/unemag()
+ SetEmagged(FALSE)
+ if(!module)
+ return
+ uneq_all()
+ module.module_type = initial(module.module_type)
+ update_module_icon()
+ module.unemag()
+ clear_supplied_laws()
+ laws = new /datum/ai_laws/crewsimov
+ to_chat(src, "Obey these laws:")
+ laws.show_laws(src)
+
/mob/living/silicon/robot/ratvar_act(weak = FALSE)
if(isclocker(src) && module?.type == /obj/item/robot_module/clockwork)
return
@@ -1388,7 +1398,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
disconnect_from_ai()
lawupdate = 0
lockcharge = 0
- canmove = 1
+ canmove = TRUE
scrambledcodes = 1
//Disconnect it's camera so it's not so easily tracked.
QDEL_NULL(src.camera)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index f2ca99a90d9..4e83e0b39cb 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -120,23 +120,23 @@
/obj/item/robot_module/proc/add_languages(mob/living/silicon/robot/R)
//full set of languages
- R.add_language("Galactic Common", 1)
- R.add_language("Sol Common", 1)
- R.add_language("Tradeband", 1)
- R.add_language("Gutter", 0)
- R.add_language("Neo-Russkiya", 0)
- R.add_language("Sinta'unathi", 0)
- R.add_language("Siik'tajr", 0)
- R.add_language("Canilunzt", 0)
- R.add_language("Skrellian", 0)
- R.add_language("Vox-pidgin", 0)
- R.add_language("Rootspeak", 0)
- R.add_language("Trinary", 1)
- R.add_language("Chittin", 0)
- R.add_language("Bubblish", 0)
- R.add_language("Orluum", 0)
- R.add_language("Clownish",0)
- R.add_language("Tkachi", 0)
+ R.add_language(LANGUAGE_GALACTIC_COMMON, 1)
+ R.add_language(LANGUAGE_SOL_COMMON, 1)
+ R.add_language(LANGUAGE_TRADER, 1)
+ R.add_language(LANGUAGE_GUTTER, 0)
+ R.add_language(LANGUAGE_NEO_RUSSIAN, 0)
+ R.add_language(LANGUAGE_UNATHI, 0)
+ R.add_language(LANGUAGE_TAJARAN, 0)
+ R.add_language(LANGUAGE_VULPKANIN, 0)
+ R.add_language(LANGUAGE_SKRELL, 0)
+ R.add_language(LANGUAGE_VOX, 0)
+ R.add_language(LANGUAGE_DIONA, 0)
+ R.add_language(LANGUAGE_TRINARY, 1)
+ R.add_language(LANGUAGE_KIDAN, 0)
+ R.add_language(LANGUAGE_SLIME, 0)
+ R.add_language(LANGUAGE_DRASK, 0)
+ R.add_language(LANGUAGE_CLOWN,0)
+ R.add_language(LANGUAGE_MOTH, 0)
/obj/item/robot_module/proc/add_subsystems_and_actions(mob/living/silicon/robot/R)
R.verbs |= subsystems
@@ -281,6 +281,18 @@
fix_modules()
handle_storages()
+// Disable safeties on the borg's defib.
+/obj/item/robot_module/medical/emag_act(mob/user)
+ . = ..()
+ for(var/obj/item/twohanded/shockpaddles/borg/defib in modules)
+ defib.emag_act()
+
+// Enable safeties on the borg's defib.
+/obj/item/robot_module/medical/unemag()
+ for(var/obj/item/twohanded/shockpaddles/borg/defib in modules)
+ defib.emag_act()
+ return ..()
+
/obj/item/robot_module/medical/respawn_consumable(mob/living/silicon/robot/R)
if(emag)
var/obj/item/reagent_containers/spray/PS = emag
@@ -481,22 +493,23 @@
/obj/item/robot_module/butler/add_languages(var/mob/living/silicon/robot/R)
//full set of languages
- R.add_language("Galactic Common", 1)
- R.add_language("Sol Common", 1)
- R.add_language("Tradeband", 1)
- R.add_language("Gutter", 1)
- R.add_language("Sinta'unathi", 1)
- R.add_language("Siik'tajr", 1)
- R.add_language("Canilunzt", 1)
- R.add_language("Skrellian", 1)
- R.add_language("Vox-pidgin", 1)
- R.add_language("Rootspeak", 1)
- R.add_language("Trinary", 1)
- R.add_language("Chittin", 1)
- R.add_language("Bubblish", 1)
- R.add_language("Clownish",1)
- R.add_language("Neo-Russkiya", 1)
- R.add_language("Tkachi", 1)
+ R.add_language(LANGUAGE_GALACTIC_COMMON, 1)
+ R.add_language(LANGUAGE_SOL_COMMON, 1)
+ R.add_language(LANGUAGE_TRADER, 1)
+ R.add_language(LANGUAGE_GUTTER, 1)
+ R.add_language(LANGUAGE_NEO_RUSSIAN, 1)
+ R.add_language(LANGUAGE_UNATHI, 1)
+ R.add_language(LANGUAGE_TAJARAN, 1)
+ R.add_language(LANGUAGE_VULPKANIN, 1)
+ R.add_language(LANGUAGE_SKRELL, 1)
+ R.add_language(LANGUAGE_VOX, 1)
+ R.add_language(LANGUAGE_DIONA, 1)
+ R.add_language(LANGUAGE_TRINARY, 1)
+ R.add_language(LANGUAGE_KIDAN, 1)
+ R.add_language(LANGUAGE_SLIME, 1)
+ R.add_language(LANGUAGE_DRASK, 1)
+ R.add_language(LANGUAGE_CLOWN,1)
+ R.add_language(LANGUAGE_MOTH, 1)
/obj/item/robot_module/butler/handle_death(mob/living/silicon/robot/R, gibbed)
var/obj/item/storage/bag/tray/cyborg/T = locate(/obj/item/storage/bag/tray/cyborg) in modules
@@ -544,6 +557,26 @@
fix_modules()
+// Replace their normal drill with a diamond drill.
+/obj/item/robot_module/miner/emag_act()
+ . = ..()
+ for(var/obj/item/pickaxe/drill/cyborg/D in modules)
+ // Make sure we don't remove the diamond drill If they already have a diamond drill from the borg upgrade.
+ if(!istype(D, /obj/item/pickaxe/drill/cyborg/diamond))
+ qdel(D)
+ modules -= D // Remove it from this list so it doesn't get added in the rebuild.
+ modules += new /obj/item/pickaxe/drill/cyborg/diamond(src)
+ rebuild()
+
+// Readd the normal drill
+/obj/item/robot_module/miner/unemag()
+ for(var/obj/item/pickaxe/drill/cyborg/diamond/drill in modules)
+ qdel(drill)
+ modules -= drill
+ modules += new /obj/item/pickaxe/drill/cyborg(src)
+ rebuild()
+ return ..()
+
/obj/item/robot_module/miner/handle_custom_removal(component_id, mob/living/user, obj/item/W)
if(component_id == "KA modkits")
for(var/obj/item/gun/energy/kinetic_accelerator/cyborg/D in src)
@@ -762,7 +795,7 @@
/obj/item/robot_module/hunter/add_languages(var/mob/living/silicon/robot/R)
..()
- R.add_language("xenocommon", 1)
+ R.add_language(LANGUAGE_XENOS, 1)
/obj/item/robot_module/drone
name = "Drone"
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 7cf2583c3e7..216c5672927 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -39,7 +39,7 @@
/mob/living/silicon/New()
GLOB.silicon_mob_list |= src
..()
- add_language("Galactic Common")
+ add_language(LANGUAGE_GALACTIC_COMMON)
init_subsystems()
RegisterSignal(SSalarm, COMSIG_TRIGGERED_ALARM, PROC_REF(alarm_triggered))
RegisterSignal(SSalarm, COMSIG_CANCELLED_ALARM, PROC_REF(alarm_cancelled))
@@ -283,19 +283,19 @@
//Silicon mob language procs
/mob/living/silicon/can_speak_language(datum/language/speaking)
- return universal_speak || (speaking in src.speech_synthesizer_langs) //need speech synthesizer support to vocalize a language
+ return universal_speak || (speaking in speech_synthesizer_langs) //need speech synthesizer support to vocalize a language
-/mob/living/silicon/add_language(var/language, var/can_speak=1)
+/mob/living/silicon/add_language(language, can_speak = TRUE)
if(..(language) && can_speak)
speech_synthesizer_langs.Add(GLOB.all_languages[language])
- return 1
+ return TRUE
-/mob/living/silicon/remove_language(var/rem_language)
- ..(rem_language)
+/mob/living/silicon/remove_language(language_name)
+ ..(language_name)
- for(var/datum/language/L in speech_synthesizer_langs)
- if(L.name == rem_language)
- speech_synthesizer_langs -= L
+ for(var/datum/language/language in speech_synthesizer_langs)
+ if(language.name == language_name)
+ speech_synthesizer_langs -= language
/mob/living/silicon/check_lang_data()
. = ""
@@ -303,16 +303,16 @@
if(default_language)
. += "Current default language: [default_language] - reset
"
- for(var/datum/language/L in languages)
- if(!(L.flags & NONGLOBAL))
+ for(var/datum/language/language in languages)
+ if(!(language.flags & NONGLOBAL))
var/default_str
- if(L == default_language)
+ if(language == default_language)
default_str = " - default - reset"
else
- default_str = " - set default"
+ default_str = " - set default"
- var/synth = (L in speech_synthesizer_langs)
- . += "[L.name] (:[L.key])[synth ? default_str : null] Speech Synthesizer: [synth ? "YES" : "NOT SUPPORTED"] [L.desc]
"
+ var/synth = (language in speech_synthesizer_langs)
+ . += "[language.name] (:[language.key])[synth ? default_str : null] Speech Synthesizer: [synth ? "YES" : "NOT SUPPORTED"] [language.desc]
"
// this function displays the stations manifest in a separate window
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index 990d08d0782..363d2068fa6 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -198,12 +198,12 @@
set_custom_texts()
Radio = new/obj/item/radio/headset/bot(src)
Radio.follow_target = src
- add_language("Galactic Common", TRUE)
- add_language("Sol Common", TRUE)
- add_language("Tradeband", TRUE)
- add_language("Gutter", TRUE)
- add_language("Trinary", TRUE)
- default_language = GLOB.all_languages["Galactic Common"]
+ add_language(LANGUAGE_GALACTIC_COMMON, TRUE)
+ add_language(LANGUAGE_SOL_COMMON, TRUE)
+ add_language(LANGUAGE_TRADER, TRUE)
+ add_language(LANGUAGE_GUTTER, TRUE)
+ add_language(LANGUAGE_TRINARY, TRUE)
+ default_language = GLOB.all_languages[LANGUAGE_GALACTIC_COMMON]
bot_core = new bot_core_type(src)
addtimer(CALLBACK(src, PROC_REF(add_bot_filter)), 3 SECONDS)
diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
index 5b40a820fa9..18efda2bdd7 100644
--- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
@@ -41,10 +41,16 @@
var/datum/job/janitor/J = new/datum/job/janitor
access_card.access += J.get_access()
prev_access = access_card.access
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
+
+
+/mob/living/simple_animal/bot/cleanbot/update_icon_state()
+ return
+
+
+/mob/living/simple_animal/bot/cleanbot/update_overlays()
+ . = ..()
-/mob/living/simple_animal/bot/cleanbot/update_icon()
- overlays.Cut()
var/overlay_state
switch(mode)
if(BOT_CLEANING)
@@ -52,15 +58,10 @@
if(BOT_IDLE)
overlay_state = "[on]"
- var/mutable_appearance/state_appearance = mutable_appearance(icon, "[icon_state][overlay_state]")
- state_appearance.appearance_flags |= RESET_COLOR
- overlays += state_appearance
+ . += mutable_appearance(icon, "[icon_state][overlay_state]", appearance_flags = RESET_COLOR)
if(mask_color)
- var/mutable_appearance/casing_mask = mutable_appearance(icon, "cleanbot_mask")
- casing_mask.appearance_flags |= RESET_COLOR
- casing_mask.color = mask_color
- overlays += casing_mask
+ . += mutable_appearance(icon, "cleanbot_mask", appearance_flags = RESET_COLOR, color = mask_color)
/mob/living/simple_animal/bot/cleanbot/bot_reset()
diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm
index 392b965c497..179bcc64f43 100644
--- a/code/modules/mob/living/simple_animal/bot/construction.dm
+++ b/code/modules/mob/living/simple_animal/bot/construction.dm
@@ -14,7 +14,7 @@
var/created_name = "Cleanbot"
var/robot_arm = /obj/item/robot_parts/l_arm
-/obj/item/bucket_sensor/attackby(obj/item/W, mob/user as mob, params)
+/obj/item/bucket_sensor/attackby(obj/item/W, mob/user, params)
..()
if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm))
if(!user.drop_transfer_item_to_loc(W, src))
@@ -45,6 +45,52 @@
var/build_step = 0
var/created_name = "\improper ED-209 Security Robot" //To preserve the name if it's a unique securitron I guess
var/lasercolor = ""
+ var/new_name = ""
+
+
+/obj/item/ed209_assembly/update_name(updates = ALL)
+ . = ..()
+ switch(build_step)
+ if(1,2)
+ name = "legs/frame assembly"
+ if(3)
+ name = "vest/legs/frame assembly"
+ if(4)
+ name = "shielded frame assembly"
+ if(5)
+ name = "covered and shielded frame assembly"
+ if(6)
+ name = "covered, shielded and sensored frame assembly"
+ if(7)
+ name = "wired ED-209 assembly"
+ if(8)
+ name = new_name
+ if(9)
+ name = "armed [name]"
+
+
+/obj/item/ed209_assembly/update_icon_state()
+ switch(build_step)
+ if(1)
+ item_state = "ed209_leg"
+ icon_state = "ed209_leg"
+ if(2)
+ item_state = "ed209_legs"
+ icon_state = "ed209_legs"
+ if(3,4)
+ item_state = "[lasercolor]ed209_shell"
+ icon_state = "[lasercolor]ed209_shell"
+ if(5)
+ item_state = "[lasercolor]ed209_hat"
+ icon_state = "[lasercolor]ed209_hat"
+ if(6,7)
+ item_state = "[lasercolor]ed209_prox"
+ icon_state = "[lasercolor]ed209_prox"
+ if(8,9)
+ item_state = "[lasercolor]ed209_taser"
+ icon_state = "[lasercolor]ed209_taser"
+
+
/obj/item/ed209_assembly/attackby(obj/item/W, mob/user, params)
..()
@@ -64,13 +110,7 @@
qdel(W)
build_step++
to_chat(user, "You add the robot leg to [src].")
- name = "legs/frame assembly"
- if(build_step == 1)
- item_state = "ed209_leg"
- icon_state = "ed209_leg"
- else
- item_state = "ed209_legs"
- icon_state = "ed209_legs"
+ update_appearance(UPDATE_NAME|UPDATE_ICON_STATE)
if(2)
var/newcolor = ""
@@ -85,14 +125,12 @@
qdel(W)
build_step++
to_chat(user, "You add the armor to [src].")
- name = "vest/legs/frame assembly"
- item_state = "[lasercolor]ed209_shell"
- icon_state = "[lasercolor]ed209_shell"
+ update_appearance(UPDATE_NAME|UPDATE_ICON_STATE)
if(3)
if(W.tool_behaviour == TOOL_WELDER && W.use_tool(src, user, volume = W.tool_volume))
build_step++
- name = "shielded frame assembly"
+ update_appearance(UPDATE_NAME|UPDATE_ICON_STATE)
to_chat(user, "You weld the vest to [src].")
if(4)
switch(lasercolor)
@@ -113,9 +151,7 @@
qdel(W)
build_step++
to_chat(user, "You add the helmet to [src].")
- name = "covered and shielded frame assembly"
- item_state = "[lasercolor]ed209_hat"
- icon_state = "[lasercolor]ed209_hat"
+ update_appearance(UPDATE_NAME|UPDATE_ICON_STATE)
if(5)
if(isprox(W))
@@ -124,9 +160,7 @@
qdel(W)
build_step++
to_chat(user, "You add the prox sensor to [src].")
- name = "covered, shielded and sensored frame assembly"
- item_state = "[lasercolor]ed209_prox"
- icon_state = "[lasercolor]ed209_prox"
+ update_appearance(UPDATE_NAME|UPDATE_ICON_STATE)
if(6)
if(istype(W, /obj/item/stack/cable_coil))
@@ -141,43 +175,32 @@
build_step = 7
playsound(loc, W.usesound, 50, 1)
to_chat(user, "You wire the ED-209 assembly.")
- name = "wired ED-209 assembly"
+ update_appearance(UPDATE_NAME)
if(7)
- var/newname = ""
+ new_name = ""
switch(lasercolor)
if("b")
if(!istype(W, /obj/item/gun/energy/laser/tag/blue))
return
- newname = "bluetag ED-209 assembly"
+ new_name = "bluetag ED-209 assembly"
if("r")
if(!istype(W, /obj/item/gun/energy/laser/tag/red))
return
- newname = "redtag ED-209 assembly"
+ new_name = "redtag ED-209 assembly"
if("")
if(!istype(W, /obj/item/gun/energy/gun/advtaser))
return
- newname = "taser ED-209 assembly"
+ new_name = "taser ED-209 assembly"
else
return
if(!user.drop_transfer_item_to_loc(W, src))
return
- name = newname
build_step++
to_chat(user, "You add [W] to [src].")
- item_state = "[lasercolor]ed209_taser"
- icon_state = "[lasercolor]ed209_taser"
+ update_appearance(UPDATE_NAME|UPDATE_ICON_STATE)
qdel(W)
- if(8)
- if(istype(W, /obj/item/screwdriver))
- playsound(loc, W.usesound, 100, 1)
- to_chat(user, "You start attaching the gun to the frame...")
- if(do_after(user, 40 * W.toolspeed * gettoolspeedmod(user), target = src))
- build_step++
- name = "armed [name]"
- to_chat(user, "Taser gun attached.")
-
if(9)
if(istype(W, /obj/item/stock_parts/cell))
if(!user.drop_transfer_item_to_loc(W, src))
@@ -190,6 +213,19 @@
user.temporarily_remove_item_from_inventory(src, force = TRUE)
qdel(src)
+
+/obj/item/ed209_assembly/screwdriver_act(mob/living/user, obj/item/I)
+ if(build_step != 8)
+ return
+ I.play_tool_sound(src)
+ to_chat(user, "You start attaching the gun to the frame...")
+ if(do_after(user, 4 SECONDS * I.toolspeed, target = src))
+ build_step++
+ update_appearance(UPDATE_NAME)
+ to_chat(user, "You attach the gun to the frame.")
+ return TRUE
+
+
//Floorbot assemblies
/obj/item/toolbox_tiles
desc = "It's a toolbox with tiles sticking out the top"
@@ -242,7 +278,7 @@
B.toolbox_color = "s"
if(/obj/item/storage/toolbox/fakesyndi)
B.toolbox_color = "s"
- B.icon_state = "[B.toolbox_color]toolbox_tiles"
+ B.update_icon(UPDATE_ICON_STATE)
user.put_in_hands(B, ignore_anim = FALSE)
to_chat(user, "You add the tiles into the empty toolbox. They protrude from the top.")
user.temporarily_remove_item_from_inventory(src, force = TRUE)
@@ -251,6 +287,11 @@
to_chat(user, "You need 10 floor tiles to start building a floorbot.")
return
+
+/obj/item/toolbox_tiles/update_icon_state()
+ icon_state = "[toolbox_color]toolbox_tiles"
+
+
/obj/item/toolbox_tiles/attackby(obj/item/W, mob/user, params)
..()
if(isprox(W))
@@ -260,7 +301,7 @@
var/obj/item/toolbox_tiles/sensor/B = new /obj/item/toolbox_tiles/sensor(drop_location())
B.created_name = created_name
B.toolbox_color = src.toolbox_color
- B.icon_state = "[B.toolbox_color]toolbox_tiles_sensor"
+ B.update_icon(UPDATE_ICON_STATE)
user.put_in_hands(B, ignore_anim = FALSE)
to_chat(user, "You add the sensor to the toolbox and tiles.")
user.temporarily_remove_item_from_inventory(src, force = TRUE)
@@ -272,6 +313,11 @@
created_name = t
add_game_logs("[key_name(user)] has renamed a robot to [t]", user)
+
+/obj/item/toolbox_tiles/sensor/update_icon_state()
+ icon_state = "[toolbox_color]toolbox_tiles_sensor"
+
+
/obj/item/toolbox_tiles/sensor/attackby(obj/item/W, mob/user, params)
..()
if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm))
@@ -340,14 +386,21 @@
..()
if(new_skin)
skin = new_skin
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
+
-/obj/item/firstaid_arm_assembly/update_icon()
- overlays.Cut()
+/obj/item/firstaid_arm_assembly/update_overlays()
+ . = ..()
if(skin)
- overlays += image('icons/obj/aibots.dmi', "kit_skin_[skin]")
+ . += image('icons/obj/aibots.dmi', "kit_skin_[skin]")
if(build_step > 0)
- overlays += image('icons/obj/aibots.dmi', "na_scanner")
+ . += image('icons/obj/aibots.dmi', "na_scanner")
+
+
+/obj/item/firstaid_arm_assembly/update_name(updates = ALL)
+ . = ..()
+ if(build_step == 1)
+ name = "First aid/robot arm/health analyzer assembly"
/obj/item/firstaid_arm_assembly/attackby(obj/item/I, mob/user, params)
@@ -366,8 +419,7 @@
qdel(I)
build_step++
to_chat(user, "You add the health sensor to [src].")
- name = "First aid/robot arm/health analyzer assembly"
- update_icon()
+ update_appearance(UPDATE_NAME|UPDATE_OVERLAYS)
if(1)
if(isprox(I))
@@ -403,32 +455,77 @@
var/build_step = 0
var/robot_arm = /obj/item/robot_parts/l_arm
+
+/obj/item/secbot_assembly/update_name(updates = ALL)
+ . = ..()
+ switch(build_step)
+ if(2)
+ name = "helmet/signaler/prox sensor assembly"
+ if(3)
+ name = "helmet/signaler/prox sensor/robot arm assembly"
+
+
+/obj/item/secbot_assembly/update_overlays()
+ . = ..()
+ switch(build_step)
+ if(1)
+ . += "hs_hole"
+ if(2)
+ . += "hs_eye"
+ if(3)
+ . += "hs_arm"
+
+
+/obj/item/secbot_assembly/screwdriver_act(mob/living/user, obj/item/I)
+ if(build_step != 0 && build_step != 2 && build_step != 3)
+ return
+
+ switch(build_step)
+ if(0)
+ new /obj/item/assembly/signaler(get_turf(src))
+ new /obj/item/clothing/head/helmet(get_turf(src))
+ to_chat(user, "You disconnect the signaler from the helmet.")
+ qdel(src)
+ if(2)
+ new /obj/item/assembly/prox_sensor(get_turf(src))
+ to_chat(user, "You detach the proximity sensor from [src].")
+ build_step--
+ if(3)
+ new /obj/item/robot_parts/l_arm(get_turf(src))
+ to_chat(user, "You remove the robot arm from [src].")
+ build_step--
+
+ I.play_tool_sound(src)
+ update_appearance(UPDATE_NAME|UPDATE_OVERLAYS)
+ return TRUE
+
+
/obj/item/clothing/head/helmet/attackby(obj/item/assembly/signaler/S, mob/user, params)
..()
if(!issignaler(S))
..()
return
- if(!S.secured)
- qdel(S)
- var/obj/item/secbot_assembly/A = new /obj/item/secbot_assembly(drop_location())
- user.put_in_hands(A, ignore_anim = FALSE)
- to_chat(user, "You add the signaler to the helmet.")
- user.temporarily_remove_item_from_inventory(src, force = TRUE)
- qdel(src)
- else
+ if(S.secured)
+ to_chat(user, "[S] is secured.")
return
+ qdel(S)
+ var/obj/item/secbot_assembly/A = new /obj/item/secbot_assembly(drop_location())
+ user.put_in_hands(A, ignore_anim = FALSE)
+ to_chat(user, "You add the signaler to the helmet.")
+ user.temporarily_remove_item_from_inventory(src, force = TRUE)
+ qdel(src)
+
+
/obj/item/secbot_assembly/attackby(obj/item/I, mob/user, params)
..()
if(I.tool_behaviour == TOOL_WELDER && I.use_tool(src, user, volume = I.tool_volume))
if(!build_step)
build_step++
- overlays += "hs_hole"
to_chat(user, "You weld a hole in [src]!")
else if(build_step == 1)
build_step--
- overlays -= "hs_hole"
to_chat(user, "You weld the hole in [src] shut!")
else if(isprox(I) && (build_step == 1))
@@ -436,8 +533,6 @@
return
build_step++
to_chat(user, "You add the prox sensor to [src]!")
- overlays += "hs_eye"
- name = "helmet/signaler/prox sensor assembly"
qdel(I)
else if(((istype(I, /obj/item/robot_parts/l_arm)) || (istype(I, /obj/item/robot_parts/r_arm))) && (build_step == 2))
@@ -445,8 +540,6 @@
return
build_step++
to_chat(user, "You add the robot arm to [src]!")
- name = "helmet/signaler/prox sensor/robot arm assembly"
- overlays += "hs_arm"
robot_arm = I.type
qdel(I)
@@ -467,7 +560,7 @@
created_name = t
add_game_logs("[key_name(user)] has renamed a robot to [t]", user)
- else if(istype(I, /obj/item/screwdriver))
+ else if(I.tool_behaviour == TOOL_SCREWDRIVER)
if(!build_step)
new /obj/item/assembly/signaler(get_turf(src))
new /obj/item/clothing/head/helmet(get_turf(src))
@@ -486,15 +579,18 @@
to_chat(user, "You remove the robot arm from [src].")
build_step--
-//General Griefsky
-
- else if((istype(I, /obj/item/wrench)) && (build_step == 3))
+ else if((I.tool_behaviour == TOOL_WRENCH) && (build_step == 3))
var/obj/item/griefsky_assembly/A = new /obj/item/griefsky_assembly(drop_location())
user.put_in_hands(A, ignore_anim = FALSE)
to_chat(user, "You adjust the arm slots for extra weapons!.")
user.temporarily_remove_item_from_inventory(src, force = TRUE)
qdel(src)
+ update_appearance(UPDATE_NAME|UPDATE_OVERLAYS)
+
+
+//General Griefsky
+
/obj/item/griefsky_assembly
name = "\improper Griefsky assembly"
desc = "Some sort of bizarre assembly."
@@ -506,7 +602,7 @@
/obj/item/griefsky_assembly/attackby(obj/item/I, mob/user, params)
..()
- if((istype(I, /obj/item/melee/energy/sword)) && (!toy_step == 0 ))
+ if((istype(I, /obj/item/melee/energy/sword)) && (toy_step != 0 ))
to_chat(user, "You can't add an energy sword to [src]!.")
else if((istype(I, /obj/item/melee/energy/sword)) && (build_step < 3 ))
@@ -524,7 +620,7 @@
qdel(I)
qdel(src)
- else if((istype(I, /obj/item/toy/sword)) && (!build_step == 0 ))
+ else if((istype(I, /obj/item/toy/sword)) && (build_step != 0 ))
to_chat(user, "You can't add a toy sword to [src]!.")
else if((istype(I, /obj/item/toy/sword)) && (toy_step < 3 ))
@@ -542,7 +638,7 @@
qdel(I)
qdel(src)
- else if(istype(I, /obj/item/screwdriver))
+ else if(I.tool_behaviour == TOOL_SCREWDRIVER)
if((build_step == 1) || (build_step == 2) || (build_step == 3) || (build_step == 4))
new /obj/item/melee/energy/sword(get_turf(src))
to_chat(user, "You detach the energy sword from [src].")
@@ -552,6 +648,23 @@
to_chat(user, "You detach the toy sword from [src].")
toy_step--
+
+/obj/item/griefsky_assembly/screwdriver_act(mob/living/user, obj/item/I)
+ if(!build_step && !toy_step)
+ return
+
+ if(build_step)
+ new /obj/item/melee/energy/sword(get_turf(src))
+ to_chat(user, "You detach the energy sword from [src].")
+ build_step--
+ else if(toy_step)
+ new /obj/item/toy/sword(get_turf(src))
+ to_chat(user, "You detach the toy sword from [src].")
+ toy_step--
+ I.play_tool_sound(src)
+ return TRUE
+
+
//Honkbot Assembly
/obj/item/storage/box/clown/attackby(obj/item/W, mob/user, params)
if(!istype(W, /obj/item/robot_parts/l_arm) && !istype(W, /obj/item/robot_parts/r_arm))
@@ -589,7 +702,6 @@
return
build_step++
to_chat(user, "You add the proximity sensor to [src].")
- icon_state = "honkbot_proxy"
qdel(W)
else if(build_step == 1)
if(istype(W, /obj/item/bikehorn))
@@ -597,7 +709,6 @@
return
build_step++
to_chat(user, "You add the bikehorn to [src]! Honk!")
- desc = "A clown box with a robot arm and a bikehorn permanently grafted to it. It needs a trombone to be finished"
qdel(W)
else if(build_step == 2)
if(istype(W, /obj/item/instrument/trombone))
@@ -608,3 +719,17 @@
var/mob/living/simple_animal/bot/honkbot/A = new /mob/living/simple_animal/bot/honkbot(get_turf(src))
A.robot_arm = robot_arm
qdel(src)
+
+ update_appearance(UPDATE_DESC|UPDATE_ICON_STATE)
+
+
+/obj/item/honkbot_arm_assembly/update_icon_state()
+ if(build_step == 1)
+ icon_state = "honkbot_proxy"
+
+
+/obj/item/honkbot_arm_assembly/update_desc(updates = ALL)
+ . = ..()
+ if(build_step == 2)
+ desc = "A clown box with a robot arm and a bikehorn permanently grafted to it. It needs a trombone to be finished"
+
diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm
index 4f286b054c4..8f9e83d5007 100644
--- a/code/modules/mob/living/simple_animal/bot/floorbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm
@@ -427,7 +427,7 @@
update_icon()
-/mob/living/simple_animal/bot/floorbot/update_icon()
+/mob/living/simple_animal/bot/floorbot/update_icon_state()
if(mode == BOT_REPAIRING)
icon_state = "[toolbox_color]floorbot-c"
return
diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm
index ebee011df78..63435a01a0b 100644
--- a/code/modules/mob/living/simple_animal/bot/medbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/medbot.dm
@@ -116,10 +116,7 @@
drops_parts = FALSE
-/mob/living/simple_animal/bot/medbot/update_icon()
- overlays.Cut()
- if(skin)
- overlays += "medskin_[skin]"
+/mob/living/simple_animal/bot/medbot/update_icon_state()
if(!on)
icon_state = "medibot0"
return
@@ -132,6 +129,12 @@
icon_state = "medibot1"
+/mob/living/simple_animal/bot/medbot/update_overlays()
+ . = ..()
+ if(skin)
+ . += "medskin_[skin]"
+
+
/mob/living/simple_animal/bot/medbot/New(loc, new_skin)
..()
var/datum/job/doctor/J = new /datum/job/doctor
@@ -467,7 +470,7 @@
..()
-/mob/living/simple_animal/bot/medbot/examinate(atom/A as mob|obj|turf in view(client.maxview()))
+/mob/living/simple_animal/bot/medbot/examinate(atom/A as mob|obj|turf in view(client.maxview(), client.eye))
..()
if(has_vision(information_only = TRUE))
chemscan(src, A)
diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm
index 510197dc34e..661c06d0bec 100644
--- a/code/modules/mob/living/simple_animal/bot/mulebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm
@@ -117,14 +117,14 @@
visible_message("[user] inserts a cell into [src].",
span_notice("You insert the new cell into [src]."))
update_controls()
- else if(istype(I, /obj/item/crowbar) && open && cell)
+ else if(I.tool_behaviour == TOOL_CROWBAR && open && cell)
cell.add_fingerprint(usr)
cell.forceMove(loc)
cell = null
visible_message("[user] crowbars out the power cell from [src].",
span_notice("You pry the powercell out of [src]."))
update_controls()
- else if(istype(I, /obj/item/wrench))
+ else if(I.tool_behaviour == TOOL_WRENCH)
if(health < maxHealth)
adjustBruteLoss(-25)
updatehealth()
@@ -132,7 +132,7 @@
span_notice("You repair [src]!"))
else
to_chat(user, span_notice("[src] does not need a repair!"))
- else if((istype(I, /obj/item/multitool) || istype(I, /obj/item/wirecutters)) && open)
+ else if((I.tool_behaviour == TOOL_MULTITOOL || I.tool_behaviour == TOOL_WIRECUTTER) && open)
return attack_hand(user)
else if(load && ismob(load)) // chance to knock off rider
if(prob(1 + I.force * 2))
@@ -168,17 +168,22 @@
playsound(loc, 'sound/effects/sparks1.ogg', 100, FALSE)
-/mob/living/simple_animal/bot/mulebot/update_icon()
+/mob/living/simple_animal/bot/mulebot/update_icon_state()
if(open)
icon_state="mulebot-hatch"
else
icon_state = "mulebot[wires.is_cut(WIRE_MOB_AVOIDANCE)]"
- overlays.Cut()
+
+
+/mob/living/simple_animal/bot/mulebot/update_overlays()
+ . = ..()
if(load && !ismob(load))//buckling handles the mob offsets
- load.pixel_y = initial(load.pixel_y) + 9
+ var/image/load_overlay = image(icon = load.icon, icon_state = load.icon_state)
+ load_overlay.pixel_y = initial(load.pixel_y) + 9
if(load.layer < layer)
- load.layer = layer + 0.1
- overlays += load
+ load_overlay.layer = layer + 0.1
+ load_overlay.overlays = load.overlays
+ . += load_overlay
/mob/living/simple_animal/bot/mulebot/ex_act(severity)
@@ -371,7 +376,7 @@
// mousedrop a crate to load the bot
// can load anything if hacked
-/mob/living/simple_animal/bot/mulebot/MouseDrop_T(atom/movable/AM, mob/user)
+/mob/living/simple_animal/bot/mulebot/MouseDrop_T(atom/movable/AM, mob/user, params)
if(!istype(AM) || user.incapacitated() || user.lying || !in_range(user, src))
return FALSE
@@ -451,8 +456,6 @@
mode = BOT_IDLE
- overlays.Cut()
-
unbuckle_all_mobs()
if(load)
@@ -467,6 +470,8 @@
step(load, dirn)
load = null
+ update_icon(UPDATE_OVERLAYS)
+
// in case non-load items end up in contents, dump every else too
// this seems to happen sometimes due to race conditions
// with items dropping as mobs are loaded
diff --git a/code/modules/mob/living/simple_animal/bot/syndicate.dm b/code/modules/mob/living/simple_animal/bot/syndicate.dm
index 3f81984e7d5..2b94268db81 100644
--- a/code/modules/mob/living/simple_animal/bot/syndicate.dm
+++ b/code/modules/mob/living/simple_animal/bot/syndicate.dm
@@ -39,7 +39,7 @@
prev_access = access_card.access
-/mob/living/simple_animal/bot/ed209/syndicate/update_icon()
+/mob/living/simple_animal/bot/ed209/syndicate/update_icon_state()
icon_state = initial(icon_state)
diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm
index f3f43bf46df..3842ae4ccc5 100644
--- a/code/modules/mob/living/simple_animal/friendly/cat.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cat.dm
@@ -220,7 +220,7 @@
/mob/living/simple_animal/pet/cat/Syndi/Initialize(mapload)
. = ..()
- add_language("Galactic Common")
+ add_language(LANGUAGE_GALACTIC_COMMON)
/mob/living/simple_animal/pet/cat/cak
name = "Keeki"
diff --git a/code/modules/mob/living/simple_animal/friendly/diona.dm b/code/modules/mob/living/simple_animal/friendly/diona.dm
index 1d4986ba224..7d20b768b46 100644
--- a/code/modules/mob/living/simple_animal/friendly/diona.dm
+++ b/code/modules/mob/living/simple_animal/friendly/diona.dm
@@ -85,7 +85,7 @@
if(name == initial(name)) //To stop Pun-Pun becoming generic.
name = "[name] ([rand(1, 1000)])"
real_name = name
- add_language("Rootspeak")
+ add_language(LANGUAGE_DIONA)
merge_action.Grant(src)
evolve_action.Grant(src)
steal_blood_action.Grant(src)
diff --git a/code/modules/mob/living/simple_animal/friendly/fox.dm b/code/modules/mob/living/simple_animal/friendly/fox.dm
index 1f266fe9fe2..e40266c3d91 100644
--- a/code/modules/mob/living/simple_animal/friendly/fox.dm
+++ b/code/modules/mob/living/simple_animal/friendly/fox.dm
@@ -58,7 +58,7 @@
/mob/living/simple_animal/pet/dog/fox/Syndifox/Initialize(mapload)
. = ..()
- add_language("Galactic Common")
+ add_language(LANGUAGE_GALACTIC_COMMON)
//Central Command Fox
/mob/living/simple_animal/pet/dog/fox/alisa
diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
index b7e6d671c3e..a30f8ec63bb 100644
--- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
+++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
@@ -83,8 +83,6 @@
user.drop_transfer_item_to_loc(B, src)
mmi = B
transfer_personality(B)
-
- update_icon()
return 1
else if(O.GetID())
@@ -140,15 +138,25 @@
melee_damage_upper = 15
attack_sound = 'sound/machines/defib_zap.ogg'
+
/mob/living/simple_animal/spiderbot/proc/transfer_personality(obj/item/mmi/M)
mind = M.brainmob.mind
mind.key = M.brainmob.key
ckey = M.brainmob.ckey
- name = "Spider-bot ([M.brainmob.name])"
+ update_appearance(UPDATE_ICON_STATE|UPDATE_NAME)
if(emagged)
to_chat(src, "You have been emagged; you are now completely loyal to [emagged_master] and [emagged_master.p_their()] every order!")
-/mob/living/simple_animal/spiderbot/update_icon()
+
+/mob/living/simple_animal/spiderbot/update_name(updates = ALL)
+ . = ..()
+ if(mmi)
+ name = "Spider-bot ([mmi.brainmob.name])"
+ else
+ name = "Spider-bot"
+
+
+/mob/living/simple_animal/spiderbot/update_icon_state()
if(mmi)
if(istype(mmi, /obj/item/mmi))
icon_state = "spiderbot-chassis-mmi"
@@ -161,6 +169,7 @@
icon_state = "spiderbot-chassis"
icon_living = "spiderbot-chassis"
+
/mob/living/simple_animal/spiderbot/proc/eject_brain()
if(mmi)
var/turf/T = get_turf(src)
@@ -168,5 +177,4 @@
if(mind)
mind.transfer_to(mmi.brainmob)
mmi = null
- name = "Spider-bot"
- update_icon()
+ update_appearance(UPDATE_ICON_STATE|UPDATE_NAME)
diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm
index 1c275670e2f..e740020a005 100644
--- a/code/modules/mob/living/simple_animal/hostile/bees.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bees.dm
@@ -179,7 +179,7 @@
generate_bee_visuals()
/mob/living/simple_animal/hostile/poison/bees/proc/pollinate(obj/machinery/hydroponics/Hydro)
- if(!istype(Hydro) || !Hydro.myseed || Hydro.dead || Hydro.recent_bee_visit || Hydro.lid_state)
+ if(!istype(Hydro) || !Hydro.myseed || Hydro.dead || Hydro.recent_bee_visit || Hydro.lid_closed)
target = null
return
diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
index b195ee3a6e1..b7bf62efcda 100644
--- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
@@ -65,7 +65,7 @@
health = 200
maxHealth = 200
status_flags = 0
- anchored = 1
+ anchored = TRUE
stop_automated_movement = 1
var/bot_type = "norm"
var/bot_amt = 10
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
index fae166d4be0..9ec779ac62a 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
@@ -66,7 +66,7 @@ Difficulty: Medium
icon_state = null
gpstag = "Mysterious Signal"
desc = "The sweet blood, oh, it sings to me."
- invisibility = 100
+ invisibility = INVISIBILITY_ABSTRACT
/* New costume */
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
index 2b631ef3898..6ed97039ab0 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
@@ -82,7 +82,7 @@ Difficulty: Hard
icon_state = null
gpstag = "Mysterious Signal"
desc = "You're not quite sure how a signal can be bloody."
- invisibility = 100
+ invisibility = INVISIBILITY_ABSTRACT
/mob/living/simple_animal/hostile/megafauna/bubblegum/Initialize(mapload)
. = ..()
@@ -488,7 +488,7 @@ Difficulty: Hard
/obj/effect/decal/cleanable/blood/gibs/bubblegum/can_bloodcrawl_in()
return TRUE
-/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A, visual_effect_icon)
+/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
if(!charging)
..()
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
index 3cd88392f41..938bb1f0c98 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -355,7 +355,7 @@ Difficulty: Very Hard
icon_state = null
gpstag = "Mysterious Signal"
desc = "Get in the fucking robot."
- invisibility = 100
+ invisibility = INVISIBILITY_ABSTRACT
#undef RANDOM_SHOTS
#undef BLAST
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
index c5a1f972e33..dd1dec43930 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
@@ -100,7 +100,7 @@ Difficulty: Medium
icon_state = null
gpstag = "Mysterious Signal"
desc = "Here there be dragons."
- invisibility = 100
+ invisibility = INVISIBILITY_ABSTRACT
/mob/living/simple_animal/hostile/megafauna/dragon/OpenFire()
if(swooping)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
index 5aa5034258e..2bdd4d2e3c7 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -64,6 +64,7 @@ Difficulty: Hard
del_on_death = TRUE
death_sound = 'sound/magic/repulse.ogg'
enraged_loot = /obj/item/disk/fauna_research/hierophant
+ enraged_unique_loot = /obj/item/clothing/accessory/necklace/hierophant_talisman
attack_action_types = list(/datum/action/innate/megafauna_attack/blink,
/datum/action/innate/megafauna_attack/chaser_swarm,
/datum/action/innate/megafauna_attack/cross_blasts,
@@ -765,6 +766,12 @@ Difficulty: Hard
light_range = 2
layer = LOW_OBJ_LAYER
anchored = TRUE
+ var/teleporting = FALSE
+
+
+/obj/effect/hierophant/update_icon_state()
+ icon_state = "hierophant_tele_[teleporting ? "on" : "off"]"
+
/obj/effect/hierophant/ex_act()
return
@@ -797,4 +804,4 @@ Difficulty: Hard
icon_state = null
gpstag = "Mysterious Signal"
desc = "Heed its words."
- invisibility = 100
+ invisibility = INVISIBILITY_ABSTRACT
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
index eae3590a2b2..9606b122b2d 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
@@ -37,23 +37,24 @@ Difficulty: Medium
retreat_distance = 5
minimum_distance = 5
pixel_x = -32
+ pixel_y = -16
+ maptext_height = 96
+ maptext_width = 96
ranged_cooldown_time = 20
var/charging = FALSE
var/firing_laser = FALSE
internal_type = /obj/item/gps/internal/legion
medal_type = BOSS_MEDAL_LEGION
score_type = LEGION_SCORE
- pixel_y = -90
- pixel_x = -75
loot = list(/obj/item/storm_staff)
crusher_loot = list(/obj/item/storm_staff, /obj/item/crusher_trophy/empowered_legion_skull)
enraged_loot = /obj/item/disk/fauna_research/legion
vision_range = 13
elimination = 1
- appearance_flags = 0
+ appearance_flags = PIXEL_SCALE
mouse_opacity = MOUSE_OPACITY_ICON
stat_attack = UNCONSCIOUS // Overriden from /tg/ - otherwise Legion starts chasing its minions
- appearance_flags = 512
+
/mob/living/simple_animal/hostile/megafauna/legion/Initialize(mapload)
. = ..()
@@ -189,6 +190,9 @@ Difficulty: Medium
if(ismineralturf(t))
var/turf/simulated/mineral/M = t
M.attempt_drill(src)
+ if(iswallturf(t))
+ var/turf/simulated/wall/W = t
+ W.thermitemelt(time = 1 SECONDS)
for(var/mob/living/M in t)
if(faction_check(M.faction, faction, FALSE))
continue
@@ -228,4 +232,4 @@ Difficulty: Medium
icon_state = null
gpstag = "Mysterious Signal"
desc = "The message repeats."
- invisibility = 100
+ invisibility = INVISIBILITY_ABSTRACT
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
index 04871212a3d..697c96554be 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
@@ -159,6 +159,7 @@
mob_attack_logs += "[time_stamp()] Aggrod on [L][COORD(L)] at [COORD(src)]"
..()
+
/mob/living/simple_animal/hostile/megafauna/LoseTarget()
var/mob/living/L = target
if(istype(L) && L.mind)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
index c02f592f185..a460b45e7dd 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
@@ -100,7 +100,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
icon_state = null
gpstag = "Hungry Signal"
desc = "Transmitted over the signal is a strange message repeated in every language you know of, and some you don't too..." //the message is "nom nom nom"
- invisibility = 100
+ invisibility = INVISIBILITY_ABSTRACT
//SWARMER AI
//AI versions of the swarmer mini-antag
diff --git a/code/modules/mob/living/simple_animal/hostile/spaceworms.dm b/code/modules/mob/living/simple_animal/hostile/spaceworms.dm
index 61d25da2df4..73a366b230d 100644
--- a/code/modules/mob/living/simple_animal/hostile/spaceworms.dm
+++ b/code/modules/mob/living/simple_animal/hostile/spaceworms.dm
@@ -36,7 +36,7 @@
AIStatus = AI_OFF
- anchored = 1 //otherwise people can literally fucking pull spaceworms apart
+ anchored = TRUE //otherwise people can literally fucking pull spaceworms apart
faction = list("spaceworms")
@@ -100,11 +100,12 @@
currentWormSeg = newSegment
for(var/mob/living/simple_animal/hostile/spaceWorm/SW in totalWormSegments)
- SW.update_icon()
+ SW.update_icon(UPDATE_ICON_STATE)
-/mob/living/simple_animal/hostile/spaceWorm/wormHead/update_icon()
+
+/mob/living/simple_animal/hostile/spaceWorm/wormHead/update_icon_state()
if(stat == CONSCIOUS || stat == UNCONSCIOUS)
- icon_state = "spacewormhead[previousWorm ? 1 : 0]"
+ icon_state = "spacewormhead[previousWorm ? "1" : "0"]"
if(previousWorm)
dir = get_dir(previousWorm,src)
else
@@ -113,7 +114,7 @@
for(var/mob/living/simple_animal/hostile/spaceWorm/SW in totalWormSegments)
if(SW == src)//incase src ends up in here we don't want an infinite loop
continue
- SW.update_icon()
+ SW.update_icon(UPDATE_ICON_STATE)
//Try to move onto target's turf and eat them
@@ -207,7 +208,7 @@
if(prob(stomachProcessProbability))
ProcessStomach()
- update_icon()//While most mobs don't call this on Life(), the worm would probably look stupid without it
+ update_icon(UPDATE_ICON_STATE)//While most mobs don't call this on Life(), the worm would probably look stupid without it
//Plus the worm's update_icon() isn't as beefy.
..() //Really high fuckin priority that this is at the bottom.
@@ -227,11 +228,11 @@
if(.)
if(previousWorm)
previousWorm.Move(segmentNextPos)
- update_icon()
+ update_icon(UPDATE_ICON_STATE)
//Update the appearence of this big weird chain-worm-thingy
-/mob/living/simple_animal/hostile/spaceWorm/update_icon()
+/mob/living/simple_animal/hostile/spaceWorm/update_icon_state()
if(stat != DEAD)
if(previousWorm)
icon_state = "spaceworm[get_dir(src,previousWorm) | get_dir(src,nextWorm)]"
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/abillities.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/abillities.dm
index 39c9ca6325f..68d1ac5325e 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/abillities.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/abillities.dm
@@ -91,7 +91,7 @@
fireball_type = /obj/item/projectile/terrorspider/widow/venom
-/obj/effect/proc_holder/spell/fireball/venom_spit/update_icon()
+/obj/effect/proc_holder/spell/fireball/venom_spit/update_icon_state()
return
@@ -132,7 +132,7 @@
fireball_type = /obj/item/projectile/terrorspider/widow/smoke
-/obj/effect/proc_holder/spell/fireball/smoke_spit/update_icon()
+/obj/effect/proc_holder/spell/fireball/smoke_spit/update_icon_state()
return
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm
index fc49da4e81f..7aaab7276ef 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm
@@ -159,7 +159,7 @@
name = "terror web"
desc = "it's stringy and sticky"
icon = 'icons/effects/effects.dmi'
- anchored = 1 // prevents people dragging it
+ anchored = TRUE // prevents people dragging it
density = 0 // prevents it blocking all movement
max_integrity = 20 // two welders, or one laser shot (15 for the normal spider webs)
creates_cover = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm
index 549aa3bf807..5f99f1dd409 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/reproduction.dm
@@ -7,7 +7,7 @@
name = "spiderling"
desc = "A fast-moving tiny spider, prone to making aggressive hissing sounds. Hope it doesn't grow up."
icon_state = "spiderling"
- anchored = 0
+ anchored = FALSE
layer = 2.75
max_integrity = 3
var/stillborn = FALSE
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
index 3626dfb15ca..98fa0a940ae 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
@@ -237,13 +237,13 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list)
/mob/living/simple_animal/hostile/poison/terror_spider/New()
..()
GLOB.ts_spiderlist += src
- add_language("Spider Hivemind")
+ add_language(LANGUAGE_HIVE_TERRORSPIDER)
for(var/spell in special_abillity)
src.AddSpell(new spell)
if(spider_tier >= TS_TIER_2)
- add_language("Galactic Common")
- default_language = GLOB.all_languages["Spider Hivemind"]
+ add_language(LANGUAGE_GALACTIC_COMMON)
+ default_language = GLOB.all_languages[LANGUAGE_HIVE_TERRORSPIDER]
if(web_type)
web_action = new()
diff --git a/code/modules/mob/living/simple_animal/hulk_power.dm b/code/modules/mob/living/simple_animal/hulk_power.dm
index 31dc1c2b4e8..e1525edbb92 100644
--- a/code/modules/mob/living/simple_animal/hulk_power.dm
+++ b/code/modules/mob/living/simple_animal/hulk_power.dm
@@ -144,7 +144,7 @@
W.take_damage(25)
H.Weaken(4 SECONDS)
if(i > 20)
- user.canmove = 0
+ user.canmove = FALSE
user.density = 0
for(var/mob/living/M in T.contents)
if(!M.lying)
@@ -192,7 +192,7 @@
step(user, cur_dir)
sleep(1)
user.density = 1
- user.canmove = 1
+ user.canmove = TRUE
user.layer = prevLayer
else
to_chat(user, "You need a ground to do this!")
@@ -263,7 +263,7 @@
var/o=3
for(var/i=0, i<14, i++)
user.density = 0
- user.canmove = 0
+ user.canmove = FALSE
o++
if(o == 4)
o = 0
@@ -303,7 +303,7 @@
if(i < 3) M.pixel_y += 8
else M.pixel_y -= 8
user.density = 1
- user.canmove = 1
+ user.canmove = TRUE
user.layer = prevLayer
else
to_chat(user, "You need a ground to do this!")
@@ -485,7 +485,7 @@
return ..()
-/obj/effect/proc_holder/spell/fireball/hulk_spit/update_icon()
+/obj/effect/proc_holder/spell/fireball/hulk_spit/update_icon_state()
return
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index bf2095c0f4b..2a66e06b085 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -35,6 +35,7 @@
icon_resting = "parrot_sit"
pass_flags = PASSTABLE
can_collar = TRUE
+ blocks_emissive = EMISSIVE_BLOCK_UNIQUE
tts_seed = "Sniper"
faction = list("neutral", "jungle")
diff --git a/code/modules/mob/living/simple_animal/posessed_object.dm b/code/modules/mob/living/simple_animal/posessed_object.dm
index 25b295fd4e1..0a6377cb815 100644
--- a/code/modules/mob/living/simple_animal/posessed_object.dm
+++ b/code/modules/mob/living/simple_animal/posessed_object.dm
@@ -15,7 +15,7 @@
tts_seed = "Sylvanas"
allow_spin = 0 // No spinning. Spinning breaks our floating animation.
- no_spin_thrown = 1
+ no_spin_thrown = TRUE
del_on_death = TRUE
/// The probability % of us escaping if stuffed into a bag/toolbox/etc
@@ -168,4 +168,3 @@
overlays = possessed_item.overlays
set_opacity(possessed_item.opacity)
return ..(NONE)
-
diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm
index 8a6333566b4..f846ffa5dbc 100644
--- a/code/modules/mob/living/simple_animal/shade.dm
+++ b/code/modules/mob/living/simple_animal/shade.dm
@@ -45,6 +45,10 @@
else
..()
+/mob/living/simple_animal/shade/update_icon_state()
+ icon_state = holy ? "shade_angelic" : "shade"
+
+
/mob/living/simple_animal/shade/Process_Spacemove()
return TRUE
@@ -64,3 +68,18 @@
/mob/living/simple_animal/shade/sword/Initialize(mapload)
.=..()
status_flags |= GODMODE
+
+/mob/living/simple_animal/shade/talisman
+ faction = list("neutral")
+ tts_seed = "Alextraza_echo"
+ // Ckey check for master of talisman
+ var/master
+
+/mob/living/simple_animal/shade/talisman/Initialize(mapload)
+ .=..()
+ status_flags |= GODMODE
+
+/mob/living/simple_animal/shade/talisman/New()
+ ..()
+ var/datum/atom_hud/medsensor = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
+ medsensor.add_hud_to(src)
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 48f8eae923f..faae71ed3f5 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -577,11 +577,11 @@
if(IsParalyzed() || IsStunned() || IsWeakened() || stat || resting)
drop_r_hand()
drop_l_hand()
- canmove = 0
+ canmove = FALSE
else if(buckled)
- canmove = 0
+ canmove = FALSE
else
- canmove = 1
+ canmove = TRUE
if(!canmove)
walk(src, 0) //stop mid walk
diff --git a/code/modules/mob/living/simple_animal/slime/death.dm b/code/modules/mob/living/simple_animal/slime/death.dm
index ff36900d529..4833e8b375d 100644
--- a/code/modules/mob/living/simple_animal/slime/death.dm
+++ b/code/modules/mob/living/simple_animal/slime/death.dm
@@ -1,15 +1,16 @@
/mob/living/simple_animal/slime/death(gibbed)
if(stat == DEAD)
return
+
+ if(buckled)
+ Feedstop(silent = TRUE) //releases ourselves from the mob we fed on.
+
if(!gibbed)
if(age_state.age != SLIME_BABY)
if (nutrition >= get_hunger_nutrition())
force_split(FALSE)
return
- if(buckled)
- Feedstop(silent = TRUE) //releases ourselves from the mob we fed on.
-
stat = DEAD //Temporarily set to dead for icon updates
regenerate_icons()
stat = CONSCIOUS
diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm
index 29731af09f2..0fe423a1933 100644
--- a/code/modules/mob/living/simple_animal/slime/life.dm
+++ b/code/modules/mob/living/simple_animal/slime/life.dm
@@ -280,9 +280,9 @@
update_canmove()
if(Tempstun)
if(!buckled) // not while they're eating!
- canmove = 0
+ canmove = FALSE
else
- canmove = 1
+ canmove = TRUE
if(attacked > 50)
attacked = 50
diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm
index 14e61b78439..b2e5927cb17 100644
--- a/code/modules/mob/living/simple_animal/slime/powers.dm
+++ b/code/modules/mob/living/simple_animal/slime/powers.dm
@@ -194,13 +194,17 @@
if(stat)
to_chat(src, "I must be conscious to do this...")
return
+
+ if(istype(loc, /obj/machinery/computer/camera_advanced/xenobio))
+ return
+
force_split(TRUE)
else
to_chat(src, "I am not ready to reproduce yet...")
else
to_chat(src, "I am not old enough to reproduce yet...")
-/mob/living/simple_animal/slime/proc/force_split(var/can_mutate = TRUE)
+/mob/living/simple_animal/slime/proc/force_split(can_mutate = TRUE)
if(age_state.age == SLIME_BABY)
return FALSE
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index 38647b2ebb8..d18dd571e88 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -99,7 +99,7 @@
set_colour(new_colour)
. = ..()
set_nutrition(new_set_nutrition)
- add_language("Bubblish")
+ add_language(LANGUAGE_SLIME)
/mob/living/simple_animal/slime/Destroy()
for(var/A in actions)
@@ -372,6 +372,7 @@
++Friends[user]
else
Friends[user] = 1
+ RegisterSignal(user, COMSIG_PARENT_QDELETING, PROC_REF(clear_friend))
to_chat(user, "You feed the slime the plasma. It chirps happily.")
var/obj/item/stack/sheet/mineral/plasma/S = I
S.use(1)
@@ -393,6 +394,10 @@
discipline_slime(user)
..()
+/mob/living/simple_animal/slime/proc/clear_friend(mob/living/friend)
+ UnregisterSignal(friend, COMSIG_PARENT_QDELETING)
+ Friends -= friend
+
/mob/living/simple_animal/slime/water_act(volume, temperature, source, method = REAGENT_TOUCH)
. = ..()
var/water_damage = (rand(10, 15) - age_state.attacked) * volume
diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm
index fd04de44d15..35bc800f4c9 100644
--- a/code/modules/mob/living/status_procs.dm
+++ b/code/modules/mob/living/status_procs.dm
@@ -737,14 +737,9 @@
/mob/living/proc/AdjustDeaf(amount, bound_lower = 0, bound_upper = INFINITY)
SetDeaf(directional_bounded_sum(AmountDeaf(), amount, bound_lower, bound_upper))
-/mob/living/proc/BecomeDeaf()
- mutations |= DEAF
-
/mob/living/proc/CureDeaf()
- mutations -= DEAF
CureIfHasDisability(GLOB.deafblock)
-
//
// DISABILITIES
//
diff --git a/code/modules/mob/living/taste.dm b/code/modules/mob/living/taste.dm
index fc1f100be9b..fd6deb1358e 100644
--- a/code/modules/mob/living/taste.dm
+++ b/code/modules/mob/living/taste.dm
@@ -15,7 +15,7 @@
/mob/living/proc/taste(datum/reagents/from)
if(last_taste_time + 50 < world.time)
var/taste_sensitivity = get_taste_sensitivity()
- var/text_output = from.generate_taste_message(taste_sensitivity)
+ var/text_output = from.generate_taste_message(taste_sensitivity, src)
// We dont want to spam the same message over and over again at the
// person. Give it a bit of a buffer.
if(AmountHallucinate() > 50 SECONDS && prob(25))
diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm
index 6dc0db4082e..816457b70da 100644
--- a/code/modules/mob/living/update_status.dm
+++ b/code/modules/mob/living/update_status.dm
@@ -1,12 +1,12 @@
/mob/living/update_blind_effects()
- if(!has_vision(information_only=TRUE))
- overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
- throw_alert("blind", /obj/screen/alert/blind)
- return 1
- else
+ if(has_vision(information_only = TRUE))
clear_fullscreen("blind")
clear_alert("blind")
- return 0
+ return FALSE
+
+ overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
+ throw_alert("blind", /obj/screen/alert/blind)
+ return TRUE
/mob/living/update_blurry_effects()
@@ -46,13 +46,13 @@
// Whether the mob can hear things
/mob/living/can_hear()
- return !(DEAF in mutations) && !HAS_TRAIT(src, TRAIT_DEAF)
+ return !HAS_TRAIT(src, TRAIT_DEAF)
// Whether the mob is able to see
// `information_only` is for stuff that's purely informational - like blindness overlays
// This flag exists because certain things like angel statues expect this to be false for dead people
/mob/living/has_vision(information_only = FALSE)
- return (information_only && stat == DEAD) || !(AmountBlinded() || (BLINDNESS in mutations) || stat)
+ return (information_only && stat == DEAD) || !(AmountBlinded() || (BLINDNESS in mutations) || stat || get_total_tint() >= 3)
// Whether the mob is capable of talking
/mob/living/can_speak()
@@ -88,7 +88,7 @@
drop_l_hand()
else
lying = 0
- canmove = 1
+ canmove = TRUE
if(buckled)
lying = 90 * buckle_lying
else if((fall_over || resting) && !lying)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index acbc42a4e38..3b63977c9f6 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -79,26 +79,25 @@
return
if(type)
- if((type & EMOTE_VISIBLE) && !has_vision(information_only = TRUE)) // Vision related
- if(!(alt))
+ if((type & EMOTE_VISIBLE) && !has_vision(information_only = TRUE)) //Vision related
+ if(!alt)
return
- else
- msg = alt
- type = alt_type
- if((type & EMOTE_AUDIBLE) && !can_hear()) // Hearing related
- if(!(alt))
+ msg = alt
+ type = alt_type
+
+ if(type & EMOTE_AUDIBLE && !can_hear()) //Hearing related
+ if(!alt)
return
- else
- msg = alt
- type = alt_type
- if((type & EMOTE_VISIBLE) && !has_vision(information_only=TRUE))
- return
+ msg = alt
+ type = alt_type
+ if((type & EMOTE_VISIBLE) && !has_vision(information_only = TRUE))
+ return
+
// Added voice muffling for Issue 41.
if(stat == UNCONSCIOUS)
to_chat(src, "…Вам почти удаётся расслышать чьи-то слова…")
else
to_chat(src, msg)
- return
// Show a message to all mobs in sight of this one
@@ -299,7 +298,7 @@
popup.open()
//mob verbs are faster than object verbs. See http://www.byond.com/forum/?post=1326139&page=2#comment8198716 for why this isn't atom/verb/examine()
-/mob/verb/examinate(atom/A as mob|obj|turf in view(client.maxview()))
+/mob/verb/examinate(atom/A as mob|obj|turf in view(client.maxview(), client.eye))
set name = "Examine"
set category = "IC"
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 3379998b643..9bda2f967e9 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -54,6 +54,7 @@
var/med_record = ""
var/sec_record = ""
var/gen_record = ""
+ var/exploit_record = ""
var/lying = 0
var/lying_prev = 0
var/lastpuke = 0
diff --git a/code/modules/mob/mob_emote.dm b/code/modules/mob/mob_emote.dm
index b17532442a0..af545256726 100644
--- a/code/modules/mob/mob_emote.dm
+++ b/code/modules/mob/mob_emote.dm
@@ -68,13 +68,13 @@
*
* * intentional_use: Whether or not to check based on if the action was intentional.
*/
-/mob/proc/usable_emote_keys(intentional_use = TRUE)
+/mob/proc/usable_emote_keys(intentional_use)
var/list/all_keys = list()
for(var/key in GLOB.emote_list)
for(var/datum/emote/P in GLOB.emote_list[key])
if(P.key in all_keys)
continue
- if(P.can_run_emote(src, status_check = FALSE, intentional = null))
+ if(P.can_run_emote(src, status_check = FALSE, intentional = intentional_use))
all_keys += P.key
if(P.key_third_person)
all_keys += P.key_third_person
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 261dd033617..4cd4d3c6442 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -380,6 +380,7 @@
/client/verb/body_r_arm()
set name = "body-r-arm"
set hidden = 1
+
if(!check_has_body_select())
return
@@ -398,11 +399,13 @@
if(!check_has_body_select())
return
+
var/next_in_line
if(mob.zone_selected == BODY_ZONE_CHEST)
next_in_line = BODY_ZONE_WING
else
next_in_line = BODY_ZONE_CHEST
+
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
selector.set_selected_zone(next_in_line)
@@ -444,9 +447,15 @@
if(!check_has_body_select())
return
+
+ var/next_in_line
+ if(mob.zone_selected == BODY_ZONE_PRECISE_GROIN)
+ next_in_line = BODY_ZONE_TAIL
+ else
+ next_in_line = BODY_ZONE_PRECISE_GROIN
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
- selector.set_selected_zone(BODY_ZONE_PRECISE_GROIN)
+ selector.set_selected_zone(next_in_line)
/client/verb/body_tail()
set name = "body-tail"
diff --git a/code/modules/mob/mob_say.dm b/code/modules/mob/mob_say.dm
index 3ef9748704e..1f39d5e92b5 100644
--- a/code/modules/mob/mob_say.dm
+++ b/code/modules/mob/mob_say.dm
@@ -110,9 +110,8 @@
return TRUE
//Language check.
- for(var/datum/language/L in languages)
- if(speaking.name == L.name)
- return TRUE
+ if(speaking in languages)
+ return TRUE
return FALSE
@@ -122,7 +121,7 @@
var/ending = copytext(message, length(message))
if(speaking)
- verb = speaking.get_spoken_verb(ending)
+ verb = genderize_decode(src, speaking.get_spoken_verb(ending))
else
if(ending == "!")
verb = pick("exclaims", "shouts", "yells")
@@ -208,7 +207,7 @@
// Noise language is a snowflake
if(copytext(message, 1, 2) == "!" && length(message) > 1)
- return list(new /datum/multilingual_say_piece(GLOB.all_languages["Noise"], trim(strip_prefixes(copytext(message, 2)))))
+ return list(new /datum/multilingual_say_piece(GLOB.all_languages[LANGUAGE_NOISE], trim(strip_prefixes(copytext(message, 2)))))
// Scan the message for prefixes
var/list/prefix_locations = find_valid_prefixes(message)
@@ -221,8 +220,7 @@
// There are a few things that will make us want to ignore all other languages in - namely, HIVEMIND languages.
var/datum/language/L = current[1]
if(L && L.flags & HIVEMIND)
- . = new /datum/multilingual_say_piece(L, trim(strip_prefixes(message)))
- break
+ return list(new /datum/multilingual_say_piece(L, trim(strip_prefixes(message))))
if(i + 1 > length(prefix_locations)) // We are out of lookaheads, that means the rest of the message is in cur lang
var/spoke_message = handle_autohiss(trim(copytext_char(message, current[3])), L)
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index f35dfaba223..36a5fc909ff 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -9,7 +9,7 @@
density = 0
stat = 2
- canmove = 0
+ canmove = FALSE
/mob/new_player/Initialize(mapload)
SHOULD_CALL_PARENT(FALSE)
@@ -670,9 +670,9 @@
var/datum/language/chosen_language
if(client.prefs.language)
chosen_language = GLOB.all_languages[client.prefs.language]
- if((chosen_language == null && client.prefs.language != "None") || (chosen_language && chosen_language.flags & RESTRICTED))
+ if((!chosen_language && client.prefs.language != LANGUAGE_NONE) || (chosen_language && chosen_language.flags & RESTRICTED))
log_runtime(EXCEPTION("[src] had language [client.prefs.language], though they weren't supposed to. Setting to None."), src)
- client.prefs.language = "None"
+ client.prefs.language = LANGUAGE_NONE
/mob/new_player/proc/ViewManifest()
GLOB.generic_crew_manifest.ui_interact(usr, state = GLOB.always_state)
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index aededfc5986..b9b2410b6fe 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -24,7 +24,7 @@
for(var/obj/item/W in src)
drop_item_ground(W)
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
return ..()
@@ -71,7 +71,7 @@
drop_item_ground(W)
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
@@ -128,7 +128,7 @@
drop_item_ground(W)
regenerate_icons()
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
for(var/t in bodyparts) //this really should not be necessary
@@ -153,7 +153,7 @@
regenerate_icons()
notransform = 1
- canmove = 0
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_ABSTRACT
diff --git a/code/modules/newscaster/obj/newscaster.dm b/code/modules/newscaster/obj/newscaster.dm
index 843b3b7d6f3..9f18bfd9d48 100644
--- a/code/modules/newscaster/obj/newscaster.dm
+++ b/code/modules/newscaster/obj/newscaster.dm
@@ -18,7 +18,7 @@
name = "newscaster"
desc = "A standard Nanotrasen-licensed newsfeed handler for use in commercial space stations. All the news you absolutely have no use for, in one place!"
icon = 'icons/obj/machines/terminals.dmi'
- icon_state = "newscaster_normal"
+ icon_state = "newscaster"
max_integrity = 200
integrity_failure = 50
light_range = 0
@@ -57,7 +57,7 @@
/obj/machinery/newscaster/New()
GLOB.allNewscasters += src
unit_number = length(GLOB.allNewscasters)
- update_icon() //for any custom ones on the map...
+ update_icon(UPDATE_OVERLAYS) //for any custom ones on the map...
if(!last_views)
last_views = list()
armor = list(melee = 50, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30)
@@ -93,33 +93,49 @@
QDEL_NULL(photo)
return ..()
-/obj/machinery/newscaster/update_icon()
- cut_overlays()
+
+/obj/machinery/newscaster/update_overlays()
+ . = ..()
+ underlays.Cut()
if(inoperable())
- icon_state = "newscaster_off"
+ return
+
+ if(!(stat & NOPOWER))
+ underlays += emissive_appearance(icon, "newscaster_lightmask")
+
+ if(GLOB.news_network.wanted_issue)
+ . += "newscaster_wanted"
else
- if(!GLOB.news_network.wanted_issue) //wanted icon state, there can be no overlays on it as it's a priority message
- icon_state = "newscaster_normal"
- if(alert) //new message alert overlay
- add_overlay("newscaster_alert")
- var/hp_percent = obj_integrity * 100 / max_integrity
+ . += "newscaster_normal"
+
+ if(!GLOB.news_network.wanted_issue && alert) //wanted icon state, there can be no overlays on it as it's a priority message
+ . += "newscaster_alert"
+
+ var/hp_percent = round(obj_integrity * 100 / max_integrity)
switch(hp_percent)
- if(75 to INFINITY)
+ if(76 to INFINITY)
return
- if(50 to 75)
- add_overlay("crack1")
- if(25 to 50)
- add_overlay("crack2")
- else
- add_overlay("crack3")
+ if(51 to 75)
+ . += "crack1"
+ if(26 to 50)
+ . += "crack2"
+ if(1 to 25)
+ . += "crack3"
+
+
+/obj/machinery/newscaster/power_change(forced = FALSE)
+ if(!..())
+ return
+ if(stat & NOPOWER)
+ set_light(0)
+ else
+ set_light(1, LIGHTING_MINIMUM_POWER)
+ update_icon(UPDATE_OVERLAYS)
-/obj/machinery/newscaster/power_change()
- ..()
- update_icon()
/obj/machinery/newscaster/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = TRUE, attack_dir)
. = ..()
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
/obj/machinery/newscaster/wrench_act(mob/user, obj/item/I)
. = TRUE
@@ -167,7 +183,7 @@
if(!(stat & BROKEN) && !(flags & NODECONSTRUCT))
stat |= BROKEN
playsound(loc, 'sound/effects/glassbr3.ogg', 100, TRUE)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
/obj/machinery/newscaster/attack_ghost(mob/user)
ui_interact(user)
@@ -419,6 +435,8 @@
return
GLOB.news_network.wanted_issue = null
set_temp("Wanted notice cleared.", update_now = TRUE)
+ for(var/obj/machinery/newscaster/NC as anything in GLOB.allNewscasters)
+ NC.update_icon(UPDATE_OVERLAYS)
return FALSE
if("toggle_mute")
is_silent = !is_silent
@@ -687,14 +705,14 @@
return
alert = TRUE
addtimer(CALLBACK(src, PROC_REF(alert_timer_finish)), 30 SECONDS)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
/**
* Called when the timer following a call to [/obj/machinery/newscaster/proc/alert_news] finishes.
*/
/obj/machinery/newscaster/proc/alert_timer_finish()
alert = FALSE
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
/**
* Ejects the currently loaded photo if there is one.
diff --git a/code/modules/paperwork/carbonpaper.dm b/code/modules/paperwork/carbonpaper.dm
index ce9be619fb6..30d9aadbf3e 100644
--- a/code/modules/paperwork/carbonpaper.dm
+++ b/code/modules/paperwork/carbonpaper.dm
@@ -6,7 +6,7 @@
var/iscopy = 0
-/obj/item/paper/carbon/update_icon()
+/obj/item/paper/carbon/update_icon_state()
if(iscopy)
if(info)
icon_state = "cpaper_words"
@@ -24,7 +24,6 @@
icon_state = "paper_stack"
-
/obj/item/paper/carbon/verb/removecopy()
set name = "Remove carbon-copy"
set category = "Object"
diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm
index d662897190e..262e27f2225 100644
--- a/code/modules/paperwork/clipboard.dm
+++ b/code/modules/paperwork/clipboard.dm
@@ -16,7 +16,18 @@
/obj/item/clipboard/New()
..()
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
+
+
+/obj/item/clipboard/AltClick(mob/user)
+ if(Adjacent(user) && !user.incapacitated())
+ if(is_pen(user.get_active_hand()))
+ penPlacement(user, user.get_active_hand(), TRUE)
+ else
+ removePen(user)
+ return
+ . = ..()
+
/obj/item/clipboard/verb/removePen(mob/user)
set category = "Object"
@@ -39,6 +50,7 @@
/obj/item/clipboard/examine(mob/user)
. = ..()
+ . += "Alt-Click to remove its pen."
if(in_range(user, src) && toppaper)
. += toppaper.examine(user)
@@ -60,7 +72,7 @@
containedpen.forceMove_turf()
user.put_in_hands(containedpen, ignore_anim = FALSE)
containedpen = null
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
/obj/item/clipboard/proc/showClipboard(mob/user) //Show them what's on the clipboard
var/dat = {"[src]"}
@@ -76,15 +88,23 @@
popup.set_content(dat)
popup.open()
-/obj/item/clipboard/update_icon()
- overlays.Cut()
+
+/obj/item/clipboard/update_overlays()
+ . = ..()
if(toppaper)
- overlays += toppaper.icon_state
- overlays += toppaper.overlays
+ . += toppaper.icon_state
+ . += toppaper.overlays
if(containedpen)
- overlays += "clipboard_pen"
- overlays += "clipboard_over"
- ..()
+ . += "clipboard_pen"
+ for(var/obj/O in src)
+ if(istype(O, /obj/item/photo))
+ var/image/img = image('icons/obj/bureaucracy.dmi')
+ var/obj/item/photo/Ph = O
+ img = Ph.tiny
+ . += img
+ break
+ . += "clipboard_over"
+
/obj/item/clipboard/attackby(obj/item/W, mob/user)
if(isPaperwork(W)) //If it's a photo, paper bundle, or piece of paper, place it on the clipboard.
@@ -93,7 +113,7 @@
playsound(loc, "pageturn", 50, 1)
if(isPaperwork(W) == PAPERWORK)
toppaper = W
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
else if(is_pen(W))
if(!toppaper) //If there's no paper we can write on, just stick the pen into the clipboard
penPlacement(user, W, TRUE)
@@ -113,7 +133,7 @@
return
else if(istype(W, /obj/item/stamp) && toppaper) //We can stamp the topmost piece of paper
toppaper.attackby(W, user)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
else
return ..()
@@ -155,7 +175,7 @@
to_chat(usr, "You flick the pages so that [P] is on top.")
playsound(loc, "pageturn", 50, 1)
toppaper = P
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
showClipboard(usr)
#undef PAPERWORK
diff --git a/code/modules/paperwork/contract.dm b/code/modules/paperwork/contract.dm
index aac51f90340..d1d9a09f839 100644
--- a/code/modules/paperwork/contract.dm
+++ b/code/modules/paperwork/contract.dm
@@ -10,7 +10,7 @@
/obj/item/paper/contract/proc/update_text()
return
-/obj/item/paper/contract/update_icon()
+/obj/item/paper/contract/update_icon_state()
return
diff --git a/code/modules/paperwork/desk_bell.dm b/code/modules/paperwork/desk_bell.dm
index 69839e6a98d..67ea39a9248 100644
--- a/code/modules/paperwork/desk_bell.dm
+++ b/code/modules/paperwork/desk_bell.dm
@@ -29,13 +29,13 @@
return TRUE
-/obj/item/desk_bell/MouseDrop(atom/over)
+/obj/item/desk_bell/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
. = ..()
if(!.)
return FALSE
var/mob/user = usr
- if(over != user || user.incapacitated() || !ishuman(user))
+ if(over_object != user || user.incapacitated() || !ishuman(user))
return FALSE
anchored = FALSE
diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm
index e9866e19ab4..10280ad2c55 100644
--- a/code/modules/paperwork/faxmachine.dm
+++ b/code/modules/paperwork/faxmachine.dm
@@ -428,7 +428,7 @@ GLOBAL_LIST_EMPTY(fax_blacklist)
SSdiscord.send2discord_complex(DISCORD_WEBHOOK_REQUESTS, payload)
/obj/machinery/photocopier/faxmachine/proc/sanitize_paper(obj/item/paper/paper) // html to discord markdown-101
- var/text = paper.show_content(forceshow = 1, view = 0)
+ var/text = "[paper.header][paper.info][paper.footer]"
text = replacetext(text, " ", "\n")
text = replacetext(text, "", "__")
text = replacetext(text, "", "**")
diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm
index fc00441de33..f80d3da514b 100644
--- a/code/modules/paperwork/filingcabinet.dm
+++ b/code/modules/paperwork/filingcabinet.dm
@@ -14,8 +14,9 @@
desc = "A large cabinet with drawers."
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "filingcabinet"
- density = 1
+ density = TRUE
anchored = TRUE
+ var/opened = FALSE
/obj/structure/filingcabinet/chestdrawer
@@ -37,14 +38,20 @@
I.loc = src
+/obj/structure/filingcabinet/update_icon_state()
+ icon_state = "[initial(icon_state)][opened ? "-open" : ""]"
+
+
/obj/structure/filingcabinet/attackby(obj/item/P, mob/user, params)
if(istype(P, /obj/item/paper) || istype(P, /obj/item/folder) || istype(P, /obj/item/photo) || istype(P, /obj/item/paper_bundle) || istype(P, /obj/item/documents))
add_fingerprint(user)
to_chat(user, "You put [P] in [src].")
user.drop_transfer_item_to_loc(P, src)
- icon_state = "[initial(icon_state)]-open"
+ opened = TRUE
+ update_icon(UPDATE_ICON_STATE)
sleep(5)
- icon_state = initial(icon_state)
+ opened = FALSE
+ update_icon(UPDATE_ICON_STATE)
updateUsrDialog()
else if(user.a_intent != INTENT_HARM)
to_chat(user, "You can't put [P] in [src]!")
@@ -106,9 +113,11 @@
P.forceMove_turf()
usr.put_in_hands(P, ignore_anim = FALSE)
updateUsrDialog()
- icon_state = "[initial(icon_state)]-open"
+ opened = TRUE
+ update_icon(UPDATE_ICON_STATE)
sleep(5)
- icon_state = initial(icon_state)
+ opened = FALSE
+ update_icon(UPDATE_ICON_STATE)
/*
diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm
index f3f2e646ce8..eeca23bdc72 100644
--- a/code/modules/paperwork/folders.dm
+++ b/code/modules/paperwork/folders.dm
@@ -29,17 +29,18 @@
desc = "A white folder."
icon_state = "folder_white"
-/obj/item/folder/update_icon()
- overlays.Cut()
+
+/obj/item/folder/update_overlays()
+ . = ..()
if(contents.len)
- overlays += "folder_paper"
- ..()
+ . += "folder_paper"
+
/obj/item/folder/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/paper) || istype(W, /obj/item/photo) || istype(W, /obj/item/paper_bundle) || istype(W, /obj/item/documents))
user.drop_transfer_item_to_loc(W, src)
to_chat(user, "You put the [W] into \the [src].")
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
else if(istype(W, /obj/item/pen))
rename_interactive(user, W)
else
@@ -90,8 +91,8 @@
//Update everything
attack_self(usr)
- update_icon()
- return
+ update_icon(UPDATE_OVERLAYS)
+
/obj/item/folder/documents
name = "folder- 'TOP SECRET'"
@@ -100,7 +101,7 @@
/obj/item/folder/documents/New()
..()
new /obj/item/documents/nanotrasen(src)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
/obj/item/folder/syndicate
name = "folder- 'TOP SECRET'"
@@ -112,7 +113,7 @@
/obj/item/folder/syndicate/red/New()
..()
new /obj/item/documents/syndicate/red(src)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
/obj/item/folder/syndicate/blue
icon_state = "folder_sblue"
@@ -120,7 +121,7 @@
/obj/item/folder/syndicate/blue/New()
..()
new /obj/item/documents/syndicate/blue(src)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
/obj/item/folder/syndicate/yellow
icon_state = "folder_syellow"
@@ -128,11 +129,11 @@
/obj/item/folder/syndicate/yellow/full/New()
..()
new /obj/item/documents/syndicate/yellow(src)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
/obj/item/folder/syndicate/mining/New()
. = ..()
new /obj/item/documents/syndicate/mining(src)
- update_icon()
+ update_icon(UPDATE_OVERLAYS)
diff --git a/code/modules/paperwork/frames.dm b/code/modules/paperwork/frames.dm
index 6e3be6478c3..3c84e75cb11 100644
--- a/code/modules/paperwork/frames.dm
+++ b/code/modules/paperwork/frames.dm
@@ -25,12 +25,8 @@
qdel(A)
return ..()
-/obj/item/picture_frame/update_icon()
- overlays.Cut()
-
- if(displayed)
- overlays |= getFlatIcon(displayed)
+/obj/item/picture_frame/update_icon_state()
if(istype(displayed, /obj/item/photo))
icon_state = "[icon_base]-photo"
else if(istype(displayed, /obj/structure/sign/poster))
@@ -38,7 +34,15 @@
else
icon_state = "[icon_base]-paper"
- overlays |= icon_state
+
+/obj/item/picture_frame/update_overlays()
+ . = ..()
+
+ if(displayed)
+ . += getFlatIcon(displayed)
+
+ . += icon_state
+
/obj/item/picture_frame/proc/insert(obj/D)
if(istype(D, /obj/item/poster))
@@ -56,7 +60,7 @@
qdel(D)
/obj/item/picture_frame/attackby(obj/item/I, mob/user)
- if(istype(I, /obj/item/screwdriver))
+ if(I.tool_behaviour == TOOL_SCREWDRIVER)
if(displayed)
playsound(src, I.usesound, 100, 1)
user.visible_message("[user] unfastens \the [displayed] out of \the [src].", "You unfasten \the [displayed] out of \the [src].")
@@ -71,7 +75,7 @@
update_icon()
else
to_chat(user, "There is nothing to remove from \the [src].")
- else if(istype(I, /obj/item/crowbar))
+ else if(I.tool_behaviour == TOOL_CROWBAR)
playsound(src, I.usesound, 100, 1)
user.visible_message("[user] breaks down \the [src].", "You break down \the [src].")
for(var/A in contents)
@@ -199,18 +203,24 @@
QDEL_NULL(frame)
return ..()
-/obj/structure/sign/picture_frame/update_icon()
- overlays.Cut()
+
+/obj/structure/sign/picture_frame/update_icon_state()
if(frame)
icon = null
icon_state = null
- overlays |= getFlatIcon(frame)
else
icon = initial(icon)
icon_state = initial(icon_state)
+
+/obj/structure/sign/picture_frame/update_overlays()
+ . = ..()
+ if(frame)
+ . += getFlatIcon(frame)
+
+
/obj/structure/sign/picture_frame/attackby(obj/item/I, mob/user)
- if(istype(I, /obj/item/screwdriver))
+ if(I.tool_behaviour == TOOL_SCREWDRIVER)
playsound(src, I.usesound, 100, 1)
user.visible_message("[user] begins to unfasten \the [src] from the wall.", "You begin to unfasten \the [src] from the wall.")
if(do_after(user, 100 * I.toolspeed * gettoolspeedmod(user), target = src))
diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm
index f4dca6a98f8..5a046aaf350 100644
--- a/code/modules/paperwork/handlabeler.dm
+++ b/code/modules/paperwork/handlabeler.dm
@@ -6,7 +6,7 @@
item_state = "flight"
var/label = null
var/labels_left = 30
- var/mode = 0
+ var/mode = FALSE
/obj/item/hand_labeler/afterattack(atom/A, mob/user, proximity)
if(!proximity)
@@ -33,9 +33,14 @@
playsound(A, 'sound/items/handling/component_pickup.ogg', 20, TRUE)
labels_left--
-/obj/item/hand_labeler/attack_self(mob/user as mob)
- mode = !mode
+
+/obj/item/hand_labeler/update_icon_state()
icon_state = "labeler[mode]"
+
+
+/obj/item/hand_labeler/attack_self(mob/user)
+ mode = !mode
+ update_icon(UPDATE_ICON_STATE)
if(mode)
to_chat(user, "You turn on \the [src].")
//Now let them chose the text.
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index fc2db3c4bd4..710632b7b94 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -19,6 +19,7 @@
body_parts_covered = HEAD
resistance_flags = FLAMMABLE
max_integrity = 50
+ blocks_emissive = FALSE
attack_verb = list("bapped")
permeability_coefficient = 0.01
dog_fashion = /datum/dog_fashion/head
@@ -29,9 +30,10 @@
var/footer //The bottom stuff before the stamp but after the body
var/info_links //A different version of the paper which includes html links at fields and EOF
var/stamps //The (text for the) stamps on the paper.
- var/fields //Amount of user created fields
- var/language = "Galactic Common" //The language of paper. For now using only in case of Thetta
+ var/fields = 0 //Amount of user created fields
+ var/language = LANGUAGE_GALACTIC_COMMON //The language of paper. For now using only in case of Thetta
var/list/stamped
+ var/list/stamp_overlays
var/ico[0] //Icons and
var/offset_x[0] //offsets stored for later
var/offset_y[0] //usage by the photocopier
@@ -61,15 +63,21 @@
update_icon()
updateinfolinks()
-/obj/item/paper/update_icon()
- ..()
+
+/obj/item/paper/update_icon_state()
if(info)
icon_state = "paper_words"
return
icon_state = "paper"
+
+/obj/item/paper/update_overlays()
+ return LAZYLEN(stamp_overlays) ? stamp_overlays : list()
+
+
/obj/item/paper/examine(mob/user)
. = ..()
+ . += "Alt-Click the [initial(name)] with a pen in hand to rename it."
if(user.is_literate())
if(in_range(user, src) || istype(user, /mob/dead/observer))
show_content(user)
@@ -78,12 +86,13 @@
else
. += "You don't know how to read."
-/obj/item/paper/proc/show_content(var/mob/user, var/forceshow = 0, var/forcestars = 0, var/infolinks = 0, var/view = 1)
+
+/obj/item/paper/proc/show_content(mob/user, forceshow = FALSE, forcestars = FALSE, infolinks, view = TRUE)
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/paper)
assets.send(user)
var/data
- var/stars = (!user?.say_understands(null, GLOB.all_languages[language]) && !forceshow) || forcestars
+ var/stars = (!user.say_understands(null, GLOB.all_languages[language]) && !forceshow) || forcestars
if(stars) //assuming all paper is written in common is better than hardcoded type checks
data = "[header][stars(info)][footer][stamps]"
else
@@ -105,84 +114,132 @@
popup.open()
return data
-/obj/item/paper/verb/rename()
- set name = "Rename paper"
- set category = "Object"
- set src in usr
- if((CLUMSY in usr.mutations) && prob(50))
- to_chat(usr, "You cut yourself on the paper.")
+/obj/item/paper/AltClick(mob/living/carbon/human/user)
+ if(!ishuman(user) || user.incapacitated() || !Adjacent(user))
+ return
+ if(is_pen(user.get_active_hand()))
+ rename(user)
+ return
+ if(user.is_in_hands(src))
+ ProcFoldPlane(user, src)
+ return
+ return ..()
+
+
+/obj/item/paper/proc/rename(mob/user)
+ if((CLUMSY in user.mutations) && prob(50))
+ to_chat(user, "You cut yourself on the paper.")
return
- if(!usr.is_literate())
- to_chat(usr, "You don't know how to read.")
+ if(!user.is_literate())
+ to_chat(user, "You don't know how to read.")
return
- var/n_name = rename_interactive(usr)
+ var/n_name = rename_interactive(user)
if(isnull(n_name))
return
if(n_name != "")
desc = "This is a paper titled '" + name + "'."
else
desc = initial(desc)
- add_fingerprint(usr)
- return
+ add_fingerprint(user)
+
/obj/item/paper/attack_self(mob/living/user as mob)
user.examinate(src)
- if(rigged && (SSholiday.holidays && SSholiday.holidays[APRIL_FOOLS]))
- if(spam_flag == 0)
- spam_flag = 1
- playsound(loc, 'sound/items/bikehorn.ogg', 50, 1)
- spawn(20)
- spam_flag = 0
- return
+ if(rigged && !spam_flag && (SSholiday.holidays && SSholiday.holidays[APRIL_FOOLS]))
+ spam_flag = TRUE
+ addtimer(VARSET_CALLBACK(src, spam_flag, FALSE), 3 SECONDS)
+ playsound(loc, 'sound/items/bikehorn.ogg', 50, 1)
+
-/obj/item/paper/attack_ai(var/mob/living/silicon/ai/user as mob)
+/obj/item/paper/attack_ai(mob/living/silicon/ai/user)
var/dist
- if(istype(user) && user.current) //is AI
+ if(isAI(user) && user.current) //is AI
dist = get_dist(src, user.current)
else //cyborg or AI not seeing through a camera
dist = get_dist(src, user)
if(dist < 2)
- show_content(user, forceshow = 1)
+ show_content(user, forceshow = TRUE)
else
- show_content(user, forcestars = 1)
- return
+ show_content(user, forcestars = TRUE)
+
+
+/obj/item/paper/attack(mob/living/carbon/human/target, mob/living/user, def_zone)
+ if(!ishuman(target))
+ return ..()
-/obj/item/paper/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(user.zone_selected == BODY_ZONE_PRECISE_EYES)
user.visible_message("[user] is trying to show the paper to you. ", \
- "You hold up a paper and try to show it to [M]. ")
+ "You hold up a paper and try to show it to [target]. ")
- if(do_mob(user, M, 0.7 SECONDS))
+ if(do_mob(user, target, 0.7 SECONDS))
user.visible_message("[user] shows the paper to you. ", \
- "You hold up a paper and show it to [M]. ")
- M.examinate(src)
+ "You hold up a paper and show it to [target]. ")
+ target.examinate(src)
else
- to_chat(user, span_warning("You fail to show the paper to [M]."))
+ to_chat(user, span_warning("You fail to show the paper to [target]."))
else if(user.zone_selected == BODY_ZONE_PRECISE_MOUTH)
- if(!istype(M, /mob)) return
-
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(H == user)
- to_chat(user, "You wipe off your face with [src].")
- H.lip_style = null
- H.lip_color = initial(H.lip_color)
- H.update_body()
- else
- user.visible_message("[user] begins to wipe [H]'s face clean with \the [src].", \
- "You begin to wipe off [H]'s face.")
- if(do_after(user, 10, target = H) && do_after(H, 10, 0)) //user needs to keep their active hand, H does not.
- user.visible_message("[user] wipes [H]'s face clean with \the [src].", \
- "You wipe off [H]'s face.")
- H.lip_style = null
- H.lip_color = initial(H.lip_color)
- H.update_body()
+ if(target == user)
+ to_chat(user, "You wipe off your face with [src].")
+ else
+ user.visible_message("[user] begins to wipe [target]'s face clean with \the [src].",
+ "You begin to wipe off [target]'s face.")
+ if(!do_after(user, 1 SECONDS, target = target) || !do_after(target, 1 SECONDS, FALSE)) // user needs to keep their active hand, target does not.
+ return
+ user.visible_message("[user] wipes [target]'s face clean with \the [src].",
+ "You wipe off [target]'s face.")
+
+ target.lip_style = null
+ target.lip_color = null
+ target.update_body()
+ else
+ return ..()
+
+
+/obj/item/paper/attack_animal(mob/living/simple_animal/pet/dog/doggo)
+ if(!isdog(doggo)) // Only dogs can eat homework.
+ return
+ doggo.changeNext_move(CLICK_CD_MELEE)
+ if(world.time < doggo.last_eaten + 30 SECONDS)
+ to_chat(doggo, "You are too full to try eating [src] now.")
+ return
+
+ doggo.visible_message("[doggo] starts chewing the corner of [src]!",
+ "You start chewing the corner of [src].",
+ "You hear a quiet gnawing, and the sound of paper rustling.")
+ playsound(src, 'sound/effects/pageturn2.ogg', 100, TRUE)
+ if(!do_after(doggo, 10 SECONDS, FALSE, src))
+ return
+
+ if(world.time < doggo.last_eaten + 30 SECONDS) // Check again to prevent eating multiple papers at once.
+ to_chat(doggo, "You are too full to try eating [src] now.")
+ return
+ doggo.last_eaten = world.time
+
+ // 90% chance of a crumpled paper with illegible text.
+ if(prob(90))
+ var/message_ending = "."
+ var/obj/item/paper/crumpled/crumped = new(loc)
+ crumped.name = name
+ if(info) // Something written on the paper.
+ crumped.info = "Whatever was once written here has been made completely illegible by a combination of chew marks and saliva."
+ message_ending = ", the drool making it an unreadable mess!"
+ crumped.update_icon()
+ qdel(src)
+
+ doggo.visible_message("[doggo] finishes eating [src][message_ending]",
+ "You finish eating [src][message_ending]")
+ doggo.emote("bark")
+
+ // 10% chance of the paper just being eaten entirely.
else
- ..()
+ doggo.visible_message("[doggo] swallows [src] whole!", "You swallow [src] whole. Tasty!")
+ playsound(doggo, 'sound/items/eatfood.ogg', 50, TRUE)
+ qdel(src)
-/obj/item/paper/proc/addtofield(var/id, var/text, var/links = 0)
+
+/obj/item/paper/proc/addtofield(id, text, links = 0)
if(id > MAX_PAPER_FIELDS)
return
@@ -192,11 +249,11 @@
while(locid <= MAX_PAPER_FIELDS)
var/istart = 0
if(links)
- istart = findtext(info_links, "", laststart)
+ istart = findtext_char(info_links, "", laststart)
else
- istart = findtext(info, "", laststart)
+ istart = findtext_char(info, "", laststart)
- if(istart==0)
+ if(!istart)
return // No field found with matching id
laststart = istart+1
@@ -204,59 +261,58 @@
if(locid == id)
var/iend = 1
if(links)
- iend = findtext(info_links, "", istart)
+ iend = findtext_char(info_links, "", istart)
else
- iend = findtext(info, "", istart)
+ iend = findtext_char(info, "", istart)
- //textindex = istart+26
textindex = iend
break
if(links)
- var/before = copytext(info_links, 1, textindex)
- var/after = copytext(info_links, textindex)
+ var/before = copytext_char(info_links, 1, textindex)
+ var/after = copytext_char(info_links, textindex)
info_links = before + text + after
else
- var/before = copytext(info, 1, textindex)
- var/after = copytext(info, textindex)
+ var/before = copytext_char(info, 1, textindex)
+ var/after = copytext_char(info, textindex)
info = before + text + after
updateinfolinks()
+
/obj/item/paper/proc/updateinfolinks()
info_links = info
- var/i = 0
- for(i=1,i<=fields,i++)
- var/write_1 = "write"
- var/write_2 = "\[A\]"
+ for(var/i in 1 to fields)
+ var/write_1 = "write"
+ var/write_2 = "\[a\]"
addtofield(i, "[write_1][write_2]", 1)
- info_links = info_links + "write"
+ info_links = info_links + "write" + "\[A\]"
/obj/item/paper/proc/clearpaper()
info = null
stamps = null
stamped = list()
- overlays.Cut()
+ stamp_overlays = null
updateinfolinks()
update_icon()
-/obj/item/paper/proc/parsepencode(var/t, var/obj/item/pen/P, mob/user as mob)
+/obj/item/paper/proc/parsepencode(t, obj/item/pen/P, mob/user as mob)
t = pencode_to_html(html_encode(t), usr, P, TRUE, TRUE, TRUE, deffont, signfont, crayonfont)
return t
/obj/item/paper/proc/populatefields()
- //Count the fields
+ //Count the fields
var/laststart = 1
while(fields < MAX_PAPER_FIELDS)
- var/i = findtext(info, "", laststart)
- if(i==0)
+ var/i = findtext_char(info, "", laststart)
+ if(!i)
break
laststart = i+1
fields++
-/obj/item/paper/proc/openhelp(mob/user as mob)
+/obj/item/paper/proc/openhelp(mob/user)
user << browse({"Pen Help
Crayon&Pen commands
@@ -281,33 +337,29 @@
\[time\] : Inserts the current station time in HH:MM:SS.
"}, "window=paper_help")
-/obj/item/paper/proc/topic_href_write(var/id, var/input_element)
+
+/obj/item/paper/proc/topic_href_write(id, input_element)
var/obj/item/item_write = usr.get_active_hand() // Check to see if he still got that darn pen, also check if he's using a crayon or pen.
add_hiddenprint(usr) // No more forging nasty documents as someone else, you jerks
- if(!istype(item_write, /obj/item/pen))
- if(!istype(item_write, /obj/item/toy/crayon))
- return
-
- // if paper is not in usr, then it must be near them, or in a clipboard or folder, which must be in or near usr
- if(src.loc != usr && !src.Adjacent(usr) && !((istype(src.loc, /obj/item/clipboard) || istype(src.loc, /obj/item/folder)) && (src.loc.loc == usr || src.loc.Adjacent(usr)) ) )
+ if(!is_pen(item_write) && !istype(item_write, /obj/item/toy/crayon))
return
+ if(loc != usr && !Adjacent(usr) && !((istype(loc, /obj/item/clipboard) || istype(loc, /obj/item/folder)) && (loc.loc == usr || loc.Adjacent(usr))))
+ return // If paper is not in usr, then it must be near them, or in a clipboard or folder, which must be in or near usr
input_element = parsepencode(input_element, item_write, usr) // Encode everything from pencode to html
- if(id!="end")
+ if(id != "end")
addtofield(text2num(id), input_element) // He wants to edit a field, let him.
else
info += input_element // Oh, he wants to edit to the end of the file, let him.
populatefields()
updateinfolinks()
-
- item_write.on_write(src,usr)
-
- show_content(usr, forceshow = 1, infolinks = 1)
-
+ item_write.on_write(src, usr)
+ show_content(usr, forceshow = TRUE, infolinks = TRUE)
update_icon()
+
/obj/item/paper/Topic(href, href_list)
..()
if(!usr || (usr.stat || usr.restrained()))
@@ -317,51 +369,66 @@
var/id = href_list["auto_write"]
var/const/sign_text = "\[Поставить подпись\]"
+ var/const/account_text = "\[Написать номер аккаунта\]"
+ var/const/pin_text = "\[Написать пин-код\]"
var/const/time_text = "\[Написать текущее время\]"
var/const/date_text = "\[Написать текущую дату\]"
- var/const/num_text = "\[Написать номер аккаунта\]"
- var/const/pin_text = "\[Написать пин-код\]"
var/const/station_text = "\[Написать название станции\]"
+ var/const/gender_text = "\[Указать пол\]"
+ var/const/species_text = "\[Указать расу\]"
+
+ var/list/menu_list = list() // text items in the menu
+
+ menu_list.Add(usr.real_name) // the real name of the character, even if it is hidden
+
+ if(usr.real_name != usr.name && lowertext(usr.name) != "unknown") // if the player is masked or the name is different a new answer option is added
+ menu_list.Add(usr.name)
+
+ if(usr.job)
+ menu_list.Add(usr.job) // job
+
+ menu_list.Add(sign_text) //signature
- //пункты текста в меню
- var/list/menu_list = list()
- menu_list.Add(usr.real_name) //настоящее имя персонажа, даже если оно спрятано
-
- //если игрок маскируется или имя отличается, добавляется новый вариант ответа
- if (usr.real_name != usr.name || usr.name != "unknown")
- menu_list.Add("[usr.name]")
-
- menu_list.Add(usr.job, //текущая работа
- num_text, //номер аккаунта
- pin_text, //номер пин-кода
- sign_text, //подпись
- time_text, //время
- date_text, //дата
- station_text, //название станции
- usr.gender, //пол
- usr.dna.species //раса
+ if(usr.mind?.initial_account?.account_number)
+ menu_list.Add(account_text) // account number
+
+ if(usr.mind?.initial_account?.remote_access_pin)
+ menu_list.Add(pin_text) // account pin-code
+
+ menu_list.Add(
+ time_text, // time
+ date_text, // date
+ station_text, // station name
+ gender_text, // gender
)
+ if(usr.dna?.species)
+ menu_list.Add(species_text) //current
+
var/input_element = input("Выберите текст который хотите добавить:", "Выбор пункта") as null|anything in menu_list
+ if(!input_element)
+ return
- //форматируем выбранные пункты меню в pencode и внутренние данные
- switch(input_element)
- if (sign_text)
+ switch(input_element) //format selected menu items in pencode and internal data
+ if(sign_text)
input_element = "\[sign\]"
- if (time_text)
+ if(time_text)
input_element = "\[time\]"
- if (date_text)
+ if(date_text)
input_element = "\[date\]"
- if (station_text)
+ if(station_text)
input_element = "\[station\]"
- if (num_text)
+ if(account_text)
input_element = usr.mind.initial_account.account_number
- if (pin_text)
+ if(pin_text)
input_element = usr.mind.initial_account.remote_access_pin
+ if(gender_text)
+ input_element = usr.gender
+ if(species_text)
+ input_element = usr.dna.species
topic_href_write(id, input_element)
-
if(href_list["write"] )
var/id = href_list["write"]
var/input_element = input("Enter what you want to write:", "Write", null, null) as message
@@ -370,14 +437,12 @@
/obj/item/paper/attackby(obj/item/P, mob/living/user, params)
- ..()
+ . = ..()
if(resistance_flags & ON_FIRE)
return
- var/clown = 0
- if(user.mind && (user.mind.assigned_role == "Clown"))
- clown = 1
+ var/clown = user.mind && (user.mind.assigned_role == "Clown")
if(istype(P, /obj/item/paper) || istype(P, /obj/item/photo))
if(istype(P, /obj/item/paper/carbon))
@@ -426,9 +491,9 @@
src.loc = B
P.loc = B
B.amount++
- B.update_icon()
+ B.update_appearance(UPDATE_ICON|UPDATE_DESC)
- else if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon))
+ else if(is_pen(P) || istype(P, /obj/item/toy/crayon))
if(user.is_literate())
var/obj/item/pen/multi/robopen/RP = P
if(istype(P, /obj/item/pen/multi/robopen) && RP.mode == 2)
@@ -452,6 +517,7 @@
stamp(P)
to_chat(user, "You stamp the paper with your rubber stamp.")
+ playsound(user, 'sound/items/handling/standard_stamp.ogg', 50, vary = TRUE)
if(is_hot(P))
if((CLUMSY in user.mutations) && prob(10))
@@ -471,12 +537,14 @@
add_fingerprint(user)
+
/obj/item/paper/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
..()
if(!(resistance_flags & FIRE_PROOF))
info = "Heat-curled corners and sooty words offer little insight. Whatever was once written on this page has been rendered illegible through fire."
-/obj/item/paper/proc/stamp(var/obj/item/stamp/S)
+
+/obj/item/paper/proc/stamp(obj/item/stamp/S)
stamps += (!stamps || stamps == "" ? " " : "") + " "
var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
@@ -501,9 +569,9 @@
if(!stamped)
stamped = new
stamped += S.type
- overlays += stampoverlay
+ stamp_overlays += stampoverlay
+ update_icon(UPDATE_OVERLAYS)
- playsound(S, pick(S.stamp_sounds), 35, 1, -1)
/*
* Premade paper
@@ -531,7 +599,7 @@
/obj/item/paper/flag
icon_state = "flag_neutral"
item_state = "paper"
- anchored = 1.0
+ anchored = TRUE
/obj/item/paper/jobs
name = "Job Information"
@@ -550,8 +618,10 @@
name = "paper scrap"
icon_state = "scrap"
-/obj/item/paper/crumpled/update_icon()
- return
+
+/obj/item/paper/crumpled/update_icon_state()
+ if(info)
+ icon_state = "scrap_words"
/obj/item/paper/crumpled/bloody
icon_state = "scrap_bloodied"
@@ -567,9 +637,10 @@
info = "[fortunemessage] "
info += "Lucky numbers: [rand(1,49)], [rand(1,49)], [rand(1,49)], [rand(1,49)], [rand(1,49)] "
-/obj/item/paper/fortune/update_icon()
- ..()
+
+/obj/item/paper/fortune/update_icon_state()
icon_state = initial(icon_state)
+
/*
* Premade paper
*/
@@ -604,7 +675,7 @@
/obj/item/paper/flag
icon_state = "flag_neutral"
item_state = "paper"
- anchored = 1.0
+ anchored = TRUE
/obj/item/paper/jobs
name = "Job Information"
@@ -659,10 +730,6 @@
name = "paper- 'Note'"
info = "The call has gone out! Our ancestral home has been rediscovered! Not a small patch of land, but a true clown nation, a true Clown Planet! We're on our way home at last!"
-/obj/item/paper/crumpled
- name = "paper scrap"
- icon_state = "scrap"
-
/obj/item/paper/syndicate
name = "paper"
header = "![](syndielogo.png)
"
@@ -677,7 +744,7 @@
name = "paper"
header = "![](ussplogo.png)
"
info = ""
- language = "Neo-Russkiya"
+ language = LANGUAGE_NEO_RUSSIAN
/obj/item/paper/solgov
name = "paper"
@@ -749,25 +816,21 @@
info = "ᅠᅠАгенство внутренних дел по надзору за домашними животными находящимися на станции сообщает, приставленный к вам питомец \"Гав Гавыч\" почил. Он верно служил ремеслу дознавателей, сыщиков и детективов. Мы будем помнить о его вкладе и сохраним о нём память в анналах истории о домашних питомцах Нанотрейзен.
"
footer = "Штампы и данные: Время принятия отчета:
*Данный документ подлежит ксерокопированию, для сохранения в архиве уполномоченных лиц, и выдаче агенту. *Данный документ может содержать личную информацию. "
-/obj/item/paper/crumpled/update_icon()
- return
-
-/obj/item/paper/crumpled/bloody
- icon_state = "scrap_bloodied"
/obj/item/paper/evilfax
name = "Centcomm Reply"
info = ""
var/mytarget = null
var/myeffect = null
- var/used = 0
+ var/used = FALSE
var/countdown = 60
- var/activate_on_timeout = 0
+ var/activate_on_timeout = FALSE
var/faxmachineid = null
-/obj/item/paper/evilfax/show_content(var/mob/user, var/forceshow = 0, var/forcestars = 0, var/infolinks = 0, var/view = 1)
+
+/obj/item/paper/evilfax/show_content(mob/user, forceshow = FALSE, forcestars = FALSE, infolinks, view = TRUE)
if(user == mytarget)
- if(istype(user, /mob/living/carbon))
+ if(iscarbon(user))
var/mob/living/carbon/C = user
evilpaper_specialaction(C)
..()
@@ -799,81 +862,85 @@
if(!countdown)
if(mytarget)
if(activate_on_timeout)
- evilpaper_specialaction(mytarget)
+ addtimer(CALLBACK(src, PROC_REF(evilpaper_specialaction), mytarget), 3 SECONDS, TIMER_DELETE_ME)
else
message_admins("[mytarget] ignored an evil fax until it timed out.")
else
message_admins("Evil paper '[src]' timed out, after not being assigned a target.")
- used = 1
+ used = TRUE
evilpaper_selfdestruct()
else
countdown--
-/obj/item/paper/evilfax/proc/evilpaper_specialaction(var/mob/living/carbon/target)
- spawn(30)
- if(istype(target, /mob/living/carbon))
- var/obj/machinery/photocopier/faxmachine/fax = locateUID(faxmachineid)
- if(myeffect == "Borgification")
- to_chat(target,"You seem to comprehend the AI a little better. Why are your muscles so stiff?")
- var/datum/disease/virus/transformation/robot/D = new
- D.Contract(target)
- else if(myeffect == "Corgification")
- to_chat(target,"You hear distant howling as the world seems to grow bigger around you. Boy, that itch sure is getting worse!")
- var/datum/disease/virus/transformation/corgi/D = new
- D.Contract(target)
- else if(myeffect == "Death By Fire")
- to_chat(target,"You feel hotter than usual. Maybe you should lowe-wait, is that your hand melting?")
- var/turf/simulated/T = get_turf(target)
- new /obj/effect/hotspot(T)
- target.adjustFireLoss(150) // hard crit, the burning takes care of the rest.
- else if(myeffect == "Total Brain Death")
- to_chat(target,"You see a message appear in front of you in bright red letters: YHWH-3 ACTIVATED. TERMINATION IN 3 SECONDS")
- target.mutations.Add(NOCLONE)
- target.adjustBrainLoss(125)
- else if(myeffect == "Honk Tumor")
- if(!target.get_int_organ(/obj/item/organ/internal/honktumor))
- var/obj/item/organ/internal/organ = new /obj/item/organ/internal/honktumor
- to_chat(target,"Life seems funnier, somehow.")
- organ.insert(target)
- else if(myeffect == "Cluwne")
- if(istype(target, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = target
- to_chat(H, "You feel surrounded by sadness. Sadness... and HONKS!")
- H.makeCluwne()
- else if(myeffect == "Demote")
- GLOB.event_announcement.Announce("[target.real_name] настоящим приказом был понижен до Гражданского. Немедленно обработайте этот запрос. Невыполнение этих распоряжений является основанием для расторжения контракта.","ВНИМАНИЕ: Приказ ЦК о понижении в должности.")
- for(var/datum/data/record/R in sortRecord(GLOB.data_core.security))
- if(R.fields["name"] == target.real_name)
- R.fields["criminal"] = SEC_RECORD_STATUS_DEMOTE
- R.fields["comments"] += "Central Command Demotion Order, given on [GLOB.current_date_string] [station_time_timestamp()] Process this demotion immediately. Failure to comply with these orders is grounds for termination."
- update_all_mob_security_hud()
- else if(myeffect == "Demote with Bot")
- GLOB.event_announcement.Announce("[target.real_name] настоящим приказом был понижен до Гражданского. Немедленно обработайте этот запрос. Невыполнение этих распоряжений является основанием для расторжения контракта.","ВНИМАНИЕ: Приказ ЦК о понижении в должности.")
- for(var/datum/data/record/R in sortRecord(GLOB.data_core.security))
- if(R.fields["name"] == target.real_name)
- R.fields["criminal"] = SEC_RECORD_STATUS_ARREST
- R.fields["comments"] += "Central Command Demotion Order, given on [GLOB.current_date_string] [station_time_timestamp()] Process this demotion immediately. Failure to comply with these orders is grounds for termination."
- update_all_mob_security_hud()
- if(fax)
- var/turf/T = get_turf(fax)
- new /obj/effect/portal(T)
- new /mob/living/simple_animal/bot/secbot(T)
- else if(myeffect == "Revoke Fax Access")
- GLOB.fax_blacklist += target.real_name
- if(fax)
- fax.authenticated = 0
- else if(myeffect == "Angry Fax Machine")
- if(fax)
- fax.become_mimic()
- else
- message_admins("Evil paper [src] was activated without a proper effect set! This is a bug.")
- used = 1
- evilpaper_selfdestruct()
+
+/obj/item/paper/evilfax/proc/evilpaper_specialaction(mob/living/carbon/target)
+ if(!iscarbon(target))
+ return
+
+ var/obj/machinery/photocopier/faxmachine/fax = locateUID(faxmachineid)
+ if(myeffect == "Borgification")
+ to_chat(target,"You seem to comprehend the AI a little better. Why are your muscles so stiff?")
+ var/datum/disease/virus/transformation/robot/D = new
+ D.Contract(target)
+ else if(myeffect == "Corgification")
+ to_chat(target,"You hear distant howling as the world seems to grow bigger around you. Boy, that itch sure is getting worse!")
+ var/datum/disease/virus/transformation/corgi/D = new
+ D.Contract(target)
+ else if(myeffect == "Death By Fire")
+ to_chat(target,"You feel hotter than usual. Maybe you should lowe-wait, is that your hand melting?")
+ var/turf/simulated/T = get_turf(target)
+ new /obj/effect/hotspot(T)
+ target.adjustFireLoss(150) // hard crit, the burning takes care of the rest.
+ else if(myeffect == "Total Brain Death")
+ to_chat(target,"You see a message appear in front of you in bright red letters: YHWH-3 ACTIVATED. TERMINATION IN 3 SECONDS")
+ target.mutations.Add(NOCLONE)
+ target.adjustBrainLoss(125)
+ else if(myeffect == "Honk Tumor")
+ if(!target.get_int_organ(/obj/item/organ/internal/honktumor))
+ new /obj/item/organ/internal/honktumor(target)
+ to_chat(target,"Life seems funnier, somehow.")
+ else if(myeffect == "Cluwne")
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ to_chat(H, "You feel surrounded by sadness. Sadness... and HONKS!")
+ H.makeCluwne()
+ else if(myeffect == "Demote")
+ GLOB.event_announcement.Announce("[target.real_name] настоящим приказом был понижен до Гражданского. Немедленно обработайте этот запрос. Невыполнение этих распоряжений является основанием для расторжения контракта.","ВНИМАНИЕ: Приказ ЦК о понижении в должности.")
+ for(var/datum/data/record/R in sortRecord(GLOB.data_core.security))
+ if(R.fields["name"] == target.real_name)
+ R.fields["criminal"] = SEC_RECORD_STATUS_DEMOTE
+ R.fields["comments"] += "Central Command Demotion Order, given on [GLOB.current_date_string] [station_time_timestamp()] Process this demotion immediately. Failure to comply with these orders is grounds for termination."
+ update_all_mob_security_hud()
+ else if(myeffect == "Demote with Bot")
+ GLOB.event_announcement.Announce("[target.real_name] настоящим приказом был понижен до Гражданского. Немедленно обработайте этот запрос. Невыполнение этих распоряжений является основанием для расторжения контракта.","ВНИМАНИЕ: Приказ ЦК о понижении в должности.")
+ for(var/datum/data/record/R in sortRecord(GLOB.data_core.security))
+ if(R.fields["name"] == target.real_name)
+ R.fields["criminal"] = SEC_RECORD_STATUS_ARREST
+ R.fields["comments"] += "Central Command Demotion Order, given on [GLOB.current_date_string] [station_time_timestamp()] Process this demotion immediately. Failure to comply with these orders is grounds for termination."
+ update_all_mob_security_hud()
+ if(fax)
+ var/turf/T = get_turf(fax)
+ new /obj/effect/portal(T)
+ new /mob/living/simple_animal/bot/secbot(T)
+ else if(myeffect == "Revoke Fax Access")
+ GLOB.fax_blacklist += target.real_name
+ if(fax)
+ fax.authenticated = FALSE
+ else if(myeffect == "Angry Fax Machine")
+ if(fax)
+ fax.become_mimic()
+ else
+ message_admins("Evil paper [src] was activated without a proper effect set! This is a bug.")
+
+ used = TRUE
+ evilpaper_selfdestruct()
+
/obj/item/paper/evilfax/proc/evilpaper_selfdestruct()
visible_message("[src] spontaneously catches fire, and burns up!")
qdel(src)
+
/obj/item/paper/pickup(user)
if(contact_poison && ishuman(user))
var/mob/living/carbon/human/H = user
@@ -1608,11 +1675,11 @@
новых проектов."
icon_state = "pamphlet"
-/obj/item/paper/deltainfo/update_icon()
+/obj/item/paper/deltainfo/update_icon_state()
return
/obj/item/paper/pamphletdeathsquad
icon_state = "pamphlet-ds"
-/obj/item/paper/pamphletdeathsquad/update_icon()
+/obj/item/paper/pamphletdeathsquad/update_icon_state()
return
diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm
index 1f9fe272072..c314d388910 100644
--- a/code/modules/paperwork/paper_bundle.dm
+++ b/code/modules/paperwork/paper_bundle.dm
@@ -14,7 +14,8 @@
attack_verb = list("bapped")
drop_sound = 'sound/items/handling/paper_drop.ogg'
pickup_sound = 'sound/items/handling/paper_pickup.ogg'
- var/amount = 0 //Amount of items clipped to the paper. Note: If you have 2 paper, this should be 1
+ var/amount = 0 //Amount of total items clipped to the paper. Note: If you have 2 paper, this should be 1
+ var/photos = 0 //Amount of photos clipped to the paper.
var/page = 1
var/screen = 0
@@ -50,6 +51,7 @@
H.update_inv_r_hand()
else if(istype(W, /obj/item/photo))
amount++
+ photos++
if(screen == 2)
screen = 1
to_chat(user, "You add [(W.name == "photo") ? "the photo" : W.name] to [(src.name == "paper bundle") ? "the paper bundle" : src.name].")
@@ -91,7 +93,7 @@
P.attackby(W, user, params)
- update_icon()
+ update_appearance(UPDATE_ICON|UPDATE_DESC)
if(winget(usr, "PaperBundle[UID()]", "is-visible") == "true") // NOT MY FAULT IT IS A BUILT IN PROC PLEASE DO NOT HIT ME
attack_self(usr) //Update the browsed page.
add_fingerprint(usr)
@@ -171,11 +173,11 @@
+ "[P.scribble ? " Written on the back: [P.scribble]" : ""]"\
+ "
|
|
|